From: bones_was_here Date: Tue, 12 Mar 2024 21:26:04 +0000 (+1000) Subject: monsters: improve following and wandering behaviour X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=edb94f749377cdb6de202153af30b742b3b3af42;p=xonotic%2Fxonotic-data.pk3dir.git monsters: improve following and wandering behaviour Makes monsters wander around the player they're following when nearby, and wander towards the player using the follow update interval when further away. This prevents them clustering tightly around the player and increases their chance of overcoming trivial obstacles. Fixes trying to walk into walls. --- diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc index 7f00250fb..d516aec2c 100644 --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@ -575,6 +575,27 @@ void Monster_Use(entity this, entity actor, entity trigger) if(Monster_ValidTarget(this, actor, true)) { this.enemy = actor; } } +/// Returns an origin that's near targetorigin and visible to this monster. +vector Monster_WanderTarget(entity this, vector targetorigin) +{ + vector pos, ang; + + ang_y = rint(random() * 500); + ang_x = this.angles_x; + ang_z = this.angles_z; + makevectors(ang); + pos = targetorigin + v_forward * this.wander_distance; + if(((this.flags & FL_FLY) && (this.spawnflags & MONSTERFLAG_FLY_VERTICAL)) || (this.flags & FL_SWIM)) + { + pos.z = random() * 200; + if(random() >= 0.5) + pos.z *= -1; + } + // truncate movement so we don't do walking into walls animations + traceline(this.origin + this.view_ofs, pos, MOVE_NORMAL, this); + return trace_endpos; +} + vector Monster_Move_Target(entity this, entity targ) { // enemy is always preferred target @@ -610,7 +631,14 @@ vector Monster_Move_Target(entity this, entity targ) { this.monster_movestate = MONSTER_MOVE_FOLLOW; this.last_trace = time + 0.3; - return (this.monster_follow) ? this.monster_follow.origin : this.origin; + if (this.monster_follow) + { + if (vdist(this.origin - this.monster_follow.origin, <, this.wander_distance)) + this.last_trace = time + this.wander_delay; + return Monster_WanderTarget(this, this.monster_follow.origin); + } + else + return this.origin; } case MONSTER_MOVE_SPAWNLOC: { @@ -635,36 +663,22 @@ vector Monster_Move_Target(entity this, entity targ) default: case MONSTER_MOVE_WANDER: { - vector pos; this.monster_movestate = MONSTER_MOVE_WANDER; - if(this.monster_moveto) { this.last_trace = time + 0.5; - pos = this.monster_moveto; + return this.monster_moveto; } else if(targ) { this.last_trace = time + 0.5; - pos = targ.origin; + return targ.origin; } else { this.last_trace = time + this.wander_delay; - - this.angles_y = rint(random() * 500); - makevectors(this.angles); - pos = this.origin + v_forward * this.wander_distance; - - if(((this.flags & FL_FLY) && (this.spawnflags & MONSTERFLAG_FLY_VERTICAL)) || (this.flags & FL_SWIM)) - { - pos.z = random() * 200; - if(random() >= 0.5) - pos.z *= -1; - } + return Monster_WanderTarget(this, this.origin); } - - return pos; } } }