QuakeC:Взрывпакет

Написано: воскресенье, 24 марта 2013 г. автор st1x51
0

Сложность: Средняя
Шаг 1
Ок, в в этом уроке мы научимся создавать Взрывпакет. Звучит внушающе, не так ли? Нельзя не согласиться! Найдите функцию Impulse Commands в файле weapons.qc. Скопируйте код, который написан ниже и добавьте импульс-команду (impulse 20), которая будет активизировать DropDetpack:
/*
============
ImpulseCommands

============
*/
void() ImpulseCommands =
{
if (self.impulse >= 1 && self.impulse <= 8) w_changeweapon ();
if (self.impulse== 9) cheatcommand ();
if (self.impulse== 10) cycleweaponcommand ();
if (self.impulse== 11) serverflagscommand ();
if (self.impulse == 20) DropDetpack (); //активизировать функцию DropDetpack, когда мы введем в консоли "impulse 20".
if (self.impulse == 255) QuadCheat ();

self.impulse = 0;
};
Шаг 2
Так, теперь нам надо добавить функцию, которую мы назовем DropDetpack, в файле weapons.qc (давайте добавим ее чуть выше блока Player Weapon Use). Вот описание этой функции:
void() DropDetpack =
{
if (self.ammo_rockets >= 25)
//Смотрим, есть ли у игрока хотя бы 25 рокет. Если есть, то...
{
self.ammo_rockets = self.ammo_rockets - 25; //забираем у него 25 рокет,

local entity item; //создаем локальный объект (пусть будет "item"),

item = spawn(); //запускаем объект "item" в игру,
item.origin = self.origin - '0 0 24'; //кладем объект "item" ниже центра игрока на 24 еденицы (т.е. под ноги игрока),

item.velocity_z = 300; //подбрасываем объект "item" на 300 едениц вверх,
item.velocity_x = -100 + (random() * 200); //а по горизонтали объект "item" полетит
item.velocity_y = -100 + (random() * 200); //в каком-нибудь случайном направлении

item.flags = FL_ITEM;
item.solid = SOLID_TRIGGER; //SOLID_TRIGGER, означает, что если кто-то коснется объекта "item",
// то активизируется некоторый триггер(его мы пропишем чуть позже).
item.movetype = MOVETYPE_TOSS; //Тип движения... эээ... броском !!
setmodel (item, "progs/backpack.mdl"); //Присваеваем объекту "item" модель "backpack", находящуюся в директории "progs/",
setsize (item, '-16 -16 0', '16 16 56'); //Задаем габариты объекта "item" ('-x -y -z' , '+x +y +z' ),
item.owner = self; //говорим объекту "item", что его выпустили мы.
item.touch = DetpackTouch; //если наш взрывпакет упал на кого-нибудь, когда мы его выкинули,
// то активируем функцию DetpackTouch

item.nextthink = time + 120; //После 2 минут переходим к функции item.think
item.think = DetpackExplode; //которая "запускает" функцию DetpackExplode
}
else //Ну, а если нету 25 рокет, то...
{
sprint (self, "You haven't enough rockets, baby.\n"); //Выводим надпись "You haven't enough rockets, baby."
return; //и возвращаемся в игру
}
};
Шаг 3
О'кей. Теперь сделаем две функции : первая - DetpackTouch, которая прикажет Взрывпакету взорваться, если на нее наступит кто-нибудь (кроме нас самих, конечно) и вторая - DetpackExplode, которая... отлично сработает, если Взрывпакет попадает на кого нибудь во время его выброса. Т.е у нас есть две причины, чтобы взорвать Взрывпакета >:)

Сейчас я опишу как это происходит:
Когда наш Взрывпакет попадает на кого-нибудь, то мы сразу взрываем его функцией DetpackExplode. Если же на Взрывпакет наступит кто-то, то мы сначала функцией DetpackTouch определяем, кто наступил на него, "мы" или "не мы", и если "не мы", то взрываем Взрывпакет функцией DetpackExplode. Т.е. в функции DetpackExplode мы нуждаемся раньше функции DetpackTouch, следовательно функция DetpackTouch должна быть ниже функции DetpackExplode.

Вот код, что мы должны написать:

void () DetpackExplode =
{
T_RadiusDamage (self, self.owner, 1000, world); //Здесь мы задаем радиус поражения, у гранат он
//равен 120, но ведь мы хотим БОЛЬШОГО ВЗРЫВА,
//и поэтому ставим 1000 !!! ;-)

//Далее указываем, что :
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); //а) объект темповый(временный),
WriteByte (MSG_BROADCAST, TE_EXPLOSION); //б) объект взрывчатый(хе-хе, а как же иначе-то?>:о).
WriteCoord (MSG_BROADCAST, self.origin_x); //создает X-координату для Backpack
WriteCoord (MSG_BROADCAST, self.origin_y); //создает Y-координату для Backpack
WriteCoord (MSG_BROADCAST, self.origin_z); //создает Z-координату для Backpack

BecomeExplosion (); //Производим ВЗРЫВ (БОЛЬШОЙ) !!!
};

void() DetpackTouch =
{
if (other == self.owner) //делаем так, чтобы detpack игнорировал нас, если он упадет на нас
{
return; //то есть возвращаемся в игру.
}
if (other.takedamage == DAMAGE_AIM) //Если игрок (кроме нас) или монстр, на которого упал наш detpack может быть поврежден,то
{
DetpackExplode(); //Производим ВЗРЫВ (см.предыдущую функцию) !!!
return; //и возвращаемся в игру.
}
if (self.velocity == '0 0 0') //если detpack уже не падает, то:
{
self.avelocity = '0 0 0'; //препятствуем "угловому движению"
}
};

Отлично... эти функции нужно добавлять ниже нашей функции DropDetpack.
Шаг 4
Последний шаг! Так, как наше дополнение использует новую модель (backpack.mdl), то нам нужно ее "подготовить". Итак, под подготовкой звуков в самом верху файла weapons.qc добавте самую нижнюю строчку примера:

precache_sound ("weapons/grenade.wav"); // звук выстрела из гранатомета
precache_sound ("weapons/bounce.wav"); // звук отскока гранаты от стены
precache_sound ("weapons/shotgn2.wav"); // звук выстрела из двустволки
precache_model ("progs/backpack.mdl"); // модель рюкзачка для DetPack

И кто тут сказал, что это трудно ?! Теперь компилируйте и посмотрите, что получилось. Во время игры наберите в консоли impulse 20 и посмотрите что получилось!!

0 коммент.: