From a2d1078ec3c98a803290f846f9b25d8a9533162f Mon Sep 17 00:00:00 2001 From: cypress Date: Tue, 21 Nov 2023 12:18:38 -0500 Subject: [PATCH] SERVER: Give dogs unique enemy targeting --- source/server/ai/ai_core.qc | 26 +++++++++++----- source/server/ai/dog_core.qc | 59 ++++++++++++++++++++++++++++++------ source/server/defs/custom.qc | 2 ++ 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/source/server/ai/ai_core.qc b/source/server/ai/ai_core.qc index 9d3213c..df4baf3 100644 --- a/source/server/ai/ai_core.qc +++ b/source/server/ai/ai_core.qc @@ -27,6 +27,7 @@ void(float what) play_sound_z; void() LinkZombiesHitbox; +entity() Dog_FindEnemy; void() path_corner_touch = { @@ -657,11 +658,18 @@ inline float(vector start, vector min, vector max, vector end, float nomonsters, #endif // FTE void(float dist) Inside_Walk = { - if(self.enemy_timeout < time || self.enemy == world || self.enemy.downed == true) { - self.enemy_timeout = time + 5; - local entity oldEnemy; - oldEnemy = self.enemy; - self.enemy = find_new_enemy(self); + // Hellhounds should only change targets if current one is in Last Stand + if (self.classname == "ai_dog" && self.enemy.downed == true) { + self.enemy = Dog_FindEnemy(); + } + // Normal Zombie time-out re-targeting + else if (self.classname != "ai_dog") { + if(self.enemy_timeout < time || self.enemy == world || self.enemy.downed == true) { + self.enemy_timeout = time + 5; + local entity oldEnemy; + oldEnemy = self.enemy; + self.enemy = find_new_enemy(self); + } } //================Check for proximity to player =========== if(vlen(self.enemy.origin - self.origin) < 60) { @@ -675,8 +683,12 @@ void(float dist) Inside_Walk = { if (self.enemy.health) self.th_melee(); - if (self.enemy.downed == true) - self.enemy = find_new_enemy(self); + if (self.enemy.downed == true) { + if (self.classname == "ai_dog") + self.enemy = Dog_FindEnemy(); + else + self.enemy = find_new_enemy(self); + } self.goalentity = self.enemy; self.chase_time = time + 5; } diff --git a/source/server/ai/dog_core.qc b/source/server/ai/dog_core.qc index 42db586..a1f19aa 100644 --- a/source/server/ai/dog_core.qc +++ b/source/server/ai/dog_core.qc @@ -33,27 +33,27 @@ void() Dog_Death; $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_runanim3 =[ $dogrun3, dog_runanim4 ] {Dog_Think();Zombie_Walk(15);self.frame = 2;zombie_footstep();}; 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;}; +void() dog_runanim7 =[ $dogrun7, Dog_Walk_Setup ] {Dog_Think();Zombie_Walk(15);self.frame = 6;zombie_footstep();}; // 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_walkanim2 =[ $dogwalk2, dog_walkanim3 ] {Dog_Think();Zombie_Walk(8);self.frame = 8;zombie_footstep();}; 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_walkanim7 =[ $dogwalk7, dog_walkanim8 ] {Dog_Think();Zombie_Walk(8);self.frame = 13;zombie_footstep();}; 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;}; +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_Walk_Setup ] {Dog_Think();Zombie_Walk(8);self.frame = 18;}; // DOG IDLE // 19-24 @@ -124,7 +124,7 @@ void() Dog_Walk_Setup = // decide our walktype based on player distance void() Dog_Think = { - if(vlen(self.enemy.origin - self.origin) < 300) + if(vlen(self.enemy.origin - self.origin) < 200) self.walktype = 2; else self.walktype = 1; @@ -205,7 +205,48 @@ void() Dog_Death_Tesla = { dog_die_wunder1(); }; +// +// Dog_FindEnemy() +// Hellhounds are assigned an enemy at start, +// based on how many Hounds are stalking each +// player already. +// +entity() Dog_FindEnemy = +{ + entity least_targeted_player = world; + // Assume that if this is being called again, stop hunting + // currently selected client + if (self.enemy != world) + self.enemy.hunt_count--; + + // Grab every player in the World + entity players = find(world, classname, "player"); + while(players != world) { + // Don't target players in Last Stand + if (!players.downed) { + // Init least_targeted_player + if (least_targeted_player == world) + least_targeted_player = players; + + // This player has less dogs following them than the last, + // make this our new golden goose. + if (players.hunt_count < least_targeted_player.hunt_count) + least_targeted_player = players; + } + + players = find(players, classname, "player"); + } + + // Return the player we found + if (least_targeted_player != world) { + least_targeted_player.hunt_count++; + return least_targeted_player; + } + + // Couldn't find a player, go lurk at a spawn point + return find(world, classname, "info_player_1_spawn"); +} void(entity where) spawn_a_dogB = { @@ -263,11 +304,11 @@ void(entity where) spawn_a_dogB = sdog.th_melee = dog_meleeanim; sdog.th_idle = dog_idleanim; sdog.th_diewunder = Dog_Death_Tesla; + sdog.enemy = Dog_FindEnemy(); sdog.electro_targeted = 0; SetZombieWalk(sdog); - sdog.walktype = 5; sdog.reload_delay = 30 + time;//save floats, equals respawn time. local entity old_self; diff --git a/source/server/defs/custom.qc b/source/server/defs/custom.qc index 845ce2a..fc37ea4 100644 --- a/source/server/defs/custom.qc +++ b/source/server/defs/custom.qc @@ -147,6 +147,8 @@ void() W_SprintStop; .float dive_delay; .vector movement; +.float hunt_count; // How many Hellhounds are hunting a client + //Weaponsystem defines void SwitchWeapon(float to); void GetUp();