#include "gamemode_invasion.qh"
-#include "../_all.qh"
#include "gamemode.qh"
#include "../../common/monsters/spawn.qh"
#include "../../common/monsters/sv_monsters.qh"
-void spawnfunc_invasion_spawnpoint()
+#include "../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;
+float autocvar_g_invasion_spawn_delay;
+
+spawnfunc(invasion_spawnpoint)
{
if(!g_invasion) { remove(self); return; }
self.classname = "invasion_spawnpoint";
if(autocvar_g_invasion_zombies_only) // precache only if it hasn't been already
- if(self.monsterid)
- MON_ACTION(self.monsterid, MR_PRECACHE);
+ if(self.monsterid) {
+ Monster mon = get_monsterinfo(self.monsterid);
+ mon.mr_precache(mon);
+ }
}
float invasion_PickMonster(float supermonster_count)
if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
{
FOR_EACH_MONSTER(head)
- monster_remove(head);
+ Monster_Remove(head);
Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_OVER);
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_OVER);
}
FOR_EACH_MONSTER(head)
- monster_remove(head);
+ Monster_Remove(head);
if(teamplay)
{
}
}
-MUTATOR_HOOKFUNCTION(invasion_MonsterDies)
-{
+MUTATOR_HOOKFUNCTION(inv, MonsterDies)
+{SELFPARAM();
if(!(self.spawnflags & MONSTERFLAG_RESPAWNED))
{
inv_numkilled += 1;
return false;
}
-MUTATOR_HOOKFUNCTION(invasion_MonsterSpawn)
-{
+MUTATOR_HOOKFUNCTION(inv, MonsterSpawn)
+{SELFPARAM();
if(!(self.spawnflags & MONSTERFLAG_SPAWNED))
return true;
self.monster_skill = inv_monsterskill;
if((get_monsterinfo(self.monsterid)).spawnflags & MON_FLAG_SUPERMONSTER)
- Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_INVASION_SUPERMONSTER, M_NAME(self.monsterid));
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_INVASION_SUPERMONSTER, self.monster_name);
self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_BOTCLIP | DPCONTENTS_MONSTERCLIP;
return false;
}
-MUTATOR_HOOKFUNCTION(invasion_OnEntityPreSpawn)
-{
+MUTATOR_HOOKFUNCTION(inv, OnEntityPreSpawn)
+{SELFPARAM();
if(startsWith(self.classname, "monster_"))
if(!(self.spawnflags & MONSTERFLAG_SPAWNED))
return true;
return false;
}
-MUTATOR_HOOKFUNCTION(invasion_StartFrame)
+MUTATOR_HOOKFUNCTION(inv, SV_StartFrame)
{
monsters_total = inv_maxspawned; // TODO: make sure numspawned never exceeds maxspawned
monsters_killed = inv_numkilled;
return false;
}
-MUTATOR_HOOKFUNCTION(invasion_PlayerRegen)
+MUTATOR_HOOKFUNCTION(inv, PlayerRegen)
{
// no regeneration in invasion
return true;
}
-MUTATOR_HOOKFUNCTION(invasion_PlayerSpawn)
-{
+MUTATOR_HOOKFUNCTION(inv, PlayerSpawn)
+{SELFPARAM();
self.bot_attack = false;
return false;
}
-MUTATOR_HOOKFUNCTION(invasion_PlayerDamage)
+MUTATOR_HOOKFUNCTION(inv, PlayerDamage_Calculate)
{
if(IS_PLAYER(frag_attacker) && IS_PLAYER(frag_target) && frag_attacker != frag_target)
{
return false;
}
-MUTATOR_HOOKFUNCTION(invasion_PlayerCommand)
-{
+MUTATOR_HOOKFUNCTION(inv, SV_ParseClientCommand)
+{SELFPARAM();
if(MUTATOR_RETURNVALUE) // command was already handled?
return false;
return false;
}
-MUTATOR_HOOKFUNCTION(invasion_BotShouldAttack)
+MUTATOR_HOOKFUNCTION(inv, BotShouldAttack)
{
if(!IS_MONSTER(checkentity))
return true;
return false;
}
-MUTATOR_HOOKFUNCTION(invasion_SetStartItems)
+MUTATOR_HOOKFUNCTION(inv, SetStartItems)
{
start_health = 200;
start_armorvalue = 200;
-
return false;
}
-MUTATOR_HOOKFUNCTION(invasion_AccuracyTargetValid)
+MUTATOR_HOOKFUNCTION(inv, AccuracyTargetValid)
{
if(IS_MONSTER(frag_target))
return MUT_ACCADD_INVALID;
return MUT_ACCADD_INDIFFERENT;
}
-MUTATOR_HOOKFUNCTION(invasion_AllowMobSpawning)
+MUTATOR_HOOKFUNCTION(inv, AllowMobSpawning)
{
// monster spawning disabled during an invasion
return true;
}
-MUTATOR_HOOKFUNCTION(invasion_GetTeamCount)
+MUTATOR_HOOKFUNCTION(inv, GetTeamCount, CBC_ORDER_EXCLUSIVE)
{
ret_float = invasion_teams;
return false;
}
+MUTATOR_HOOKFUNCTION(inv, AllowMobButcher)
+{
+ ret_string = "This command does not work during an invasion!";
+ return true;
+}
+
void invasion_ScoreRules(float inv_teams)
{
if(inv_teams) { CheckAllowedTeams(world); }
void invasion_Initialize()
{
- if(autocvar_g_invasion_zombies_only)
- MON_ACTION(MON_ZOMBIE.monsterid, MR_PRECACHE);
- else
+ if(autocvar_g_invasion_zombies_only) {
+ Monster mon = MON_ZOMBIE;
+ mon.mr_precache(mon);
+ } else
{
float i;
entity mon;
if((mon.spawnflags & MONSTER_TYPE_FLY) || (mon.spawnflags & MONSTER_TYPE_SWIM))
continue; // flying/swimming monsters not yet supported
- MON_ACTION(i, MR_PRECACHE);
+ mon.mr_precache(mon);
}
}
InitializeEntity(world, invasion_DelayedInit, INITPRIO_GAMETYPE);
}
-MUTATOR_DEFINITION(gamemode_invasion)
+REGISTER_MUTATOR(inv, IS_GAMETYPE(INVASION))
{
- MUTATOR_HOOK(MonsterDies, invasion_MonsterDies, CBC_ORDER_ANY);
- MUTATOR_HOOK(MonsterSpawn, invasion_MonsterSpawn, CBC_ORDER_ANY);
- MUTATOR_HOOK(OnEntityPreSpawn, invasion_OnEntityPreSpawn, CBC_ORDER_ANY);
- MUTATOR_HOOK(SV_StartFrame, invasion_StartFrame, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerRegen, invasion_PlayerRegen, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerSpawn, invasion_PlayerSpawn, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerDamage_Calculate, invasion_PlayerDamage, CBC_ORDER_ANY);
- MUTATOR_HOOK(SV_ParseClientCommand, invasion_PlayerCommand, CBC_ORDER_ANY);
- MUTATOR_HOOK(BotShouldAttack, invasion_BotShouldAttack, CBC_ORDER_ANY);
- MUTATOR_HOOK(SetStartItems, invasion_SetStartItems, CBC_ORDER_ANY);
- MUTATOR_HOOK(AccuracyTargetValid, invasion_AccuracyTargetValid, CBC_ORDER_ANY);
- MUTATOR_HOOK(AllowMobSpawning, invasion_AllowMobSpawning, CBC_ORDER_ANY);
- MUTATOR_HOOK(GetTeamCount, invasion_GetTeamCount, CBC_ORDER_ANY);
+ 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");