]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Use an intrusive list for monster targets instead of findradius, allows crouching...
authorMario <mario@smbclan.net>
Wed, 17 May 2017 11:09:18 +0000 (21:09 +1000)
committerMario <mario@smbclan.net>
Wed, 17 May 2017 11:09:18 +0000 (21:09 +1000)
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/triggers/func/breakable.qc
qcsrc/server/client.qc
qcsrc/server/defs.qh
qcsrc/server/mutators/mutator/gamemode_invasion.qc

index c2320b5cb6629d9b2d13fa7f013c25acca54694d..fe17ee871157f9a6e164db637a515e32bedfb0cd 100644 (file)
@@ -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);
 
index dc2e6f7dc0a062a2a19e8c2a611ee12b8cb14ea2..59a5fbc3c6061379c3584ee39ceca4758d0b7927 100644 (file)
@@ -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;
 
index 95f28752714a9c322ebfb08ba67cf0ffbcb930e6..2b42f9dcf236beae18760c9a9c1edc487c9bd332 100644 (file)
@@ -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);
 
index e210151dce99f3a6e8a5cb1dd9531ebc489c51c1..9fc2c60591d35b2f63167fa454146570a6b55d17 100644 (file)
@@ -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(); }
index 1355134bb1e92ed923ff0cb3fa265490c3fd4d9f..74955ecf0e3c087e96b4fa6661960185f31f7471 100644 (file)
@@ -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)