From 8b168a411c49c503a047237b82b6869cf8068857 Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 14 Jan 2017 00:12:02 +1000 Subject: [PATCH] Fix monsters not attacking some targets, also fix monster paths --- qcsrc/common/monsters/sv_monsters.qc | 12 +-- qcsrc/server/mutators/events.qh | 1 + .../mutators/mutator/gamemode_invasion.qc | 78 +++++++++++++++---- 3 files changed, 69 insertions(+), 22 deletions(-) diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc index 8456e7a64..3e90b07e4 100644 --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@ -99,9 +99,10 @@ bool Monster_ValidTarget(entity this, entity targ) return false; } - traceline(this.origin + this.view_ofs, targ.origin, MOVE_NOMONSTERS, this); + vector targ_origin = ((targ.absmin + targ.absmax) * 0.5); + traceline(this.origin + this.view_ofs, targ_origin, MOVE_NOMONSTERS, this); - if(trace_fraction < 1) + if(trace_fraction < 1 && trace_ent != targ) return false; // solid if(autocvar_g_monsters_target_infront || (this.spawnflags & MONSTERFLAG_INFRONT)) @@ -693,7 +694,8 @@ void Monster_CalculateVelocity(entity this, vector to, vector from, float turnra void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed) { // update goal entity if lost - if(this.target2 && this.goalentity.targetname != this.target2) { this.goalentity = find(NULL, targetname, this.target2); } + if(this.target2 && this.target2 != "" && this.goalentity.targetname != this.target2) + this.goalentity = find(NULL, targetname, this.target2); if(STAT(FROZEN, this) == 2) { @@ -866,9 +868,9 @@ void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed) else { entity e = this.goalentity; //find(NULL, targetname, this.target2); - if(e.target2) + if(e.target2 && e.target2 != "") this.target2 = e.target2; - else if(e.target) // compatibility + else if(e.target && e.target != "") // compatibility this.target2 = e.target; movelib_brake_simple(this, stpspeed); diff --git a/qcsrc/server/mutators/events.qh b/qcsrc/server/mutators/events.qh index ebe03df12..2d32dc966 100644 --- a/qcsrc/server/mutators/events.qh +++ b/qcsrc/server/mutators/events.qh @@ -308,6 +308,7 @@ MUTATOR_HOOKABLE(MonsterDropItem, EV_MonsterDropItem); /** walk speed */ i(float, MUTATOR_ARGV_2_float) \ /**/ o(float, MUTATOR_ARGV_2_float) \ /** move target */ i(entity, MUTATOR_ARGV_3_entity) \ + /**/ o(entity, MUTATOR_ARGV_3_entity) \ /**/ MUTATOR_HOOKABLE(MonsterMove, EV_MonsterMove); diff --git a/qcsrc/server/mutators/mutator/gamemode_invasion.qc b/qcsrc/server/mutators/mutator/gamemode_invasion.qc index e62a392ce..1355134bb 100644 --- a/qcsrc/server/mutators/mutator/gamemode_invasion.qc +++ b/qcsrc/server/mutators/mutator/gamemode_invasion.qc @@ -5,6 +5,9 @@ #include +IntrusiveList g_invasion_waves; +STATIC_INIT(g_invasion_waves) { g_invasion_waves = IL_NEW(); } + IntrusiveList g_invasion_spawns; STATIC_INIT(g_invasion_spawns) { g_invasion_spawns = IL_NEW(); } @@ -17,6 +20,13 @@ float autocvar_g_invasion_spawn_delay; .string spawnmob; +spawnfunc(invasion_wave) +{ + if(!g_invasion) { delete(this); return; } + + IL_PUSH(g_invasion_waves, this); +} + spawnfunc(invasion_spawnpoint) { if(!g_invasion) { delete(this); return; } @@ -55,11 +65,41 @@ entity invasion_PickSpawn() return RandomSelection_chosen_ent; } +entity invasion_GetWaveEntity(int wavenum) +{ + IL_EACH(g_invasion_waves, it.cnt == wavenum, + { + return it; // found one + }); + + // if no specific one is found, find the last existing wave ent + entity best = NULL; + IL_EACH(g_invasion_waves, it.cnt <= wavenum, + { + if(!best || it.cnt > best.cnt) + best = it; + }); + + return best; +} + void invasion_SpawnChosenMonster(Monster mon) { - entity spawn_point, monster; + entity monster; + entity spawn_point = invasion_PickSpawn(); + entity wave_ent = invasion_GetWaveEntity(inv_roundcnt); - spawn_point = invasion_PickSpawn(); + string tospawn = ""; + if(wave_ent && wave_ent.spawnmob && wave_ent.spawnmob != "") + { + RandomSelection_Init(); + FOREACH_WORD(wave_ent.spawnmob, true, + { + RandomSelection_AddString(it, 1, 1); + }); + + tospawn = RandomSelection_chosen_string; + } if(spawn_point == NULL) { @@ -68,7 +108,7 @@ void invasion_SpawnChosenMonster(Monster mon) setsize(e, mon.mins, mon.maxs); if(MoveToRandomMapLocation(e, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256)) - monster = spawnmonster(e, "", mon.monsterid, NULL, NULL, e.origin, false, false, 2); + monster = spawnmonster(e, tospawn, mon.monsterid, NULL, NULL, e.origin, false, false, 2); else { delete(e); @@ -76,31 +116,35 @@ void invasion_SpawnChosenMonster(Monster mon) } } else // if spawnmob field falls through (unset), fallback to mon (relying on spawnmonster for that behaviour) - monster = spawnmonster(spawn(), spawn_point.spawnmob, mon.monsterid, spawn_point, spawn_point, spawn_point.origin, false, false, 2); + monster = spawnmonster(spawn(), ((spawn_point.spawnmob && spawn_point.spawnmob != "") ? spawn_point.spawnmob : tospawn), mon.monsterid, spawn_point, spawn_point, spawn_point.origin, false, false, 2); if(!monster) return; - if(spawn_point) monster.target2 = spawn_point.target2; monster.spawnshieldtime = time; - if(spawn_point && spawn_point.target_range) monster.target_range = spawn_point.target_range; - if(teamplay) - if(spawn_point && spawn_point.team && inv_monsters_perteam[spawn_point.team] > 0) - monster.team = spawn_point.team; - else + if(spawn_point) { - RandomSelection_Init(); - if(inv_monsters_perteam[NUM_TEAM_1] > 0) RandomSelection_AddFloat(NUM_TEAM_1, 1, 1); - if(inv_monsters_perteam[NUM_TEAM_2] > 0) RandomSelection_AddFloat(NUM_TEAM_2, 1, 1); - if(invasion_teams >= 3) if(inv_monsters_perteam[NUM_TEAM_3] > 0) { RandomSelection_AddFloat(NUM_TEAM_3, 1, 1); } - if(invasion_teams >= 4) if(inv_monsters_perteam[NUM_TEAM_4] > 0) { RandomSelection_AddFloat(NUM_TEAM_4, 1, 1); } - - monster.team = RandomSelection_chosen_float; + if(spawn_point.target_range) + monster.target_range = spawn_point.target_range; + monster.target2 = spawn_point.target2; } if(teamplay) { + if(spawn_point && spawn_point.team && inv_monsters_perteam[spawn_point.team] > 0) + monster.team = spawn_point.team; + else + { + RandomSelection_Init(); + if(inv_monsters_perteam[NUM_TEAM_1] > 0) RandomSelection_AddFloat(NUM_TEAM_1, 1, 1); + if(inv_monsters_perteam[NUM_TEAM_2] > 0) RandomSelection_AddFloat(NUM_TEAM_2, 1, 1); + if(invasion_teams >= 3) if(inv_monsters_perteam[NUM_TEAM_3] > 0) { RandomSelection_AddFloat(NUM_TEAM_3, 1, 1); } + if(invasion_teams >= 4) if(inv_monsters_perteam[NUM_TEAM_4] > 0) { RandomSelection_AddFloat(NUM_TEAM_4, 1, 1); } + + monster.team = RandomSelection_chosen_float; + } + monster_setupcolors(monster); if(monster.sprite) -- 2.39.2