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