Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
main.qc
Go to the documentation of this file.
1#include "main.qh"
2
4#include <client/draw.qh>
5#include <client/hud/_mod.qh>
10#include <client/items/items.qh>
12#include <client/shownames.qh>
13#include <client/view.qh>
18#include <common/effects/all.qh>
21#include <common/ent_cs.qh>
23#include <common/items/_mod.qh>
24#include <common/mapinfo.qh>
29#include <common/net_linked.qh>
30#include <common/net_notice.qh>
31#include <common/scores.qh>
37
38// --------------------------------------------------------------------------
39// BEGIN REQUIRED CSQC FUNCTIONS
40//include "main.qh"
41
42#define DP_CSQC_ENTITY_REMOVE_IS_B0RKED
43
44// CSQC_Init : Called every time the CSQC code is initialized (essentially at map load)
45// Useful for precaching things
46
47void CSQC_Init(float apilevel, string enginename, float engineversion)
48{
49 prvm_language = strzone(cvar_string("prvm_language"));
50
51#ifdef WATERMARK
52 LOG_TRACEF("^4CSQC Build information: ^1%s", WATERMARK);
53#endif
54
56
57 {
58 int i = 0;
59 for ( ; i < 255; ++i)
60 if (getplayerkeyvalue(i, "viewentity") == "")
61 break;
62 maxclients = i;
63 }
64
65 // needs to be done so early because of the constants they create
69
70 binddb = db_create();
71 tempdb = db_create();
72 ClientProgsDB = db_load("client.db");
73
75
76 //registercommand("hud_configure");
77 //registercommand("hud_save");
78 //registercommand("menu_action");
79
81
82 registercvar("hud_usecsqc", "1");
83 registercvar("scoreboard_columns", "default");
84
85 registercvar("cl_nade_type", "3");
86 registercvar("cl_pokenade_type", "zombie");
87
88 registercvar("cl_jumpspeedcap_min", "");
89 registercvar("cl_jumpspeedcap_max", "");
90
91 registercvar("cl_shootfromfixedorigin", "");
92
93 registercvar("cl_multijump", "-1");
94
95 registercvar("cl_dodging", "0");
96
97 registercvar("cl_autoswitch_cts", "-1");
98
99 registercvar("cl_spawn_near_teammate", "1");
100
101 registercvar("cl_weapon_switch_reload", "1");
102 registercvar("cl_weapon_switch_fallback_to_impulse", "1");
103
104 registercvar("cl_allow_uidranking", "1");
105
107 cvar_set("cl_lockview", "0");
108
109 if (cvar_type("_scoreboard_team_selection_available") & CVAR_TYPEFLAG_EXISTS)
110 cvar_settemp("_scoreboard_team_selection_available", "1");
111 cvar_set("_scoreboard_team_selection", "0"); // in case it has been left set to 1
112
113 // XONRELEASE: default values for <= 0.8.6 can be removed after next release
114 registercvar("hud_panel_checkpoints_pos", "0.700000 0.190000");
115 registercvar("hud_panel_checkpoints_size", "0.250000 0.170000");
116
117 gametype = NULL;
118
119 postinit = false;
120
121 calledhooks = 0;
122
123 teams = Sort_Spawn();
125
126 GetTeam(NUM_SPECTATOR, true); // add specs first
127
128 for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
129 weapon_accuracy[w] = -1;
130
131 // precaches
132
134 {
135 precache_pic("gfx/reticle_normal");
136 // weapon reticles are precached in weapon files
137 }
138
139 {
140 get_mi_min_max_texcoords(1); // try the CLEVER way first
141 minimapname = strcat("gfx/", mi_shortname, "_radar");
142
143 if (precache_pic(minimapname) == "")
144 {
145 // but maybe we have a non-clever minimap
146 minimapname = strcat("gfx/", mi_shortname, "_mini");
147 if (precache_pic(minimapname) == "")
148 minimapname = ""; // FAIL
149 else
150 get_mi_min_max_texcoords(0); // load new texcoords
151 }
152
153 mi_center = (mi_min + mi_max) * 0.5;
156 }
157
160}
161
162// CSQC_Shutdown : Called every time the CSQC code is shutdown (changing maps, quitting, etc)
164{
166
167 delete(teams);
168 delete(players);
172 db_dump(ClientProgsDB, "client.db");
173 else
174 db_save(ClientProgsDB, "client.db");
176
177 if(camera_active)
178 cvar_set("chase_active",ftos(chase_active_backup));
179
180 // unset the event chasecam's chase_active
182 cvar_set("chase_active", "0");
183
185 cvar_set("r_drawviewmodel", "0");
186
187 cvar_set("slowmo", cvar_defstring("slowmo")); // reset it back to 'default'
188
189 // if _cl_hook_gamestart wasn't called with an actual gametype
190 // before CSQC VM shutdown then call it with nop fallback here
191 if (!(calledhooks & HOOK_START) && !isdemo())
192 localcmd("\n_cl_hook_gamestart nop\n");
193
194 // fire game or demo end hooks when CSQC VM shuts down
195 if (!(calledhooks & HOOK_END))
196 {
197 // call gameend hook if it hasn't somehow yet fired by intermission starting
198 if (!isdemo())
199 {
200 localcmd("\ncl_hook_gameend\n");
201
202 // NOTE: using localcmd here to ensure it's executed AFTER cl_hook_gameend
203 // earlier versions of the game abuse the hook to set this cvar
204 int gamecount = cvar("cl_matchcount");
205 localcmd(strcat("cl_matchcount ", itos(gamecount + 1), "\n"));
206 //cvar_set("cl_matchcount", itos(gamecount + 1));
207 }
208 else
209 localcmd("\ncl_hook_demoend\n");
210
211 calledhooks |= HOOK_END; // mark the hook as having fired
212 }
213
214 localcmd("\ncl_hook_shutdown\n");
215
216 localcmd("\n-button12\n");
217
219
222
224}
225
227{
228 entity e;
230 for(e = prev.sort_next; e; prev = e, e = e.sort_next)
231 {
232 if(prev != e.sort_prev)
233 error(strcat("sort list chain error\nplease submit the output of 'prvm_edicts client' to the developers"));
234 }
235
236 prev = teams;
237 for(e = prev.sort_next; e; prev = e, e = e.sort_next)
238 {
239 if(prev != e.sort_prev)
240 error(strcat("sort list chain error\nplease submit the output of 'prvm_edicts client' to the developers"));
241 }
242}
243
245{
246 entity pl;
247 AuditLists();
248 for(pl = players.sort_next; pl; pl = pl.sort_next)
249 if(pl == player)
250 error("Player already registered!");
251 player.sort_next = players.sort_next;
252 player.sort_prev = players;
253 if(players.sort_next)
254 players.sort_next.sort_prev = player;
255 players.sort_next = player;
256 AuditLists();
257 return true;
258}
259
261{
262 entity pl, parent;
263 AuditLists();
264 parent = players;
265 for(pl = players.sort_next; pl && pl != player; pl = pl.sort_next)
266 parent = pl;
267
268 if(!pl)
269 {
270 error("Trying to remove a player which is not in the playerlist!");
271 return;
272 }
273 parent.sort_next = player.sort_next;
274 if(player.sort_next)
275 player.sort_next.sort_prev = parent;
276 AuditLists();
277}
278
280{
281 AuditLists();
282 entity ent = e.sort_next;
283 while(ent)
284 {
285 SORT_SWAP(ent, e);
286 ent = e.sort_next;
287 }
288 AuditLists();
289}
290
292{
293 assert_once(Team.team, eprint(Team));
294 entity tm;
295 AuditLists();
296 for(tm = teams.sort_next; tm; tm = tm.sort_next)
297 if(tm == Team)
298 error("Team already registered!");
299 Team.sort_next = teams.sort_next;
300 Team.sort_prev = teams;
301 if(teams.sort_next)
302 teams.sort_next.sort_prev = Team;
303 teams.sort_next = Team;
304 if(Team.team && Team.team != NUM_SPECTATOR)
305 ++team_count;
306 AuditLists();
307 return true;
308}
309
311{
312 entity tm, parent;
313 AuditLists();
314 parent = teams;
315 for(tm = teams.sort_next; tm && tm != Team; tm = tm.sort_next)
316 parent = tm;
317
318 if(!tm)
319 {
320 LOG_INFO(_("Trying to remove a team which is not in the teamlist!"));
321 return;
322 }
323 parent.sort_next = Team.sort_next;
324 if(Team.sort_next)
325 Team.sort_next.sort_prev = parent;
326 if(Team.team && Team.team != NUM_SPECTATOR)
327 --team_count;
328 AuditLists();
329}
330
331entity GetTeam(int Team, bool add)
332{
333 TC(int, Team); TC(bool, add);
334 int num = (Team == NUM_SPECTATOR) ? 16 : Team;
335 if(teamslots[num])
336 return teamslots[num];
337 if (!add)
338 return NULL;
339 entity tm = new_pure(team);
340 tm.team = Team;
341 teamslots[num] = tm;
342 RegisterTeam(tm);
343 return tm;
344}
345
346.float has_team;
347bool SetTeam(entity o, int Team)
348{
349 TC(int, Team);
350 //devassert_once(Team);
351 entity tm;
352 if(teamplay)
353 {
354 switch(Team)
355 {
356 case -1:
357 case NUM_TEAM_1:
358 case NUM_TEAM_2:
359 case NUM_TEAM_3:
360 case NUM_TEAM_4:
361 break;
362 default:
363 if(GetTeam(Team, false) == NULL)
364 {
365 LOG_TRACEF("trying to switch to unsupported team %d", Team);
366 Team = NUM_SPECTATOR;
367 }
368 break;
369 }
370 }
371 else
372 {
373 switch(Team)
374 {
375 case -1:
376 case 0:
377 break;
378 default:
379 if(GetTeam(Team, false) == NULL)
380 {
381 LOG_TRACEF("trying to switch to unsupported team %d", Team);
382 Team = NUM_SPECTATOR;
383 }
384 break;
385 }
386 }
387 if(Team == -1) // leave
388 {
389 if(o.has_team)
390 {
391 tm = GetTeam(o.team, false);
392 --tm.team_size;
393 o.has_team = 0;
394 return true;
395 }
396 }
397 else
398 {
399 if (!o.has_team)
400 {
401 o.team = Team;
402 tm = GetTeam(Team, true);
403 ++tm.team_size;
404 o.has_team = 1;
405 return true;
406 }
407 else if(Team != o.team)
408 {
409 tm = GetTeam(o.team, false);
410 --tm.team_size;
411 o.team = Team;
412 tm = GetTeam(Team, true);
413 ++tm.team_size;
414 return true;
415 }
416 }
417 return false;
418}
419
421{
422 int i;
423 entity e;
424 for(i = 0; i < maxclients; ++i)
425 {
426 e = playerslots[i];
427 if(entcs_GetName(i) == "")
428 {
429 if(e.sort_prev)
430 {
431 // player disconnected
432 SetTeam(e, -1);
433 RemovePlayer(e);
434 e.sort_prev = NULL;
435 //e.gotscores = 0;
436 }
437 }
438 else
439 {
440 if (!e.sort_prev)
441 {
442 // player connected
443 if (!e)
444 {
445 playerslots[i] = e = new_pure(playerslot);
446 }
447 e.sv_entnum = i;
448 e.ping = 0;
449 e.ping_packetloss = 0;
450 e.ping_movementloss = 0;
451 //e.gotscores = 0; // we might already have the scores...
452 int t = entcs_GetScoreTeam(i);
453 if (t) SetTeam(e, t); // will not hurt; later updates come with Scoreboard_UpdatePlayerTeams
456 }
457 }
458 }
459 this.nextthink = time + 0.2;
460}
461
463{
464 entity playerchecker = new_pure(playerchecker);
465 setthink(playerchecker, Playerchecker_Think);
466 playerchecker.nextthink = time + 0.2;
467
468 TrueAim_Init();
469
470 // this can't be called in CSQC_Init as it'd send cvars too early
472
473 postinit = true;
474}
475
477{
478 localcmd("-fire\n");
479 localcmd("-fire2\n");
480 localcmd("-use\n");
481 localcmd("-hook\n");
482 localcmd("-jump\n");
483 localcmd("-forward\n");
484 localcmd("-back\n");
485 localcmd("-moveleft\n");
486 localcmd("-moveright\n");
487}
488
489// CSQC_InputEvent : Used to perform actions based on any key pressed, key released and mouse on the client.
490// Return value should be 1 if CSQC handled the input, otherwise return 0 to have the input passed to the engine.
491// All keys are in ascii.
492// bInputType = 0 is key pressed, 1 is key released, 2 and 3 are mouse input.
493// In the case of keyboard input, nPrimary is the ascii code, and nSecondary is 0.
494// In the case of mouse input, nPrimary is xdelta, nSecondary is ydelta.
495// In the case of mouse input after a setcursormode(1) call, nPrimary is xpos, nSecondary is ypos.
496float CSQC_InputEvent(int bInputType, float nPrimary, float nSecondary)
497{
498 TC(int, bInputType);
499 bool override = false;
500
501 override |= HUD_Scoreboard_InputEvent(bInputType, nPrimary, nSecondary);
502 if (override)
503 return true;
504
505 override |= HUD_Panel_InputEvent(bInputType, nPrimary, nSecondary);
506 if (override)
507 return true;
508
509 override |= View_InputEvent(bInputType, nPrimary, nSecondary);
510 if (override)
511 return true;
512
513 override |= HUD_Panel_Chat_InputEvent(bInputType, nPrimary, nSecondary);
514
515 override |= QuickMenu_InputEvent(bInputType, nPrimary, nSecondary);
516
517 override |= HUD_Radar_InputEvent(bInputType, nPrimary, nSecondary);
518
519 override |= MapVote_InputEvent(bInputType, nPrimary, nSecondary);
520
521 override |= HUD_Minigame_InputEvent(bInputType, nPrimary, nSecondary);
522
523 if(override)
524 return true;
525
526 if(bInputType == 3 || bInputType == 2)
527 return false;
528
529 // at this point bInputType can only be 0 or 1 (key pressed or released)
530 bool key_pressed = (bInputType == 0);
531
532 if(key_pressed) {
533 if(nPrimary == K_ALT) hudShiftState |= S_ALT;
534 if(nPrimary == K_CTRL) hudShiftState |= S_CTRL;
535 if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
536 if(nPrimary == K_TAB) hudShiftState |= S_TAB;
537 }
538 else {
539 if(nPrimary == K_ALT) hudShiftState &= ~S_ALT;
540 if(nPrimary == K_CTRL) hudShiftState &= ~S_CTRL;
541 if(nPrimary == K_SHIFT) hudShiftState &= ~S_SHIFT;
542 if(nPrimary == K_TAB) hudShiftState &= ~S_TAB;
543 }
544
545 // NOTE: Shift-Escape must be filtered out because it's the hardcoded console shortcut
546 if (nPrimary == K_ESCAPE && !(hudShiftState & S_SHIFT) && key_pressed)
547 {
548 if (hudShiftState & S_TAB)
549 {
551 return true;
552 }
553 if (autocvar_menu_gamemenu && !isdemo() && cvar("_menu_gamemenu_dialog_available"))
554 {
555 localcmd("\nmenu_showgamemenudialog\n");
556 return true;
557 }
558 }
559
560 return false;
561}
562
563// END REQUIRED CSQC FUNCTIONS
564// --------------------------------------------------------------------------
565
566// --------------------------------------------------------------------------
567// BEGIN OPTIONAL CSQC FUNCTIONS
570{
571 if(this.owner) {
572 SetTeam(this.owner, -1);
573 this.owner.gotscores = 0;
574 FOREACH(Scores, true, {
575 this.owner.(scores(it)) = 0; // clear all scores
576 });
577 this.owner.ready = 0;
578 this.owner.eliminated = 0;
579 this.owner.ignored = false;
580 this.owner.colormap = 0;
581 // TODO add a hook to reset this Survival field
582 this.owner.survival_status = 0;
583 }
584}
585
586NET_HANDLE(ENT_CLIENT_SCORES, bool isnew)
587{
588 make_pure(this);
589 entity o;
590
591 // damnit -.- don't want to go change every single .sv_entnum in hud.qc AGAIN
592 // (no I've never heard of M-x replace-string, sed, or anything like that)
593 bool isNew = !this.owner; // workaround for DP bug
594 int n = ReadByte()-1;
595
596#ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
597 if(!isNew && n != this.sv_entnum)
598 {
599 //print("A CSQC entity changed its owner!\n");
600 LOG_INFOF("A CSQC entity changed its owner! (edict: %d, classname: %s)", etof(this), this.classname);
601 isNew = true;
602 Ent_Remove(this);
603 }
604#endif
605
606 this.sv_entnum = n;
607
608 o = playerslots[this.sv_entnum];
609 if (!o)
610 {
611 o = playerslots[this.sv_entnum] = new_pure(playerslot);
612 }
613 this.owner = o;
614 o.sv_entnum = this.sv_entnum;
615 o.gotscores = 1;
616
617 //if (!o.sort_prev)
618 // RegisterPlayer(o);
619 //playerchecker will do this for us later, if it has not already done so
620
621 int sf = ReadShort();
622 int lf = ReadShort();
623 FOREACH(Scores, true, {
624 int p = BIT(i % 16);
625 if (sf & p)
626 {
627 if (lf & p)
628 o.(scores(it)) = ReadInt24_t();
629 else
630 o.(scores(it)) = ReadChar();
631 }
632 });
633
634 return = true;
635
636 if(o.sort_prev)
637 Scoreboard_UpdatePlayerPos(o); // if not registered, we cannot do this yet!
638
639 this.entremove = Ent_RemovePlayerScore;
640}
641
642NET_HANDLE(ENT_CLIENT_TEAMSCORES, bool isnew)
643{
644 make_pure(this);
645 int i;
646
647 this.team = ReadByte();
648 entity o = this.owner = GetTeam(this.team, true); // these team numbers can always be trusted
649
650#if MAX_TEAMSCORE <= 8
651 int sf = ReadByte();
652 int lf = ReadByte();
653#else
654 int sf = ReadShort();
655 int lf = ReadShort();
656#endif
657 for(i = 0; i < MAX_TEAMSCORE; ++i)
658 if(sf & BIT(i))
659 {
660 if(lf & BIT(i))
661 o.(teamscores(i)) = ReadInt24_t();
662 else
663 o.(teamscores(i)) = ReadChar();
664 }
665
666 return = true;
667
669}
670
672{
673 for (entity pl = players.sort_next; pl; pl = pl.sort_next)
674 pl.ignored = false;
675
677
678 if (ignore_list == "")
679 return;
680
682 {
683 bool found = false;
684 int ignore_id = stoi(it);
685 for (entity pl = players.sort_next; pl; pl = pl.sort_next)
686 {
687 if (ignore_id == pl.sv_entnum + 1)
688 {
689 pl.ignored = true;
690 found = true;
691 break;
692 }
693 }
694 // when an ignored player is not found, it means their playerslot is not initialized yet
695 if (!found)
696 ignore_list_apply_time = time + 0.5; // retry after a while
697 });
698
699 if (ignore_list_apply_time == 0) // ignore_list applied
701}
702
703NET_HANDLE(ENT_CLIENT_CLIENTDATA, bool isnew)
704{
705 make_pure(this);
706 int newspectatee_status;
707
708 int f = ReadByte();
709
711
712 if(f & BIT(1))
713 {
714 newspectatee_status = ReadByte();
715 if(newspectatee_status == player_localnum + 1)
716 newspectatee_status = -1; // observing
717 }
718 else
719 newspectatee_status = 0;
720
721 spectatorbutton_zoom = (f & BIT(2));
722 observe_blocked = (f & BIT(3));
723
724 if(f & BIT(4))
725 {
727
728 float i, slot;
729
730 for(i = 0; i < MAX_SPECTATORS; ++i)
731 spectatorlist[i] = 0; // reset list first
732
733 int limit = min(num_spectators, MAX_SPECTATORS);
734 for(i = 0; i < limit; ++i)
735 {
736 slot = ReadByte();
737 spectatorlist[i] = slot - 1;
738 }
739 }
740 else
741 {
742 for(int j = 0; j < MAX_SPECTATORS; ++j)
743 spectatorlist[j] = 0; // reset list if showspectators has been turned off
744 num_spectators = 0;
745 }
746
747 return = true;
748
749 if(newspectatee_status != spectatee_status)
750 {
753 }
755 {
756 if ( (spectatee_status == -1 && newspectatee_status > 0) //before observing, now spectating
757 || (spectatee_status > 0 && newspectatee_status > 0 && spectatee_status != newspectatee_status) //changed spectated player
758 )
759 prev_p_health = -1;
760 else if(spectatee_status && !newspectatee_status) //before observing/spectating, now playing
761 prev_health = -1;
762 }
763 spectatee_status = newspectatee_status;
764
765 // we could get rid of spectatee_status, and derive it from player_localentnum and player_localnum
766
767 teamnagger = (f & 0x60) >> 5; // 0x60 = BIT(5) | BIT(6)
768
769 if (f & BIT(7))
770 {
773 }
774}
775
776NET_HANDLE(ENT_CLIENT_NAGGER, bool isnew)
777{
778 make_pure(this);
779
780 int nags = ReadByte(); // NAGS NAGS NAGS NAGS NAGS NAGS NADZ NAGS NAGS NAGS
781
782 if(!(nags & BIT(2)))
783 {
785 vote_active = 0;
786 }
787 else
788 {
789 vote_active = 1;
790 }
791
792 if(nags & BIT(6))
793 {
797 vote_highlighted = ReadChar();
798 }
799
800 if(nags & BIT(7))
801 {
803 }
804
805 if(nags & BIT(0))
806 for(int i = 0; i < maxclients;)
807 for(int f = ReadByte(), b = 0; b < 8 && i < maxclients; ++b, ++i)
808 if(playerslots[i])
809 playerslots[i].ready = f & BIT(b);
810
811 return = true;
812
813 ready_waiting = (nags & BIT(0));
814 ready_waiting_for_me = (nags & BIT(1));
815 vote_waiting = (nags & BIT(2));
816 vote_waiting_for_me = (nags & BIT(3));
817 warmup_stage = (nags & BIT(4));
818}
819
820NET_HANDLE(ENT_CLIENT_ELIMINATEDPLAYERS, bool isnew)
821{
822 make_pure(this);
823 for (int j = 0; j < maxclients; ++j) {
824 if (playerslots[j]) {
825 playerslots[j].eliminated = true;
826 }
827 }
828 for (int i = 1; i <= maxclients; i += 8) {
829 int f = ReadByte();
830 for (int b = 0; b < 8; ++b) {
831 if (f & BIT(b)) continue;
832 int j = i - 1 + b;
833 if (playerslots[j]) {
834 playerslots[j].eliminated = false;
835 }
836 }
837 }
838 return true;
839}
840
841NET_HANDLE(ENT_CLIENT_RANDOMSEED, bool isnew)
842{
843 make_pure(this);
845 float s = ReadShort();
846 psrandom(s);
847 return true;
848}
849
850NET_HANDLE(ENT_CLIENT_ACCURACY, bool isnew)
851{
852 make_pure(this);
853 int sf = ReadInt24_t();
854 if (sf == 0) {
855 for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
856 weapon_accuracy[w] = -1;
857 return true;
858 }
859
860 int f = 1;
861 for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w) {
862 if (sf & f) {
863 int b = ReadByte();
864 if (b == 0)
865 weapon_accuracy[w] = -1;
866 else if (b == 255)
867 weapon_accuracy[w] = 1.0; // no better error handling yet, sorry
868 else
869 weapon_accuracy[w] = (b - 1.0) / 100.0;
870 }
871 f = (f == 0x800000) ? 1 : f * 2;
872 }
873 return true;
874}
875
876// CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured.
877// The parameter isnew reflects if the entity is "new" to the client, meaning it just came into the client's PVS.
878void CSQC_Ent_Update(entity this, bool isnew)
879{
880 this.sourceLoc = __FILE__":"STR(__LINE__);
881 int t = ReadByte();
882
883 // set up the "time" global for received entities to be correct for interpolation purposes
884 float savetime = time;
885 if(servertime)
886 {
888 }
889 else
890 {
892 serverdeltatime = STAT(MOVEVARS_TICRATE) * STAT(MOVEVARS_TIMESCALE);
894 }
895
896#ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
897 if (this.enttype)
898 {
899 if (t != this.enttype || isnew)
900 {
901 LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)", etof(this), this.entnum, this.enttype, t);
902 Ent_Remove(this);
903 ONREMOVE(this);
904 clearentity(this);
905 isnew = true;
906 }
907 }
908 else
909 {
910 if (!isnew)
911 {
912 LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)", etof(this), this.entnum, t);
913 isnew = true;
914 }
915 }
916#endif
917 this.enttype = t;
918 bool done = false;
919 FOREACH(LinkedEntities, it.m_id == t, {
920 if (isnew) this.classname = it.netname;
921 if (autocvar_developer_csqcentities)
922 LOG_INFOF("CSQC_Ent_Update(%i, %d) at %f {.entnum=%d, .enttype=%d} t=%s (%d)", this, isnew, savetime, this.entnum, this.enttype, this.classname, t);
923 done = it.m_read(this, NULL, isnew);
924 MUTATOR_CALLHOOK(Ent_Update, this, isnew);
925 break;
926 });
927 time = savetime;
928 if (!done)
929 {
930 LOG_FATALF("CSQC_Ent_Update(%i, %d) at %f {.entnum=%d, .enttype=%d} t=%s (%d)", this, isnew, savetime, this.entnum, this.enttype, this.classname, t);
931 }
932}
933
934// Destructor, but does NOT deallocate the entity by calling remove(). Also
935// used when an entity changes its type. For an entity that someone interacts
936// with others, make sure it can no longer do so.
938{
939 if(this.entremove) this.entremove(this);
940
941 if(this.skeletonindex)
942 {
943 skel_delete(this.skeletonindex);
944 this.skeletonindex = 0;
945 }
946
947 if(this.snd_looping > 0)
948 {
950 this.snd_looping = 0;
951 }
952
953 this.enttype = 0;
954 this.classname = "";
955 this.draw = func_null;
956 this.entremove = func_null;
957 // TODO possibly set more stuff to defaults
958}
959// CSQC_Ent_Remove : Called when the server requests a SSQC / CSQC entity to be removed. Essentially call remove(this) as well.
961{
962 if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Ent_Remove() with this=%i {.entnum=%d, .enttype=%d}", this, this.entnum, this.enttype);
963 if (wasfreed(this))
964 {
965 LOG_WARN("CSQC_Ent_Remove called for already removed entity. Packet loss?");
966 return;
967 }
968 if (this.enttype) Ent_Remove(this);
969 delete(this);
970}
971
973{
974 // fire game or demo start hooks here
975 if (!(calledhooks & HOOK_START))
976 {
977 if (!isdemo())
978 localcmd("\n_cl_hook_gamestart ", MapInfo_Type_ToString(gametype), "\n");
979 else
980 localcmd("\ncl_hook_demostart\n");
981
982 calledhooks |= HOOK_START; // mark start hook as fired
983 }
984}
985
986// CSQC_Parse_StuffCmd : Provides the stuffcmd string in the first parameter that the server provided. To execute standard behavior, simply execute localcmd with the string.
987void CSQC_Parse_StuffCmd(string strMessage)
988{
989 if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_StuffCmd(\"%s\")", strMessage);
990 localcmd(strMessage);
991}
992
993// CSQC_Parse_Print : Provides the print string in the first parameter that the server provided. To execute standard behavior, simply execute print with the string.
994void CSQC_Parse_Print(string strMessage)
995{
996 if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_Print(\"%s\")", strMessage);
997 print(ColorTranslateRGB(strMessage));
998}
999
1000// CSQC_Parse_CenterPrint : Provides the centerprint_AddStandard string in the first parameter that the server provided.
1001void CSQC_Parse_CenterPrint(string strMessage)
1002{
1003 if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_CenterPrint(\"%s\")", strMessage);
1004 centerprint_AddStandard(strMessage);
1005}
1006
1007// CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer.
1008// You must ALWAYS first acquire the temporary ID, which is sent as a byte.
1009// Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event.
1011{
1012 // Acquire TE ID
1013 int nTEID = ReadByte();
1014
1015 FOREACH(TempEntities, it.m_id == nTEID, {
1016 if (autocvar_developer_csqcentities)
1017 LOG_INFOF("CSQC_Parse_TempEntity() nTEID=%s (%d)", it.netname, nTEID);
1018 return it.m_read(NULL, NULL, true);
1019 });
1020
1022 LOG_INFOF("CSQC_Parse_TempEntity() with nTEID=%d", nTEID);
1023
1024 // No special logic for this temporary entity; return 0 so the engine can handle it
1025 return false;
1026}
1027
1030void Fog_Set(string fog, bool force)
1031{
1032 static string saved = string_null;
1033 if (force) // else just set the fog once
1034 strcpy(saved, fog);
1035 else if (saved)
1036 fog = saved;
1037
1039 {
1041 cvar_set("r_drawfog", "0");
1042 }
1043 else if (fog)
1044 {
1045 // "fog none" in the mapinfo just disables r_drawfog, client's worldspawn fog values aren't changed
1046 bool drawfog = boolean(fog != "");
1047 if (autocvar_r_drawfog != drawfog)
1048 cvar_set("r_drawfog", ftos(drawfog));
1050 cvar_set("r_fog_exp2", "0");
1051 if (fog != "")
1052 localcmd(strcat("\nfog ", fog, " \n"));
1053 }
1054}
1055
1057NET_HANDLE(ENT_CLIENT_SCORES_INFO, bool isnew)
1058{
1059 make_pure(this);
1060 gametype = ReadRegistered(Gametypes);
1064 FOREACH(Scores, true, {
1066 scores_flags(it) = ReadByte();
1067 });
1068 for (int i = 0; i < MAX_TEAMSCORE; ++i)
1069 {
1072 }
1073 bool welcome_msg_too = ReadByte();
1074 if (welcome_msg_too)
1075 net_handle_ServerWelcome(); // executes cl_hook_mutator_* hooks too
1076 return = true;
1078 Gametype_Init(); // executes cl_hook_gamestart_* hooks
1079}
1080
1081NET_HANDLE(ENT_CLIENT_INIT, bool isnew)
1082{
1083 nb_pb_period = ReadByte() / 32; //Accuracy of 1/32th
1084
1093
1095
1096 armorblockpercent = ReadByte() / 255.0;
1097 damagepush_speedfactor = ReadByte() / 255.0;
1098
1100
1101 g_trueaim_minrange = ReadCoord();
1102
1103 return = true;
1104
1105 MUTATOR_CALLHOOK(Ent_Init);
1106
1107 if (!postinit) PostInit();
1108}
1109
1110float GetSpeedUnitFactor(int speed_unit)
1111{
1112 switch(speed_unit)
1113 {
1114 default:
1115 case 1: return 1.0;
1116 case 2: return 0.0254;
1117 case 3: return 0.0254 * 3.6;
1118 case 4: return 0.0254 * 3.6 * 0.6213711922;
1119 case 5: return 0.0254 * 1.943844492; // 1 m/s = 1.943844492 knots, because 1 knot = 1.852 km/h
1120 }
1121}
1122
1123string GetSpeedUnit(int speed_unit)
1124{
1125 switch(speed_unit)
1126 {
1127 // translator-friendly strings without the initial space
1128 default:
1129 case 1: return strcat(" ", _("qu/s"));
1130 case 2: return strcat(" ", _("m/s"));
1131 case 3: return strcat(" ", _("km/h"));
1132 case 4: return strcat(" ", _("mph"));
1133 case 5: return strcat(" ", _("knots"));
1134 }
1135}
1136
1137NET_HANDLE(TE_CSQC_RACE, bool isNew)
1138{
1139 int b = ReadByte();
1140
1141 switch (b)
1142 {
1148 string pbestname = ReadString();
1153 {
1157 }
1158 else
1159 strcpy(race_previousbestname, pbestname);
1160
1162
1163 if(race_checkpoint == 0 || race_checkpoint == 254)
1164 {
1166 race_laptime = time; // valid
1167 }
1168 break;
1169
1171 race_laptime = 0;
1173 break;
1174
1176 race_laptime = ReadCoord();
1177 race_checkpointtime = -99999;
1178 // fall through
1181
1183 if(b != RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING) // not while spectating (matches server)
1185 string newname = ReadString();
1187 if(b != RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING) // not while spectating (matches server)
1190 {
1193 race_mybesttime = 0;
1194 race_mybestspeed = 0;
1196 }
1197 else
1198 strcpy(race_nextbestname, newname);
1199 break;
1200
1208 int who = ReadByte();
1209 if(who)
1211 else
1212 strcpy(race_mycheckpointenemy, ""); // TODO: maybe string_null works fine here?
1213 break;
1214
1222 int what = ReadByte();
1223 if(what)
1225 else
1226 strcpy(race_othercheckpointenemy, ""); // TODO: maybe string_null works fine here?
1227 break;
1228
1232 race_penaltytime = ReadShort();
1233 string reason = ReadString();
1234 if (reason == "missing a checkpoint")
1235 reason = _("missing a checkpoint");
1236 strcpy(race_penaltyreason, reason);
1239 break;
1240
1243 break;
1247 break;
1251 break;
1254 break;
1256 float prevpos, del;
1257 int pos = ReadShort();
1258 prevpos = ReadShort();
1259 del = ReadShort();
1260
1261 // move other rankings out of the way
1262 int i;
1263 if (prevpos) {
1264 int m = min(prevpos, RANKINGS_DISPLAY_CNT);
1265 for (i=m-1; i>pos-1; --i) {
1266 grecordtime[i] = grecordtime[i-1];
1268 }
1269 } else if (del) { // a record has been deleted by the admin
1270 for (i=pos-1; i<= RANKINGS_DISPLAY_CNT-1; ++i) {
1271 if (i == RANKINGS_DISPLAY_CNT-1) { // clear out last record
1272 grecordtime[i] = 0;
1274 }
1275 else {
1276 grecordtime[i] = grecordtime[i+1];
1278 }
1279 }
1280 } else { // player has no ranked record yet
1281 for (i=RANKINGS_DISPLAY_CNT-1;i>pos-1;--i) {
1282 grecordtime[i] = grecordtime[i-1];
1284 }
1285 }
1286
1288 // kick off the player who fell from the last displayed position
1291 }
1292
1293 // store new ranking
1294 strcpy(grecordholder[pos-1], ReadString());
1295 grecordtime[pos-1] = ReadInt24_t();
1296 if(strdecolorize(grecordholder[pos-1]) == strdecolorize(entcs_GetName(player_localnum)))
1297 race_myrank = pos;
1298 break;
1300 race_status = ReadShort();
1302 }
1303 return true;
1304}
1305
1306NET_HANDLE(TE_CSQC_PINGPLREPORT, bool isNew)
1307{
1308 int i = ReadByte();
1309 int pi = ReadShort();
1310 int pl = ReadByte();
1311 int ml = ReadByte();
1312 return = true;
1313 entity e = playerslots[i];
1314 if (!e) return;
1315 e.ping = pi;
1316 e.ping_packetloss = pl / 255.0;
1317 e.ping_movementloss = ml / 255.0;
1318}
1319
1320NET_HANDLE(TE_CSQC_WEAPONCOMPLAIN, bool isNew)
1321{
1322 int weapon_id = ReadByte();
1323 complain_weapon = REGISTRY_GET(Weapons, weapon_id);
1325 return = true;
1326
1328 weapontime = time; // ping the weapon panel
1329
1330 switch(complain_weapon_type)
1331 {
1332 case 0: Local_Notification(MSG_MULTI, ITEM_WEAPON_NOAMMO, weapon_id); break;
1333 case 1: Local_Notification(MSG_MULTI, ITEM_WEAPON_DONTHAVE, weapon_id); break;
1334 default: Local_Notification(MSG_MULTI, ITEM_WEAPON_UNAVAILABLE, weapon_id); break;
1335 }
1336}
1337
1338string build_weaponarena_list(int arena_type, WepSet set)
1339{
1340 switch (arena_type)
1341 {
1342 default:
1343 case WEPARENA_OFF: return "";
1344 case WEPARENA_NONE: return _("No Weapons Arena");
1345 case WEPARENA_ALL: return _("All Weapons Arena");
1346 case WEPARENA_ALL_AVAILABLE: return _("All Available Weapons Arena");
1347 case WEPARENA_STANDARD: return _("Standard Weapons Arena");
1348 case WEPARENA_STANDARD_AVAILABLE: return _("Standard Available Weapons Arena");
1349 case WEPARENA_EXTENDED: return _("Extended Weapons Arena");
1350 case WEPARENA_EXTENDED_AVAILABLE: return _("Extended Available Weapons Arena");
1351 case WEPARENA_DEVALL: return "Dev All Weapons Arena"; // development option, won't bother translating
1352 case WEPARENA_DEVALL_AVAILABLE: return "Dev All Available Weapons Arena"; // development option, won't bother translating
1353 case WEPARENA_CUSTOM:
1354 {
1355 string wpn_list = "";
1356 FOREACH(Weapons, it != WEP_Null && (set & it.m_wepset), wpn_list = cons_mid(wpn_list, " & ", it.m_name));
1357 return sprintf(_("%s Arena"), wpn_list); // it shouldn't be empty
1358 }
1359 }
1360}
1361
1362string GetVersionMessage(string hostversion, bool version_mismatch, bool version_check)
1363{
1364 string xonotic_hostversion = strcat("Xonotic ", hostversion);
1365 if (version_mismatch)
1366 {
1367 if(!version_check)
1368 return strcat(sprintf(_("This is %s"), xonotic_hostversion), "\n^3",
1369 _("Your client version is outdated."), "\n\n\n",
1370 _("### YOU WON'T BE ABLE TO PLAY ON THIS SERVER ###"), "\n\n\n",
1371 _("Please update!"));
1372 else
1373 return strcat(sprintf(_("This is %s"), xonotic_hostversion), "\n^3",
1374 _("This server is using an outdated Xonotic version."), "\n\n\n",
1375 _("### THIS SERVER IS INCOMPATIBLE AND THUS YOU CANNOT JOIN ###"));
1376 }
1377 return sprintf(_("Welcome to %s"), xonotic_hostversion);
1378}
1379
1381{
1382 int flags = ReadByte();
1383
1384 campaign = flags & 1;
1385 if (campaign)
1386 {
1387 int campaign_level = ReadByte();
1388 // Menu can't build the whole campaign message because it lacks getcommandkey and CCR
1389 // so we build part of the message here and let the menu insert the level description
1390 // (that client doesn't know) by replacing the keyword _LEVEL_DESC
1391 string key = getcommandkey(_("jump"), "+jump");
1392 string msg = strcat(
1393 CCR("^F1"), sprintf(_("Level %d:"), campaign_level),
1394 sprintf(CCR(" ^BG%s\n\n"), "_LEVEL_DESC"),
1395 sprintf(CCR(_("^BGPress ^F2%s^BG to enter the game")), key));
1396 msg = MakeConsoleSafe(strreplace("\n", "\\n", msg));
1397 string welcomedialog_args = strcat("CAMPAIGN ", itos(campaign_level), " \"", msg, "\"");
1398
1399 localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n");
1400 return true;
1401 }
1402
1404 string hostversion = ReadString();
1405 bool version_mismatch = flags & 2;
1406 bool version_check = flags & 4;
1408 MapInfo_Map_author = flags & 8 ? ReadString() : "";
1411 string modifications = build_mutator_list(ReadString()); // executes cl_hook_mutator_* hooks too
1412 int weaponarena_type = ReadByte();
1413 string weaponarena_list = build_weaponarena_list(weaponarena_type, (weaponarena_type == WEPARENA_CUSTOM) ? ReadWepSet() : '0 0 0');
1414 string cache_mutatormsg = ReadString();
1415 string motd = ReadString();
1416
1417 string msg = GetVersionMessage(hostversion, version_mismatch, version_check);
1418
1419 msg = strcat(msg, "\n\n", _("Gametype:"), " ^1", MapInfo_Type_ToText(gametype), "\n");
1420
1421 msg = strcat(msg, "\n", _("Map:"), " ", MapInfo_Map_titlestring, "\n");
1422 if (flags & 8)
1423 msg = strcat(msg, "^9", _("by:"), " ", MapInfo_Map_author, "\n");
1424
1426 {
1427 msg = strcat(msg, "\n", _("This match supports"), " ^5");
1429 msg = strcat(msg, sprintf(_("%d players"), srv_maxplayers), "\n");
1430 else if (srv_minplayers && srv_maxplayers)
1431 msg = strcat(msg, sprintf(_("%d to %d players"), srv_minplayers, srv_maxplayers), "\n");
1432 else if (srv_maxplayers)
1433 msg = strcat(msg, sprintf(_("%d players maximum"), srv_maxplayers), "\n");
1434 else
1435 msg = strcat(msg, sprintf(_("%d players minimum"), srv_minplayers), "\n");
1436 }
1437
1438 modifications = cons_mid(modifications, ", ", weaponarena_list);
1439 if(modifications != "")
1440 msg = strcat(msg, "\n", _("Active modifications:"), " ^3", modifications, "\n");
1441
1442 if (cache_mutatormsg != "")
1443 msg = strcat(msg, "\n", _("Special gameplay tips:"), " ^7", cache_mutatormsg, "\n");
1444 string mutator_msg = "";
1445 MUTATOR_CALLHOOK(BuildGameplayTipsString, mutator_msg);
1446 mutator_msg = M_ARGV(0, string);
1447 msg = strcat(msg, mutator_msg); // trust that the mutator will do proper formatting
1448
1449 if (motd != "")
1450 msg = strcat(msg, "\n^9↓ ", _("Server's message"), " ↓\n", motd);
1451
1452 strcpy(welcome_msg, msg);
1453 welcome_msg_menu_check_maxtime = time + 1; // wait for menu to load before showing the welcome dialog
1454 return true;
1455}
1456
1458{
1460 return;
1461
1462 // if want dialog check if menu is initialized but for a short time
1463 if (cvar("_menu_initialized") == 2 || time > welcome_msg_menu_check_maxtime)
1464 {
1465 if (cvar("_menu_welcome_dialog_available"))
1466 {
1467 string welcomedialog_args = strcat("HOSTNAME \"", hostname, "\"");
1468 string msg = MakeConsoleSafe(strreplace("\n", "\\n", welcome_msg));
1469 welcomedialog_args = strcat(welcomedialog_args, " WELCOME \"", msg, "\"");
1470
1472 {
1473 if (cvar("_menu_cmd_closemenu_available"))
1474 {
1475 // initialize the dialog without opening it
1476 localcmd("\nmenu_cmd closemenu Welcome ", welcomedialog_args, "\n");
1477 }
1478 else
1479 {
1480 // legacy code for clients with old menus
1481 // since togglemenu 0 doesn't close the dialog but only hides it,
1482 // playing back a demo the Welcome dialog will pop up on the first ESC press
1483 localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n");
1484 // close it after it's been initialized so it can still be opened manually
1485 localcmd("\ntogglemenu 0\n");
1486 }
1487 }
1488 else
1489 localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n");
1490 }
1491
1494 }
1495}
1496
1497NET_HANDLE(TE_CSQC_SERVERWELCOME, bool isNew)
1498{
1499 return net_handle_ServerWelcome();
1500}
1501
1502string _getcommandkey(string cmd_name, string command, bool forcename)
1503{
1505 return cmd_name;
1506
1507 string key, keys = db_get(binddb, command);
1508 int n, j, found = 0;
1509 float k;
1510
1511 if (keys == "")
1512 {
1513 const bool joy_active = cvar("joy_active");
1514 n = tokenize(findkeysforcommand(command, 0)); // uses '...' strings
1515 for (j = 0; j < n; ++j)
1516 {
1517 k = stof(argv(j));
1518 if (k == -1)
1519 continue;
1520 key = keynumtostring(k);
1521 if (!joy_active && startsWith(key, "JOY"))
1522 continue;
1523
1524 keys = cons_mid(keys, ", ", translate_key(key));
1525
1527 break;
1528 }
1529 if (keys == "")
1530 keys = "NO_KEY";
1531 db_put(binddb, command, keys);
1532 }
1533
1534 if (keys == "NO_KEY")
1535 {
1536 if (autocvar_hud_showbinds > 1)
1537 return sprintf(_("%s (not bound)"), cmd_name);
1538 else
1539 return cmd_name;
1540 }
1541 else if (autocvar_hud_showbinds > 1 || forcename)
1542 return sprintf("%s (%s)", cmd_name, keys);
1543 return keys;
1544}
1545
1547void URI_Get_Callback(int id, int status, string data)
1548{
1549 TC(int, id); TC(int, status);
1550 if(url_URI_Get_Callback(id, status, data))
1551 {
1552 // handled
1553 }
1554 else if (id == URI_GET_DISCARD)
1555 {
1556 // discard
1557 }
1558 else if (id >= URI_GET_CURL && id <= URI_GET_CURL_END)
1559 {
1560 // sv_cmd curl
1561 Curl_URI_Get_Callback(id, status, data);
1562 }
1563 else
1564 {
1565 LOG_INFOF("Received HTTP request data for an invalid id %d.", id);
1566 }
1567}
entity parent
Definition animhost.qc:7
vector arc_shotorigin[4]
Definition arc.qh:108
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
#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
void centerprint_AddStandard(string strMessage)
void CheckEngineExtensions(void)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
void ConsoleCommand_macro_init()
Definition cl_cmd.qc:605
float MapVote_InputEvent(int bInputType, float nPrimary, float nSecondary)
void deactivate_minigame()
#define ReadString
void HUD_MinigameMenu_Close(entity this, entity actor, entity trigger)
float HUD_Minigame_InputEvent(float bInputType, float nPrimary, float nSecondary)
float nb_pb_period
Definition cl_nexball.qh:7
#define draw_endBoldFont()
Definition draw.qh:5
float HUD_Panel_Chat_InputEvent(float bInputType, float nPrimary, float nSecondary)
Definition chat.qc:14
string build_weaponarena_list(int arena_type, WepSet set)
Definition main.qc:1338
string _getcommandkey(string cmd_name, string command, bool forcename)
Definition main.qc:1502
void CSQC_Parse_CenterPrint(string strMessage)
Definition main.qc:1001
void Ent_Remove(entity this)
Definition main.qc:937
void RemovePlayer(entity player)
Definition main.qc:260
string GetVersionMessage(string hostversion, bool version_mismatch, bool version_check)
Definition main.qc:1362
void AuditLists()
Definition main.qc:226
void Gametype_Init()
Definition main.qc:972
float has_team
Definition main.qc:346
void Welcome_Message_Show_Try()
Definition main.qc:1457
string GetSpeedUnit(int speed_unit)
Definition main.qc:1123
void Release_Common_Keys()
Definition main.qc:476
void PostInit()
Definition main.qc:462
int survival_status
Definition main.qc:568
void Ent_RemovePlayerScore(entity this)
Definition main.qc:569
bool net_handle_ServerWelcome()
Definition main.qc:1380
float RegisterTeam(entity Team)
Definition main.qc:291
void Fog_Set(string fog, bool force)
Definition main.qc:1030
void Playerchecker_Think(entity this)
Definition main.qc:420
bool CSQC_Parse_TempEntity()
Definition main.qc:1010
void CSQC_Parse_Print(string strMessage)
Definition main.qc:994
entity GetTeam(int Team, bool add)
Definition main.qc:331
void MoveToLast(entity e)
Definition main.qc:279
void Shutdown()
Definition main.qc:163
bool autocvar_r_fog_exp2
Definition main.qc:1029
bool SetTeam(entity o, int Team)
Definition main.qc:347
void URI_Get_Callback(int id, int status, string data)
engine callback
Definition main.qc:1547
void CSQC_Parse_StuffCmd(string strMessage)
Definition main.qc:987
float RegisterPlayer(entity player)
Definition main.qc:244
bool autocvar_r_drawfog
Definition main.qc:1028
void RemoveTeam(entity Team)
Definition main.qc:310
void ignore_list_apply()
Definition main.qc:671
float GetSpeedUnitFactor(int speed_unit)
Definition main.qc:1110
int enttype
Definition main.qh:185
entity playerslots[255]
Definition main.qh:84
float g_trueaim_minrange
Definition main.qh:171
int ClientProgsDB
Definition main.qh:204
float spectatee_status_changed_time
Definition main.qh:198
int srv_maxplayers
Definition main.qh:126
bool autocvar_developer_csqcentities
Definition main.qh:14
bool autocvar_cl_db_saveasdump
Definition main.qh:6
bool autocvar_cl_welcome
Definition main.qh:31
bool vote_waiting_for_me
Definition main.qh:146
float grecordtime[RANKINGS_CNT]
Definition main.qh:82
int calledhooks
Definition main.qh:164
bool autocvar_cl_race_cptimes_onlyself
Definition main.qh:29
bool ready_waiting
Definition main.qh:143
bool autocvar_menu_gamemenu
Definition main.qh:34
string hostname
Definition main.qh:123
entity players
Definition main.qh:57
entity owner
Definition main.qh:87
int spectatorlist[MAX_SPECTATORS]
Definition main.qh:178
float armorblockpercent
Definition main.qh:160
string gametype_custom_name
Definition main.qh:44
bool postinit
Definition main.qh:42
int binddb
Definition main.qh:191
#define getcommandkey(cmd_name, command)
Definition main.qh:137
float chase_active_backup
Definition main.qh:154
float welcome_msg_menu_check_maxtime
Definition main.qh:127
bool autocvar_hud_showbinds
Definition main.qh:11
bool observe_blocked
Definition main.qh:115
const int HOOK_START
Definition main.qh:165
entity teamslots[17]
Definition main.qh:85
int spectatee_status
the -1 disables HUD panels before CSQC receives necessary data
Definition main.qh:197
string ignore_list
Definition main.qh:130
string grecordholder[RANKINGS_CNT]
Definition main.qh:81
bool warmup_stage
Definition main.qh:120
entity gametype
Definition main.qh:43
int sv_entnum
Definition main.qh:186
int tempdb
Definition main.qh:203
vector mi_scale
Definition main.qh:38
int serverflags
Definition main.qh:211
vector mi_center
Definition main.qh:37
vector hook_shotorigin[4]
Definition main.qh:205
bool vote_waiting
Definition main.qh:145
float team_count
Definition main.qh:59
float RANKINGS_DISPLAY_CNT
Definition main.qh:80
string vote_called_vote
Definition main.qh:142
int team
Definition main.qh:188
float damagepush_speedfactor
Definition main.qh:161
const int HOOK_END
Definition main.qh:166
bool autocvar_hud_showbinds_limit
Definition main.qh:12
entity teams
Definition main.qh:58
int num_spectators
Definition main.qh:176
int srv_minplayers
Definition main.qh:125
float serverdeltatime
Definition main.qh:207
string minimapname
Definition main.qh:40
float camera_active
Definition main.qh:153
float serverprevtime
Definition main.qh:207
bool spectatorbutton_zoom
Definition main.qh:114
bool ignore_list_apply_time
Definition main.qh:131
bool campaign
Definition main.qh:122
string welcome_msg
Definition main.qh:124
bool ready_waiting_for_me
Definition main.qh:144
const int MAX_SPECTATORS
Definition main.qh:177
#define M_ARGV(x, type)
Definition events.qh:17
#define scores_label(this)
Definition scores.qh:146
#define MAX_TEAMSCORE
Definition scores.qh:149
#define teamscores_flags(i)
Definition scores.qh:156
#define teamscores_label(i)
Definition scores.qh:154
#define scores_flags(this)
Definition scores.qh:147
void get_mi_min_max_texcoords(float mode)
Definition util.qc:766
string build_mutator_list(string s)
Definition util.qc:272
string translate_key(string key)
Definition util.qc:1612
float cvar_settemp(string tmp_cvar, string tmp_value)
Definition util.qc:809
vector decompressShotOrigin(int f)
Definition util.qc:1377
string mi_shortname
Definition util.qh:133
vector mi_min
Definition util.qh:134
vector mi_max
Definition util.qh:135
void TrueAim_Init()
Definition crosshair.qc:44
bool autocvar_cl_reticle
Definition crosshair.qh:3
string classname
float flags
float maxclients
float player_localnum
float CVAR_TYPEFLAG_EXISTS
float skeletonindex
float time
float nextthink
float intermission
float entnum
int snd_looping
float autocvar_cl_jetpack_attenuation
ERASEABLE string MakeConsoleSafe(string input)
Escape the string to make it safe for consoles.
Definition cvar.qh:24
string entcs_GetName(int i)
Definition ent_cs.qh:148
int entcs_GetScoreTeam(int i)
Same as entcs_GetTeam, but returns -1 for no team in teamplay.
Definition ent_cs.qh:138
void Curl_URI_Get_Callback(int id, float status, string data)
Definition generic.qc:31
Weapons
Definition guide.qh:113
bool autocvar_hud_panel_healtharmor_progressbar_gfx
void LoadMenuSkinValues()
Definition hud.qc:42
int vote_highlighted
Definition hud.qh:96
int vote_nocount
Definition hud.qh:94
float HUD_Radar_InputEvent(float bInputType, float nPrimary, float nSecondary)
int vote_needed
Definition hud.qh:95
int vote_active
Definition hud.qh:98
int complain_weapon_type
Definition hud.qh:114
const int S_SHIFT
Definition hud.qh:129
int hudShiftState
Definition hud.qh:128
const int S_ALT
Definition hud.qh:131
int teamnagger
Definition hud.qh:126
float hud_dynamic_shake_factor
Definition hud.qh:214
string autocvar_hud_skin
Definition hud.qh:203
int vote_yescount
Definition hud.qh:93
entity complain_weapon
Definition hud.qh:113
int prev_health
Definition hud.qh:243
void HUD_ModIcons_SetFunc()
Definition modicons.qc:19
float complain_weapon_time
Definition hud.qh:115
int weapon_accuracy[REGISTRY_MAX(Weapons)]
Definition hud.qh:111
string hud_skin_path
Definition hud.qh:136
int prev_p_health
Definition hud.qh:246
float weapontime
Definition hud.qh:122
const int S_TAB
Definition hud.qh:132
const int S_CTRL
Definition hud.qh:130
float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
string prvm_language
Definition i18n.qh:8
prev
Definition all.qh:53
#define stoi(s)
Definition int.qh:4
#define itos(i)
Definition int.qh:6
#define FOREACH_WORD(words, cond, body)
Definition iter.qh:33
#define FOREACH(list, cond, body)
Definition iter.qh:19
float K_SHIFT
Definition keycodes.qc:22
float K_CTRL
Definition keycodes.qc:21
float K_ALT
Definition keycodes.qc:20
float K_TAB
Definition keycodes.qc:7
float K_ESCAPE
Definition keycodes.qc:9
#define CSQC_Init
Definition _all.inc:295
#define CSQC_InputEvent
Definition _all.inc:310
#define CSQC_Ent_Remove
Definition _all.inc:321
#define TC(T, sym)
Definition _all.inc:82
#define CSQC_Ent_Update
Definition _all.inc:318
#define ReadFloat()
Definition net.qh:348
#define NET_HANDLE(id, param)
Definition net.qh:15
float servertime
Definition net.qh:329
int ReadInt24_t()
Definition net.qh:337
#define ReadRegistered(r)
Definition net.qh:290
int ReadByte()
const int REPLICATEVARS_DESTROY
destroy data associated with cvars (shutdown)
Definition replicate.qh:6
void ReplicateVars_Start()
Definition replicate.qh:50
#define STAT(...)
Definition stats.qh:94
void WarpZone_Shutdown()
Definition client.qc:280
#define LOG_FATALF(...)
Definition log.qh:51
#define LOG_TRACEF(...)
Definition log.qh:75
#define LOG_INFO(...)
Definition log.qh:62
#define LOG_INFOF(...)
Definition log.qh:63
#define LOG_WARN(...)
Definition log.qh:58
#define assert_once(expr,...)
Definition log.qh:11
#define STR(it)
Definition macro.qh:20
ERASEABLE void db_close(int db)
Definition map.qh:86
ERASEABLE int db_load(string filename)
Definition map.qh:35
ERASEABLE int db_create()
Definition map.qh:25
ERASEABLE void db_save(int db, string filename)
Definition map.qh:8
ERASEABLE string db_get(int db, string key)
Definition map.qh:93
ERASEABLE void db_put(int db, string key, string value)
Definition map.qh:103
ERASEABLE void db_dump(int db, string filename)
Definition map.qh:70
string MapInfo_Type_ToString(Gametype t)
Definition mapinfo.qc:655
string MapInfo_Type_ToText(Gametype t)
Definition mapinfo.qc:660
float _MapInfo_GetTeamPlayBool(Gametype t)
Definition mapinfo.qc:538
string MapInfo_Map_author
Definition mapinfo.qh:10
string MapInfo_Map_titlestring
Definition mapinfo.qh:8
string cmd_name
Definition events.qh:12
float registercvar(string name, string value, float flags)
void localcmd(string command,...)
void cvar_set(string name, string value)
float isdemo()
float stof(string val,...)
float cvar(string name)
string keynumtostring(float keynum)
string precache_pic(string name,...)
const string cvar_string(string name)
float min(float f,...)
string ftos(float f)
void eprint(entity e)
void print(string text,...)
const string cvar_defstring(string name)
float tokenize(string s)
string strzone(string s)
string argv(float n)
#define etof(e)
Definition misc.qh:25
@ RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT
Definition net_linked.qh:17
@ RACE_NET_SPEED_AWARD_BEST
Definition net_linked.qh:23
@ RACE_NET_CHECKPOINT_NEXT_QUALIFYING
Definition net_linked.qh:15
@ RACE_NET_PENALTY_QUALIFYING
Definition net_linked.qh:20
@ RACE_NET_SPEED_AWARD
Definition net_linked.qh:22
@ RACE_NET_CHECKPOINT_CLEAR
Definition net_linked.qh:14
@ RACE_NET_SERVER_RANKINGS
Definition net_linked.qh:24
@ RACE_NET_RANKINGS_CNT
Definition net_linked.qh:28
@ RACE_NET_PENALTY_RACE
Definition net_linked.qh:19
@ RACE_NET_CHECKPOINT_HIT_RACE
Definition net_linked.qh:16
@ RACE_NET_SERVER_RECORD
Definition net_linked.qh:21
@ RACE_NET_SERVER_STATUS
Definition net_linked.qh:25
@ RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING
Definition net_linked.qh:18
@ RACE_NET_CHECKPOINT_HIT_QUALIFYING
Definition net_linked.qh:13
var void func_null()
string string_null
Definition nil.qh:9
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
void Local_Notification(MSG net_type, Notification net_name,...count)
Definition all.qc:1176
void ReplicateVars(bool would_destroy)
Definition all.qh:884
#define make_pure(e)
direct use is
Definition oo.qh:13
void clearentity(entity e)
Definition oo.qh:99
#define new_pure(class)
purely logical entities (not linked to the area grid)
Definition oo.qh:66
string sourceLoc
Location entity was spawned from in source.
Definition oo.qh:27
#define NULL
Definition post.qh:14
#define error
Definition pre.qh:6
bool QuickMenu_InputEvent(int bInputType, float nPrimary, float nSecondary)
Definition quickmenu.qc:485
float race_myrank
Definition racetimer.qh:49
float race_othercheckpointtime
Definition racetimer.qh:42
string race_othercheckpointenemy
Definition racetimer.qh:45
float race_nextcheckpoint
Definition racetimer.qh:19
float race_othercheckpoint
Definition racetimer.qh:41
float race_penaltyaccumulator
Definition racetimer.qh:25
float race_speedaward_alltimebest
Definition racetimer.qh:32
float race_server_record
Definition racetimer.qh:29
float race_mycheckpointlapsdelta
Definition racetimer.qh:39
string race_penaltyreason
Definition racetimer.qh:28
string race_speedaward_holder
Definition racetimer.qh:31
string race_speedaward_alltimebest_holder
Definition racetimer.qh:33
string race_status_name
Definition racetimer.qh:48
bool scoreboard_showscores_force
Definition racetimer.qh:46
float race_nextbestspeed
Definition racetimer.qh:21
string race_nextbestname
Definition racetimer.qh:24
float race_mybestspeed
Definition racetimer.qh:23
float race_checkpoint
Definition racetimer.qh:8
string race_mycheckpointenemy
Definition racetimer.qh:40
float race_othercheckpointdelta
Definition racetimer.qh:43
float race_previousbesttime
Definition racetimer.qh:16
float race_nextbesttime
Definition racetimer.qh:20
float race_mypreviousbesttime
Definition racetimer.qh:17
float race_time
Definition racetimer.qh:9
float race_penaltytime
Definition racetimer.qh:27
float race_status
Definition racetimer.qh:47
float race_mybesttime
Definition racetimer.qh:22
float race_timebestspeed
Definition racetimer.qh:11
float race_timespeed
Definition racetimer.qh:10
float race_mycheckpoint
Definition racetimer.qh:36
float race_checkpointtime
Definition racetimer.qh:13
float race_mycheckpointtime
Definition racetimer.qh:37
float race_othercheckpointlapsdelta
Definition racetimer.qh:44
float race_penaltyeventtime
Definition racetimer.qh:26
float race_mycheckpointdelta
Definition racetimer.qh:38
string race_previousbestname
Definition racetimer.qh:18
float race_speedaward
Definition racetimer.qh:30
float race_laptime
Definition racetimer.qh:12
void psrandom(float seed)
Definition random.qc:133
#define prandom_debug()
Definition random.qh:44
#define REGISTRY_GET(id, i)
Definition registry.qh:62
void Scoreboard_UpdatePlayerPos(entity player)
void Scoreboard_InitScores()
float HUD_Scoreboard_InputEvent(float bInputType, float nPrimary, float nSecondary)
void Scoreboard_UI_Enable(int mode)
void Scoreboard_UpdateTeamPos(entity Team)
#define setthink(e, f)
float campaign_level
Definition campaign.qc:17
ERASEABLE entity Sort_Spawn()
Definition sortlist.qc:4
#define SORT_SWAP(a, b)
Swap two neighbours in a sortlist.
Definition sortlist.qh:14
const float VOL_BASE
Definition sound.qh:36
#define sound(e, c, s, v, a)
Definition sound.qh:52
#define static_init_late()
Definition static.qh:39
#define static_init_precache()
Definition static.qh:44
#define static_init()
Definition static.qh:34
void ONREMOVE(entity this)
ERASEABLE string ColorTranslateRGB(string s)
Definition string.qh:194
#define strfree(this)
Definition string.qh:57
string CCR(string input)
color code replace, place inside of sprintf and parse the string
Definition string.qh:214
ERASEABLE string cons_mid(string a, string mid, string b)
Definition string.qh:285
#define startsWith(haystack, needle)
Definition string.qh:234
#define strcpy(this, s)
Definition string.qh:51
const int NUM_TEAM_2
Definition teams.qh:14
const int NUM_SPECTATOR
Definition teams.qh:23
const int NUM_TEAM_4
Definition teams.qh:16
const int NUM_TEAM_3
Definition teams.qh:15
bool teamplay
Definition teams.qh:59
const int NUM_TEAM_1
Definition teams.qh:13
ERASEABLE float url_URI_Get_Callback(int id, float status, string data)
Definition urllib.qc:28
const int URI_GET_CURL
Definition urllib.qh:7
const int URI_GET_DISCARD
Definition urllib.qh:4
const int URI_GET_CURL_END
Definition urllib.qh:8
bool View_InputEvent(int bInputType, float nPrimary, float nSecondary)
Definition view.qc:465
bool autocvar_cl_orthoview
Definition view.qh:21
bool autocvar_cl_orthoview_nofog
Definition view.qh:22
int autocvar_chase_active
Definition view.qh:17
bool autocvar_r_drawviewmodel
Definition view.qh:97
bool autocvar_cl_lockview
Definition view.qh:20
WepSet ReadWepSet()
Definition all.qc:88
#define WEP_LAST
Definition all.qh:345
const int WEP_FIRST
Definition all.qh:344
@ WEPARENA_ALL
Definition weapon.qh:276
@ WEPARENA_ALL_AVAILABLE
Definition weapon.qh:277
@ WEPARENA_NONE
Definition weapon.qh:274
@ WEPARENA_EXTENDED_AVAILABLE
Definition weapon.qh:281
@ WEPARENA_STANDARD_AVAILABLE
Definition weapon.qh:279
@ WEPARENA_EXTENDED
Definition weapon.qh:280
@ WEPARENA_DEVALL
Definition weapon.qh:282
@ WEPARENA_STANDARD
Definition weapon.qh:278
@ WEPARENA_DEVALL_AVAILABLE
Definition weapon.qh:283
@ WEPARENA_OFF
Definition weapon.qh:273
@ WEPARENA_CUSTOM
Definition weapon.qh:275
vector WepSet
Definition weapon.qh:14
string fog
Definition world.qh:65
string cache_mutatormsg
Definition world.qh:69