quakec/source/server/ai/dog_core.qc

376 lines
No EOL
12 KiB
C++

/*
server/ai/dog_core.qc
dog things
Copyright (C) 2021 NZ:P Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
void() Dog_Think;
void() Dog_Death;
// DOG RUN
// 0-6
$frame dogrun1 dogrun2 dogrun3 dogrun4 dogrun5 dogrun6 dogrun7
void() dog_runanim =[ $dogrun1, dog_runanim2 ] {Dog_Think();Zombie_Walk(25);self.frame = 0;};
void() dog_runanim2 =[ $dogrun2, dog_runanim3 ] {Dog_Think();Zombie_Walk(15);self.frame = 1;};
void() dog_runanim3 =[ $dogrun3, dog_runanim4 ] {Dog_Think();Zombie_Walk(15);self.frame = 2;};
void() dog_runanim4 =[ $dogrun4, dog_runanim5 ] {Dog_Think();Zombie_Walk(15);self.frame = 3;};
void() dog_runanim5 =[ $dogrun5, dog_runanim6 ] {Dog_Think();Zombie_Walk(15);self.frame = 4;};
void() dog_runanim6 =[ $dogrun6, dog_runanim7 ] {Dog_Think();Zombie_Walk(15);self.frame = 5;};
void() dog_runanim7 =[ $dogrun7, dog_runanim ] {Dog_Think();Zombie_Walk(15);self.frame = 6;};
// DOG WALK
// 7-18
$frame dogwalk1 dogwalk2 dogwalk3 dogwalk4 dogwalk5 dogwalk6 dogwalk7 dogwalk8 dogwalk9 dogwalk10 dogwalk11 dogwalk12
void() dog_walkanim =[ $dogwalk1, dog_walkanim2 ] {Dog_Think();Zombie_Walk(8);self.frame = 7;};
void() dog_walkanim2 =[ $dogwalk2, dog_walkanim3 ] {Dog_Think();Zombie_Walk(8);self.frame = 8;};
void() dog_walkanim3 =[ $dogwalk3, dog_walkanim4 ] {Dog_Think();Zombie_Walk(8);self.frame = 9;};
void() dog_walkanim4 =[ $dogwalk4, dog_walkanim5 ] {Dog_Think();Zombie_Walk(8);self.frame = 10;};
void() dog_walkanim5 =[ $dogwalk5, dog_walkanim6 ] {Dog_Think();Zombie_Walk(8);self.frame = 11;};
void() dog_walkanim6 =[ $dogwalk6, dog_walkanim7 ] {Dog_Think();Zombie_Walk(8);self.frame = 12;};
void() dog_walkanim7 =[ $dogwalk7, dog_walkanim8 ] {Dog_Think();Zombie_Walk(8);self.frame = 13;};
void() dog_walkanim8 =[ $dogwalk8, dog_walkanim9 ] {Dog_Think();Zombie_Walk(8);self.frame = 14;};
void() dog_walkanim9 =[ $dogwalk9, dog_walkanim10 ] {Dog_Think();Zombie_Walk(8);self.frame = 15;};
void() dog_walkanim10 =[ $dogwalk10, dog_walkanim11 ] {Dog_Think();Zombie_Walk(8);self.frame = 16;};
void() dog_walkanim11 =[ $dogwalk11, dog_walkanim12 ] {Dog_Think();Zombie_Walk(8);self.frame = 17;};
void() dog_walkanim12 =[ $dogwalk12, dog_walkanim ] {Dog_Think();Zombie_Walk(8);self.frame = 18;};
// DOG IDLE
// 19-24
$frame dogstand1 dogstand2 dogstand3 dogstand4 dogstand5 dogstand6
void() dog_idleanim =[ $dogstand1, dog_idleanim2 ] {self.frame = 19;};
void() dog_idleanim2 =[ $dogstand2, dog_idleanim3 ] {self.frame = 20;};
void() dog_idleanim3 =[ $dogstand3, dog_idleanim4 ] {self.frame = 21;};
void() dog_idleanim4 =[ $dogstand4, dog_idleanim5 ] {self.frame = 22;};
void() dog_idleanim5 =[ $dogstand5, dog_idleanim6 ] {self.frame = 23;};
void() dog_idleanim6 =[ $dogstand6, dog_idleanim ] {self.frame = 24;};
// DOG MELEE
// 25-34
$frame dogmelee1 dogmelee2 dogmelee3 dogmelee4 dogmelee5 dogmelee6 dogmelee7 dogmelee8 dogmelee9 dogmelee10
void() dog_meleeanim =[ $dogmelee1, dog_meleeanim2 ] {Zombie_Walk(0);self.frame = 25;};
void() dog_meleeanim2 =[ $dogmelee2, dog_meleeanim3 ] {Zombie_Walk(0);self.frame = 26;};
void() dog_meleeanim3 =[ $dogmelee3, dog_meleeanim4 ] {Zombie_Walk(0);self.frame = 27;};
void() dog_meleeanim4 =[ $dogmelee4, dog_meleeanim5 ] {Zombie_Walk(0);self.frame = 28;};
void() dog_meleeanim5 =[ $dogmelee5, dog_meleeanim6 ] {Zombie_Walk(0);self.frame = 29;};
void() dog_meleeanim6 =[ $dogmelee6, dog_meleeanim7 ] {Zombie_Walk(0);zombie_attack2();self.frame = 30;};
void() dog_meleeanim7 =[ $dogmelee7, dog_meleeanim8 ] {Zombie_Walk(0);self.frame = 31;};
void() dog_meleeanim8 =[ $dogmelee8, dog_meleeanim9 ] {Zombie_Walk(0);self.frame = 32;};
void() dog_meleeanim9 =[ $dogmelee9, dog_meleeanim10 ] {Zombie_Walk(0);self.frame = 33;};
void() dog_meleeanim10 =[ $dogmelee10, dog_runanim ] {Zombie_Walk(0);self.frame = 34;};
// DOG DEATH
// 35 - 36
$frame dogdeath1 dogdeath2
void() dog_deathanim =[ $dogdeath1, dog_deathanim2 ] {self.frame = 35;};
void() dog_deathanim2 =[ $dogdeath2, SUB_Null ] {self.nextthink = time + 3; self.think = removeZombie; self.frame = 36;};
// DOG WAFFE DEATH
// 37-46
$frame dogwunder1 dogwunder2 dogwunder3 dogwunder4 dogwunder5 dogwunder6 dogwunder7 dogwunder8 dogwunder9 dogwunder10
void() die_dog_wunder1 =[ $dogwunder1, die_dog_wunder2 ] {Zombie_Walk(0);Zombie_Tesla_Light();self.frame = 37;};
void() die_dog_wunder2 =[ $dogwunder2, die_dog_wunder3 ] {Zombie_Walk(0);self.frame = 38;};
void() die_dog_wunder3 =[ $dogwunder3, die_dog_wunder4 ] {Zombie_Walk(0);self.frame = 39;};
void() die_dog_wunder4 =[ $dogwunder4, die_dog_wunder5 ] {Zombie_Walk(0);self.frame = 40;};
void() die_dog_wunder5 =[ $dogwunder5, die_dog_wunder6 ] {Zombie_Walk(0);self.frame = 41;};
void() die_dog_wunder6 =[ $dogwunder6, die_dog_wunder7 ] {Zombie_Walk(0);Zombie_Find_Tesla_Target();self.frame = 42;};
void() die_dog_wunder7 =[ $dogwunder7, die_dog_wunder8 ] {Zombie_Walk(0);self.frame = 43;};
void() die_dog_wunder8 =[ $dogwunder8, die_dog_wunder9 ] {Zombie_Walk(0);self.frame = 44;};
void() die_dog_wunder9 =[ $dogwunder9, die_dog_wunder10 ] {Zombie_Walk(0);self.frame = 45;};
void() die_dog_wunder10 =[ $dogwunder10, die_dog_wunder10 ] {Zombie_Walk(0);self.frame = 46;self.health = 0; self.th_die();};
// DOG LIGHTNING SPAWN
// 1-13
$frame dls1 dls2 dls3 dls4 dls5 dls6 dls7 dls8 dls9 dls10 dls11 dls12 dls13
void() dog_lightninganim =[ $dls1, dog_lightninganim2 ] {self.frame = 1;};
void() dog_lightninganim2 =[ $dls2, dog_lightninganim3 ] {self.frame = 2;};
void() dog_lightninganim3 =[ $dls3, dog_lightninganim4 ] {self.frame = 3;};
void() dog_lightninganim4 =[ $dls4, dog_lightninganim5 ] {self.frame = 4;};
void() dog_lightninganim5 =[ $dls5, dog_lightninganim6 ] {self.frame = 5;};
void() dog_lightninganim6 =[ $dls6, dog_lightninganim7 ] {self.frame = 6;};
void() dog_lightninganim7 =[ $dls7, dog_lightninganim8 ] {self.frame = 7;};
void() dog_lightninganim8 =[ $dls8, dog_lightninganim9 ] {self.frame = 8;};
void() dog_lightninganim9 =[ $dls9, dog_lightninganim10 ] {self.frame = 9;};
void() dog_lightninganim10 =[ $dls10, dog_lightninganim11 ] {self.frame = 10;};
void() dog_lightninganim11 =[ $dls11, dog_lightninganim12 ] {self.frame = 11;};
void() dog_lightninganim12 =[ $dls12, dog_lightninganim13 ] {self.frame = 12;};
void() dog_lightninganim13 =[ $dls13, SUB_Null ] {self.frame = 13; remove(self);};
// DOG EXPLODE SPRITE
// 1-5
$frame des1 des2 des3 des4 des5 des6
void() dog_explodeanim =[ $des1, dog_explodeanim2 ] {self.frame = 1;};
void() dog_explodeanim2 =[ $des2, dog_explodeanim3 ] {self.frame = 2;};
void() dog_explodeanim3 =[ $des3, dog_explodeanim4 ] {self.frame = 3;};
void() dog_explodeanim4 =[ $des4, dog_explodeanim5 ] {self.frame = 4;};
void() dog_explodeanim5 =[ $des5, dog_explodeanim6 ] {self.frame = 5;};
void() dog_explodeanim6 =[ $des5, SUB_Null ] {remove(self);};
void() Dog_Walk_Setup =
{
if (self.walktype == 1)
dog_walkanim();
else
dog_runanim();
};
// decide our walktype based on player distance
void() Dog_Think =
{
// FIXME - crash
self.walktype = 2;
/*
if(vlen(self.enemy.origin - self.origin) < 300)
self.walktype = 2;
else
self.walktype = 1;*/
}
float dogCount;
void() Dog_Death =
{
self.aistatus = "0";
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_NONE;
self.takedamage = DAMAGE_NO;
sound(self,CHAN_VOICE,"sounds/null.wav",1,ATTN_NORM);
self.usedent = world;
self.health = 0;
Remaining_Zombies = Remaining_Zombies - 1;
dogCount -= 1;
play_sound_z(3);
//Gotta' make sure we set it back down instead of glitching it up, yo'
if(self.s_time > 0 && sounds_playing > 0)
{
sounds_playing --;
self.s_time = 0;
}
if (rounds == dogRound)
{
if (!Remaining_Zombies)
Spawn_Powerup(self.origin + '0 0 12', PU_MAXAMMO);
}
float r = random();
// explode chance
if (r < 0.75 || self.electro_targeted == true) {
self.frame = 0;
setmodel (self, "models/sprites/explosion.spr");
sound (self, CHAN_VOICE, "sounds/weapons/grenade/explode.wav", 1, ATTN_NORM);
dog_explodeanim();
} else {
dog_deathanim();
}
};
void(entity where) spawn_a_dogB =
{
local entity sdog;//USED FOR WHAT TO SPAWN
sdog = getFreeZombieEnt(self);
if(sdog == world)
{
return;
}
sdog.origin = where.origin;
sdog.frame = 0;
sdog.target = where.target;
sdog.solid = SOLID_CORPSE;
sdog.movetype = MOVETYPE_WALK;
setmodel(sdog, "models/ai/dog.mdl");
sdog.hop_step = 0;
sdog.gravity = 1.0;
sdog.mins = '-8 -8 -32';//-16 16 -32
sdog.maxs = '8 8 30';//16 16 40
setsize (sdog, sdog.mins, sdog.maxs);
if(pointcontents(sdog.origin - '0 0 36') == -2)
{
while(pointcontents (sdog.origin - '0 0 36') == -2)
{
sdog.origin = sdog.origin + '0 0 1';
setorigin(sdog,sdog.origin );
}
}
sdog.classname = "ai_dog";
sdog.aistatus = "1";
setorigin (sdog.goaldummy, '0 0 0');
sdog.origin_z = sdog.origin_z + 1;
sdog.takedamage = DAMAGE_YES;
setorigin(sdog, sdog.origin);
sdog.flags = sdog.flags | FL_PARTIALGROUND | FL_MONSTER;
sdog.spawnflags = where.spawnflags;
sdog.spawnflags = sdog.spawnflags | 1;
sdog.ideal_yaw = sdog.angles_y;
sdog.yaw_speed = 20;
sdog.health = z_health;
sdog.th_die = Dog_Death;
sdog.th_walk = Dog_Walk_Setup;
sdog.outside = FALSE;
sdog.iszomb = 1;
sdog.th_melee = dog_meleeanim;
sdog.th_idle = dog_idleanim;
sdog.th_diewunder = die_dog_wunder1;
sdog.electro_targeted = 0;
SetZombieWalk(sdog);
sdog.walktype = 5;
sdog.reload_delay = 30 + time;//save floats, equals respawn time.
local entity old_self;
old_self = self;
self = sdog;
//droptofloor();
self.th_walk();
self = old_self;
};
void() dogsprite_think =
{
self.frame++;
if (self.frame >= 3)
self.frame = 0;
// suicide timer!
if(self.ltime < time) {
spawn_a_dogB(self.owner);
remove(self);
}
self.nextthink = time + 0.05;
}
void(entity where) spawn_dog_lightning =
{
local entity tempe;
local entity doglight;
local entity dogsprite;
// lightning model
doglight = spawn();
setmodel(doglight, "models/ai/dog_lightning.mdl");
setorigin(doglight, where.origin - '0 0 20');
tempe = self;
self = doglight;
dog_lightninganim();
self = tempe;
// lightning sprite
dogsprite = spawn();
setmodel(dogsprite, "models/sprites/lightning.spr");
setorigin(dogsprite, where.origin);
dogsprite.owner = where;
dogsprite.think = dogsprite_think;
dogsprite.nextthink = time + 0.05;
dogsprite.ltime = time + 1.3; // we use ltime here to be out remove timer,
// since using frames interrupts think()
}
float() spawn_a_dogA =
{
local float pcount;
local entity thing, szombie;
local float FAIL;
FAIL = false;
pcount = 0;
szombie = getFreeZombieEnt(self);
if(szombie == world || dogCount >= (2 * (player_count + 1)))
{
return 0;
}
lastspawn = find(lastspawn, classname, "spawn_dog");
while (random() < 0.4)
{
lastspawn = find(lastspawn, classname, "spawn_dog");
}
while(lastspawn)
{
thing = findradius(lastspawn.origin, 60);
while (thing)
{
pcount = 0;
if (thing.classname == "ai_dog")
{
pcount = 1;
break;
}
thing = thing.chain;
}
if (!pcount && random() < 0.6)
{
//spawn_a_dogB(lastspawn);
spawn_dog_lightning(lastspawn);
dogCount++;
spawn_delay = time + 2;
return true;
}
lastspawn = find(lastspawn, classname, "spawn_dog");
}
return 0; //no free locations fround
};
void() spawn_dog =
{
precache_model("models/ai/dog.mdl");
precache_model("models/ai/dog_lightning.mdl");
precache_model("models/sprites/lightning.spr");
precache_model("models/sprites/explosion.spr");
precache_sound("sounds/rounds/droundend.wav");
precache_sound("sounds/rounds/droundstart.wav");
setsize(self, '0 0 0', '0 0 0');
if (self.spawnflags & INACTIVE)
{
if (cvar("developer"))
setmodel(self, "models/player.mdl");
self.classname = "spawn_dog_in";
}
else
{
if (cvar("developer"))
setmodel(self, "models/ai/dog.mdl");
self.classname = "spawn_dog";
}
self.solid = SOLID_NOT;
};