29 actor.inv_endreached =
true;
92 bprint(
"Invasion: round completed.\n");
130 FOREACH(Monsters, it != MON_Null,
167 if(!best || it.cnt > best.cnt)
181 if(wave_ent && wave_ent.spawnmob && wave_ent.spawnmob !=
"")
186 RandomSelection_AddString(it, 1, 1);
192 if(spawn_point ==
NULL)
197 LOG_TRACE(
"Warning: couldn't find any invasion_spawnpoint spawnpoints, attempting to spawn monsters in random locations");
211 monster =
spawnmonster(
spawn(), ((spawn_point.spawnmob && spawn_point.spawnmob !=
"") ? spawn_point.spawnmob : tospawn), mon, spawn_point, spawn_point, spawn_point.origin,
false,
false, 2);
220 if(spawn_point.target_range)
221 monster.target_range = spawn_point.target_range;
222 monster.target2 = spawn_point.target2;
228 monster.team = spawn_point.team;
244 WaypointSprite_UpdateTeamRadar(monster.sprite, RADARICON_DANGER, ((monster.team) ?
Team_ColorRGB(monster.team) :
'1 0 0'));
246 monster.sprite.team = 0;
247 monster.sprite.SendFlags |= 1;
251 if(monster.monster_attack)
253 monster.monster_attack =
false;
276 Send_Notification(NOTIF_ALL,
NULL, MSG_CENTER, CENTER_ROUND_OVER);
277 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_ROUND_OVER);
282 float total_alive_monsters = 0, supermonster_count = 0, red_alive = 0, blue_alive = 0, yellow_alive = 0, pink_alive = 0;
287 ++supermonster_count;
288 ++total_alive_monsters;
293 case NUM_TEAM_1: ++red_alive; break;
294 case NUM_TEAM_2: ++blue_alive; break;
295 case NUM_TEAM_3: ++yellow_alive; break;
296 case NUM_TEAM_4: ++pink_alive; break;
316 if(((red_alive > 0) + (blue_alive > 0) + (yellow_alive > 0) + (pink_alive > 0)) > 1)
323 float winning_score = 0, winner_team = 0;
328 if(red_alive > 0) { winner_team =
NUM_TEAM_1; }
331 if(winner_team) { winner_team = 0; }
336 if(winner_team) { winner_team = 0; }
341 if(winner_team) { winner_team = 0; }
349 if(cs > winning_score)
367 Send_Notification(NOTIF_ALL,
NULL, MSG_CENTER,
APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN));
368 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN));
373 Send_Notification(NOTIF_ALL,
NULL, MSG_CENTER, CENTER_ROUND_PLAYER_WIN, winner.netname);
374 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_ROUND_PLAYER_WIN, winner.netname);
391 it.player_blocked =
false;
432 if(
SAME_TEAM(frag_attacker, frag_target))
464 Send_Notification(NOTIF_ALL,
NULL, MSG_CENTER, CENTER_INVASION_SUPERMONSTER, mon.monster_name);
486 if(player.bot_attack)
488 player.bot_attack =
false;
495 float frag_damage =
M_ARGV(4,
float);
498 if(
IS_PLAYER(frag_attacker) &&
IS_PLAYER(frag_target) && frag_attacker != frag_target)
501 frag_force =
'0 0 0';
503 M_ARGV(4,
float) = frag_damage;
537 M_ARGV(1,
string) =
"You cannot spawn monsters during an invasion!";
558 M_ARGV(0,
string) =
"This command does not work during an invasion!";
ERASEABLE void IL_REMOVE(IntrusiveList this, entity it)
Remove any element, anywhere in the list.
void invasion_ScoreRules(int inv_teams)
#define APP_TEAM_NUM(num, prefix)
const int MONSTERFLAG_RESPAWNED
#define GameRules_scoring(teams, spprio, stprio, fields)
#define IL_EACH(this, cond, body)
const int MON_FLAG_HIDDEN
IntrusiveList g_invasion_waves
entity spawnmonster(entity e, string monster, Monster monster_id, entity spawnedby, entity own, vector orig, bool respwn, bool removeifinvalid, int moveflag)
#define IL_CLEAR(this)
Remove all elements.
const int CBC_ORDER_EXCLUSIVE
void invasion_SpawnMonsters(int supermonster_count)
IntrusiveList g_monster_targets
const int MONSTER_SIZE_QUAKE
string RandomSelection_chosen_string
void invasion_Initialize()
void round_handler_Spawn(bool() canRoundStart_func, bool() canRoundEnd_func, void() roundStart_func)
void target_invasion_roundend_use(entity this, entity actor, entity trigger)
float DPCONTENTS_MONSTERCLIP
vector Team_ColorRGB(int teamid)
void SetWinners(.float field, float value)
ERASEABLE void RandomSelection_Init()
float TeamScore_AddToTeam(int t, float scorefield, float score)
Adds a score to the given team.
Monster invasion_PickMonster(int supermonster_count)
const int SFL_SORT_PRIO_SECONDARY
Scoring priority (NOTE: PRIMARY is used for fraglimit)
float autocvar_g_invasion_spawn_delay
float autocvar_g_invasion_warmup
#define FOREACH_CLIENT(cond, body)
#define GameRules_scoring_add(client, fld, value)
float autocvar_g_invasion_round_timelimit
const int SFL_SORT_PRIO_PRIMARY
Effect is being removed by a function, calls regular removal mechanics.
float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance)
float DPCONTENTS_PLAYERCLIP
float autocvar_g_invasion_spawnpoint_spawn_delay
#define spawn_point(name, color)
float RandomSelection_chosen_float
MUTATOR_HOOKFUNCTION(inv, MonsterDies)
void GameRules_score_enabled(bool value)
Disabling score disables the "score" column on the scoreboard.
const int MONSTER_TYPE_FLY
int autocvar_g_invasion_monster_count
#define FOREACH_WORD(words, cond, body)
IntrusiveList g_bot_targets
#define IS_REAL_CLIENT(v)
ERASEABLE float DistributeEvenly_Get(float weight)
void monster_setupcolors(entity this)
#define RandomSelection_AddEnt(e, weight, priority)
const int MONSTER_TYPE_UNDEAD
IntrusiveList g_invasion_roundends
entity invasion_GetWaveEntity(int wavenum)
const int MONSTERFLAG_MINIBOSS
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
void Invasion_RoundStart()
bool Invasion_CheckPlayers()
entity RandomSelection_chosen_ent
int WinningCondition_Invasion()
IntrusiveList g_invasion_spawns
void Monster_Remove(entity this)
bool autocvar_g_invasion_zombies_only
int autocvar_g_invasion_type
#define round_handler_GetEndTime()
void invasion_SpawnChosenMonster(Monster mon)
vector(float skel, float bonenum) _skel_get_boneabs_hidden
float inv_monsters_perteam[17]
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
#define RandomSelection_AddFloat(f, weight, priority)
void InitializeEntity(entity e, void(entity this) func, int order)
const int MONSTER_TYPE_PASSIVE
ERASEABLE void DistributeEvenly_Init(float amount, float totalweight)
const int MONSTER_TYPE_SWIM
bool Invasion_CheckWinner()
entity TeamBalance_CheckAllowedTeams(entity for_whom)
Checks whether the player can join teams according to global configuration and mutator settings...
void invasion_DelayedInit(entity this)
int autocvar_g_invasion_teams
float DPCONTENTS_DONOTENTER
void round_handler_Init(float the_delay, float the_count, float the_round_timelimit)
#define FOREACH(list, cond, body)
spawnfunc(target_invasion_roundend)
const int MON_FLAG_SUPERMONSTER
void WinningConditionHelper(entity this)
Sets the following results for the current scores entities.
const int MONSTERFLAG_SPAWNED
entity invasion_PickSpawn()