From 155668ad2440426923ac70c306b84c2d27a5bb28 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 17 May 2017 21:09:18 +1000 Subject: [PATCH] Use an intrusive list for monster targets instead of findradius, allows crouching to lower target range --- qcsrc/common/monsters/sv_monsters.qc | 36 ++++++++++++------- qcsrc/common/triggers/func/breakable.qc | 4 +++ qcsrc/server/client.qc | 2 ++ qcsrc/server/defs.qh | 3 ++ .../mutators/mutator/gamemode_invasion.qc | 2 ++ 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc index c2320b5cb6..fe17ee8711 100644 --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@ -125,21 +125,27 @@ entity Monster_FindTarget(entity this) vector my_center = CENTER_OR_VIEWOFS(this); // find the closest acceptable target to pass to - FOREACH_ENTITY_RADIUS(this.origin, this.target_range, it.monster_attack, + IL_EACH(g_monster_targets, it.monster_attack, { - if(Monster_ValidTarget(this, it)) - { - // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc) - vector targ_center = CENTER_OR_VIEWOFS(it); + float trange = this.target_range; + if(PHYS_INPUT_BUTTON_CROUCH(it)) + trange *= 0.75; // TODO cvar this + vector theirmid = (it.absmin + it.absmax) * 0.5; + if(vdist(theirmid - this.origin, >, trange)) + continue; + if(!Monster_ValidTarget(this, it)) + continue; - if(closest_target) - { - vector closest_target_center = CENTER_OR_VIEWOFS(closest_target); - if(vlen2(my_center - targ_center) < vlen2(my_center - closest_target_center)) - { closest_target = it; } - } - else { closest_target = it; } + // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc) + vector targ_center = CENTER_OR_VIEWOFS(it); + + if(closest_target) + { + vector closest_target_center = CENTER_OR_VIEWOFS(closest_target); + if(vlen2(my_center - targ_center) < vlen2(my_center - closest_target_center)) + { closest_target = it; } } + else { closest_target = it; } }); return closest_target; @@ -178,6 +184,8 @@ void monster_changeteam(entity this, int newteam) if(!teamplay) { return; } this.team = newteam; + if(!this.monster_attack) + IL_PUSH(g_monster_targets, this); this.monster_attack = true; // new team, activate attacking monster_setupcolors(this); @@ -1266,7 +1274,11 @@ bool Monster_Spawn_Setup(entity this) Monster_Sounds_Update(this); if(teamplay) + { + if(!this.monster_attack) + IL_PUSH(g_monster_targets, this); this.monster_attack = true; // we can have monster enemies in team games + } Monster_Sound(this, monstersound_spawn, 0, false, CH_VOICE); diff --git a/qcsrc/common/triggers/func/breakable.qc b/qcsrc/common/triggers/func/breakable.qc index dc2e6f7dc0..59a5fbc3c6 100644 --- a/qcsrc/common/triggers/func/breakable.qc +++ b/qcsrc/common/triggers/func/breakable.qc @@ -339,6 +339,7 @@ spawnfunc(func_breakable) this.takedamage = DAMAGE_NO; this.event_damage = func_null; this.bot_attack = false; + this.monster_attack = false; } // precache all the models @@ -358,6 +359,9 @@ spawnfunc(func_breakable) this.reset = func_breakable_reset; this.reset(this); + if(this.monster_attack) + IL_PUSH(g_monster_targets, this); + IL_PUSH(g_initforplayer, this); this.init_for_player = func_breakable_init_for_player; diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index 95f2875271..2b42f9dcf2 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -658,6 +658,8 @@ void PutClientInServer(entity this) if(!this.bot_attack) IL_PUSH(g_bot_targets, this); this.bot_attack = true; + if(!this.monster_attack) + IL_PUSH(g_monster_targets, this); this.monster_attack = true; navigation_dynamicgoal_init(this, false); diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index e210151dce..9fc2c60591 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -467,3 +467,6 @@ STATIC_INIT(g_bot_dodge) { g_bot_dodge = IL_NEW(); } IntrusiveList g_damagedbycontents; STATIC_INIT(g_damagedbycontents) { g_damagedbycontents = IL_NEW(); } + +IntrusiveList g_monster_targets; +STATIC_INIT(g_monster_targets) { g_monster_targets = IL_NEW(); } diff --git a/qcsrc/server/mutators/mutator/gamemode_invasion.qc b/qcsrc/server/mutators/mutator/gamemode_invasion.qc index 1355134bb1..74955ecf0e 100644 --- a/qcsrc/server/mutators/mutator/gamemode_invasion.qc +++ b/qcsrc/server/mutators/mutator/gamemode_invasion.qc @@ -156,6 +156,8 @@ void invasion_SpawnChosenMonster(Monster mon) } } + if(monster.monster_attack) + IL_REMOVE(g_monster_targets, monster); monster.monster_attack = false; // it's the player's job to kill all the monsters if(inv_roundcnt >= inv_maxrounds) -- 2.39.2