Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
sv_lms.qc
Go to the documentation of this file.
1#include "sv_lms.qh"
2
4#include <server/campaign.qh>
6#include <server/world.qh>
8
29
33bool lms_visible_leaders = true; // triggers lms_visible_leaders_time update in the first frame
36
37// main functions
39{
40 int fl = floor(autocvar_fraglimit);
41 if(fl == 0 || fl > 999)
42 fl = 999;
43
44 // first player has left the game for dying too much? Nobody else can get in.
45 if(lms_lowest_lives < 1)
46 return 0;
47
50 return 0;
51
52 return bound(1, lms_lowest_lives, fl);
53}
54
55void ClearWinners();
56
57// LMS winning condition: game terminates if and only if there's at most one
58// one player who's living lives. Top two scores being equal cancels the time
59// limit.
61{
63 return WINNING_NO;
64
65 entity first_player = NULL;
66 int totalplayers = 0;
67 int totalplayed = 0;
68 FOREACH_CLIENT(true, {
69 if (IS_PLAYER(it) && it.frags == FRAGS_PLAYER)
70 {
71 if (!totalplayers)
72 first_player = it;
73 ++totalplayers;
74 }
75 else if (GameRules_scoring_add(it, LMS_RANK, 0))
76 ++totalplayed;
77 });
78
79 if (totalplayers)
80 {
81 if (totalplayers > 1)
82 {
83 // two or more active players - continue with the game
84
86 {
88 float pl_lives = GameRules_scoring_add(it, LMS_LIVES, 0);
89 if (!pl_lives)
90 return WINNING_YES; // human player lost, game over
91 break;
92 });
93 }
94 }
95 else
96 {
97 // exactly one player?
98
100
101 if (LMS_NewPlayerLives())
102 {
103 if (totalplayed && game_starttime > 0 && time > game_starttime + autocvar_g_lms_forfeit_min_match_time) // give players time to join
104 {
105 GameRules_scoring_add(first_player, LMS_RANK, 1);
106 first_player.winning = 1;
107 return WINNING_YES;
108 }
109 // game still running (that is, nobody got removed from the game by a frag yet)? then continue
110 return WINNING_NO;
111 }
112 else
113 {
114 // a winner!
115 // and assign them their first place
116 GameRules_scoring_add(first_player, LMS_RANK, 1);
117 first_player.winning = 1;
118 return WINNING_YES;
119 }
120 }
121 }
122 else
123 {
124 // nobody is playing at all...
125 if (LMS_NewPlayerLives())
126 {
127 if (totalplayed && game_starttime > 0 && time > game_starttime + autocvar_g_lms_forfeit_min_match_time) // give players time to join
128 {
129 ClearWinners();
130 return WINNING_YES;
131 }
132 // wait for players...
133 }
134 else
135 {
136 // SNAFU (maybe a draw game?)
137 ClearWinners();
138 LOG_TRACE("No players, ending game.");
139 return WINNING_YES;
140 }
141 }
142
143 // When we get here, we have at least two players who are actually LIVING,
144 // now check if the top two players have equal score.
146
147 ClearWinners();
149 WinningConditionHelper_winner.winning = true;
151 return WINNING_NEVER;
152
153 // Top two have different scores? Way to go for our beloved TIMELIMIT!
154 return WINNING_NO;
155}
156
157// runs on waypoints which are attached to leaders, updates once per frame
159{
160 if(view.lms_leader)
161 if(IS_SPEC(player))
162 return false; // we don't want spectators of leaders to see the attached waypoint on the top of their screen
163
165 return false;
166
167 return true;
168}
169
172{
173 int max_lives = 0;
174 int pl_cnt = 0;
176 int lives = GameRules_scoring_add(it, LMS_LIVES, 0);
177 if (lives > max_lives)
178 max_lives = lives;
179 ++pl_cnt;
180 });
181
182 int second_max_lives = 0;
183 int pl_cnt_with_max_lives = 0;
185 int lives = GameRules_scoring_add(it, LMS_LIVES, 0);
186 if (lives == max_lives)
187 ++pl_cnt_with_max_lives;
188 else if (lives > second_max_lives)
189 second_max_lives = lives;
190 });
191
192 lms_leaders_lives_diff = max_lives - second_max_lives;
193
194 int lives_diff = autocvar_g_lms_leader_lives_diff;
195 if (lms_leaders_lives_diff >= lives_diff && pl_cnt_with_max_lives <= pl_cnt * autocvar_g_lms_leader_minpercent)
197 int lives = GameRules_scoring_add(it, LMS_LIVES, 0);
198 if (lives == max_lives)
199 {
200 if (!it.lms_leader)
201 it.lms_leader = true;
202 }
203 else
204 {
205 it.lms_leader = false;
206 }
207 });
208 else
210 if (it.waypointsprite_attachedforcarrier)
211 WaypointSprite_Kill(it.waypointsprite_attachedforcarrier);
212 it.lms_leader = false;
213 });
214}
215
216// mutator hooks
217MUTATOR_HOOKFUNCTION(lms, reset_map_global)
218{
219 lms_lowest_lives = 999;
220}
221
222MUTATOR_HOOKFUNCTION(lms, reset_map_players)
223{
224 FOREACH_CLIENT(true, {
225 if (it.frags == FRAGS_PLAYER_OUT_OF_GAME)
226 it.frags = FRAGS_PLAYER;
227
228 CS(it).killcount = 0;
230 it.lms_spectate = false;
231 GameRules_scoring_add(it, LMS_RANK, -GameRules_scoring_add(it, LMS_RANK, 0));
232 GameRules_scoring_add(it, LMS_LIVES, -GameRules_scoring_add(it, LMS_LIVES, 0));
233
234 if (it.frags != FRAGS_PLAYER)
235 continue;
236
237 TRANSMUTE(Player, it);
239 it.lms_leader = false;
240 if (it.waypointsprite_attachedforcarrier)
241 WaypointSprite_Kill(it.waypointsprite_attachedforcarrier);
242 });
243}
244
245// FIXME add support for sv_ready_restart_after_countdown
246// that is find a way to respawn/reset players IN GAME without setting lives to 0
247MUTATOR_HOOKFUNCTION(lms, ReadLevelCvars)
248{
249 // incompatible
251}
252
253// returns true if player is added to the game
255{
256 if (!INGAME(player))
257 {
258 int lives = GameRules_scoring_add(player, LMS_LIVES, LMS_NewPlayerLives());
259 if(lives <= 0)
260 return false;
261 if (time < game_starttime)
263 else
264 INGAME_STATUS_SET(player, INGAME_STATUS_JOINING); // this is just to delay setting health and armor that can't be done here
265 }
267 {
268 player.lms_spectate = false;
269 GameRules_scoring_add(player, LMS_RANK, -GameRules_scoring_add(player, LMS_RANK, 0));
270 int lives = GameRules_scoring_add(player, LMS_LIVES, 0);
271 if(lives <= 0)
272 GameRules_scoring_add(player, LMS_LIVES, LMS_NewPlayerLives());
273 }
274 else if (GameRules_scoring_add(player, LMS_LIVES, 0) <= 0)
275 return false;
276 return true;
277}
278
280{
281 entity player = M_ARGV(0, entity);
282 if (!warmup_stage && (IS_BOT_CLIENT(player) || CS(player).jointime != time))
283 {
284 if (GameRules_scoring_add(player, LMS_RANK, 0) || !lms_AddPlayer(player))
285 {
286 TRANSMUTE(Observer, player);
287 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_LMS_NOLIVES);
288 }
289 }
290}
291
295MUTATOR_HOOKFUNCTION(lms, PlayerSpawn)
296{
297 entity player = M_ARGV(0, entity);
298
300 return true;
301
302 if (INGAME_JOINING(player))
303 {
304 // spawn player with the same amount of health / armor
305 // as the least healthy player with the least number of lives
306 int pl_lives = GameRules_scoring_add(player, LMS_LIVES, 0);
307 float min_health = start_health;
308 float min_armorvalue = start_armorvalue;
309 if (last_forfeiter_lives == pl_lives)
310 {
311 min_health = last_forfeiter_health;
312 min_armorvalue = last_forfeiter_armorvalue;
313 }
314 FOREACH_CLIENT(it != player && IS_PLAYER(it) && !IS_DEAD(it) && GameRules_scoring_add(it, LMS_LIVES, 0) == pl_lives, {
315 if (GetResource(it, RES_HEALTH) < min_health)
316 min_health = GetResource(it, RES_HEALTH);
317 if (GetResource(it, RES_ARMOR) < min_armorvalue)
318 min_armorvalue = GetResource(it, RES_ARMOR);
319 });
320 if (min_health != start_health)
321 SetResource(player, RES_HEALTH, max(1, min_health));
322 if (min_armorvalue != start_armorvalue)
323 SetResource(player, RES_ARMOR, min_armorvalue);
325 }
326}
327
328MUTATOR_HOOKFUNCTION(lms, ForbidSpawn)
329{
330 entity player = M_ARGV(0, entity);
331
332 if (warmup_stage || lms_AddPlayer(player))
333 return false;
334
335 return true;
336}
337
339{
341 return;
342
343 float player_rank = GameRules_scoring_add(player, LMS_RANK, 0);
344 if (!player_rank)
345 {
346 if (!player.lms_spectate)
347 {
348 player.frags = FRAGS_PLAYER_OUT_OF_GAME;
349 int pl_cnt = 0;
350 FOREACH_CLIENT(IS_PLAYER(it) && it.frags == FRAGS_PLAYER, {
351 ++pl_cnt;
352 });
353 GameRules_scoring_add(player, LMS_RANK, pl_cnt + 1);
354 }
355 else if (INGAME(player))
356 {
357 FOREACH_CLIENT(it != player, {
358 // update rank of other players
359 if (it.frags == FRAGS_PLAYER_OUT_OF_GAME)
360 GameRules_scoring_add(it, LMS_RANK, -1);
361 });
362 int rank = GameRules_scoring_add(player, LMS_RANK, 0);
363 GameRules_scoring_add(player, LMS_RANK, -rank);
364 if(!warmup_stage)
365 {
366 int pl_lives = GameRules_scoring_add(player, LMS_LIVES, 0);
367 float pl_health = IS_DEAD(player) ? start_health : GetResource(player, RES_HEALTH);
368 float pl_armor = IS_DEAD(player) ? start_armorvalue : GetResource(player, RES_ARMOR);
370 {
371 last_forfeiter_lives = pl_lives;
372 last_forfeiter_health = pl_health;
373 last_forfeiter_armorvalue = pl_armor;
374 }
375 else if (pl_lives == last_forfeiter_lives)
376 {
377 // these values actually can belong to a different forfeiter
380 }
381 GameRules_scoring_add(player, LMS_LIVES, -pl_lives);
382 }
383 INGAME_STATUS_CLEAR(player);
384 player.lms_spectate = false;
385 CS(player).killcount = FRAGS_SPECTATOR;
386 }
389 }
390}
391
393{
394 entity player = M_ARGV(0, entity);
395
396 player.lms_spectate = true;
397
398 lms_RemovePlayer(player);
399 INGAME_STATUS_CLEAR(player);
400}
401
402MUTATOR_HOOKFUNCTION(lms, MakePlayerObserver)
403{
404 entity player = M_ARGV(0, entity);
405 bool is_forced = M_ARGV(1, bool);
406
407 if (!player.frags) // init
408 {
409 player.frags = FRAGS_SPECTATOR; // don't be on the scoreboard yet
410 return true; // resetting at init can end match before it starts
411 }
412 if (player.frags == FRAGS_PLAYER_OUT_OF_GAME) // eliminated
413 return true; // prevent team reset (and spec notification)
414
416 {
417 GameRules_scoring_add(player, LMS_LIVES, -GameRules_scoring_add(player, LMS_LIVES, 0));
418 INGAME_STATUS_CLEAR(player);
419 }
420 else
421 {
422 if (is_forced || player.killindicator_teamchange == -2) // player is forced or wants to spectate
423 player.lms_spectate = true;
424 if (!GameRules_scoring_add(player, LMS_RANK, 0))
425 lms_RemovePlayer(player);
426 }
427}
428
430{
431 entity player = M_ARGV(0, entity);
432
433 // recycled REDALIVE and BLUEALIVE to avoid adding a dedicated stat
434 STAT(REDALIVE, player) = lms_leaders;
435 STAT(BLUEALIVE, player) = lms_leaders_lives_diff;
436
437 if(player.deadflag == DEAD_DYING)
438 player.deadflag = DEAD_RESPAWNING;
439}
440
441MUTATOR_HOOKFUNCTION(lms, SV_StartFrame)
442{
444 return;
445
446 lms_leaders = 0;
447 FOREACH_CLIENT(true, {
448 if (IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME && it.lms_leader)
449 ++lms_leaders;
450 });
451
452 float leader_time = autocvar_g_lms_leader_wp_time;
453 float leader_interval = leader_time + autocvar_g_lms_leader_wp_interval;
458
459 FOREACH_CLIENT(true, {
460 STAT(OBJECTIVE_STATUS, it) = lms_visible_leaders;
461 if (IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME)
462 {
463 if (it.lms_leader)
464 {
465 if (!it.waypointsprite_attachedforcarrier)
466 {
467 WaypointSprite_AttachCarrier(WP_LmsLeader, it, RADARICON_FLAGCARRIER);
468 it.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = lms_waypointsprite_visible_for_player;
469 WaypointSprite_UpdateRule(it.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT);
470 vector pl_color = colormapPaletteColor(it.clientcolors & 0x0F, false);
471 WaypointSprite_UpdateTeamRadar(it.waypointsprite_attachedforcarrier, RADARICON_FLAGCARRIER, pl_color);
472 WaypointSprite_Ping(it.waypointsprite_attachedforcarrier);
473 }
475 Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_LMS_VISIBLE_LEADER);
476 }
477 else // if (!it.lms_leader)
478 {
479 if (IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME)
480 {
482 Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_LMS_VISIBLE_OTHER);
483 }
484 if (it.waypointsprite_attachedforcarrier)
485 WaypointSprite_Kill(it.waypointsprite_attachedforcarrier);
486 }
487 }
488 });
489}
490
491MUTATOR_HOOKFUNCTION(lms, PlayerRegen)
492{
494 M_ARGV(2, float) = 0;
496 M_ARGV(3, float) = 0;
498}
499
500MUTATOR_HOOKFUNCTION(lms, PlayerPowerups)
501{
502 entity player = M_ARGV(0, entity);
503 if (player.waypointsprite_attachedforcarrier)
504 player.effects |= (EF_ADDITIVE | EF_FULLBRIGHT);
505 else
506 player.effects &= ~(EF_ADDITIVE | EF_FULLBRIGHT);
507}
508
509MUTATOR_HOOKFUNCTION(lms, ForbidThrowCurrentWeapon)
510{
511 // forbode!
512 return true;
513}
514
515MUTATOR_HOOKFUNCTION(lms, Damage_Calculate)
516{
518 return;
519
520 entity frag_attacker = M_ARGV(1, entity);
522 float frag_damage = M_ARGV(4, float);
523
524 if (IS_PLAYER(frag_attacker) && !IS_DEAD(frag_attacker)
525 && IS_PLAYER(frag_target) && !IS_DEAD(frag_target) && frag_attacker != frag_target)
526 {
527 float vampire_factor = 0;
528
529 int frag_attacker_lives = GameRules_scoring_add(frag_attacker, LMS_LIVES, 0);
530 int frag_target_lives = GameRules_scoring_add(frag_target, LMS_LIVES, 0);
531 int diff = frag_target_lives - frag_attacker_lives - autocvar_g_lms_dynamic_vampire_min_lives_diff;
532
533 if (diff >= 0)
535 if (vampire_factor > 0)
536 {
537 vampire_factor = min(vampire_factor, autocvar_g_lms_dynamic_vampire_factor_max);
538 SetResourceExplicit(frag_attacker, RES_HEALTH,
539 min(GetResource(frag_attacker, RES_HEALTH) + frag_damage * vampire_factor, start_health));
540 }
541 }
542}
543
549
550MUTATOR_HOOKFUNCTION(lms, CalculateRespawnTime)
551{
552 entity player = M_ARGV(0, entity);
553 player.respawn_flags |= RESPAWN_FORCE;
554
555 int pl_lives = GameRules_scoring_add(player, LMS_LIVES, 0);
556 if (pl_lives <= 0)
557 {
558 player.respawn_flags = RESPAWN_SILENT;
559 // prevent unwanted sudden rejoin as spectator and movement of spectator camera
560 player.respawn_time = time + 2;
561 return true;
562 }
563
565 return false;
566
567 int max_lives = 0;
568 int pl_cnt = 0;
569 FOREACH_CLIENT(it != player && IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, {
570 int lives = GameRules_scoring_add(it, LMS_LIVES, 0);
571 if (lives > max_lives)
572 max_lives = lives;
573 ++pl_cnt;
574 });
575
576 // min delay with only 2 players
577 if (pl_cnt == 1) // player wasn't counted
578 max_lives = 0;
579
581 autocvar_g_lms_dynamic_respawn_delay_increase * max(0, max_lives - pl_lives);
582 player.respawn_time = time + min(autocvar_g_lms_dynamic_respawn_delay_max, dlay);
583 return true;
584}
585
586MUTATOR_HOOKFUNCTION(lms, GiveFragsForKill)
587{
589
591 {
592 // remove a life
593 int tl = GameRules_scoring_add(frag_target, LMS_LIVES, -1);
594 if(tl < lms_lowest_lives)
595 lms_lowest_lives = tl;
596 if(tl <= 0)
597 {
598 int pl_cnt = 0;
599 FOREACH_CLIENT(IS_PLAYER(it) && it.frags == FRAGS_PLAYER, {
600 ++pl_cnt;
601 });
603 GameRules_scoring_add(frag_target, LMS_RANK, pl_cnt);
604 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_LMS_NOLIVES, frag_target.netname);
605 }
606 }
607 M_ARGV(2, float) = 0; // frag score
608
609 return true;
610}
611
612MUTATOR_HOOKFUNCTION(lms, SetStartItems)
613{
615 if(!cvar("g_use_ammunition"))
617
618 start_health = warmup_start_health = cvar("g_lms_start_health");
619 start_armorvalue = warmup_start_armorvalue = cvar("g_lms_start_armor");
620 start_ammo_shells = warmup_start_ammo_shells = cvar("g_lms_start_ammo_shells");
621 start_ammo_nails = warmup_start_ammo_nails = cvar("g_lms_start_ammo_nails");
622 start_ammo_rockets = warmup_start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
623 start_ammo_cells = warmup_start_ammo_cells = cvar("g_lms_start_ammo_cells");
624 start_ammo_fuel = warmup_start_ammo_fuel = cvar("g_lms_start_ammo_fuel");
625}
626
627MUTATOR_HOOKFUNCTION(lms, FilterItemDefinition)
628{
630 return false;
631
632 entity def = M_ARGV(0, entity);
633 if (autocvar_g_powerups && autocvar_g_lms_extra_lives && (def == ITEM_ExtraLife || def == ITEM_HealthMega))
634 return false;
635
636 return true;
637}
638
640{
641 entity e = new(item_extralife);
642 Item_CopyFields(this, e);
643
644 StartItem(e, ITEM_ExtraLife);
645}
646
647MUTATOR_HOOKFUNCTION(lms, FilterItem)
648{
649 entity item = M_ARGV(0, entity);
650 entity def = item.itemdef;
651 if(def == ITEM_HealthMega && !(autocvar_g_lms_items || autocvar_g_pickup_items > 0))
652 {
655 return true;
656 }
657
658 return false;
659}
660
661MUTATOR_HOOKFUNCTION(lms, ItemTouch)
662{
663 if(MUTATOR_RETURNVALUE) return false;
664
665 entity item = M_ARGV(0, entity);
667
668 if(item.itemdef == ITEM_ExtraLife)
669 {
670 Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_EXTRALIVES, autocvar_g_lms_extra_lives);
672 Inventory_pickupitem(item.itemdef, toucher);
674 }
675
677}
678
680{
682 if (INGAME(it))
683 ++M_ARGV(0, int); // activerealplayers
684 ++M_ARGV(1, int); // realplayers
685 });
686
687 return true;
688}
689
690MUTATOR_HOOKFUNCTION(lms, ClientCommand_Spectate)
691{
692 entity player = M_ARGV(0, entity);
693 if(player.frags != FRAGS_SPECTATOR && player.frags != FRAGS_PLAYER_OUT_OF_GAME)
695 // ranked players (out of game) can no longer become real spectators
696 return MUT_SPECCMD_RETURN;
697}
698
700{
701 M_ARGV(0, float) = WinningCondition_LMS();
702 return true;
703}
704
705MUTATOR_HOOKFUNCTION(lms, SetWeaponArena)
706{
707 if(M_ARGV(0, string) == "0" || M_ARGV(0, string) == "")
709}
710
711MUTATOR_HOOKFUNCTION(lms, AddPlayerScore)
712{
713 if(game_stopped)
714 if(M_ARGV(0, entity) == SP_LMS_RANK) // score field
715 return true; // allow writing to this field in intermission as it is needed for newly joining players
716}
717
719{
720 lms_lowest_lives = 999;
721}
#define MUTATOR_HOOKFUNCTION(...)
Definition base.qh:335
const int CBC_ORDER_EXCLUSIVE
Definition base.qh:12
#define MUTATOR_RETURNVALUE
Definition base.qh:328
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
void SetResource(entity e, Resource res_type, float amount)
Sets the current amount of resource the given entity will have.
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
bool warmup_stage
Definition main.qh:120
#define colormapPaletteColor(c, isPants)
Definition color.qh:5
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
#define autocvar_fraglimit
Definition stats.qh:90
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
const int FRAGS_PLAYER
not 0 because all fields are initially 0
Definition constants.qh:3
const int FRAGS_SPECTATOR
engine expects this value
Definition constants.qh:5
const float EF_ADDITIVE
const float EF_FULLBRIGHT
float time
RES_ARMOR
Definition ent_cs.qc:155
SetResourceExplicit(ent, RES_ARMOR, ReadByte() *DEC_FACTOR)) ENTCS_PROP(NAME
bool intermission_running
void Inventory_pickupitem(Pickup this, entity player)
Definition inventory.qh:161
#define PlayerPreThink
Definition _all.inc:258
#define PutClientInServer
Definition _all.inc:250
#define ClientDisconnect
Definition _all.inc:246
#define STAT(...)
Definition stats.qh:94
#define LOG_TRACE(...)
Definition log.qh:74
bool autocvar_g_campaign
Definition menu.qc:752
float bound(float min, float value, float max)
float cvar(string name)
float random(void)
float min(float f,...)
float floor(float f)
float max(float f,...)
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1500
#define TRANSMUTE(cname, this,...)
Definition oo.qh:139
#define NULL
Definition post.qh:14
float DEAD_DYING
Definition progsdefs.qc:275
float DEAD_RESPAWNING
Definition progsdefs.qc:278
void WinningConditionHelper(entity this)
Sets the following results for the current scores entities.
Definition scores.qc:440
vector
Definition self.qh:96
entity entity toucher
Definition self.qh:76
bool campaign_bots_may_start
campaign mode: bots shall spawn but wait for the player to spawn before they do anything in other gam...
Definition campaign.qh:26
const int RESPAWN_SILENT
Definition client.qh:327
float jointime
Definition client.qh:66
const int RESPAWN_FORCE
Definition client.qh:326
void Item_CopyFields(entity this, entity to)
Definition items.qc:851
void StartItem(entity this, entity def)
Definition items.qc:1007
int autocvar_g_pickup_items
Definition items.qh:11
@ MUT_ITEMTOUCH_PICKUP
Definition events.qh:736
@ MUT_ITEMTOUCH_CONTINUE
Definition events.qh:734
@ MUT_SPECCMD_RETURN
Definition events.qh:999
@ MUT_SPECCMD_CONTINUE
Definition events.qh:998
float WinningConditionHelper_secondscore
second highest score
Definition scores.qh:108
entity WinningConditionHelper_winner
the winning player, or NULL if none
Definition scores.qh:112
float WinningConditionHelper_topscore
highest score
Definition scores.qh:107
ClientState CS(Client this)
Definition state.qh:47
float frag_damage
Definition sv_ctf.qc:2316
entity frag_target
Definition sv_ctf.qc:2315
int autocvar_g_lms_last_join
Definition sv_lms.qc:12
int autocvar_g_lms_leader_lives_diff
Definition sv_lms.qc:15
void lms_RemovePlayer(entity player)
Definition sv_lms.qc:338
float autocvar_g_lms_dynamic_vampire_factor_base
Definition sv_lms.qc:25
float autocvar_g_lms_dynamic_vampire_factor_increase
Definition sv_lms.qc:26
void lms_UpdateLeaders()
Definition sv_lms.qc:171
void ClearWinners()
Definition world.qc:1552
int LMS_NewPlayerLives()
Definition sv_lms.qc:38
bool autocvar_g_lms_rot
Definition sv_lms.qc:35
bool lms_AddPlayer(entity player)
Definition sv_lms.qc:254
bool autocvar_g_lms_dynamic_vampire
Definition sv_lms.qc:24
float autocvar_g_lms_dynamic_respawn_delay_increase
Definition sv_lms.qc:22
bool lms_visible_leaders_prev
Definition sv_lms.qc:34
float autocvar_g_lms_dynamic_respawn_delay_base
Definition sv_lms.qc:21
float autocvar_g_lms_dynamic_vampire_factor_max
Definition sv_lms.qc:27
void lms_replace_with_extralife(entity this)
Definition sv_lms.qc:639
float autocvar_g_lms_leader_minpercent
Definition sv_lms.qc:16
bool autocvar_g_lms_items
Definition sv_lms.qc:13
float lms_visible_leaders_time
Definition sv_lms.qc:32
float last_forfeiter_health
Definition sv_lms.qc:293
int lms_leaders_lives_diff
Definition sv_lms.qc:170
float autocvar_g_lms_dynamic_respawn_delay_max
Definition sv_lms.qc:23
void lms_Initialize()
Definition sv_lms.qc:718
int autocvar_g_lms_extra_lives
Definition sv_lms.qc:9
float autocvar_g_lms_dynamic_respawn_delay
Definition sv_lms.qc:20
float autocvar_g_lms_forfeit_min_match_time
Definition sv_lms.qc:10
int last_forfeiter_lives
Definition sv_lms.qc:292
bool autocvar_g_lms_join_anytime
Definition sv_lms.qc:11
bool autocvar_g_lms_regenerate
Definition sv_lms.qc:14
float autocvar_g_lms_leader_wp_interval_jitter
Definition sv_lms.qc:18
float lms_leader
Definition sv_lms.qc:30
float autocvar_g_lms_leader_wp_time
Definition sv_lms.qc:19
int WinningCondition_LMS()
Definition sv_lms.qc:60
int lms_leaders
Definition sv_lms.qc:31
float autocvar_g_lms_leader_wp_interval
Definition sv_lms.qc:17
bool lms_waypointsprite_visible_for_player(entity this, entity player, entity view)
Definition sv_lms.qc:158
float last_forfeiter_armorvalue
Definition sv_lms.qc:294
int autocvar_g_lms_dynamic_vampire_min_lives_diff
Definition sv_lms.qc:28
bool lms_visible_leaders
Definition sv_lms.qc:33
string autocvar_g_lms_weaponarena
Definition sv_lms.qh:11
int lms_lowest_lives
Definition sv_lms.qh:35
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(client, fld, value)
Definition sv_rules.qh:85
#define INGAME_STATUS_CLEAR(it)
Definition sv_rules.qh:22
#define INGAME_STATUS_SET(it, s)
Definition sv_rules.qh:21
#define INGAME_JOINING(it)
Definition sv_rules.qh:26
#define IS_SPEC(v)
Definition utils.qh:10
#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 WaypointSprite_Kill(entity wp)
void WaypointSprite_UpdateTeamRadar(entity e, entity icon, vector col)
void WaypointSprite_Ping(entity e)
entity WaypointSprite_AttachCarrier(entity spr, entity carrier, entity icon)
void WaypointSprite_UpdateRule(entity e, float t, float r)
const int SPRITERULE_DEFAULT
void CheckRules_World()
Definition world.qc:1723
const int WINNING_NEVER
Definition world.qh:134
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
const int WINNING_NO
Definition world.qh:132
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
float warmup_start_ammo_fuel
Definition world.qh:106
const int WINNING_YES
Definition world.qh:133
float start_health
Definition world.qh:96
bool sv_ready_restart_after_countdown
Definition world.qh:116
float warmup_start_armorvalue
Definition world.qh:108
float start_ammo_nails
Definition world.qh:85