#include "gamemode_invasion.qh"
-#ifndef GAMEMODE_INVASION_H
-#define GAMEMODE_INVASION_H
-#define autocvar_g_invasion_point_limit cvar("g_invasion_point_limit")
-int autocvar_g_invasion_teams;
-bool autocvar_g_invasion_team_spawns;
-bool g_invasion;
-void invasion_Initialize();
-
-REGISTER_MUTATOR(inv, false)
-{
- MUTATOR_ONADD
- {
- if (time > 1) // game loads at time 1
- error("This is a game type and it cannot be added at runtime.");
- g_invasion = true;
- invasion_Initialize();
-
- cvar_settemp("g_monsters", "1");
-
- SetLimits(autocvar_g_invasion_point_limit, autocvar_leadlimit_override, autocvar_timelimit_override, -1);
- if (autocvar_g_invasion_teams >= 2)
- {
- ActivateTeamplay();
- if (autocvar_g_invasion_team_spawns)
- have_team_spawns = -1; // request team spawns
- }
- }
-
- MUTATOR_ONROLLBACK_OR_REMOVE
- {
- // we actually cannot roll back invasion_Initialize here
- // BUT: we don't need to! If this gets called, adding always
- // succeeds.
- }
-
- MUTATOR_ONREMOVE
- {
- LOG_INFO("This is a game type and it cannot be removed at runtime.");
- return -1;
- }
-
- return 0;
-}
-
-float inv_numspawned;
-float inv_maxspawned;
-float inv_roundcnt;
-float inv_maxrounds;
-float inv_numkilled;
-float inv_lastcheck;
-float inv_maxcurrent;
-
-float invasion_teams;
-float inv_monsters_perteam[17];
-
-float inv_monsterskill;
-
-const float ST_INV_KILLS = 1;
-#endif
-
-#ifdef IMPLEMENTATION
-
-#include <common/monsters/spawn.qh>
+#include <common/monsters/sv_spawn.qh>
#include <common/monsters/sv_monsters.qh>
#include <server/teamplay.qh>
+IntrusiveList g_invasion_spawns;
+STATIC_INIT(g_invasion_spawns) { g_invasion_spawns = IL_NEW(); }
float autocvar_g_invasion_round_timelimit;
float autocvar_g_invasion_spawnpoint_spawn_delay;
if(!g_invasion) { delete(this); return; }
this.classname = "invasion_spawnpoint";
+ IL_PUSH(g_invasion_spawns, this);
if(autocvar_g_invasion_zombies_only) // precache only if it hasn't been already
if(this.monsterid) {
}
}
-float invasion_PickMonster(float supermonster_count)
+int invasion_PickMonster(int supermonster_count)
{
if(autocvar_g_invasion_zombies_only)
return MON_ZOMBIE.monsterid;
- float i;
- entity mon;
-
RandomSelection_Init();
- for(i = MON_FIRST; i <= MON_LAST; ++i)
+ FOREACH(Monsters, it != MON_Null,
{
- mon = get_monsterinfo(i);
- if((mon.spawnflags & MONSTER_TYPE_FLY) || (mon.spawnflags & MONSTER_TYPE_SWIM) || ((mon.spawnflags & MON_FLAG_SUPERMONSTER) && supermonster_count >= 1))
- continue; // flying/swimming monsters not yet supported
-
- RandomSelection_Add(NULL, i, string_null, 1, 1);
- }
+ if((it.spawnflags & MONSTER_TYPE_FLY) || (it.spawnflags & MONSTER_TYPE_SWIM) || (it.spawnflags & MONSTER_SIZE_QUAKE) || ((it.spawnflags & MON_FLAG_SUPERMONSTER) && supermonster_count >= 1))
+ continue;
+ RandomSelection_Add(NULL, it.monsterid, string_null, 1, 1);
+ });
return RandomSelection_chosen_float;
}
{
RandomSelection_Init();
- FOREACH_ENTITY_CLASS("invasion_spawnpoint", true,
+ IL_EACH(g_invasion_spawns, true,
{
RandomSelection_Add(it, 0, string_null, 1, ((time >= it.spawnshieldtime) ? 0.2 : 1)); // give recently used spawnpoints a very low rating
it.spawnshieldtime = time + autocvar_g_invasion_spawnpoint_spawn_delay;
monster.spawnflags |= MONSTERFLAG_MINIBOSS; // last round spawns minibosses
}
-void invasion_SpawnMonsters(float supermonster_count)
+void invasion_SpawnMonsters(int supermonster_count)
{
- float chosen_monster = invasion_PickMonster(supermonster_count);
+ int chosen_monster = invasion_PickMonster(supermonster_count);
invasion_SpawnChosenMonster(chosen_monster);
}
-float Invasion_CheckWinner()
+bool Invasion_CheckWinner()
{
if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
{
{
entity player = M_ARGV(0, entity);
+ if(player.bot_attack)
+ IL_REMOVE(g_bot_targets, player);
player.bot_attack = false;
}
InitializeEntity(NULL, invasion_DelayedInit, INITPRIO_GAMETYPE);
}
-
-#endif