Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
all.qh
Go to the documentation of this file.
1#pragma once
2
4
5#include <common/constants.qh>
6#include <common/teams.qh>
7#include <common/util.qh>
10
11// Operator for bold notifications
12#define BOLD_OPERATOR "^BOLD"
13
15ENUMCLASS(MSG)
17 CASE(MSG, ANNCE)
19 CASE(MSG, INFO)
21 CASE(MSG, CENTER)
23 CASE(MSG, MULTI)
25 CASE(MSG, CHOICE)
27 CASE(MSG, CENTER_KILL)
29
31{
32 switch (net_type)
33 {
34 case MSG_ANNCE: return "MSG_ANNCE";
35 case MSG_INFO: return "MSG_INFO";
36 case MSG_CENTER: return "MSG_CENTER";
37 case MSG_MULTI: return "MSG_MULTI";
38 case MSG_CHOICE: return "MSG_CHOICE";
39 case MSG_CENTER_KILL: return "MSG_CENTER_KILL";
40 }
41 LOG_WARNF("Get_Notif_TypeName(%d): Improper net type!", ORDINAL(net_type));
42 return "";
43}
44
45ENUMCLASS(CPID)
46 CASE(CPID, ASSAULT_ROLE)
47 CASE(CPID, ROUND)
48 CASE(CPID, CAMPCHECK)
49 CASE(CPID, CTF_CAPSHIELD)
50 CASE(CPID, CTF_LOWPRIO)
51 CASE(CPID, CTF_PASS)
52 CASE(CPID, STALEMATE)
53 CASE(CPID, NADES)
54 CASE(CPID, IDLING)
55 CASE(CPID, REMOVE)
56 CASE(CPID, ITEM)
57 CASE(CPID, PREVENT_JOIN)
58 CASE(CPID, KEEPAWAY)
59 CASE(CPID, KEEPAWAY_WARN)
60 CASE(CPID, KEYHUNT)
61 CASE(CPID, KEYHUNT_OTHER)
62 CASE(CPID, LMS)
63 CASE(CPID, MISSING_PLAYERS)
64 CASE(CPID, INSTAGIB_FINDAMMO)
65 CASE(CPID, NIX)
66 CASE(CPID, ONSLAUGHT)
67 CASE(CPID, ONS_CAPSHIELD)
68 CASE(CPID, OVERTIME)
69 CASE(CPID, POWERUP)
70 CASE(CPID, RACE_FINISHLAP)
71 CASE(CPID, SURVIVAL)
72 CASE(CPID, TEAMCHANGE)
73 CASE(CPID, TIMEOUT)
74 CASE(CPID, TIMEIN)
75 CASE(CPID, VEHICLES)
76 CASE(CPID, VEHICLES_OTHER)
78 CASE(CPID, LAST)
79ENUMCLASS_END(CPID)
80
82
83// used for notification system multi-team identifiers
84#define APP_TEAM_NUM(num, prefix) ((num == NUM_TEAM_1) ? prefix##_RED : ((num == NUM_TEAM_2) ? prefix##_BLUE : ((num == NUM_TEAM_3) ? prefix##_YELLOW : prefix##_PINK)))
85#define APP_NUM(num, prefix) ((num) ? APP_TEAM_NUM(num, prefix) : prefix##_NEUTRAL)
86
87#define EIGHT_VARS_TO_VARARGS_VARLIST \
88 VARITEM(1, 0, s1) \
89 VARITEM(2, 0, XPD(s1, s2)) \
90 VARITEM(3, 0, XPD(s1, s2, s3)) \
91 VARITEM(4, 0, XPD(s1, s2, s3, s4)) \
92 VARITEM(0, 1, f1) \
93 VARITEM(1, 1, XPD(s1, f1)) \
94 VARITEM(2, 1, XPD(s1, s2, f1)) \
95 VARITEM(3, 1, XPD(s1, s2, s3, f1)) \
96 VARITEM(4, 1, XPD(s1, s2, s3, s4, f1)) \
97 VARITEM(0, 2, XPD(f1, f2)) \
98 VARITEM(1, 2, XPD(s1, f1, f2)) \
99 VARITEM(2, 2, XPD(s1, s2, f1, f2)) \
100 VARITEM(3, 2, XPD(s1, s2, s3, f1, f2)) \
101 VARITEM(4, 2, XPD(s1, s2, s3, s4, f1, f2)) \
102 VARITEM(0, 3, XPD(f1, f2, f3)) \
103 VARITEM(1, 3, XPD(s1, f1, f2, f3)) \
104 VARITEM(2, 3, XPD(s1, s2, f1, f2, f3)) \
105 VARITEM(3, 3, XPD(s1, s2, s3, f1, f2, f3)) \
106 VARITEM(4, 3, XPD(s1, s2, s3, s4, f1, f2, f3)) \
107 VARITEM(0, 4, XPD(f1, f2, f3, f4)) \
108 VARITEM(1, 4, XPD(s1, f1, f2, f3, f4)) \
109 VARITEM(2, 4, XPD(s1, s2, f1, f2, f3, f4)) \
110 VARITEM(3, 4, XPD(s1, s2, s3, f1, f2, f3, f4)) \
111 VARITEM(4, 4, XPD(s1, s2, s3, s4, f1, f2, f3, f4))
112
115 float var_default,
116 float var_cvar,
117 MSG typeId,
118 string namestring,
119 int teamnum);
121 float var_cvar,
122 string namestring,
123 /* MSG_ANNCE */
124 float channel,
125 string snd,
126 float vol,
127 float position,
128 float queuetime);
129
131 float var_cvar,
132 string namestring,
133 int strnum,
134 int flnum,
135 /* MSG_INFO & MSG_CENTER */
136 string args,
137 string hudargs,
138 string icon,
139 CPID cpid,
140 string durcnt,
141 string normal,
142 string gentle);
143
145 float var_cvar,
146 string namestring,
147 /* MSG_MULTI */
148 Notification anncename,
149 Notification infoname,
150 Notification centername);
151
153 float var_cvar,
154 string namestring,
155 /* MSG_CHOICE */
156 float challow_def,
157 float challow_var,
158 MSG chtype,
159 Notification optiona,
160 Notification optionb);
161
162void Dump_Notifications(int fh, bool alsoprint);
163
164#define DEFAULT_FILENAME "notifications_dump.cfg"
165// NOTE: dumpeffectinfo, dumpnotifs, dumpturrets and dumpweapons use similar code
166GENERIC_COMMAND(dumpnotifs, "Dump all notifications into " DEFAULT_FILENAME, false)
167{
168 switch (request)
169 {
171 {
172 #ifdef GAMEQC
173 string filename = argv(1);
174 bool alsoprint = false;
175 if (filename == "")
176 {
177 filename = DEFAULT_FILENAME;
178 alsoprint = false;
179 }
180 else if (filename == "-")
181 {
182 filename = DEFAULT_FILENAME;
183 alsoprint = true;
184 }
185 int fh = fopen(filename, FILE_WRITE);
186 if (fh >= 0)
187 {
188 Dump_Notifications(fh, alsoprint);
189 LOG_INFOF("Dumping notifications... File located in ^2data/data/%s^7.", filename);
190 fclose(fh);
191 }
192 else
193 {
194 LOG_INFOF("^1Error: ^7Could not open file '%s'!", filename);
195 }
196 #else
197 LOG_INFO("Notification dump command only works with cl_cmd and sv_cmd.");
198 #endif
199 return;
200 }
201 default:
203 {
204 LOG_HELP("Usage:^3 ", GetProgramCommandPrefix(), " dumpnotifs [<filename>]");
205 LOG_HELPF(" Where <filename> is the file to write (default is %s),", DEFAULT_FILENAME);
206 LOG_HELP(" if supplied with '-' output to console as well as default,");
207 LOG_HELP(" if left blank, it will only write to default.");
208 return;
209 }
210 }
211}
212#undef DEFAULT_FILENAME
213
214#ifdef NOTIFICATIONS_DEBUG
215bool autocvar_notification_debug = false;
216void Debug_Notification(string input)
217{
218 switch (autocvar_notification_debug)
219 {
220 case 1: { LOG_TRACE(input); break; }
221 case 2: { LOG_INFO(input); break; }
222 }
223}
224#endif
225
226void Local_Notification(MSG net_type, Notification net_name, ...count);
229 MSG net_type, Notification net_name,
230 float stringcount, float floatcount,
231 string s1, string s2, string s3, string s4,
232 float f1, float f2, float f3, float f4);
233
234#ifdef CSQC
237#endif
238
239#ifdef SVQC
242#endif
243
244#ifdef SVQC
245ENUMCLASS(NOTIF)
247 CASE(NOTIF, ONE)
249 CASE(NOTIF, ONE_ONLY)
251 CASE(NOTIF, TEAM)
253 CASE(NOTIF, TEAM_EXCEPT)
255 CASE(NOTIF, ALL)
257 CASE(NOTIF, ALL_EXCEPT)
258ENUMCLASS_END(NOTIF)
259
261{
262 switch (broadcast)
263 {
264 case NOTIF_ONE: return "NOTIF_ONE";
265 case NOTIF_ONE_ONLY: return "NOTIF_ONE_ONLY";
266 case NOTIF_ALL_EXCEPT: return "NOTIF_ALL_EXCEPT";
267 case NOTIF_ALL: return "NOTIF_ALL";
268 case NOTIF_TEAM: return "NOTIF_TEAM";
269 case NOTIF_TEAM_EXCEPT: return "NOTIF_TEAM_EXCEPT";
270 }
271 LOG_WARNF("Get_Notif_BroadcastName(%d): Improper broadcast!", broadcast);
272 return "";
273}
274
276 NOTIF broadcast, entity client,
277 MSG net_type, CPID net_name);
279 NOTIF broadcast, entity client,
280 MSG net_type, Notification net_name,
281 ...count);
283 NOTIF broadcast, entity client,
284 MSG net_type, Notification net_name,
285 float stringcount, float floatcount,
286 string s1, string s2, string s3, string s4,
287 float f1, float f2, float f3, float f4);
289 NOTIF broadcast, entity client,
290 MSG net_type, Notification net_name,
291 string s1, string s2, string s3, string s4,
292 float f1, float f2, float f3, float f4);
293#endif
294
295// ===========================
296// Special CVAR Declarations
297// ===========================
298
299// MAKE SURE THIS IS ALWAYS SYNCHRONIZED WITH THE DUMP
300// NOTIFICATIONS FUNCTION IN THE .QC FILE!
301
302#define NOTIF_ADD_AUTOCVAR(name,defaultvalue) float autocvar_notification_##name = defaultvalue;
303
305string autocvar_notification_show_location_string = ""; //_(" at the %s");
307float autocvar_notification_show_sprees_info = 3; // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker
311#ifdef SVQC
314#endif
315
316#ifdef SVQC
317void Notification_GetCvars(entity this, entity store);
319#else
320float autocvar_notification_item_centerprinttime = 1.5;
321
322// 0 = no, 1 = yes, 2 = forced on for all MSG_INFO notifs
323// DISABLED IN CODE, BUT ENABLED IN CONFIG FOR COMPATIBILITY WITH OLD CLIENTS
324float autocvar_notification_allow_chatboxprint = 0;
325
326float autocvar_notification_show_sprees_center = true;
327float autocvar_notification_show_sprees_center_specialonly = true;
328#endif
329
330
331// ============================
332// Notification Argument List
333// ============================
334/*
335 These arguments get replaced with the Local_Notification_sprintf
336 and other such functions found in all.qc to supply data
337 from networked notifications to their usage in sprintf... It
338 allows for more dynamic data to be inferred by the local
339 notification parser, so that the server does not have to network
340 anything too crazy on a per-client/per-situation basis.
341
342 Pay attention to the CSQC/SVQC relations, some of these are redefined
343 in slightly different ways for different programs, this is because the
344 server does a more conservative approach to the notifs than the client.
345
346 All arguments are swapped into strings, so be sure that your
347 sprintf usage matches with proper %s placement.
348
349 Argument descriptions:
350 s1-s4: string arguments to be literally swapped into sprintf
351 s2loc: s2 string of locations of deaths or other events
352 s3loc: s3 string of locations of deaths or other events
353 s4loc: s4 string of locations of deaths or other events
354 f1-f4: float arguments expanded into strings to be swapped into sprintf
355 f1dtime: f1 float to string with 2 decimal places
356 f2dtime: f2 float to string with 2 decimal places
357 f2primsec: f2 float primary or secondary selection for weapons
358 f3primsec: f3 float primary or secondary selection for weapons
359 f1secs: count_seconds of f1
360 f1points: point or points depending on f1
361 f1ord: count_ordinal of f1
362 f1time: process_time of f1
363 f1race_time: TIME_ENCODED_TOSTRING of f1
364 f2race_time: TIME_ENCODED_TOSTRING of f2
365 f3race_time: TIME_ENCODED_TOSTRING of f3
366 race_col: color of race time/position (i.e. good or bad)
367 race_diff: show time difference between f2 and f3
368 pass_key: find the keybind for "passing" or "dropping" in CTF gametype
369 nade_key: find the keybind for nade throwing
370 join_key: find the keybind for joining the game
371 frag_ping: show the ping of a player
372 frag_stats: show health/armor/ping of a player
373 frag_pos: show score status and position in the match of a player
374 spree_cen: centerprint notif for kill spree/how many kills they have
375 spree_inf: info notif for kill spree/how many kills they have
376 spree_end: placed at the end of murder messages to show ending of sprees
377 spree_lost: placed at the end of suicide messages to show losing of sprees
378 item_wepname: return full name of a weapon from weaponid
379 item_wepammo: ammo display for weapon from f1 and f2
380 item_centime: amount of time to display weapon message in centerprint
381 item_buffname: return full name of a buff from buffid f1
382 f3buffname: return full name of a buff from buffid f3
383 death_team: show the full name of the team a player is switching from
384 minigame1_name: return human readable name of a minigame from its id(s1)
385 minigame1_d: return descriptor name of a minigame from its id(s1)
386*/
387
388const float NOTIF_MAX_ARGS = 7;
389const float NOTIF_MAX_HUDARGS = 2;
390const float NOTIF_MAX_DURCNT = 2;
391
392#ifdef CSQC
393const int NOTIF_QUEUE_MAX = 10;
397
400
402
403// replaces # with attacker_name in ent_msg (if not found attacker_name is appended)
404string hash_replace(string full_msg, int ent_msg_num, string ent_msg, string attacker_name)
405{
406 int s_ofs = 0;
407 while (--ent_msg_num >= 0)
408 s_ofs += strstrofs(full_msg, "%s", s_ofs);
409 string col = find_last_color_code(substring(full_msg, 0, s_ofs));
410
411 int hash_ofs = strstrofs(ent_msg, "#", 0);
412 if (hash_ofs < 0)
413 ent_msg = strcat(ent_msg, " ", CCR("^BG"), attacker_name, col);
414 else
415 ent_msg = strreplace("#", strcat(CCR("^BG"), attacker_name, col), ent_msg);
416 return ent_msg;
417}
418
419#define HASH_REPLACE(full_msg, num, attacker_name) hash_replace(input, num, s##num, attacker_name)
420#endif
421
423
424const float ARG_CS_SV_HA = 1; // enabled on CSQC, SVQC, and Hudargs
425const float ARG_CS_SV_DC = 2; // enabled on CSQC, SVQC, and durcnt centerprint
426const float ARG_CS_SV = 3; // enabled on CSQC and SVQC
427const float ARG_CS = 4; // unique result to CSQC
428const float ARG_SV = 5; // unique result to SVQC
429const float ARG_DC = 6; // unique result to durcnt/centerprint
430
431// todo possible idea.... declare how many floats/strings each arg needs, and then dynamically increment the input
432// this way, we don't need to have duplicates like i.e. s2loc and s3loc?
433
434string BUFF_NAME(int i);
435
436#define NOTIF_ARGUMENT_LIST \
437 ARG_CASE(ARG_CS_SV_HA, "s1", s1) \
438 ARG_CASE(ARG_CS_SV_HA, "s2", s2) \
439 ARG_CASE(ARG_CS_SV_HA, "s3", s3) \
440 ARG_CASE(ARG_CS_SV_HA, "s4", s4) \
441 ARG_CASE(ARG_CS_SV, "s2loc", ((autocvar_notification_show_location && (s2 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s2) : "")) \
442 ARG_CASE(ARG_CS_SV, "s3loc", ((autocvar_notification_show_location && (s3 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s3) : "")) \
443 ARG_CASE(ARG_CS_SV, "s4loc", ((autocvar_notification_show_location && (s4 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s4) : "")) \
444 ARG_CASE(ARG_CS_SV_DC, "f1", ftos(f1)) \
445 ARG_CASE(ARG_CS_SV_DC, "f2", ftos(f2)) \
446 ARG_CASE(ARG_CS_SV, "f3", ftos(f3)) \
447 ARG_CASE(ARG_CS_SV, "f4", ftos(f4)) \
448 ARG_CASE(ARG_CS_SV, "f1dtime", ftos_decimals(TIME_DECODE(f1), 2)) \
449 ARG_CASE(ARG_CS_SV, "f2dtime", ftos_decimals(TIME_DECODE(f2), 2)) \
450 ARG_CASE(ARG_CS, "f2primsec", (f2 ? _("secondary") : _("primary"))) \
451 ARG_CASE(ARG_CS, "f3primsec", (f3 ? _("secondary") : _("primary"))) \
452 ARG_CASE(ARG_CS, "f1secs", count_seconds(f1)) \
453 ARG_CASE(ARG_CS, "f1points", (f1 == 1 ? _("1 point") : sprintf(_("%d points"), f1))) \
454 ARG_CASE(ARG_CS_SV, "f1ord", count_ordinal(f1)) \
455 ARG_CASE(ARG_CS_SV, "f1time", process_time(2, f1)) \
456 ARG_CASE(ARG_CS_SV_HA, "f1race_time", TIME_ENCODED_TOSTRING(f1, true)) \
457 ARG_CASE(ARG_CS_SV_HA, "f2race_time", TIME_ENCODED_TOSTRING(f2, true)) \
458 ARG_CASE(ARG_CS_SV_HA, "f3race_time", TIME_ENCODED_TOSTRING(f3, true)) \
459 ARG_CASE(ARG_CS_SV, "race_col", CCR((f1 == 1) ? "^F1" : "^F2")) \
460 ARG_CASE(ARG_CS_SV, "race_diff", ((TIME_ENCODED_TOSTRING(fabs(f2 - f3), true) == "0.00") ? "^3[+0.0]" : (f2 > f3) ? sprintf("^1[+%s]", TIME_ENCODED_TOSTRING(f2 - f3, true)) : sprintf("^2[-%s]", TIME_ENCODED_TOSTRING(f3 - f2, true)))) \
461 ARG_CASE(ARG_CS, "pass_key", getcommandkey(_("drop flag"), "+use")) \
462 ARG_CASE(ARG_CS, "nade_key", getcommandkey(_("throw nade"), "dropweapon")) \
463 ARG_CASE(ARG_CS, "join_key", getcommandkey(_("jump"), "+jump")) \
464 ARG_CASE(ARG_CS, "frag_ping", notif_arg_frag_ping(true, f2)) \
465 ARG_CASE(ARG_CS, "frag_stats", notif_arg_frag_stats(f2, f3, f4)) \
466 /*ARG_CASE(ARG_CS, "frag_pos", ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \
467 ARG_CASE(ARG_CS, "spree_cen", (autocvar_notification_show_sprees ? notif_arg_spree_cen(f1) : "")) \
468 ARG_CASE(ARG_CS_SV, "spree_inf", (autocvar_notification_show_sprees ? notif_arg_spree_inf(1, input, s2, f2) : "")) \
469 ARG_CASE(ARG_CS_SV, "spree_end", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
470 ARG_CASE(ARG_CS_SV, "spree_lost", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \
471 ARG_CASE(ARG_CS_SV, "item_wepname", REGISTRY_GET(Weapons, f1).m_name) \
472 ARG_CASE(ARG_CS_SV, "item_buffname", BUFF_NAME(f1)) \
473 ARG_CASE(ARG_CS_SV, "f3buffname", BUFF_NAME(f3)) \
474 ARG_CASE(ARG_CS_SV, "item_wepammo", (f2 > 0 ? notif_arg_item_wepammo(f1, f2) : "")) \
475 ARG_CASE(ARG_DC, "item_centime", ftos(autocvar_notification_item_centerprinttime)) \
476 ARG_CASE(ARG_SV, "death_team", Team_ColoredFullName(f1)) \
477 ARG_CASE(ARG_CS, "death_team", Team_ColoredFullName(f1 - 1)) \
478 ARG_CASE(ARG_SV, "s3#s2", s3) \
479 ARG_CASE(ARG_SV, "#s2", s2) \
480 ARG_CASE(ARG_CS, "s3#s2", HASH_REPLACE(input, 3, s2)) \
481 ARG_CASE(ARG_CS, "#s2", "") \
482 ARG_CASE(ARG_CS_SV_HA, "minigame1_name",find(NULL,netname,s1).descriptor.message) \
483 ARG_CASE(ARG_CS_SV_HA, "minigame1_d", find(NULL,netname,s1).descriptor.netname)
484
485#define NOTIF_HIT_MAX(count,funcname) MACRO_BEGIN \
486 if(sel_num == count) { backtrace(sprintf("%s: Hit maximum arguments!\n", funcname)); break; } \
487MACRO_END
488
489#define NOTIF_HIT_UNKNOWN(token,funcname) { backtrace(sprintf("%s: Hit unknown token in selected string! '%s'\n", funcname, selected)); break; }
490
491#define KILL_SPREE_LIST \
492 SPREE_ITEM(3, 03, _("TRIPLE FRAG!"), _("%s^K1 made a TRIPLE FRAG!"), _("%s^K1 made a TRIPLE SCORE!")) \
493 SPREE_ITEM(5, 05, _("RAGE!"), _("%s^K1 unlocked RAGE!"), _("%s^K1 made FIVE SCORES IN A ROW!")) \
494 SPREE_ITEM(10, 10, _("MASSACRE!"), _("%s^K1 started a MASSACRE!"), _("%s^K1 made TEN SCORES IN A ROW!")) \
495 SPREE_ITEM(15, 15, _("MAYHEM!"), _("%s^K1 executed MAYHEM!"), _("%s^K1 made FIFTEEN SCORES IN A ROW!")) \
496 SPREE_ITEM(20, 20, _("BERSERKER!"), _("%s^K1 is a BERSERKER!"), _("%s^K1 made TWENTY SCORES IN A ROW!")) \
497 SPREE_ITEM(25, 25, _("CARNAGE!"), _("%s^K1 inflicts CARNAGE!"), _("%s^K1 made TWENTY FIVE SCORES IN A ROW!")) \
498 SPREE_ITEM(30, 30, _("ARMAGEDDON!"), _("%s^K1 unleashes ARMAGEDDON!"), _("%s^K1 made THIRTY SCORES IN A ROW!"))
499
500#ifdef CSQC
501string notif_arg_frag_ping(bool newline, float fping)
502{
503 string s = newline ? "\n" : " ";
504 if (fping < 0)
505 return sprintf(CCR(_("%s(^F1Bot^BG)")), s);
506 else
507 return sprintf(CCR(_("%s(Ping ^F1%d^BG)")), s, fping);
508}
509
510string notif_arg_frag_stats(float fhealth, float farmor, float fping)
511{
512 string s = notif_arg_frag_ping(false, fping);
513 if (fhealth > 1)
514 return sprintf(CCR(_("\n(Health ^1%d^BG / Armor ^2%d^BG)%s")), fhealth, farmor, s);
515 else
516 return sprintf(CCR(_("\n(^F4Dead^BG)%s")), s);
517}
518
519string notif_arg_spree_cen(float spree)
520{
521 // 0 = off, 1 = target (but only for first victim) and attacker
522 if(autocvar_notification_show_sprees_center)
523 {
524 if(spree > 1)
525 {
526 #define SPREE_ITEM(counta,countb,center,normal,gentle) \
527 case counta: \
528 return strcat(normal_or_gentle(center, sprintf(_("%d score spree!"), spree)), " ");
529
530 switch(spree)
531 {
533 default:
534 {
535 if (!autocvar_notification_show_sprees_center_specialonly)
536 {
537 return
538 sprintf(
540 _("%d frag spree!"),
541 _("%d score spree!")
542 ), " "),
543 spree);
544 }
545 else { return ""; } // don't show spree information if it isn't an achievement
546 }
547 }
548
549 #undef SPREE_ITEM
550 }
551 else if(spree == -1) // first blood
552 {
553 return strcat(normal_or_gentle(_("First blood!"), _("First score!")), " ");
554 }
555 else if(spree == -2) // first victim
556 {
557 return strcat(normal_or_gentle(_("First victim!"), _("First casualty!")), " ");
558 }
559 }
560 return "";
561}
562#endif
563
564string notif_arg_spree_inf(float type, string input, string player, float spree)
565{
566 switch(type)
567 {
568 case 1: // attacker kill spree
569 {
570 // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker
571 // this conditional (& 2) is true for 2 and 3
573 {
574 #ifdef CSQC
575 string spree_newline =
577 ((substring(input, 0, 1) == "\{3}") ? "\n\{3}" : "\n") : "" );
578 #else
579 string spree_newline =
581 #endif
582
583 if(spree > 1)
584 {
585 #define SPREE_ITEM(counta,countb,center,normal,gentle) \
586 case counta: \
587 return sprintf(CCR(strcat(normal_or_gentle(normal, gentle), " %s^BG")), \
588 player, spree_newline);
589
590 switch(spree)
591 {
593 default:
594 {
596 {
597 return
598 sprintf(
600 _("%s^K1 has %d frags in a row!"),
601 _("%s^K1 made %d scores in a row!")
602 ), " %s^BG")),
603 player,
604 spree,
605 spree_newline
606 );
607 }
608 else { return ""; } // don't show spree information if it isn't an achievement
609 }
610 }
611
612 #undef SPREE_ITEM
613 }
614 else if(spree == -1) // firstblood
615 {
616 return
617 sprintf(
619 _("%s^K1 drew first blood!"),
620 _("%s^K1 got the first score!")
621 ), " %s^BG")),
622 player,
623 spree_newline
624 );
625 }
626 }
627 break;
628 }
629
630 case -1: // kill spree ended
631 {
632 if((spree > 1) && (autocvar_notification_show_sprees_info & 1))
633 {
634 return
635 sprintf(normal_or_gentle(
636 _(", ending their %d frag spree"),
637 _(", ending their %d score spree")
638 ),
639 spree
640 );
641 }
642 break;
643 }
644
645 case -2: // kill spree lost
646 {
647 if((spree > 1) && (autocvar_notification_show_sprees_info & 1))
648 {
649 return
650 sprintf(normal_or_gentle(
651 _(", losing their %d frag spree"),
652 _(", losing their %d score spree")
653 ),
654 spree
655 );
656 }
657 break;
658 }
659 }
660 return "";
661}
662
663string notif_arg_item_wepammo(float f1, float f2)
664{
666 if(wep.ammo_type == RES_NONE)
667 return ""; // doesn't use ammo
668 // example for translators: You dropped the Vortex with 5 cells
669 return sprintf(_(" with %d %s"), f2, strtolower(wep.ammo_type.m_name));
670}
671
672
673// ====================================
674// Initialization/Create Declarations
675// ====================================
676
677// common notification entity values
681.string nent_name;
685
686// MSG_ANNCE entity values
688.string nent_snd;
689.float nent_vol;
692
693// MSG_INFO and MSG_CENTER entity values
694.string nent_args; // used by both
695.string nent_hudargs; // used by info
696.string nent_icon; // used by info
697.CPID nent_cpid; // used by center
698.string nent_durcnt; // used by center
699.string nent_string; // used by both
700
701// MSG_MULTI entity values
705
706// MSG_CHOICE entity values
711
712// networked notification entity values
713#ifdef SVQC
715#endif
719.string nent_strings[4];
720.float nent_floats[4];
721
722#define ACVNN(name) autocvar_notification_##name
723
724REGISTRY(Notifications, BITS(11))
725REGISTER_REGISTRY(Notifications)
726REGISTRY_SORT(Notifications)
727
728REGISTRY_DEFINE_GET(Notifications, NULL)
729STATIC_INIT(Notifications) { FOREACH(Notifications, true, it.m_id = i); }
730REGISTRY_CHECK(Notifications)
731
732const int NOTIF_CHOICE_MAX = 20;
733// NOTE: a team choice is actually made of 4 choices (one per team) with the same nent_choice_idx
734// thus they are counted as 1 in nent_choice_count
737.int msg_choice_choices[NOTIF_CHOICE_MAX]; // set on each player containing MSG_CHOICE choices
738// initialization error detection
741
742STATIC_INIT_LATE(Notif_Choices)
743{
745 LOG_FATALF("Too many MSG_CHOICE notifications (%d), hit NOTIF_CHOICE_MAX (%d) limit",
747}
748
750{
751 if(!notif.nent_teamnum)
752 return notif.nent_name;
753 return substring(notif.nent_name, 0, -strlen(Static_Team_ColorName(notif.nent_teamnum)) - 2);
754}
755
756Notification Get_Notif_Ent(MSG net_type, int net_name)
757{
758 Notification it = REGISTRY_GET(Notifications, net_name);
759 if (it.nent_type != net_type) {
760 LOG_WARNF("Get_Notif_Ent(%s (%d), %s (%d)): Improper net type '%s'!",
761 Get_Notif_TypeName(net_type), net_type,
762 it.registered_id, net_name,
763 Get_Notif_TypeName(it.nent_type)
764 );
765 return NULL;
766 }
767 return it;
768}
769
770#define MSG_ANNCE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \
771 MSG_ANNCE_NOTIF_(teamnum, ANNCE_##name, ANNCE_##cvarname, defaultvalue, sound, channel, volume, position, queuetime)
772
773#define MSG_ANNCE_NOTIF(name, defaultvalue, sound, channel, volume, position, queuetime) \
774 NOTIF_ADD_AUTOCVAR(ANNCE_##name, defaultvalue) \
775 MSG_ANNCE_NOTIF_(0, ANNCE_##name, ANNCE_##name, defaultvalue, sound, channel, volume, position, queuetime)
776
777#define MSG_ANNCE_NOTIF_(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \
778 REGISTER(Notifications, name, m_id, new_pure(msg_annce_notification)) { \
779 Create_Notification_Entity (this, defaultvalue, ACVNN(cvarname), MSG_ANNCE, strtoupper(#name), teamnum); \
780 Create_Notification_Entity_Annce(this, ACVNN(cvarname), strtoupper(#name), \
781 channel, /* channel */ \
782 sound, /* snd */ \
783 volume, /* vol */ \
784 position, /* position */ \
785 queuetime); /* queuetime */ \
786 }
787
788#define MSG_INFO_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle) \
789 MSG_INFO_NOTIF_(teamnum, INFO_##name, INFO_##cvarname, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle)
790
791#define MSG_INFO_NOTIF(name, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle) \
792 NOTIF_ADD_AUTOCVAR(INFO_##name, defaultvalue) \
793 MSG_INFO_NOTIF_(0, INFO_##name, INFO_##name, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle)
794
795#define MSG_INFO_NOTIF_(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle) \
796 REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) { \
797 Create_Notification_Entity (this, defaultvalue, ACVNN(cvarname), MSG_INFO, strtoupper(#name), teamnum); \
798 Create_Notification_Entity_InfoCenter(this, ACVNN(cvarname), strtoupper(#name), strnum, flnum, \
799 args, /* args */ \
800 hudargs, /* hudargs */ \
801 icon, /* icon */ \
802 CPID_Null,/* cpid */ \
803 "", /* durcnt */ \
804 normal, /* normal */ \
805 gentle); /* gentle */ \
806 }
807
809#define MULTIICON_INFO(name, defaultvalue, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \
810 MULTIICON_INFO_(INFO_##name, defaultvalue, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle)
811#define MULTIICON_INFO_(name, defaultvalue, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \
812 NOTIF_ADD_AUTOCVAR(name, defaultvalue) \
813 REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) { \
814 Create_Notification_Entity (this, defaultvalue, ACVNN(name), MSG_INFO, strtoupper(#name), 0); \
815 Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \
816 args, /* args */ \
817 hudargs, /* hudargs */ \
818 icon, /* icon */ \
819 CPID_Null,/* cpid */ \
820 "", /* durcnt */ \
821 normal, /* normal */ \
822 gentle); /* gentle */ \
823 this.nent_iconargs = iconargs; \
824 }
825
826#define MSG_CENTER_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, cpid, durcnt, normal, gentle) \
827 MSG_CENTER_NOTIF_(teamnum, CENTER_##name, CENTER_##cvarname, defaultvalue, strnum, flnum, args, cpid, durcnt, normal, gentle)
828
829#define MSG_CENTER_NOTIF(name, defaultvalue, strnum, flnum, args, cpid, durcnt, normal, gentle) \
830 NOTIF_ADD_AUTOCVAR(CENTER_##name, defaultvalue) \
831 MSG_CENTER_NOTIF_(0, CENTER_##name, CENTER_##name, defaultvalue, strnum, flnum, args, cpid, durcnt, normal, gentle)
832
833#define MSG_CENTER_NOTIF_(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, cpid, durcnt, normal, gentle) \
834 REGISTER(Notifications, name, m_id, new_pure(msg_center_notification)) { \
835 Create_Notification_Entity (this, defaultvalue, ACVNN(cvarname), MSG_CENTER, strtoupper(#name), teamnum); \
836 Create_Notification_Entity_InfoCenter(this, ACVNN(cvarname), strtoupper(#name), strnum, flnum, \
837 args, /* args */ \
838 "", /* hudargs */ \
839 "", /* icon */ \
840 cpid, /* cpid */ \
841 durcnt, /* durcnt */ \
842 normal, /* normal */ \
843 gentle); /* gentle */ \
844 }
845
846#define MSG_MULTI_NOTIF(name, defaultvalue, anncename, infoname, centername) \
847 NOTIF_ADD_AUTOCVAR(name, defaultvalue) \
848 REGISTER(Notifications, name, m_id, new_pure(msg_multi_notification)) { \
849 Create_Notification_Entity (this, defaultvalue, ACVNN(name), MSG_MULTI, strtoupper(#name), 0); \
850 Create_Notification_Entity_Multi(this, ACVNN(name), strtoupper(#name), \
851 anncename, /* anncename */ \
852 infoname, /* infoname */ \
853 centername); /* centername */ \
854 }
855
856#define MSG_CHOICE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, challow, chtype, optiona, optionb) \
857 MSG_CHOICE_NOTIF_(teamnum, CHOICE_##name, CHOICE_##cvarname, defaultvalue, challow, chtype, optiona, optionb)
858
859#define MSG_CHOICE_NOTIF(name, defaultvalue, challow, chtype, optiona, optionb) \
860 NOTIF_ADD_AUTOCVAR(CHOICE_##name, defaultvalue) \
861 NOTIF_ADD_AUTOCVAR(CHOICE_##name##_ALLOWED, challow) \
862 MSG_CHOICE_NOTIF_(0, CHOICE_##name, CHOICE_##name, defaultvalue, challow, chtype, optiona, optionb)
863
864#define MSG_CHOICE_NOTIF_(teamnum, name, cvarname, defaultvalue, challow, chtype, optiona, optionb) \
865 REGISTER(Notifications, name, m_id, new_pure(msg_choice_notification)) { \
866 this.nent_choice_idx = nent_choice_count; \
867 if (!teamnum || teamnum == NUM_TEAM_4) \
868 nent_choice_count++; \
869 Create_Notification_Entity (this, defaultvalue, ACVNN(cvarname), MSG_CHOICE, strtoupper(#name), teamnum); \
870 Create_Notification_Entity_Choice(this, ACVNN(cvarname), strtoupper(#name), \
871 challow, /* challow_def */ \
872 autocvar_notification_##cvarname##_ALLOWED, /* challow_var */ \
873 chtype, /* chtype */ \
874 optiona, /* optiona */ \
875 optionb); /* optionb */ \
876 }
877
878REGISTRY_BEGIN(Notifications)
879{
880 notif_global_error = false;
881}
882
883REGISTRY_END(Notifications)
884{
885 if (!notif_global_error) return;
886 // shit happened... stop the loading of the program now if this is unacceptable
888 LOG_FATAL("Notification initialization failed! Read above and fix the errors!");
889 else
890 LOG_SEVERE("Notification initialization failed! Read above and fix the errors!");
891}
892
893#ifdef CSQC
895void ReplicateVars(bool would_destroy)
896{
897 if (!would_destroy)
898 FOREACH(Notifications, it.nent_type == MSG_CHOICE && (!it.nent_teamnum || it.nent_teamnum == NUM_TEAM_1), {
899 string cvarname = strcat("notification_", Get_Notif_CvarName(it));
900 // NOTE: REPLICATE_SIMPLE can return;
901 REPLICATE_SIMPLE(it.cvar_value, cvarname);
902 });
903}
904#endif
905
906#include "all.inc"
#define BITS(n)
Definition bits.qh:9
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
string() ReadString_Raw
limitations: NULL cannot be present elements can only be present once a maximum of IL_MAX lists can e...
string m_name
Definition resources.qh:31
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:44
Resource ammo_type
M: ammotype : main ammo type.
Definition weapon.qh:51
float count
Definition powerups.qc:22
const int CMD_REQUEST_COMMAND
Definition command.qh:3
const int CMD_REQUEST_USAGE
Definition command.qh:4
#define GENERIC_COMMAND(id, description, menubased)
Definition reg.qh:12
string find_last_color_code(string s)
Definition util.qc:960
#define normal_or_gentle(normal, gentle)
Definition util.qh:243
string strtolower(string s)
const float FILE_WRITE
#define strstrofs
#define strlen
#define ORDINAL(it)
Definition enumclass.qh:25
#define ENUMCLASS_END(id)
Definition enumclass.qh:24
#define CASE(class, id)
Definition enumclass.qh:23
#define ENUMCLASS(id)
Definition enumclass.qh:22
#define GetProgramCommandPrefix()
Definition generic.qh:25
Weapons
Definition guide.qh:113
#define IL_NEW()
#define FOREACH(list, cond, body)
Definition iter.qh:19
#define USING(name, T)
Definition _all.inc:72
#define LOG_WARNF(...)
Definition log.qh:62
#define LOG_HELP(...)
Definition log.qh:85
#define LOG_FATALF(...)
Definition log.qh:54
#define LOG_INFO(...)
Definition log.qh:65
#define LOG_TRACE(...)
Definition log.qh:76
#define LOG_HELPF(...)
Definition log.qh:86
#define LOG_SEVERE(...)
Definition log.qh:57
#define LOG_FATAL(...)
Definition log.qh:53
#define LOG_INFOF(...)
Definition log.qh:66
void fclose(float fhandle)
string substring(string s, float start, float length)
float fopen(string filename, float mode)
string argv(float n)
spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2 f1points f2
Definition all.inc:364
spree_inf s1 s2 s3loc s2 s1
Definition all.inc:281
spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2 f1points s1 s2
Definition all.inc:469
f1
Definition all.inc:561
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
void Create_Notification_Entity_InfoCenter(entity notif, float var_cvar, string namestring, int strnum, int flnum, string args, string hudargs, string icon, CPID cpid, string durcnt, string normal, string gentle)
Definition all.qc:494
float autocvar_notification_show_location
Definition all.qh:304
void Kill_Notification(NOTIF broadcast, entity client, MSG net_type, CPID net_name)
Definition all.qc:1537
#define KILL_SPREE_LIST
Definition all.qh:491
string nent_string
Definition all.qh:699
CPID nent_cpid
Definition all.qh:697
entity nent_msginfo
Definition all.qh:703
int msg_choice_choices[NOTIF_CHOICE_MAX]
Definition all.qh:737
entity nent_msgannce
Definition all.qh:702
string arg_slot[NOTIF_MAX_ARGS]
Definition all.qh:422
#define DEFAULT_FILENAME
Definition all.qh:164
int nent_floatcount
Definition all.qh:683
const float ARG_CS_SV
Definition all.qh:426
int cvar_value
Definition all.qh:894
void Create_Notification_Entity_Annce(entity notif, float var_cvar, string namestring, float channel, string snd, float vol, float position, float queuetime)
Definition all.qc:446
int nent_choice_idx
Definition all.qh:736
void ReplicateVars(bool would_destroy)
Definition all.qh:895
float nent_position
Definition all.qh:690
float notif_queue_next_time
Definition all.qh:398
int nent_stringcount
Definition all.qh:682
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1573
int nent_teamnum
Definition all.qh:684
void Create_Notification_Entity_Multi(entity notif, float var_cvar, string namestring, Notification anncename, Notification infoname, Notification centername)
Definition all.qc:653
entity notif_queue_entity[NOTIF_QUEUE_MAX]
Definition all.qh:394
void Local_Notification(MSG net_type, Notification net_name,...count)
Definition all.qc:1236
bool notif_error
Definition all.qh:739
const float NOTIF_MAX_HUDARGS
Definition all.qh:389
const float NOTIF_MAX_DURCNT
Definition all.qh:390
string nent_hudargs
Definition all.qh:695
IntrusiveList g_notifications
Definition all.qh:240
float nent_challow_def
Definition all.qh:707
string nent_durcnt
Definition all.qh:698
float autocvar_notification_lifetime_mapload
Definition all.qh:313
Notification Get_Notif_Ent(MSG net_type, int net_name)
Definition all.qh:756
const int NOTIF_QUEUE_MAX
Definition all.qh:393
MSG notif_queue_type[NOTIF_QUEUE_MAX]
Definition all.qh:395
string nent_iconargs
Definition all.qh:808
string nent_name
Definition all.qh:681
string notif_arg_item_wepammo(float f1, float f2)
Definition all.qh:663
const float ARG_CS_SV_DC
Definition all.qh:425
void Create_Notification_Entity_Choice(entity notif, float var_cvar, string namestring, float challow_def, float challow_var, MSG chtype, Notification optiona, Notification optionb)
Definition all.qc:704
float autocvar_notification_lifetime_runtime
Definition all.qh:312
float nent_net_name
Definition all.qh:718
string BUFF_NAME(int i)
Definition buffs.qc:3
float autocvar_notification_errors_are_fatal
Definition all.qh:310
int nent_channel
Definition all.qh:687
entity nent_optiona
Definition all.qh:709
string nent_strings[4]
Definition all.qh:719
string Get_Notif_BroadcastName(NOTIF broadcast)
send to one client and their spectators
Definition all.qh:260
entity Notification
always last
Definition all.qh:81
void Send_Notification_WOCOVA(NOTIF broadcast, entity client, MSG net_type, Notification net_name, string s1, string s2, string s3, string s4, float f1, float f2, float f3, float f4)
Definition all.qc:1762
NOTIF nent_broadcast
Definition all.qh:714
float nent_queuetime
Definition all.qh:691
float autocvar_notification_show_sprees_info
Definition all.qh:307
string prev_soundfile
Definition all.qh:235
string notif_arg_frag_ping(bool newline, float fping)
Definition all.qh:501
float nent_vol
Definition all.qh:689
void Create_Notification_Entity(entity notif, float var_default, float var_cvar, MSG typeId, string namestring, int teamnum)
Definition all.qc:396
entity nent_msgcenter
Definition all.qh:704
void Local_Notification_Queue_Process()
Definition all.qc:1218
string Get_Notif_TypeName(MSG net_type)
main types/groups of notifications
Definition all.qh:30
string nent_icon
Definition all.qh:696
string autocvar_notification_show_location_string
Definition all.qh:305
string hash_replace(string full_msg, int ent_msg_num, string ent_msg, string attacker_name)
Definition all.qh:404
string notif_arg_spree_cen(float spree)
Definition all.qh:519
void Local_Notification_WOVA(MSG net_type, Notification net_name, float stringcount, float floatcount, string s1, string s2, string s3, string s4, float f1, float f2, float f3, float f4)
glue for networking, forwards to Local_Notification
Definition all.qc:1420
void Destroy_All_Notifications()
Definition all.qc:159
string nent_snd
Definition all.qh:688
const float ARG_CS
Definition all.qh:427
float notif_queue_time[NOTIF_QUEUE_MAX]
Definition all.qh:396
MSG nent_net_type
Definition all.qh:717
bool notif_global_error
Definition all.qh:740
int notif_queue_length
Definition all.qh:399
float prev_soundtime
Definition all.qh:236
string nent_args
Definition all.qh:694
float autocvar_notification_show_sprees_info_specialonly
Definition all.qh:309
entity nent_client
Definition all.qh:716
void Send_Notification_WOVA(NOTIF broadcast, entity client, MSG net_type, Notification net_name, float stringcount, float floatcount, string s1, string s2, string s3, string s4, float f1, float f2, float f3, float f4)
Definition all.qc:1728
const int NOTIF_CHOICE_MAX
Definition all.qh:732
string notif_arg_spree_inf(float type, string input, string player, float spree)
Definition all.qh:564
int nent_default
Definition all.qh:678
MSG nent_type
Definition all.qh:680
int nent_choice_count
Definition all.qh:735
const float ARG_DC
Definition all.qh:429
string notif_arg_frag_stats(float fhealth, float farmor, float fping)
Definition all.qh:510
float autocvar_notification_show_sprees
Definition all.qh:306
void Dump_Notifications(int fh, bool alsoprint)
used to output notifications.cfg file
Definition all.qc:783
float autocvar_notification_show_sprees_info_newline
Definition all.qh:308
float nent_floats[4]
Definition all.qh:720
float nent_challow_var
Definition all.qh:708
entity nent_optionb
Definition all.qh:710
const float NOTIF_MAX_ARGS
Definition all.qh:388
bool nent_enabled
Definition all.qh:679
float autocvar_notification_server_allows_location
Definition all.qh:318
const float ARG_SV
Definition all.qh:428
const float ARG_CS_SV_HA
Definition all.qh:424
string Get_Notif_CvarName(Notification notif)
Definition all.qh:749
void Notification_GetCvars(entity this, entity store)
Definition all.qc:767
#define NULL
Definition post.qh:14
#define REGISTRY_SORT(...)
Definition registry.qh:128
#define REGISTRY_BEGIN(id)
Called before initializing a registry.
Definition registry.qh:50
#define REGISTRY_END(id)
Called after initializing a registry.
Definition registry.qh:54
#define REGISTER_REGISTRY(id)
Definition registry.qh:229
#define REGISTRY(id, max)
Declare a new registry.
Definition registry.qh:26
#define REGISTRY_CHECK(id)
Definition registry.qh:175
#define REGISTRY_DEFINE_GET(id, null)
Definition registry.qh:40
#define REGISTRY_GET(id, i)
Definition registry.qh:43
#define STATIC_INIT_LATE(func)
directly after STATIC_INIT
Definition static.qh:37
#define STATIC_INIT(func)
during worldspawn
Definition static.qh:32
string CCR(string input)
color code replace, place inside of sprintf and parse the string
Definition string.qh:216
string Static_Team_ColorName(int teamid)
Definition teams.qh:103
const int NUM_TEAM_1
Definition teams.qh:13