+#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;
#ifdef IMPLEMENTATION
-#include "../../../common/monsters/spawn.qh"
-#include "../../../common/monsters/sv_monsters.qh"
+#include <common/monsters/spawn.qh>
+#include <common/monsters/sv_monsters.qh>
-#include "../../teamplay.qh"
+#include <server/teamplay.qh>
-bool g_invasion;
float autocvar_g_invasion_round_timelimit;
-int autocvar_g_invasion_teams;
-bool autocvar_g_invasion_team_spawns;
float autocvar_g_invasion_spawnpoint_spawn_delay;
-#define autocvar_g_invasion_point_limit cvar("g_invasion_point_limit")
float autocvar_g_invasion_warmup;
int autocvar_g_invasion_monster_count;
bool autocvar_g_invasion_zombies_only;
spawnfunc(invasion_spawnpoint)
{
- if(!g_invasion) { remove(self); return; }
+ if(!g_invasion) { remove(this); return; }
- self.classname = "invasion_spawnpoint";
+ this.classname = "invasion_spawnpoint";
if(autocvar_g_invasion_zombies_only) // precache only if it hasn't been already
- if(self.monsterid) {
- Monster mon = get_monsterinfo(self.monsterid);
+ if(this.monsterid) {
+ Monster mon = get_monsterinfo(this.monsterid);
mon.mr_precache(mon);
}
}
monster = spawnmonster("", mon, world, world, e.origin, false, false, 2);
else return;
- e.think = SUB_Remove;
+ setthink(e, SUB_Remove);
e.nextthink = time + 0.1;
}
else
float Invasion_CheckWinner()
{
- entity head;
if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
{
- FOR_EACH_MONSTER(head)
- Monster_Remove(head);
+ FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, LAMBDA(Monster_Remove(it)));
Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_OVER);
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_OVER);
float total_alive_monsters = 0, supermonster_count = 0, red_alive = 0, blue_alive = 0, yellow_alive = 0, pink_alive = 0;
- FOR_EACH_MONSTER(head) if(head.health > 0)
- {
- if((get_monsterinfo(head.monsterid)).spawnflags & MON_FLAG_SUPERMONSTER)
- ++supermonster_count;
- ++total_alive_monsters;
-
- if(teamplay)
- switch(head.team)
+ FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, LAMBDA(
+ if(it.health > 0)
{
- case NUM_TEAM_1: ++red_alive; break;
- case NUM_TEAM_2: ++blue_alive; break;
- case NUM_TEAM_3: ++yellow_alive; break;
- case NUM_TEAM_4: ++pink_alive; break;
+ if((get_monsterinfo(it.monsterid)).spawnflags & MON_FLAG_SUPERMONSTER)
+ ++supermonster_count;
+ ++total_alive_monsters;
+
+ if(teamplay)
+ switch(it.team)
+ {
+ case NUM_TEAM_1: ++red_alive; break;
+ case NUM_TEAM_2: ++blue_alive; break;
+ case NUM_TEAM_3: ++yellow_alive; break;
+ case NUM_TEAM_4: ++pink_alive; break;
+ }
}
- }
+ ));
if((total_alive_monsters + inv_numkilled) < inv_maxspawned && inv_maxcurrent < inv_maxspawned)
{
else { winner_team = NUM_TEAM_4; }
}
else
- FOR_EACH_PLAYER(head)
{
- float cs = PlayerScore_Add(head, SP_KILLS, 0);
- if(cs > winning_score)
- {
- winning_score = cs;
- winner = head;
- }
+ FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(
+ float cs = PlayerScore_Add(it, SP_KILLS, 0);
+ if(cs > winning_score)
+ {
+ winning_score = cs;
+ winner = it;
+ }
+ ));
}
- FOR_EACH_MONSTER(head)
- Monster_Remove(head);
+ FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, LAMBDA(Monster_Remove(it)));
if(teamplay)
{
if(winner_team)
{
- Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner_team, CENTER_ROUND_TEAM_WIN_));
- Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner_team, INFO_ROUND_TEAM_WIN_));
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN));
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN));
}
}
else if(winner)
return 1;
}
-float Invasion_CheckPlayers()
+bool Invasion_CheckPlayers()
{
return true;
}
void Invasion_RoundStart()
{
- entity e;
- float numplayers = 0;
- FOR_EACH_PLAYER(e)
- {
- e.player_blocked = 0;
+ int numplayers = 0;
+ FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(
+ it.player_blocked = false;
++numplayers;
- }
+ ));
if(inv_roundcnt < inv_maxrounds)
inv_roundcnt += 1; // a limiter to stop crazy counts
}
MUTATOR_HOOKFUNCTION(inv, MonsterDies)
-{SELFPARAM();
- if(!(self.spawnflags & MONSTERFLAG_RESPAWNED))
+{
+ if(!(frag_target.spawnflags & MONSTERFLAG_RESPAWNED))
{
inv_numkilled += 1;
inv_maxcurrent -= 1;
- if(teamplay) { inv_monsters_perteam[self.team] -= 1; }
+ if(teamplay) { inv_monsters_perteam[frag_target.team] -= 1; }
if(IS_PLAYER(frag_attacker))
- if(SAME_TEAM(frag_attacker, self)) // in non-teamplay modes, same team = same player, so this works
+ if(SAME_TEAM(frag_attacker, frag_target)) // in non-teamplay modes, same team = same player, so this works
PlayerScore_Add(frag_attacker, SP_KILLS, -1);
else
{
ScoreRules_basics_end();
}
-void invasion_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
+void invasion_DelayedInit(entity this) // Do this check with a delay so we can wait for teams to be set up.
{
if(autocvar_g_invasion_teams)
invasion_teams = bound(2, autocvar_g_invasion_teams, 4);
InitializeEntity(world, invasion_DelayedInit, INITPRIO_GAMETYPE);
}
-REGISTER_MUTATOR(inv, IS_GAMETYPE(INVASION))
-{
- SetLimits(autocvar_g_invasion_point_limit, -1, -1, -1);
- if(autocvar_g_invasion_teams >= 2)
- {
- ActivateTeamplay();
- if(autocvar_g_invasion_team_spawns)
- have_team_spawns = -1; // request team spawns
- }
-
- 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");
- }
-
- 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;
-}
#endif