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"), "dropweapon")) \
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", BUFF_NAME(f1)) \
461 ARG_CASE(ARG_CS_SV, "f3buffname", BUFF_NAME(f3)) \
462 ARG_CASE(ARG_CS_SV, "item_wepammo", (f2 > 0 ? notif_arg_item_wepammo(f1, f2) : "")) \
463 ARG_CASE(ARG_DC, "item_centime", ftos(autocvar_notification_item_centerprinttime)) \
464 ARG_CASE(ARG_SV, "death_team", Team_ColoredFullName(f1)) \
465 ARG_CASE(ARG_CS, "death_team", Team_ColoredFullName(f1 - 1)) \
466 ARG_CASE(ARG_SV, "s3#s2", s3) \
467 ARG_CASE(ARG_SV, "#s2", s2) \
468 ARG_CASE(ARG_CS, "s3#s2", HASH_REPLACE(input, 3, s2)) \
469 ARG_CASE(ARG_CS, "#s2", "") \
470 ARG_CASE(ARG_CS_SV_HA, "minigame1_name",find(NULL, netname, s1).descriptor.message) \
471 ARG_CASE(ARG_CS_SV_HA, "minigame1_d", find(NULL, netname, s1).descriptor.netname)
472
473#define NOTIF_HIT_MAX(count, funcname) MACRO_BEGIN \
474 if (sel_num == count) \
475 { \
476 backtrace(sprintf("%s: Hit maximum arguments!\n", funcname)); \
477 break; \
478 } \
479MACRO_END
480
481#define NOTIF_HIT_UNKNOWN(token, funcname) \
482{ \
483 backtrace(sprintf("%s: Hit unknown token in selected string! '%s'\n", funcname, selected)); \
484 break; \
485}
486
487#define KILL_SPREE_LIST \
488 SPREE_ITEM(3, 03, _("TRIPLE FRAG!"), _("%s^K1 made a TRIPLE FRAG!"), _("%s^K1 made a TRIPLE SCORE!")) \
489 SPREE_ITEM(5, 05, _("RAGE!"), _("%s^K1 unlocked RAGE!"), _("%s^K1 made FIVE SCORES IN A ROW!")) \
490 SPREE_ITEM(10, 10, _("MASSACRE!"), _("%s^K1 started a MASSACRE!"), _("%s^K1 made TEN SCORES IN A ROW!")) \
491 SPREE_ITEM(15, 15, _("MAYHEM!"), _("%s^K1 executed MAYHEM!"), _("%s^K1 made FIFTEEN SCORES IN A ROW!")) \
492 SPREE_ITEM(20, 20, _("BERSERKER!"), _("%s^K1 is a BERSERKER!"), _("%s^K1 made TWENTY SCORES IN A ROW!")) \
493 SPREE_ITEM(25, 25, _("CARNAGE!"), _("%s^K1 inflicts CARNAGE!"), _("%s^K1 made TWENTY FIVE SCORES IN A ROW!")) \
494 SPREE_ITEM(30, 30, _("ARMAGEDDON!"), _("%s^K1 unleashes ARMAGEDDON!"), _("%s^K1 made THIRTY SCORES IN A ROW!"))
495
496#ifdef CSQC
497string notif_arg_frag_ping(bool newline, float fping)
498{
499 string s = newline ? "\n" : " ";
500 if (fping < 0)
501 return sprintf(CCR(_("%s(^F1Bot^BG)")), s);
502 else
503 return sprintf(CCR(_("%s(Ping ^F1%d^BG)")), s, fping);
504}
505
506string notif_arg_frag_stats(float fhealth, float farmor, float fping)
507{
508 string s = notif_arg_frag_ping(false, fping);
509 if (fhealth > 1)
510 return sprintf(CCR(_("\n(Health ^1%d^BG / Armor ^2%d^BG)%s")), fhealth, farmor, s);
511 else
512 return sprintf(CCR(_("\n(^F4Dead^BG)%s")), s);
513}
514
515string notif_arg_spree_cen(float spree)
516{
517 // 0 = off, 1 = target (but only for first victim) and attacker
518 if (autocvar_notification_show_sprees_center)
519 {
520 if (spree > 1)
521 {
522 #define SPREE_ITEM(counta, countb, center, normal, gentle) \
523 case counta: \
524 return strcat(normal_or_gentle(center, sprintf(_("%d score spree!"), spree)), " ");
525
526 switch (spree)
527 {
529 default:
530 if (!autocvar_notification_show_sprees_center_specialonly)
531 return sprintf(
533 _("%d frag spree!"),
534 _("%d score spree!")
535 ), " "),
536 spree);
537 else
538 return ""; // don't show spree information if it isn't an achievement
539 }
540 #undef SPREE_ITEM
541 }
542 else if (spree == -1) // first blood
543 return strcat(normal_or_gentle(_("First blood!"), _("First score!")), " ");
544 else if (spree == -2) // first victim
545 return strcat(normal_or_gentle(_("First victim!"), _("First casualty!")), " ");
546 }
547 return "";
548}
549#endif
550
551string notif_arg_spree_inf(float type, string input, string player, float spree)
552{
553 switch (type)
554 {
555 case 1: // attacker kill spree
556 {
557 // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker
558 // this conditional (& 2) is true for 2 and 3
560 {
561 #ifdef CSQC
563 ? ((substring(input, 0, 1) == "\{3}") ? "\n\{3}" : "\n")
564 : "";
565 #else
567 ? "\n"
568 : "";
569 #endif
570
571 if (spree > 1)
572 {
573 #define SPREE_ITEM(counta, countb, center, normal, gentle) \
574 case counta: \
575 return sprintf(CCR(strcat(normal_or_gentle(normal, gentle), " %s^BG")), \
576 player, spree_newline);
577
578 switch (spree)
579 {
581 default:
583 return sprintf(
585 _("%s^K1 has %d frags in a row!"),
586 _("%s^K1 made %d scores in a row!")
587 ), " %s^BG")),
588 player,
589 spree,
590 spree_newline
591 );
592 else
593 return ""; // don't show spree information if it isn't an achievement
594 }
595 #undef SPREE_ITEM
596 }
597 else if (spree == -1) // firstblood
598 return sprintf(
600 _("%s^K1 drew first blood!"),
601 _("%s^K1 got the first score!")
602 ), " %s^BG")),
603 player,
604 spree_newline
605 );
606 }
607 break;
608 }
609
610 case -1: // kill spree ended
611 if (spree > 1 && (autocvar_notification_show_sprees_info & 1))
612 return sprintf(normal_or_gentle(
613 _(", ending their %d frag spree"),
614 _(", ending their %d score spree")
615 ),
616 spree
617 );
618 break;
619
620 case -2: // kill spree lost
621 if (spree > 1 && (autocvar_notification_show_sprees_info & 1))
622 return sprintf(normal_or_gentle(
623 _(", losing their %d frag spree"),
624 _(", losing their %d score spree")
625 ),
626 spree
627 );
628 break;
629 }
630 return "";
631}
632
633string notif_arg_item_wepammo(float f1, float f2)
634{
636 if (wep.ammo_type == RES_NONE)
637 return ""; // doesn't use ammo
638 // example for translators: You dropped the Vortex with 5 cells
639 return sprintf(_(" with %d %s"), f2, strtolower(wep.ammo_type.m_name));
640}
641
642
643// ====================================
644// Initialization/Create Declarations
645// ====================================
646
647// common notification entity values
654
655// MSG_ANNCE entity values
657.string nent_snd;
658.float nent_vol;
661
662// MSG_INFO and MSG_CENTER entity values
663.string nent_args; // used by both
664.string nent_hudargs; // used by info
665.string nent_icon; // used by info
666.CPID nent_cpid; // used by center
667.string nent_durcnt; // used by center
668.string nent_string; // used by both
669
670// MSG_MULTI entity values
674
675// MSG_CHOICE entity values
680
681// networked notification entity values
682#ifdef SVQC
684#endif
688.string nent_strings[4];
689.float nent_floats[4];
690
691// ACVNN: autocvar notification name, ACVNNA: autocvar notification name _ALLOWED
692#ifdef CSQC
693 #define ACVNN(name, defaultvalue) autocvar_notification_##name
694 #define ACVNNA(name, defaultvalue) autocvar_notification_##name##_ALLOWED
695 #define NOTIF_ADD_AUTOCVAR(name, defaultvalue) int autocvar_notification_##name = defaultvalue;
696 #define NOTIF_ADD_AUTOCVAR_ALLOWED(name, defaultvalue) int autocvar_notification_##name##_ALLOWED = defaultvalue;
697#else
698 // SVQC doesn't need the autocvars, it can just use the default values
699 #define ACVNN(name, defaultvalue) (defaultvalue)
700 #define ACVNNA(name, defaultvalue) (defaultvalue)
701 #define NOTIF_ADD_AUTOCVAR(name, defaultvalue)
702 #define NOTIF_ADD_AUTOCVAR_ALLOWED(name, defaultvalue)
703#endif
704
705REGISTRY(Notifications, BITS(11))
706REGISTER_REGISTRY(Notifications)
707REGISTRY_SORT(Notifications)
708
709REGISTRY_DEFINE_GET(Notifications, NULL)
710STATIC_INIT(Notifications)
711{
712 FOREACH(Notifications, true, it.m_id = i);
713}
714REGISTRY_CHECK(Notifications)
715
716const int NOTIF_CHOICE_MAX = 20;
717// NOTE: a team choice is actually made of 4 choices (one per team) with the same nent_choice_idx
718// thus they are counted as 1 in nent_choice_count
722// initialization error detection
725
726STATIC_INIT_LATE(Notif_Choices)
727{
729 LOG_FATALF("Too many MSG_CHOICE notifications (%d), hit NOTIF_CHOICE_MAX (%d) limit",
731}
732
734{
735 if (!notif.nent_teamnum)
736 return Get_Notif_Name(notif);
737 return substring(Get_Notif_Name(notif), 0, -strlen(Static_Team_ColorName(notif.nent_teamnum)) - 2);
738}
739
740Notification Get_Notif_Ent(MSG net_type, int net_name)
741{
742 Notification it = REGISTRY_GET(Notifications, net_name);
743 if (it.nent_type != net_type)
744 {
745 LOG_WARNF("Get_Notif_Ent(%s (%d), %s (%d)): Improper net type '%s'!",
746 Get_Notif_TypeName(net_type), net_type,
747 Get_Notif_Name(it), net_name,
748 Get_Notif_TypeName(it.nent_type)
749 );
750 return NULL;
751 }
752 return it;
753}
754
755#define MSG_ANNCE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \
756 MSG_ANNCE_NOTIF_(teamnum, ANNCE_##name, ANNCE_##cvarname, defaultvalue, sound, channel, volume, position, queuetime)
757#define MSG_ANNCE_NOTIF(name, defaultvalue, sound, channel, volume, position, queuetime) \
758 NOTIF_ADD_AUTOCVAR(ANNCE_##name, defaultvalue) \
759 MSG_ANNCE_NOTIF_(0, ANNCE_##name, ANNCE_##name, defaultvalue, sound, channel, volume, position, queuetime)
760
761#define MSG_ANNCE_NOTIF_(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \
762 REGISTER(Notifications, name, m_id, new_pure(msg_annce_notification)) \
763 { \
764 Create_Notification_Entity(this, defaultvalue, ACVNN(cvarname, defaultvalue), MSG_ANNCE, teamnum); \
765 Create_Notification_Entity_Annce(this, ACVNN(cvarname, defaultvalue), \
766 channel, /* channel */ \
767 sound, /* snd */ \
768 volume, /* vol */ \
769 position, /* position */ \
770 queuetime); /* queuetime */ \
771 }
772
773#define MSG_INFO_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle) \
774 MSG_INFO_NOTIF_(teamnum, INFO_##name, INFO_##cvarname, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle)
775
776#define MSG_INFO_NOTIF(name, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle) \
777 NOTIF_ADD_AUTOCVAR(INFO_##name, defaultvalue) \
778 MSG_INFO_NOTIF_(0, INFO_##name, INFO_##name, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle)
779
780#define MSG_INFO_NOTIF_(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle) \
781 REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) \
782 { \
783 Create_Notification_Entity(this, defaultvalue, ACVNN(cvarname, defaultvalue), MSG_INFO, teamnum); \
784 Create_Notification_Entity_InfoCenter(this, ACVNN(cvarname, defaultvalue), strnum, flnum, \
785 args, /* args */ \
786 hudargs, /* hudargs */ \
787 icon, /* icon */ \
788 CPID_Null, /* cpid */ \
789 "", /* durcnt */ \
790 normal, /* normal */ \
791 gentle); /* gentle */ \
792 }
793
795#define MULTIICON_INFO(name, defaultvalue, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \
796 MULTIICON_INFO_(INFO_##name, defaultvalue, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle)
797
798#define MULTIICON_INFO_(name, defaultvalue, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \
799 NOTIF_ADD_AUTOCVAR(name, defaultvalue) \
800 REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) \
801 { \
802 Create_Notification_Entity(this, defaultvalue, ACVNN(name, defaultvalue), MSG_INFO, 0); \
803 Create_Notification_Entity_InfoCenter(this, ACVNN(name, defaultvalue), strnum, flnum, \
804 args, /* args */ \
805 hudargs, /* hudargs */ \
806 icon, /* icon */ \
807 CPID_Null, /* cpid */ \
808 "", /* durcnt */ \
809 normal, /* normal */ \
810 gentle); /* gentle */ \
811 this.nent_iconargs = iconargs; \
812 }
813
814#define MSG_CENTER_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, cpid, durcnt, normal, gentle) \
815 MSG_CENTER_NOTIF_(teamnum, CENTER_##name, CENTER_##cvarname, defaultvalue, strnum, flnum, args, cpid, durcnt, normal, gentle)
816#define MSG_CENTER_NOTIF(name, defaultvalue, strnum, flnum, args, cpid, durcnt, normal, gentle) \
817 NOTIF_ADD_AUTOCVAR(CENTER_##name, defaultvalue) \
818 MSG_CENTER_NOTIF_(0, CENTER_##name, CENTER_##name, defaultvalue, strnum, flnum, args, cpid, durcnt, normal, gentle)
819
820#define MSG_CENTER_NOTIF_(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, cpid, durcnt, normal, gentle) \
821 REGISTER(Notifications, name, m_id, new_pure(msg_center_notification)) \
822 { \
823 Create_Notification_Entity(this, defaultvalue, ACVNN(cvarname, defaultvalue), MSG_CENTER, teamnum); \
824 Create_Notification_Entity_InfoCenter(this, ACVNN(cvarname, defaultvalue), strnum, flnum, \
825 args, /* args */ \
826 "", /* hudargs */ \
827 "", /* icon */ \
828 cpid, /* cpid */ \
829 durcnt, /* durcnt */ \
830 normal, /* normal */ \
831 gentle); /* gentle */ \
832 }
833
834#define MSG_MULTI_NOTIF(name, defaultvalue, anncename, infoname, centername) \
835 NOTIF_ADD_AUTOCVAR(name, defaultvalue) \
836 REGISTER(Notifications, name, m_id, new_pure(msg_multi_notification)) \
837 { \
838 Create_Notification_Entity(this, defaultvalue, ACVNN(name, defaultvalue), MSG_MULTI, 0); \
839 Create_Notification_Entity_Multi(this, ACVNN(name, defaultvalue), \
840 anncename, /* anncename */ \
841 infoname, /* infoname */ \
842 centername); /* centername */ \
843 }
844
845#define MSG_CHOICE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, challow, chtype, optiona, optionb) \
846 MSG_CHOICE_NOTIF_(teamnum, CHOICE_##name, CHOICE_##cvarname, defaultvalue, challow, chtype, optiona, optionb)
847#define MSG_CHOICE_NOTIF(name, defaultvalue, challow, chtype, optiona, optionb) \
848 NOTIF_ADD_AUTOCVAR(CHOICE_##name, defaultvalue) \
849 NOTIF_ADD_AUTOCVAR_ALLOWED(CHOICE_##name, challow) \
850 MSG_CHOICE_NOTIF_(0, CHOICE_##name, CHOICE_##name, defaultvalue, challow, chtype, optiona, optionb)
851
852#define MSG_CHOICE_NOTIF_(teamnum, name, cvarname, defaultvalue, challow, chtype, optiona, optionb) \
853 REGISTER(Notifications, name, m_id, new_pure(msg_choice_notification)) \
854 { \
855 this.nent_choice_idx = nent_choice_count; \
856 if (!teamnum || teamnum == NUM_TEAM_4) \
857 ++nent_choice_count; \
858 Create_Notification_Entity(this, defaultvalue, ACVNN(cvarname, defaultvalue), MSG_CHOICE, teamnum); \
859 Create_Notification_Entity_Choice(this, ACVNN(cvarname, defaultvalue), \
860 challow, /* challow_def */ \
861 ACVNNA(cvarname, challow), /* challow_var */ \
862 chtype, /* chtype */ \
863 optiona, /* optiona */ \
864 optionb); /* optionb */ \
865 }
866
867REGISTRY_BEGIN(Notifications)
868{
869 notif_global_error = false;
870}
871
872REGISTRY_END(Notifications)
873{
875 return;
876 // shit happened... stop the loading of the program now if this is unacceptable
878 LOG_FATAL("Notification initialization failed! Read above and fix the errors!");
879 else
880 LOG_SEVERE("Notification initialization failed! Read above and fix the errors!");
881}
882
883#ifdef CSQC
885void ReplicateVars(bool would_destroy)
886{
887 if (!would_destroy)
888 FOREACH(Notifications, it.nent_type == MSG_CHOICE && (!it.nent_teamnum || it.nent_teamnum == NUM_TEAM_1),
889 {
890 string cvarname = strcat("notification_", Get_Notif_CvarName(it));
891 // NOTE: REPLICATE_SIMPLE can return;
892 REPLICATE_SIMPLE(it.cvar_value, cvarname);
893 });
894}
895#endif
896
897#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:369
spree_inf s1 s2 s3loc s2 s1
Definition all.inc:284
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:474
f1
Definition all.inc:566
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:487
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:668
CPID nent_cpid
Definition all.qh:666
entity nent_msginfo
Definition all.qh:672
int msg_choice_choices[NOTIF_CHOICE_MAX]
set on each player containing MSG_CHOICE choices
Definition all.qh:721
const string BOLD_OPERATOR
Definition all.qh:13
entity nent_msgannce
Definition all.qh:671
string arg_slot[NOTIF_MAX_ARGS]
Definition all.qh:412
#define DEFAULT_FILENAME
Definition all.qh:164
int nent_floatcount
Definition all.qh:652
int cvar_value
Definition all.qh:884
int nent_choice_idx
Definition all.qh:720
void ReplicateVars(bool would_destroy)
Definition all.qh:885
bool autocvar_notification_show_location
Definition all.qh:294
float nent_position
Definition all.qh:659
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:651
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1500
int nent_teamnum
Definition all.qh:653
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:723
string nent_hudargs
Definition all.qh:664
IntrusiveList g_notifications
Definition all.qh:235
bool autocvar_notification_show_sprees
Definition all.qh:296
string nent_durcnt
Definition all.qh:667
float autocvar_notification_lifetime_mapload
Definition all.qh:303
Notification Get_Notif_Ent(MSG net_type, int net_name)
Definition all.qh:740
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:677
MSG notif_queue_type[NOTIF_QUEUE_MAX]
Definition all.qh:385
string nent_iconargs
Definition all.qh:794
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:633
float autocvar_notification_lifetime_runtime
Definition all.qh:302
int nent_channel
Definition all.qh:656
int nent_net_name
Definition all.qh:687
entity nent_optiona
Definition all.qh:678
string nent_strings[4]
Definition all.qh:688
string Get_Notif_BroadcastName(NOTIF broadcast)
send to one client and their spectators
Definition all.qh:258
NOTIF nent_broadcast
Definition all.qh:683
float nent_queuetime
Definition all.qh:660
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:497
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:658
entity nent_msgcenter
Definition all.qh:673
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:665
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:515
void Destroy_All_Notifications()
Definition all.qc:110
string nent_snd
Definition all.qh:657
float notif_queue_time[NOTIF_QUEUE_MAX]
Definition all.qh:386
MSG nent_net_type
Definition all.qh:686
bool notif_global_error
Definition all.qh:724
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:663
entity nent_client
Definition all.qh:685
const int NOTIF_CHOICE_MAX
Definition all.qh:716
string notif_arg_spree_inf(float type, string input, string player, float spree)
Definition all.qh:551
int nent_default
Definition all.qh:648
MSG nent_type
Definition all.qh:650
const int ARG_CS
unique result to CSQC
Definition all.qh:417
int nent_choice_count
Definition all.qh:719
int nent_challow_def
Definition all.qh:676
bool autocvar_notification_errors_are_fatal
Definition all.qh:300
string notif_arg_frag_stats(float fhealth, float farmor, float fping)
Definition all.qh:506
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:689
entity nent_optionb
Definition all.qh:679
const int ARG_CS_SV_DC
enabled on CSQC, SVQC, and durcnt centerprint
Definition all.qh:415
bool nent_enabled
Definition all.qh:649
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:733
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