Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
sv_clanarena.qc
Go to the documentation of this file.
1#include "sv_clanarena.qh"
2
6
14
16
18{
19 total_players = 0;
20 for (int i = 1; i <= AVAILABLE_TEAMS; ++i)
21 {
23 }
25 {
27 if (IS_DEAD(it))
28 {
29 continue;
30 }
31 entity team_ = Entity_GetTeam(it);
32 int num_alive = Team_GetNumberOfAlivePlayers(team_);
33 ++num_alive;
34 Team_SetNumberOfAlivePlayers(team_, num_alive);
35 });
37 {
42 });
43}
44
46{
47 //bprint("PreventStalemate running\n");
48
49 // g_ca_prevent_stalemate:
50 // Run survivor count check with 1 aka bit 0b0001
51 // Run total health check with 2 aka bit 0b0010
52 // With a value like 3 which has both bits both are ran
53
54 bool prevent_stalemate_by_survivors = (autocvar_g_ca_prevent_stalemate & BIT(0));
55 bool prevent_stalemate_by_health = (autocvar_g_ca_prevent_stalemate & BIT(1));
56
57 // Check which team has more alive players
58 if (prevent_stalemate_by_survivors)
59 {
60 int winnerTeam = 0;
61 int secondTeam = 0;
62
63 for(int i = 1; i <= AVAILABLE_TEAMS; ++i)
64 {
66 {
67 secondTeam = winnerTeam;
68 winnerTeam = Team_IndexToTeam(i);
69 }
70 else
71 {
73 secondTeam = Team_IndexToTeam(i);
74 }
75 }
76
78 {
79 bprint(sprintf("Stalemate broken by alive players. Best team: %s%s (%d)^7 - Trailing team: %s%s (%d)\n",
80 Team_ColorCode(winnerTeam), Team_ColorName(winnerTeam), Team_GetNumberOfAlivePlayers(Team_GetTeam(winnerTeam)),
81 Team_ColorCode(secondTeam), Team_ColorName(secondTeam), Team_GetNumberOfAlivePlayers(Team_GetTeam(secondTeam))));
82 return winnerTeam;
83 }
84 }
85
86 // Check which team has more health
87 if (prevent_stalemate_by_health)
88 {
89 int winnerTeam = 0;
90 int secondTeam = 0;
91 int winnerTeamHealth = 0;
92 int secondTeamHealth = 0;
93 int teamIndex, teamHealth;
94
95 for(int i = 1; i <= AVAILABLE_TEAMS; ++i)
96 {
97 teamIndex = i;
98 teamHealth = 0;
99
100 // Add up health for the players in this team
101 FOREACH_CLIENT(IS_PLAYER(it) && Entity_HasValidTeam(it) && it.team == Team_IndexToTeam(teamIndex),
102 {
103 if (IS_DEAD(it))
104 continue;
105 teamHealth += floor(GetResource(it, RES_HEALTH)) + floor(GetResource(it, RES_ARMOR));
106 });
107
108 // Round the resulting team health just in case
109 teamHealth = rint(teamHealth);
110
111 // Set the winner teams
112 if(!winnerTeam || teamHealth > winnerTeamHealth)
113 {
114 secondTeam = winnerTeam;
115 secondTeamHealth = winnerTeamHealth;
116 winnerTeam = Team_IndexToTeam(i);
117 winnerTeamHealth = teamHealth;
118 }
119 else
120 {
121 if(!secondTeam || teamHealth > secondTeamHealth)
122 {
123 secondTeam = Team_IndexToTeam(i);
124 secondTeamHealth = teamHealth;
125 }
126 }
127 }
128
129 if(winnerTeamHealth != secondTeamHealth)
130 {
131 bprint(sprintf("Stalemate broken by team health. Best team: %s%s (%d)^7 - Trailing team: %s%s (%d)\n",
132 Team_ColorCode(winnerTeam), Team_ColorName(winnerTeam), winnerTeamHealth,
133 Team_ColorCode(secondTeam), Team_ColorName(secondTeam), secondTeamHealth));
134 return winnerTeam;
135 }
136 }
137
138 return -2; // Equality. Can't avoid the stalemate.
139}
140
142{
143 int winner_team = 0;
144
146 {
147 // attempt to prevent stalemate by survivor count AND/OR total team health?
148 bool prevent_stalemate_by_survivors = (autocvar_g_ca_prevent_stalemate & BIT(0));
149 bool prevent_stalemate_by_health = (autocvar_g_ca_prevent_stalemate & BIT(1));
150
151 if(prevent_stalemate_by_survivors || prevent_stalemate_by_health)
152 winner_team = CA_PreventStalemate();
153 else
154 winner_team = -2;
155 }
156
158 if (!winner_team)
159 winner_team = Team_GetWinnerAliveTeam();
160 if (!winner_team)
161 {
162 // Dr. Jaska:
163 // reset delay time here only for consistency
164 // CA players currently have no known ways to resurrect
166 return 0;
167 }
168
169 // delay round ending a bit
172 && round_handler_GetEndTime() - time > 0) // don't delay past timelimit
173 {
175 {
177 return 0;
178 }
180 {
181 return 0;
182 }
183 }
184
185 if(winner_team > 0)
186 {
187 Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN));
188 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN));
189 TeamScore_AddToTeam(winner_team, ST_CA_ROUNDS, +1);
190 }
191 else if(winner_team == -1)
192 {
193 Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_ROUND_TIED);
194 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ROUND_TIED);
195 }
196 else if(winner_team == -2)
197 {
198 Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_ROUND_OVER);
199 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ROUND_OVER);
200 }
201
202 allowed_to_spawn = false;
203 game_stopped = true;
205
208 });
209
210 return 1;
211}
212
214{
216 if (!warmup_stage)
217 FOREACH_CLIENT(IS_PLAYER(it), it.prev_team = it.team);
218}
219
221{
222 static int prev_missing_teams_mask;
223 allowed_to_spawn = true;
227 return true;
228 if(total_players == 0)
229 return false;
230 for (int i = 1; i <= AVAILABLE_TEAMS; ++i)
231 {
234 {
236 }
237 }
238 if(prev_missing_teams_mask != missing_teams_mask)
239 prev_missing_teams_mask = missing_teams_mask;
240 return false;
241}
242
244{
245 if(INGAME_JOINED(e) && (IS_DEAD(e) || e.frags == FRAGS_PLAYER_OUT_OF_GAME))
246 return true;
247 if(INGAME_JOINING(e))
248 return true;
249 return false;
250}
251
254{
255 if (SAME_TEAM(start, player)) return start;
256 // continue from current player
257 for (entity e = start; (e = find(e, classname, STR_PLAYER)); )
258 {
259 if (SAME_TEAM(player, e)) return e;
260 }
261 // restart from the beginning
262 for (entity e = NULL; (e = find(e, classname, STR_PLAYER)); )
263 {
264 if (SAME_TEAM(player, e)) return e;
265 }
266 return start;
267}
268
269
270// field where the decimal part of SCORE is accumulated (shared with other gametypes)
272MUTATOR_HOOKFUNCTION(ca, PlayerSpawn)
273{
274 entity player = M_ARGV(0, entity);
275
277 if (time <= game_starttime) // reset on game restart, not on round start
278 player.float2int_decimal_fld = 0;
279 if (!warmup_stage)
280 eliminatedPlayers.SendFlags = 0xFFFFFF;
281}
282
283MUTATOR_HOOKFUNCTION(ca, ForbidSpawn)
284{
285 entity player = M_ARGV(0, entity);
286
287 // spectators / observers that weren't playing can join; they are
288 // immediately forced to observe in the PutClientInServer hook
289 // this way they are put in a team and can play in the next round
290 if (!allowed_to_spawn && INGAME(player))
291 return true;
292 return false;
293}
294
296{
297 entity player = M_ARGV(0, entity);
298
299 if (!allowed_to_spawn && IS_PLAYER(player)) // this is true even when player is trying to join
300 {
301 TRANSMUTE(Observer, player);
302 if (CS(player).jointime != time && !INGAME(player)) // not when connecting
303 {
305 Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_JOIN_LATE);
306 }
307 }
308
309 if (!warmup_stage)
310 eliminatedPlayers.SendFlags = 0xFFFFFF;
311}
312
313MUTATOR_HOOKFUNCTION(ca, reset_map_players)
314{
317 // we can avoid sending observe_blocked_if_eliminated to all clients here (with ClientData_Touch)
318 // since it will get sent whenever the client spectates someone anyway
319
320 FOREACH_CLIENT(true, {
321 CS(it).killcount = 0;
322 if (INGAME(it) || IS_BOT_CLIENT(it))
323 {
324 TRANSMUTE(Player, it);
327 }
328 it.prev_team = 0;
329 });
330 return true;
331}
332
333MUTATOR_HOOKFUNCTION(ca, reset_map_global)
334{
335 allowed_to_spawn = true;
336 return true;
337}
338
339MUTATOR_HOOKFUNCTION(ca, MatchEnd_BeforeScores)
340{
342 return true;
343}
344
346{
347 entity last_pl = NULL;
348 FOREACH_CLIENT(IS_PLAYER(it) && it != this, {
349 if (!IS_DEAD(it) && SAME_TEAM(this, it))
350 {
351 if (!last_pl)
352 last_pl = it;
353 else
354 return NULL;
355 }
356 });
357 return last_pl;
358}
359
361{
363 {
364 entity pl = ca_LastPlayerForTeam(this);
365 if (pl)
366 Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_ALONE);
367 }
368}
369
370MUTATOR_HOOKFUNCTION(ca, PlayerDies)
371{
373
375 if (!allowed_to_spawn)
376 {
377 frag_target.respawn_flags = RESPAWN_SILENT;
378 // prevent unwanted sudden rejoin as spectator and movement of spectator camera
379 frag_target.respawn_time = time + 2;
380 }
381 frag_target.respawn_flags |= RESPAWN_FORCE;
382 if (!warmup_stage)
383 eliminatedPlayers.SendFlags = 0xFFFFFF;
384 return true;
385}
386
387
389{
390 entity player = M_ARGV(0, entity);
391
392 if (IS_PLAYER(player) && !IS_DEAD(player))
394 return true;
395}
396
397MUTATOR_HOOKFUNCTION(ca, MakePlayerObserver)
398{
399 entity player = M_ARGV(0, entity);
400
401 bool is_forced = M_ARGV(1, bool);
402 if (is_forced && INGAME(player))
403 INGAME_STATUS_CLEAR(player);
404
405 if (IS_PLAYER(player) && !IS_DEAD(player))
407 if (player.killindicator_teamchange == -2) // player wants to spectate
408 {
409 entcs_update_players(player);
410 INGAME_STATUS_CLEAR(player);
411 }
412 if (INGAME(player))
413 {
414 player.frags = FRAGS_PLAYER_OUT_OF_GAME;
415 player.would_spectate = observe_blocked_if_eliminated; // if blocked from observing force to spectate now
416 }
417 if (!warmup_stage)
418 eliminatedPlayers.SendFlags = 0xFFFFFF;
419 if (!INGAME(player))
420 return false; // allow team reset
421 return true; // prevent team reset
422}
423
424MUTATOR_HOOKFUNCTION(ca, ForbidThrowCurrentWeapon)
425{
426 return true;
427}
428
430{
431 M_ARGV(2, float) = 0; // score will be given to the winner team when the round ends
432 return true;
433}
434
449
450MUTATOR_HOOKFUNCTION(ca, Damage_Calculate)
451{
452 entity frag_attacker = M_ARGV(1, entity);
454 float frag_deathtype = M_ARGV(3, float);
455 float frag_damage = M_ARGV(4, float);
456 float frag_mirrordamage = M_ARGV(5, float);
457
459 if (!IS_DEAD(frag_target))
460 if (frag_target == frag_attacker || SAME_TEAM(frag_target, frag_attacker) || frag_deathtype == DEATH_FALL.m_id)
461 frag_damage = 0;
462
463 frag_mirrordamage = 0;
464
465 M_ARGV(4, float) = frag_damage;
466 M_ARGV(5, float) = frag_mirrordamage;
467}
468
469MUTATOR_HOOKFUNCTION(ca, FilterItem)
470{
471 entity item = M_ARGV(0, entity);
472
473 if (autocvar_g_powerups <= 0)
474 if (item.itemdef.instanceOfPowerup)
475 return true;
476
478 return true;
479}
480
481MUTATOR_HOOKFUNCTION(ca, PlayerDamage_SplitHealthArmor)
482{
484 return;
485
486 entity frag_attacker = M_ARGV(1, entity);
488 float frag_deathtype = M_ARGV(6, float);
489 float damage_take = M_ARGV(4, float);
490 float damage_save = M_ARGV(5, float);
491
492 float realdmg = damage_take + damage_save;
493
494 if (autocvar_g_ca_damage2score <= 0 || realdmg == 0) return;
495
496 entity scorer = NULL;
497 float scorer_damage = 0;
498
499 if (IS_PLAYER(frag_attacker))
500 {
501 if (DIFF_TEAM(frag_target, frag_attacker))
502 scorer_damage = realdmg;
503 else // friendly fire
504 scorer_damage = -realdmg;
505
506 scorer = frag_attacker;
507 }
508 else
509 {
510 //handle (environmental hazard) suiciding, check first if player has a registered attacker who most likely pushed them there to avoid punishing pushed players as pushers are already rewarded
511 //deathtypes:
512 //kill = suicide, drown = drown in water/liquid, hurttrigger = out of the map void or hurt triggers inside maps like electric sparks
513 //camp = campcheck, lava = lava, slime = slime
514 //team change / rebalance suicides are currently not included
515 if (frag_deathtype == DEATH_KILL.m_id ||
516 frag_deathtype == DEATH_DROWN.m_id ||
517 frag_deathtype == DEATH_HURTTRIGGER.m_id ||
518 frag_deathtype == DEATH_CAMP.m_id ||
519 frag_deathtype == DEATH_LAVA.m_id ||
520 frag_deathtype == DEATH_SLIME.m_id ||
521 frag_deathtype == DEATH_SWAMP.m_id)
522 {
523 scorer_damage = -realdmg;
524 scorer = frag_target;
525 }
526 }
527
528 if (scorer)
530}
531
532MUTATOR_HOOKFUNCTION(ca, CalculateRespawnTime)
533{
534 // no respawn calculations needed, player is forced to spectate anyway
535 return true;
536}
537
538MUTATOR_HOOKFUNCTION(ca, PlayerRegen)
539{
540 // no regeneration in CA
541 return true;
542}
543
544MUTATOR_HOOKFUNCTION(ca, Scores_CountFragsRemaining)
545{
546 // announce remaining frags
547 return true;
548}
549
551{
552 entity client = M_ARGV(0, entity);
553 entity targ = M_ARGV(1, entity);
554
555 if (g_ca_spectate_enemies != 1 && INGAME(client))
556 if (DIFF_TEAM(targ, client))
557 return true;
558}
559
561{
562 entity client = M_ARGV(0, entity);
563
564 if (g_ca_spectate_enemies != 1 && INGAME(client)
566 {
567 entity targ = M_ARGV(1, entity);
568 M_ARGV(1, entity) = CA_SpectateNext(client, targ);
569 return true;
570 }
571}
572
574{
575 entity client = M_ARGV(0, entity);
576 entity targ = M_ARGV(1, entity);
577 entity first = M_ARGV(2, entity);
578
579 if (g_ca_spectate_enemies != 1 && INGAME(client)
581 {
582 do { targ = targ.chain; }
583 while(targ && DIFF_TEAM(targ, client));
584
585 if (!targ)
586 {
587 for (targ = first; targ && DIFF_TEAM(targ, client); targ = targ.chain);
588
589 if (targ == client.enemy)
590 return MUT_SPECPREV_RETURN;
591 }
592 }
593 else
595
596 M_ARGV(1, entity) = targ;
597
598 return MUT_SPECPREV_FOUND;
599}
600
602{
604 if (IS_PLAYER(it) || INGAME_JOINED(it))
605 ++M_ARGV(0, int);
606 ++M_ARGV(1, int);
607 });
608 return true;
609}
610
611MUTATOR_HOOKFUNCTION(ca, ClientCommand_Spectate)
612{
613 entity player = M_ARGV(0, entity);
614
615 if (INGAME(player))
616 {
617 // they're going to spec, we can do other checks
618 if (autocvar_sv_spectate && (IS_SPEC(player) || IS_OBSERVER(player)))
619 Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_LEAVE);
620 return MUT_SPECCMD_FORCE;
621 }
622
624}
625
626MUTATOR_HOOKFUNCTION(ca, SetWeaponArena)
627{
628 if (M_ARGV(0, string) == "0" || M_ARGV(0, string) == "")
630}
631
632MUTATOR_HOOKFUNCTION(ca, SV_ParseServerCommand)
633{
634 string cmd_name = M_ARGV(0, string);
635 if (cmd_name == "shuffleteams")
637 return false;
638}
const int CBC_ORDER_FIRST
Definition base.qh:10
#define MUTATOR_HOOKFUNCTION(...)
Definition base.qh:335
const int CBC_ORDER_EXCLUSIVE
Definition base.qh:12
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition bits.qh:8
#define boolean(value)
Definition bool.qh:9
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
bool warmup_stage
Definition main.qh:120
const int IT_UNLIMITED_AMMO
Definition item.qh:23
const int IT_UNLIMITED_SUPERWEAPONS
Definition item.qh:24
#define M_ARGV(x, type)
Definition events.qh:17
#define IS_DEAD(s)
Definition player.qh:244
#define IS_PLAYER(s)
Definition player.qh:242
int missing_teams_mask
Definition stats.qh:85
float game_starttime
Definition stats.qh:82
float game_stopped
Definition stats.qh:81
const int FRAGS_PLAYER_OUT_OF_GAME
still shown with a score and/or a team, but currently forced to spec/observe
Definition constants.qh:6
string classname
float time
entity eliminatedPlayers
Definition elimination.qh:3
RES_ARMOR
Definition ent_cs.qc:155
void entcs_update_players(entity player)
Definition ent_cs.qc:208
#define PutClientInServer
Definition _all.inc:250
#define ClientDisconnect
Definition _all.inc:246
#define STAT(...)
Definition stats.qh:94
string cmd_name
Definition events.qh:12
float cvar(string name)
entity find(entity start,.string field, string match)
void bprint(string text,...)
float min(float f,...)
float rint(float f)
float floor(float f)
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1500
#define APP_TEAM_NUM(num, prefix)
Definition all.qh:88
#define TRANSMUTE(cname, this,...)
Definition oo.qh:139
#define NULL
Definition post.qh:14
void round_handler_Init(float the_delay, float the_count, float the_round_timelimit)
#define round_handler_IsActive()
#define round_handler_GetEndTime()
#define round_handler_SetEndDelayTime(t)
#define round_handler_GetEndDelayTime()
#define round_handler_IsRoundStarted()
#define round_handler_ResetEndDelayTime()
float TeamScore_AddToTeam(int t, float scorefield, float score)
Adds a score to the given team.
Definition scores.qc:108
#define AVAILABLE_TEAMS
Number of teams that exist currently.
bool SpectateSet(entity this)
Definition client.qc:1886
bool SpectateNext(entity this)
Definition client.qc:1988
bool SpectatePrev(entity this)
Definition client.qc:2002
const int RESPAWN_SILENT
Definition client.qh:327
bool autocvar_sv_spectate
Definition client.qh:57
float jointime
Definition client.qh:66
const int RESPAWN_FORCE
Definition client.qh:326
int autocvar_g_pickup_items
Definition items.qh:11
@ MUT_SPECPREV_RETURN
Definition events.qh:979
@ MUT_SPECPREV_CONTINUE
Definition events.qh:978
@ MUT_SPECPREV_FOUND
Definition events.qh:980
@ MUT_SPECCMD_FORCE
Definition events.qh:1000
@ MUT_SPECCMD_CONTINUE
Definition events.qh:998
ClientState CS(Client this)
Definition state.qh:47
float autocvar_g_ca_start_ammo_rockets
float autocvar_g_ca_start_ammo_cells
float autocvar_g_ca_damage2score
float autocvar_g_ca_start_armor
void CA_RoundStart()
float autocvar_g_ca_start_ammo_nails
float autocvar_g_ca_start_health
float autocvar_g_ca_start_ammo_fuel
bool CA_CheckTeams()
void ca_LastPlayerForTeam_Notify(entity this)
float float2int_decimal_fld
void CA_count_alive_players()
entity CA_SpectateNext(entity player, entity start)
Returns next available player to spectate if g_ca_spectate_enemies == 0.
int autocvar_g_ca_prevent_stalemate
float CA_CheckWinner()
entity ca_LastPlayerForTeam(entity this)
bool ca_isEliminated(entity e)
float autocvar_g_ca_start_ammo_shells
int prev_team
float autocvar_g_ca_round_enddelay
int CA_PreventStalemate()
bool g_ca_spectate_enemies
bool allowed_to_spawn
float autocvar_g_ca_round_timelimit
const int ST_CA_ROUNDS
string autocvar_g_ca_weaponarena
int autocvar_g_ca_spectate_enemies
float autocvar_g_ca_warmup
bool shuffleteams_on_reset_map
Definition sv_cmd.qh:7
float frag_damage
Definition sv_ctf.qc:2316
entity frag_target
Definition sv_ctf.qc:2315
void nades_RemovePlayer(entity this)
Remove nades and bonus nades from a player.
Definition sv_nades.qc:894
int autocvar_g_powerups
Definition sv_powerups.qh:7
#define INGAME_STATUS_JOINED
Definition sv_rules.qh:17
#define INGAME_STATUS_JOINING
Definition sv_rules.qh:16
#define INGAME(it)
Definition sv_rules.qh:24
#define GameRules_scoring_add_float2int(client, fld, value, float_field, score_factor)
Definition sv_rules.qh:83
#define INGAME_STATUS_CLEAR(it)
Definition sv_rules.qh:22
#define INGAME_JOINED(it)
Definition sv_rules.qh:25
#define INGAME_STATUS_SET(it, s)
Definition sv_rules.qh:21
int total_players
Definition sv_rules.qh:12
#define INGAME_JOINING(it)
Definition sv_rules.qh:26
int Team_GetNumberOfAlivePlayers(entity team_ent)
Returns the number of alive players in a team.
Definition teamplay.qc:114
entity Team_GetTeam(int team_num)
Returns the global team entity that corresponds to the given TEAM_NUM value.
Definition teamplay.qc:95
entity Entity_GetTeam(entity this)
Returns the team entity of the given entity.
Definition teamplay.qc:215
int Team_GetWinnerAliveTeam()
Returns the winner team.
Definition teamplay.qc:124
bool Entity_HasValidTeam(entity this)
Returns whether the given entity belongs to a valid team.
Definition teamplay.qc:205
int Team_GetNumberOfAliveTeams()
Returns the number of alive teams.
Definition teamplay.qc:139
void Team_SetNumberOfAlivePlayers(entity team_ent, int number)
Sets the number of alive players in a team.
Definition teamplay.qc:119
entity Team_GetTeamFromIndex(int index)
Returns the global team entity at the given index.
Definition teamplay.qc:86
int teamplay_bitmask
The set of currently available teams (AVAILABLE_TEAMS is the number of them).
Definition teamplay.qh:18
#define SAME_TEAM(a, b)
Definition teams.qh:241
string Team_ColorName(int teamid)
Definition teams.qh:89
int Team_IndexToTeam(int index)
Converts team index into team value.
Definition teams.qh:169
#define DIFF_TEAM(a, b)
Definition teams.qh:242
int Team_IndexToBit(int index)
Converts team index into bit value that is used in team bitmasks.
Definition teams.qh:211
string Team_ColorCode(int teamid)
Definition teams.qh:63
#define IS_OBSERVER(v)
Definition utils.qh:11
#define IS_SPEC(v)
Definition utils.qh:10
const string STR_PLAYER
Definition utils.qh:5
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition utils.qh:15
void MatchEnd_RestoreSpectatorAndTeamStatus(.int prev_team_field)
Definition world.qc:1368
float warmup_start_ammo_cells
Definition world.qh:105
float start_ammo_shells
Definition world.qh:84
float warmup_start_ammo_rockets
Definition world.qh:104
float warmup_start_ammo_shells
Definition world.qh:102
float start_ammo_fuel
Definition world.qh:88
int start_items
Definition world.qh:83
float warmup_start_ammo_nails
Definition world.qh:103
float start_ammo_cells
Definition world.qh:87
float warmup_start_health
Definition world.qh:107
float start_ammo_rockets
Definition world.qh:86
float start_armorvalue
Definition world.qh:97
bool observe_blocked_if_eliminated
Definition world.qh:160
float warmup_start_ammo_fuel
Definition world.qh:106
float start_health
Definition world.qh:96
float warmup_start_armorvalue
Definition world.qh:108
float start_ammo_nails
Definition world.qh:85