X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fmutators%2Fmutator%2Fgamemode_invasion.qc;h=d3e40465c1376323c526c52193c83b8ecee32445;hb=cf1edea8694548556934b5b05f526bc192f576cb;hp=4dc5ed63ab2d5a8acaf6835e49f6130adf94a1ff;hpb=a0b626ee78db909c214cc0fc7e829f8a8379704f;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/mutators/mutator/gamemode_invasion.qc b/qcsrc/server/mutators/mutator/gamemode_invasion.qc index 4dc5ed63a..d3e40465c 100644 --- a/qcsrc/server/mutators/mutator/gamemode_invasion.qc +++ b/qcsrc/server/mutators/mutator/gamemode_invasion.qc @@ -1,6 +1,49 @@ +#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; @@ -19,18 +62,14 @@ const float ST_INV_KILLS = 1; #ifdef IMPLEMENTATION -#include "../../../common/monsters/spawn.qh" -#include "../../../common/monsters/sv_monsters.qh" +#include +#include -#include "../../teamplay.qh" +#include -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; @@ -38,13 +77,13 @@ float autocvar_g_invasion_spawn_delay; 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); } } @@ -102,7 +141,7 @@ void invasion_SpawnChosenMonster(float 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 @@ -154,11 +193,9 @@ void invasion_SpawnMonsters(float supermonster_count) 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); @@ -168,21 +205,23 @@ float Invasion_CheckWinner() 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) { @@ -224,25 +263,25 @@ float Invasion_CheckWinner() 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) @@ -256,20 +295,18 @@ float Invasion_CheckWinner() 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 @@ -293,15 +330,15 @@ void Invasion_RoundStart() } 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 { @@ -445,7 +482,7 @@ void invasion_ScoreRules(float inv_teams) 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); @@ -487,39 +524,4 @@ void invasion_Initialize() 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