]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/notifications.qh
Adding more announcements
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / notifications.qh
1 // ================================================
2 //  Unified notification system, written by Samual
3 //  Last updated: March, 2013
4 // ================================================
5
6 // main types/groups of notifications
7 #define MSG_ANNCE 1 // "Global" AND "personal" announcer messages
8 #define MSG_INFO 2 // "Global" information messages 
9 #define MSG_CENTER 3 // "Personal" centerprint messages
10 #define MSG_CENTER_CPID 4 // Kill centerprint message
11 #define MSG_MULTI 5 // Subcall MSG_INFO and/or MSG_CENTER notifications
12
13 #define NO_MSG -12345 
14
15 #define EIGHT_VARS_TO_VARARGS_VARLIST \
16         VARITEM(1, 0, s1) \
17         VARITEM(2, 0, XPD(s1, s2)) \
18         VARITEM(3, 0, XPD(s1, s2, s3)) \
19         VARITEM(4, 0, XPD(s1, s2, s3, s4)) \
20         VARITEM(0, 1, f1) \
21         VARITEM(1, 1, XPD(s1, f1)) \
22         VARITEM(2, 1, XPD(s1, s2, f1)) \
23         VARITEM(3, 1, XPD(s1, s2, s3, f1)) \
24         VARITEM(4, 1, XPD(s1, s2, s3, s4, f1)) \
25         VARITEM(0, 2, XPD(f1, f2)) \
26         VARITEM(1, 2, XPD(s1, f1, f2)) \
27         VARITEM(2, 2, XPD(s1, s2, f1, f2)) \
28         VARITEM(3, 2, XPD(s1, s2, s3, f1, f2)) \
29         VARITEM(4, 2, XPD(s1, s2, s3, s4, f1, f2)) \
30         VARITEM(0, 3, XPD(f1, f2, f3)) \
31         VARITEM(1, 3, XPD(s1, f1, f2, f3)) \
32         VARITEM(2, 3, XPD(s1, s2, f1, f2, f3)) \
33         VARITEM(3, 3, XPD(s1, s2, s3, f1, f2, f3)) \
34         VARITEM(4, 3, XPD(s1, s2, s3, s4, f1, f2, f3)) \
35         VARITEM(0, 4, XPD(f1, f2, f3, f4)) \
36         VARITEM(1, 4, XPD(s1, f1, f2, f3, f4)) \
37         VARITEM(2, 4, XPD(s1, s2, f1, f2, f3, f4)) \
38         VARITEM(3, 4, XPD(s1, s2, s3, f1, f2, f3, f4)) \
39         VARITEM(4, 4, XPD(s1, s2, s3, s4, f1, f2, f3, f4))
40
41 void Destroy_All_Notifications(void);
42 void Create_Notification_Entity(
43         float var_default,
44         float var_cvar,
45         float typeid,
46         float nameid,
47         string namestring,
48         float infoname,
49         float centername,
50         float strnum,
51         float flnum,
52         string args,
53         string hudargs,
54         string icon,
55         float cpid,
56         string durcnt,
57         string normal,
58         string gentle,
59         float msg_is_info,
60         float msg_is_multi);
61
62 void Dump_Notifications(float fh, float alsoprint);
63
64 void Local_Notification(float net_type, float net_name, ...count);
65 void Local_Notification_WOVA(
66         float net_type, float net_name,
67         float stringcount, float floatcount,
68         string s1, string s2, string s3, string s4,
69         float f1, float f2, float f3, float f4);
70
71 #ifdef CSQC // CLIENT ONLY
72 void Read_Notification(float is_new);
73 #endif
74
75 #ifdef SVQC // SERVER ONLY
76 #define NOTIF_ONE 1
77 #define NOTIF_ONE_ONLY 2
78 #define NOTIF_TEAM 3
79 #define NOTIF_TEAM_EXCEPT 4
80 #define NOTIF_ALL 5
81 #define NOTIF_ALL_EXCEPT 6
82
83 #define IFSTR(num) ((num < notif.nent_stringcount) ? ...(num, string) : "")
84 #define IFFL(num) ((((notif.nent_stringcount-1) + num) < count) ? ...(((notif.nent_stringcount-1) + num), float) : 0)
85
86 void Kill_Notification(
87         float broadcast, entity client,
88         float net_type, float net_name);
89 void Send_Notification(
90         float broadcast, entity client,
91         float net_type, float net_name,
92         ...count);
93 void Send_Notification_WOVA(
94         float broadcast, entity client,
95         float net_type, float net_name,
96         string s1, string s2, string s3, string s4,
97         float f1, float f2, float f3, float f4);
98 #endif
99
100
101 // ====================================
102 //  Notifications List and Information
103 // ====================================
104 /*
105  List of all notifications (including identifiers and display information)
106  Possible Tokens: default, name, infoname, centername, strnum, flnum, args, hudargs, icon, cpid, durcnt, normal, gentle
107  Format Specifications:
108     MSG_ANNCE: 
109     MSG_INFO:
110       default: FLOAT: Default setting for whether the notification is enabled or not
111          ^-> 0 = disabled, 1 = enabled, 2 = also print to chat box
112       name: VAR: Name of notification
113       strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive)
114       flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive)
115       args: STRING: Arguments for Local_Notification_sprintf()
116       hudargs: STRING: Arguments for Local_Notification_HUD_Notify_Push()
117       icon: STRING: icon string name for the hud notify panel, "" if no icon is used
118       normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled)
119       gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled)
120     MSG_CENTER:
121       default: FLOAT: Default setting for whether the notification is enabled or not
122          ^-> 0 = disabled, 1 = enabled
123       name: VAR: Name of notification
124       strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive)
125       flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive)
126       args: STRING: Arguments for Local_Notification_sprintf()
127       cpid: FLOAT: centerprint ID number (CPID_*), NO_CPID if no CPID is needed
128       durcnt: XPD(FLOAT, FLOAT): Duration/Countdown: extra arguments for centerprint messages
129       normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled)
130       gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled)
131     MSG_MULTI:
132       default: FLOAT: Default setting for whether the notification is enabled or not
133          ^-> 0 = disabled, 1 = enabled
134       name: VAR: Name of chaining notification
135       anncename: VAR: Name of announcer notification for reference
136       infoname: VAR: Name of info notification for reference
137       centername: VAR: Name of centerprint notification for reference
138
139  Messages with ^F1, ^BG, ^TC, etc etc in them will replace those strings
140  with colors according to the cvars the user has chosen. This allows for
141  users to create unique color profiles for their HUD, giving more customization
142  options to HUD designers and end users who want such a feature.
143
144  Check out the definitions in util.qc/util.qh/teams.qh for string CCR(...) and
145  string TCR(...) to better understand how these code replacements work.
146  
147  Additionally, you can find all the definitions and explanations for
148  the argument values and what they return down below in this file.
149
150  Guidlines for notification declaration (please try and follow these):
151   Specific rules:
152     -ALWAYS start the string with a color, preferably background.
153     -ALWAYS reset a color after a name (this way they don't set it for the whole string).
154     -NEVER re-declare an event twice.
155     -NEVER add or remove tokens from the format, it SHOULD already work.
156     -MSG_INFO messages must ALWAYS end with a new line: \n
157     -MSG_INFO hudargs must always be ATTACKER -> VICTIM
158     -MSG_CENTER should NOT end with a new line
159
160  General rules:
161     -Be clean and simple with your notification naming,
162      nothing too long for the name field... Abbreviations are your friend. :D
163     -Keep the spacing as clean as possible... if the arguments are abnormally long,
164       it's okay to go out of line a bit... but try and keep it clean still.
165     - Use ONLY spaces for spacing in the notification list, tabs are too inconsistent
166       with keeping alignment on different mediums.
167     -Sort the notifications in the most appropriate order for their tasks.
168     -ARIRE unir frk jvgu lbhe bja zbgure. (gvc sbe zvxrrhfn) -- Don't pay attention to this ^_^
169
170  Final note: DO NOT PROVIDE MORE ARGUMENTS THAN NECESSARY FOR THE NOTIFICATION YOU'RE CALLING!
171       The system is designed to save as much networking bandwidth as possible,
172       so please dynamically control your argument sending to fit *exactly* what is required.
173       If you send a notification with mismatching arguments, Send_Notification() will error.
174 */
175
176         // default, name, channel, sound, volume, position
177         // default 0 = off, 1 = only if gentle is DISABLED, 2 = always enabled
178 #define MSG_ANNCE_NOTIFICATIONS \
179         MSG_ANNCE_NOTIF(2, ANNCE_REMAINING_ONEMIN,          CH_INFO, "1minutesremain",  VOL_BASEVOICE, ANNCE_GLOBAL) \
180         MSG_ANNCE_NOTIF(2, ANNCE_REMAINING_FIVEMIN,         CH_INFO, "5minutesremain",  VOL_BASEVOICE, ANNCE_GLOBAL) \
181         MSG_ANNCE_NOTIF(2, ANNCE_ACHIEVEMENT_ELECTROBITCH,  CH_INFO, "electrobitch",    VOL_BASEVOICE, ANNCE_GLOBAL) \
182         MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_AIRSHOT,       CH_INFO, "airshot",         VOL_BASEVOICE, ANNCE_GLOBAL) \
183         MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_BOTLIKE,       CH_INFO, "botlike",         VOL_BASEVOICE, ANNCE_GLOBAL) \
184         MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_YODA,          CH_INFO, "yoda",            VOL_BASEVOICE, ANNCE_GLOBAL) \
185         MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_AMAZING,       CH_INFO, "amazing",         VOL_BASEVOICE, ANNCE_GLOBAL) \
186         MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_AWESOME,       CH_INFO, "awesome",         VOL_BASEVOICE, ANNCE_GLOBAL) \
187         MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_IMPRESSIVE,    CH_INFO, "impressive",      VOL_BASEVOICE, ANNCE_GLOBAL) \
188         MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_3,              CH_INFO, "03kills",         VOL_BASEVOICE, ANNCE_GLOBAL) \
189         MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_5,              CH_INFO, "05kills",         VOL_BASEVOICE, ANNCE_GLOBAL) \
190         MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_10,             CH_INFO, "10kills",         VOL_BASEVOICE, ANNCE_GLOBAL) \
191         MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_15,             CH_INFO, "15kills",         VOL_BASEVOICE, ANNCE_GLOBAL) \
192         MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_20,             CH_INFO, "20kills",         VOL_BASEVOICE, ANNCE_GLOBAL) \
193         MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_25,             CH_INFO, "25kills",         VOL_BASEVOICE, ANNCE_GLOBAL) \
194         MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_30,             CH_INFO, "30kills",         VOL_BASEVOICE, ANNCE_GLOBAL) \
195         MSG_ANNCE_NOTIF(2, ANNCE_NUM_1,                     CH_INFO, "1",               VOL_BASEVOICE, ANNCE_GLOBAL) \
196         MSG_ANNCE_NOTIF(2, ANNCE_NUM_2,                     CH_INFO, "2",               VOL_BASEVOICE, ANNCE_GLOBAL) \
197         MSG_ANNCE_NOTIF(2, ANNCE_NUM_3,                     CH_INFO, "3",               VOL_BASEVOICE, ANNCE_GLOBAL) \
198         MSG_ANNCE_NOTIF(2, ANNCE_NUM_4,                     CH_INFO, "4",               VOL_BASEVOICE, ANNCE_GLOBAL) \
199         MSG_ANNCE_NOTIF(2, ANNCE_NUM_5,                     CH_INFO, "5",               VOL_BASEVOICE, ANNCE_GLOBAL) \
200         MSG_ANNCE_NOTIF(2, ANNCE_NUM_6,                     CH_INFO, "6",               VOL_BASEVOICE, ANNCE_GLOBAL) \
201         MSG_ANNCE_NOTIF(2, ANNCE_NUM_7,                     CH_INFO, "7",               VOL_BASEVOICE, ANNCE_GLOBAL) \
202         MSG_ANNCE_NOTIF(2, ANNCE_NUM_8,                     CH_INFO, "8",               VOL_BASEVOICE, ANNCE_GLOBAL) \
203         MSG_ANNCE_NOTIF(2, ANNCE_NUM_9,                     CH_INFO, "9",               VOL_BASEVOICE, ANNCE_GLOBAL) \
204         MSG_ANNCE_NOTIF(2, ANNCE_NUM_10,                    CH_INFO, "10",              VOL_BASEVOICE, ANNCE_GLOBAL) \
205         MSG_ANNCE_NOTIF(2, ANNCE_
206         MSG_ANNCE_NOTIF(2, ANNCE_
207
208 #define MULTITEAM_INFO(default,prefix,teams,strnum,flnum,args,hudargs,icon,normal,gentle) \
209         MSG_INFO_NOTIF(default, prefix##RED, strnum, flnum, args, hudargs, sprintf(icon, strtolower(NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \
210         MSG_INFO_NOTIF(default, prefix##BLUE, strnum, flnum, args, hudargs, sprintf(icon, strtolower(NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) \
211         #if teams >= 3 \
212                 MSG_INFO_NOTIF(default, prefix##YELLOW, strnum, flnum, args, hudargs, sprintf(icon, strtolower(NAME_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) \
213         #endif \
214         #if teams >= 4 \
215                 MSG_INFO_NOTIF(default, prefix##PINK, strnum, flnum, args, hudargs, sprintf(icon, strtolower(NAME_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) \
216         #endif
217 #define MSG_INFO_NOTIFICATIONS \
218         MULTITEAM_INFO(1, INFO_CTF_CAPTURE_, 2,                1, 0, "s1", "s1",                        "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag\n"), "") \
219         MULTITEAM_INFO(1, INFO_CTF_CAPTURE_BROKEN_, 2,         2, 2, "s1 f1p2dec s2 f2p2dec", "s1",     "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG%s^BG's previous record of ^F2%s^BG seconds\n"), "") \
220         MULTITEAM_INFO(1, INFO_CTF_CAPTURE_TIME_, 2,           1, 1, "s1 f1p2dec", "s1",                "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds\n"), "") \
221         MULTITEAM_INFO(1, INFO_CTF_CAPTURE_UNBROKEN_, 2,       2, 2, "s1 f1p2dec s2 f2p2dec", "s1",     "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%s^BG seconds\n"), "") \
222         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_ABORTRUN_, 2,    0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag was returned to base by its owner\n"), "") \
223         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DAMAGED_, 2,     0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag was destroyed and returned to base\n"), "") \
224         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DROPPED_, 2,     0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself\n"), "") \
225         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_NEEDKILL_, 2,    0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base\n"), "") \
226         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_SPEEDRUN_, 2,    0, 1, "f1p2dec", "",                     "",                     _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself\n"), "") \
227         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_TIMEOUT_, 2,     0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag has returned to the base\n"), "") \
228         MULTITEAM_INFO(1, INFO_CTF_LOST_, 2,                   1, 0, "s1", "s1",                        "notify_%s_lost",       _("^BG%s^BG lost the ^TC^TT^BG flag\n"), "") \
229         MULTITEAM_INFO(1, INFO_CTF_PICKUP_, 2,                 1, 0, "s1", "s1",                        "notify_%s_taken",      _("^BG%s^BG got the ^TC^TT^BG flag\n"), "") \
230         MULTITEAM_INFO(1, INFO_CTF_RETURN_, 2,                 1, 0, "s1", "s1",                        "notify_%s_returned",   _("^BG%s^BG returned the ^TC^TT^BG flag\n"), "") \
231         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_CHEAT,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s\n"), "") \
232         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_DROWN,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_water",         _("^BG%s%s^K1 was drowned by ^BG%s^K1%s%s\n"), "") \
233         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FALL,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_fall",          _("^BG%s%s^K1 was grounded by ^BG%s^K1%s%s\n"), "") \
234         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FIRE,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s\n"), _("^BG%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s\n")) \
235         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_LAVA,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_lava",          _("^BG%s%s^K1 was cooked by ^BG%s^K1%s%s\n"), "") \
236         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SHOOTING_STAR,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_shootingstar",  _("^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s\n"), "") \
237         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SLIME,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_slime",         _("^BG%s%s^K1 was slimed by ^BG%s^K1%s%s\n"), "") \
238         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SWAMP,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_slime",         _("^BG%s%s^K1 was preserved by ^BG%s^K1%s%s\n"), "") \
239         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_TELEFRAG,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_telefrag",      _("^BG%s%s^K1 was telefragged by ^BG%s^K1%s%s\n"), _("^BG%s^K1 tried to occupy ^BG%s^K1's teleport destination space%s%s\n")) \
240         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_TOUCHEXPLODE,      3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 died in an accident with ^BG%s^K1%s%s\n"), "") \
241         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Bumblebee exploded%s%s\n"), "") \
242         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_GUN,       3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 saw the pretty lights of ^BG%s^K1's Bumblebee gun%s%s\n"), "") \
243         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_CRUSH,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was crushed by ^BG%s^K1%s%s\n"), "") \
244         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_BOMB,      3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was cluster bombed by ^BG%s^K1's Raptor%s%s\n"), "") \
245         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_CANNON,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 couldn't resist ^BG%s^K1's purple blobs%s%s\n"), "") \
246         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Raptor exploded%s%s\n"), "") \
247         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Spiderbot exploded%s%s\n"), "") \
248         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_MINIGUN,   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got shredded by ^BG%s^K1's Spiderbot%s%s\n"), "") \
249         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_ROCKET,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was blasted to bits by ^BG%s^K1's Spiderbot%s%s\n"), "") \
250         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s\n"), "") \
251         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_GUN,       3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s\n"), "") \
252         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_ROCKET,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s\n"), "") \
253         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VOID,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_void",          _("^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s\n"), "") \
254         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_AUTOTEAMCHANGE,      2, 1, "s1 s2loc death_team", "",         "",                     _("^BG%s^K1 was moved into the %s%s\n"), "") \
255         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_BETRAYAL,            2, 1, "s1 s2loc spree_lost", "s1",       "notify_teamkill_red",  _("^BG%s^K1 became enemies with the Lord of Teamplay%s%s\n"), "") \
256         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CAMP,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_camping",       _("^BG%s^K1 thought they found a nice camping ground%s%s\n"), "") \
257         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CHEAT,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_selfkill",      _("^BG%s^K1 unfairly eliminated themself%s%s\n"), "") \
258         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CUSTOM,              3, 1, "s1 s2 s3loc spree_lost", "s1",    "notify_void",          _("^BG%s^K1 %s^K1%s%s\n"), "") \
259         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_DROWN,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_water",         _("^BG%s^K1 couldn't catch their breath%s%s\n"), _("^BG%s^K1 was in the water for too long%s%s\n")) \
260         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FALL,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_fall",          _("^BG%s^K1 hit the ground with a crunch%s%s\n"), _("^BG%s^K1 hit the ground with a bit too much force%s%s\n")) \
261         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FIRE,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 became a bit too crispy%s%s\n"), _("^BG%s^K1 felt a little hot%s%s\n")) \
262         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_GENERIC,             2, 1, "s1 s2loc spree_lost", "s1",       "notify_selfkill",      _("^BG%s^K1 died%s%s\n"), "") \
263         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_LAVA,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_lava",          _("^BG%s^K1 turned into hot slag%s%s\n"), _("^BG%s^K1 found a hot place%s%s\n")) \
264         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NOAMMO,              2, 1, "s1 s2loc spree_lost", "s1",       "notify_outofammo",     _("^BG%s^K1 died%s%s. What's the point of living without ammo?\n"), _("^BG%s^K1 ran out of ammo%s%s\n")) \
265         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_ROT,                 2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 rotted away%s%s\n"), "") \
266         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SHOOTING_STAR,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_shootingstar",  _("^BG%s^K1 became a shooting star%s%s\n"), "") \
267         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SLIME,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_slime",         _("^BG%s^K1 was slimed%s%s\n"), "") \
268         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SUICIDE,             2, 1, "s1 s2loc spree_lost", "s1",       "notify_selfkill",      _("^BG%s^K1 couldn't take it anymore%s%s\n"), "") \
269         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SWAMP,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_slime",         _("^BG%s^K1 is now preserved for centuries to come%s%s\n"), "") \
270         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TEAMCHANGE,          2, 1, "s1 s2loc death_team", "",         "",                     _("^BG%s^K1 switched to the %s%s\n"), "") \
271         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TOUCHEXPLODE,        2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 died in an accident%s%s\n"), "") \
272         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET,              2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 ran into a turret%s%s\n"), "") \
273         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_EWHEEL,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted away by an eWheel turret%s%s\n"), "") \
274         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_FLAC,         2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught up in the FLAC turret fire%s%s\n"), "") \
275         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_HELLION,      2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted away by a Hellion turret%s%s\n"), "") \
276         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_HK,           2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 could not hide from the Hunter turret%s%s\n"), "") \
277         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_MACHINEGUN,   2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was riddled full of holes by a Machinegun turret%s%s\n"), "") \
278         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_MLRS,         2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got turned into smoldering gibs by an MLRS turret%s%s\n"), "") \
279         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_PHASER,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was phased out by a turret%s%s\n"), "") \
280         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_PLASMA,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got served some superheated plasma from a turret%s%s\n"), "") \
281         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_TESLA,        2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was electrocuted by a Tesla turret%s%s\n"), "") \
282         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_GUN,     2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got served a lead enrichment by a Walker turret%s%s\n"), "") \
283         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_MEELE,   2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was impaled by a Walker turret%s%s\n"), "") \
284         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_ROCKET,  2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted away by a Walker turret%s%s\n"), "") \
285         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_BUMB_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Bumblebee explosion%s%s\n"), "") \
286         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_CRUSH,            2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was crushed by a vehicle%s%s\n"), "") \
287         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_RAPT_BOMB,        2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was caught in a Raptor cluster bomb%s%s\n"), "") \
288         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_RAPT_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Raptor explosion%s%s\n"), "") \
289         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_SPID_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Spiderbot explosion%s%s\n"), "") \
290         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_SPID_ROCKET,      2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted to bits by a Spiderbot rocket%s%s\n"), "") \
291         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_WAKI_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Racer explosion%s%s\n"), "") \
292         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_WAKI_ROCKET,      2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 couldn't find shelter from a Racer rocket%s%s\n"), "") \
293         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VOID,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_void",          _("^BG%s^K1 was in the wrong place%s%s\n"), "") \
294         MULTITEAM_INFO(1, INFO_DEATH_TEAMKILL_, 4,             3, 1, "s1 s2 s3loc spree_end", "s2 s1",  "notify_teamkill_%s",   _("^BG%s^K1 was betrayed by ^BG%s^K1%s\n"), "") \
295         MSG_INFO_NOTIF(1, INFO_FREEZETAG_FREEZE,               2, 0, "s1 s2", "",                       "",                     _("^BG%s^K1 was frozen by ^BG%s\n"), "") \
296         MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVE,               2, 0, "s1 s2", "",                       "",                     _("^BG%s^K3 was revived by ^BG%s\n"), "") \
297         MULTITEAM_INFO(1, INFO_FREEZETAG_ROUND_WIN_, 4,        0, 0, "", "",                            "",                     _("^TC^TT^BG team wins the round, all other teams were frozen\n"), "") \
298         MSG_INFO_NOTIF(1, INFO_FREEZETAG_SELF,                 1, 0, "s1", "",                          "",                     _("^BG%s^K1 froze themself\n"), "") \
299         MSG_INFO_NOTIF(1, INFO_GODMODE_OFF,                    0, 1, "f1", "",                          "",                     _("^BGGodmode saved you %s units of damage, cheater!\n"), "") \
300         MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DONTHAVE,           0, 1, "item_wepname", "",                      "",               _("^BGYou do not have the ^F1%s\n"), "") \
301         MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DROP,               1, 1, "item_wepname item_wepammo", "",         "",               _("^BGYou dropped the ^F1%s^BG%s\n"), "") \
302         MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_GOT,                0, 1, "item_wepname", "",                      "",               _("^BGYou got the ^F1%s\n"), "") \
303         MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_NOAMMO,             0, 1, "item_wepname", "",                      "",               _("^BGYou don't have enough ammo for the ^F1%s\n"), "") \
304         MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_PRIMORSEC,          0, 3, "item_wepname f2primsec f3primsec", "",  "",               _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can\n"), "") \
305         MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_UNAVAILABLE,        0, 1, "item_wepname", "",                      "",               _("^F1%s^BG is ^F4not available^BG on this map\n"), "") \
306         MSG_INFO_NOTIF(2, INFO_JOIN_CONNECT,                   1, 0, "s1", "",                          "",                     _("^BG%s^F3 connected%s\n"), "") \
307         MULTITEAM_INFO(2, INFO_JOIN_CONNECT_TEAM_, 4,          1, 0, "s1", "",                          "",                     _("^BG%s^F3 connected and joined the ^TC^TT\n"), "") \
308         MSG_INFO_NOTIF(1, INFO_JOIN_PLAY,                      1, 0, "s1", "",                          "",                     _("^BG%s^F3 is now playing\n"), "") \
309         MSG_INFO_NOTIF(1, INFO_KEEPAWAY_DROPPED,               1, 0, "s1", "s1",                        "notify_balldropped",   _("^BG%s^BG has dropped the ball!\n"), "") \
310         MSG_INFO_NOTIF(1, INFO_KEEPAWAY_PICKUP,                1, 0, "s1", "s1",                        "notify_ballpickedup",  _("^BG%s^BG has picked up the ball!\n"), "") \
311         MULTITEAM_INFO(1, INFO_KEYHUNT_CAPTURE_, 4,            1, 0, "s1", "",                          "",                     _("^BG%s^BG captured the keys for the ^TC^TT team\n"), "") \
312         MULTITEAM_INFO(1, INFO_KEYHUNT_DROP_, 4,               1, 0, "s1", "",                          "",                     _("^BG%s^BG dropped the ^TC^TT Key\n"), "") \
313         MULTITEAM_INFO(1, INFO_KEYHUNT_LOST_, 4,               1, 0, "s1", "",                          "",                     _("^BG%s^BG lost the ^TC^TT Key\n"), "") \
314         MULTITEAM_INFO(1, INFO_KEYHUNT_PICKUP_, 4,             1, 0, "s1", "",                          "",                     _("^BG%s^BG picked up the ^TC^TT Key\n"), "") \
315         MSG_INFO_NOTIF(1, INFO_LMS_FORFEIT,                    1, 0, "s1", "",                          "",                     _("^BG%s^F3 forfeited\n"), "") \
316         MSG_INFO_NOTIF(1, INFO_LMS_NOLIVES,                    1, 0, "s1", "",                          "",                     _("^BG%s^F3 has no more lives left\n"), "") \
317         MSG_INFO_NOTIF(1, INFO_POWERUP_INVISIBILITY,           1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up Invisibility\n"), "") \
318         MSG_INFO_NOTIF(1, INFO_POWERUP_SHIELD,                 1, 0, "s1", "s1",                        "shield",               _("^BG%s^K1 picked up Shield\n"), "") \
319         MSG_INFO_NOTIF(1, INFO_POWERUP_SPEED,                  1, 0, "s1", "s1",                        "shield",               _("^BG%s^K1 picked up Speed\n"), "") \
320         MSG_INFO_NOTIF(1, INFO_POWERUP_STRENGTH,               1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up Strength\n"), "") \
321         MSG_INFO_NOTIF(2, INFO_QUIT_DISCONNECT,                1, 0, "s1", "",                          "",                     _("^BG%s^F3 disconnected\n"), "") \
322         MSG_INFO_NOTIF(2, INFO_QUIT_KICK_IDLING,               1, 0, "s1", "",                          "",                     _("^BG%s^F3 was kicked for idling\n"), "") \
323         MSG_INFO_NOTIF(1, INFO_QUIT_KICK_SPECTATING,           0, 0, "", "",                            "",                     _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment.\n"), "") \
324         MSG_INFO_NOTIF(1, INFO_QUIT_SPECTATE,                  1, 0, "s1", "",                          "",                     _("^BG%s^F3 is now spectating\n"), "") \
325         MSG_INFO_NOTIF(1, INFO_RACE_ABANDONED,                 1, 0, "s1", "",                                                        "",                      _("^BG%s^BG has abandoned the race\n"), "") \
326         MSG_INFO_NOTIF(1, INFO_RACE_FAIL_RANKED,               1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1",        "race_newfail",          _("^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s\n"), "") \
327         MSG_INFO_NOTIF(1, INFO_RACE_FAIL_UNRANKED,             1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1",        "race_newfail",          _("^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s\n"), "") \
328         MSG_INFO_NOTIF(1, INFO_RACE_FINISHED,                  1, 0, "s1", "",                                                        "",                      _("^BG%s^BG has finished the race\n"), "") \
329         MSG_INFO_NOTIF(1, INFO_RACE_NEW_BROKEN,                2, 3, "s1 s2 race_col f1ord race_col f2race_time race_diff", "s1 s2",  "race_newrankyellow",    _("^BG%s^BG broke %s^BG's %s%s^BG place record with %s%s %s\n"), "") \
330         MSG_INFO_NOTIF(1, INFO_RACE_NEW_IMPROVED,              1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1",        "race_newtime",          _("^BG%s^BG improved their %s%s^BG place record with %s%s %s\n"), "") \
331         MSG_INFO_NOTIF(1, INFO_RACE_NEW_MISSING_UID,           1, 1, "s1 f1race_time", "s1",                                          "race_newfail",          _("^BG%s^BG scored a new record with ^F2%s^BG, but unfortunately lacks a UID and will be lost.\n"), "") \
332         MSG_INFO_NOTIF(1, INFO_RACE_NEW_SET,                   1, 2, "s1 race_col f1ord race_col f2race_time", "s1",                  "race_newrecordserver",  _("^BG%s^BG set the %s%s^BG place record with %s%s\n"), "") \
333         MULTITEAM_INFO(1, INFO_SCORES_, 4,                     0, 0, "", "",                            "",                     _("^TC^TT ^BGteam scores!\n"), "") \
334         MSG_INFO_NOTIF(1, INFO_SPECTATE_WARNING,               0, 1, "f1secs", "",                      "",                     _("^F2You have to become a player within the next %s, otherwise you will be kicked, because spectating isn't allowed at this time!\n"), "") \
335         MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP,             1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up a Superweapon\n"), "") \
336         MSG_INFO_NOTIF(2, INFO_VERSION_BETA,                   2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s\n"), "") \
337         MSG_INFO_NOTIF(2, INFO_VERSION_OLD,                    2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s\n"), "") \
338         MSG_INFO_NOTIF(2, INFO_VERSION_OUTDATED,               2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get the update from ^F3http://www.xonotic.org/^BG!\n"), "") \
339         MSG_INFO_NOTIF(1, INFO_WATERMARK,                      1, 0, "s1", "",                          "",                     _("^F3SVQC Build information: ^F4%s\n"), "") \
340         MSG_INFO_NOTIF(1, INFO_WEAPON_ACCORDEON_MURDER,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapontuba",             _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Accordeon%s%s\n"), "") \
341         MSG_INFO_NOTIF(1, INFO_WEAPON_ACCORDEON_SUICIDE,             2, 1, "s1 s2loc spree_lost", "s1",                 "weapontuba",             _("^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s%s\n"), "") \
342         MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_MURDER,                3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponcrylink",          _("^BG%s%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s%s\n"), "") \
343         MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_SUICIDE,               2, 1, "s1 s2loc spree_lost", "s1",                 "weaponcrylink",          _("^BG%s^K1 felt the strong pull of their Crylink%s%s\n"), "") \
344         MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_BOLT,           3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponelectro",          _("^BG%s%s^K1 was blasted by ^BG%s^K1's Electro bolt%s%s\n"), "") \
345         MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_COMBO,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponelectro",          _("^BG%s%s^K1 felt the electrifying air of ^BG%s^K1's Electro combo%s%s\n"), "") \
346         MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_ORBS,           3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponelectro",          _("^BG%s%s^K1 got too close to ^BG%s^K1's Electro plasma%s%s\n"), "") \
347         MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_SUICIDE_BOLT,          2, 1, "s1 s2loc spree_lost", "s1",                 "weaponelectro",          _("^BG%s^K1 played with Electro plasma%s%s\n"), "") \
348         MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_SUICIDE_ORBS,          2, 1, "s1 s2loc spree_lost", "s1",                 "weaponelectro",          _("^BG%s^K1 could not remember where they put their Electro plasma%s%s\n"), "") \
349         MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_MURDER_BLAST,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponfireball",         _("^BG%s%s^K1 got too close to ^BG%s^K1's fireball%s%s\n"), "") \
350         MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_MURDER_FIREMINE,      3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponfireball",         _("^BG%s%s^K1 got burnt by ^BG%s^K1's firemine%s%s\n"), "") \
351         MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_SUICIDE_BLAST,        2, 1, "s1 s2loc spree_lost", "s1",                 "weaponfireball",         _("^BG%s^K1 should have used a smaller gun%s%s\n"), "") \
352         MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE,     2, 1, "s1 s2loc spree_lost", "s1",                 "weaponfireball",         _("^BG%s^K1 forgot about their firemine%s%s\n"), "") \
353         MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_MURDER_BURST,            3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhagar",            _("^BG%s%s^K1 was pummeled by a burst of ^BG%s^K1's Hagar rockets%s%s\n"), "") \
354         MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_MURDER_SPRAY,            3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhagar",            _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Hagar rockets%s%s\n"), "") \
355         MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_SUICIDE,                 2, 1, "s1 s2loc spree_lost", "s1",                 "weaponhagar",            _("^BG%s^K1 played with tiny Hagar rockets%s%s\n"), "") \
356         MSG_INFO_NOTIF(1, INFO_WEAPON_HLAC_MURDER,                   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhlac",             _("^BG%s%s^K1 was cut down with ^BG%s^K1's HLAC%s%s\n"), "") \
357         MSG_INFO_NOTIF(1, INFO_WEAPON_HLAC_SUICIDE,                  2, 1, "s1 s2loc spree_lost", "s1",                 "weaponhlac",             _("^BG%s^K1 got a little jumpy with their HLAC%s%s\n"), "") \
358         MSG_INFO_NOTIF(1, INFO_WEAPON_HOOK_MURDER,                   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhook",             _("^BG%s%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s%s\n"), "") \
359         MSG_INFO_NOTIF(1, INFO_WEAPON_KLEINBOTTLE_MURDER,            3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapontuba",             _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s%s\n"), "") \
360         MSG_INFO_NOTIF(1, INFO_WEAPON_KLEINBOTTLE_SUICIDE,           2, 1, "s1 s2loc spree_lost", "s1",                 "weapontuba",             _("^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s%s\n"), "") \
361         MSG_INFO_NOTIF(1, INFO_WEAPON_LASER_MURDER,                  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponlaser",            _("^BG%s%s^K1 was shot to death by ^BG%s^K1's Laser%s%s\n"), "") \
362         MSG_INFO_NOTIF(1, INFO_WEAPON_LASER_SUICIDE,                 2, 1, "s1 s2loc spree_lost", "s1",                 "weaponlaser",            _("^BG%s^K1 shot themself to hell with their Laser%s%s\n"), "") \
363         MSG_INFO_NOTIF(1, INFO_WEAPON_MINELAYER_MURDER,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponminelayer",        _("^BG%s%s^K1 got too close to ^BG%s^K1's mine%s%s\n"), "") \
364         MSG_INFO_NOTIF(1, INFO_WEAPON_MINELAYER_SUICIDE,             2, 1, "s1 s2loc spree_lost", "s1",                 "weaponminelayer",        _("^BG%s^K1 forgot about their mine%s%s\n"), "") \
365         MSG_INFO_NOTIF(1, INFO_WEAPON_MINSTANEX_MURDER,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponminstanex",        _("^BG%s%s^K1 has been vaporized by ^BG%s^K1's Minstanex%s%s\n"), "") \
366         MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_MURDER_BOUNCE,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapongrenadelauncher",  _("^BG%s%s^K1 got too close to ^BG%s^K1's Mortar grenade%s%s\n"), "") \
367         MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_MURDER_EXPLODE,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapongrenadelauncher",  _("^BG%s%s^K1 ate ^BG%s^K1's Mortar grenade%s%s\n"), "") \
368         MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_SUICIDE_BOUNCE,         2, 1, "s1 s2loc spree_lost", "s1",                 "weapongrenadelauncher",  _("^BG%s^K1 didn't see their own Mortar grenade%s%s\n"), "") \
369         MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_SUICIDE_EXPLODE,        2, 1, "s1 s2loc spree_lost", "s1",                 "weapongrenadelauncher",  _("^BG%s^K1 blew themself up with their own Mortar%s%s\n"), "") \
370         MSG_INFO_NOTIF(1, INFO_WEAPON_NEX_MURDER,                    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponnex",              _("^BG%s%s^K1 has been vaporized by ^BG%s^K1's Nex%s%s\n"), "") \
371         MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER,                  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 was sniped with a Rifle by ^BG%s^K1%s%s\n"), "") \
372         MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 died in ^BG%s^K1's Rifle bullet hail%s%s\n"), "") \
373         MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s%s\n"), "") \
374         MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HEADSHOT,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_headshot",        _("^BG%s%s^K1 was shot in the head with a Rifle by ^BG%s^K1%s%s\n"), "") \
375         MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_PIERCING,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle%s%s\n"), "") \
376         MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrocketlauncher",   _("^BG%s%s^K1 ate ^BG%s^K1's rocket%s%s\n"), "") \
377         MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrocketlauncher",   _("^BG%s%s^K1 got too close ^BG%s^K1's rocket%s%s\n"), "") \
378         MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_SUICIDE,        2, 1, "s1 s2loc spree_lost", "s1",                 "weaponrocketlauncher",   _("^BG%s^K1 blew themself up with their Rocketlauncher%s%s\n"), "") \
379         MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_MURDER_SPRAY,           3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponseeker",           _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s\n"), "") \
380         MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_MURDER_TAG,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponseeker",           _("^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s\n"), "") \
381         MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_SUICIDE,                2, 1, "s1 s2loc spree_lost", "s1",                 "weaponseeker",           _("^BG%s^K1 played with tiny Seeker rockets%s%s\n"), "") \
382         MSG_INFO_NOTIF(1, INFO_WEAPON_SHOTGUN_MURDER,                3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponshotgun",          _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s\n"), "") \
383         MSG_INFO_NOTIF(1, INFO_WEAPON_SHOTGUN_MURDER_SLAP,           3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1",  "notify_melee_shotgun",   _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s\n"), "") \
384         MSG_INFO_NOTIF(1, INFO_WEAPON_THINKING_WITH_PORTALS,         2, 1, "s1 s2loc spree_lost", "s1",                 "notify_selfkill",        _("^BG%s^K1 is now thinking with portals%s%s\n"), "") \
385         MSG_INFO_NOTIF(1, INFO_WEAPON_TUBA_MURDER,                   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapontuba",             _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s%s\n"), "") \
386         MSG_INFO_NOTIF(1, INFO_WEAPON_TUBA_SUICIDE,                  2, 1, "s1 s2loc spree_lost", "s1",                 "weapontuba",             _("^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s%s\n"), "") \
387         MSG_INFO_NOTIF(1, INFO_WEAPON_UZI_MURDER_SNIPE,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponuzi",              _("^BG%s%s^K1 was sniped by ^BG%s^K1's Machine Gun%s%s\n"), "") \
388         MSG_INFO_NOTIF(1, INFO_WEAPON_UZI_MURDER_SPRAY,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponuzi",              _("^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s\n"), "") 
389
390 #define MULTITEAM_CENTER(default,prefix,teams,strnum,flnum,args,cpid,durcnt,normal,gentle) \
391         MSG_CENTER_NOTIF(default, prefix##RED, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \
392         MSG_CENTER_NOTIF(default, prefix##BLUE, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) \
393         #if teams >= 3 \
394                 MSG_CENTER_NOTIF(default, prefix##YELLOW, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) \
395         #endif \
396         #if teams >= 4 \
397                 MSG_CENTER_NOTIF(default, prefix##PINK, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) \
398         #endif
399 #define MSG_CENTER_NOTIFICATIONS \
400         MSG_CENTER_NOTIF(1, CENTER_ARENA_BEGIN,                 0, 0, "",             CPID_ARENA,          "2 0", _("^F4Begin!"), "") \
401         MSG_CENTER_NOTIF(1, CENTER_ARENA_NEEDPLAYER,            0, 0, "",             CPID_ARENA,          "2 0", _("^BGNeed at least 1 player in each team to play Clan Arena!"), "") \
402         MSG_CENTER_NOTIF(1, CENTER_ARENA_ROUNDSTART,            0, 1, "",             CPID_ARENA,          "1 f1", _("^F4Round will start in ^COUNT"), "") \
403         MSG_CENTER_NOTIF(1, CENTER_ASSAULT_ATTACKING,           0, 0, "",             CPID_ASSAULT_ROLE,   "0 0", _("^BGYou are attacking!"), "") \
404         MSG_CENTER_NOTIF(1, CENTER_ASSAULT_DEFENDING,           0, 0, "",             CPID_ASSAULT_ROLE,   "0 0", _("^BGYou are defending!"), "") \
405         MSG_CENTER_NOTIF(1, CENTER_COUNTDOWN_BEGIN,             0, 0, "",             CPID_GAMESTART,      "2 0", _("^F4Begin!"), "") \
406         MSG_CENTER_NOTIF(1, CENTER_COUNTDOWN_GAMESTART,         0, 1, "",             CPID_GAMESTART,      "1 f1", _("^F4Game starts in ^COUNT"), "") \
407         MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_FREE,      0, 0, "",             CPID_CTF_CAPSHIELD,  "0 0", _("^BGYou are now free.\n^BGFeel free to ^F2try to capture^BG the flag again\n^BGif you think you will succeed."), "") \
408         MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_SHIELDED,  0, 0, "",             CPID_CTF_CAPSHIELD,  "0 0", _("^BGYou are now ^F1shielded^BG from the flag\n^BGfor ^F2too many unsuccessful attempts^BG to capture.\n^BGMake some defensive scores before trying again."), "") \
409         MULTITEAM_CENTER(1, CENTER_CTF_CAPTURE_, 2,             0, 0, "",             CPID_CTF_LOWPRIO,    "0 0", _("^BGYou captured the ^TC^TT^BG flag!"), "") \
410         MSG_CENTER_NOTIF(1, CENTER_CTF_FLAG_THROW_PUNISH,       0, 1, "f1secs",       CPID_CTF_LOWPRIO,    "0 0", _("^BGToo many flag throws! Throwing disabled for %s."), "") \
411         MULTITEAM_CENTER(1, CENTER_CTF_PASS_OTHER_, 2,          2, 0, "s1 s2",        CPID_CTF_PASS,       "0 0", _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") \
412         MULTITEAM_CENTER(1, CENTER_CTF_PASS_RECEIVED_, 2,       1, 0, "s1",           CPID_CTF_PASS,       "0 0", _("^BGYou received the ^TC^TT^BG flag from %s"), "") \
413         MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_REQUESTED,          1, 0, "s1 pass_key",  CPID_CTF_PASS,       "0 0", _("^BG%s^BG requests you to pass the flag%s"), "") \
414         MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_REQUESTING,         1, 0, "s1",           CPID_CTF_PASS,       "0 0", _("^BGRequesting %s^BG to pass you the flag"), "") \
415         MULTITEAM_CENTER(1, CENTER_CTF_PASS_SENT_, 2,           1, 0, "s1",           CPID_CTF_PASS,       "0 0", _("^BGYou passed the ^TC^TT^BG flag to %s"), "") \
416         MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_, 2,              0, 0, "",             CPID_CTF_LOWPRIO,    "0 0", _("^BGYou got the ^TC^TT^BG flag!"), "") \
417         MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY,            1, 0, "s1",           CPID_CTF_LOWPRIO,    "0 0", _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") \
418         MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_VERBOSE,    2, 0, "s1 s2 s1",     CPID_CTF_LOWPRIO,    "0 0", _("^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"), "") \
419         MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM,             1, 0, "s1",           CPID_CTF_LOWPRIO,    "0 0", _("^BGYour %steam mate^BG got the flag! Protect them!"), "") \
420         MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_VERBOSE,     2, 0, "s1 s2 s1",     CPID_CTF_LOWPRIO,    "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "") \
421         MULTITEAM_CENTER(1, CENTER_CTF_RETURN_, 2,              0, 0, "",             CPID_CTF_LOWPRIO,    "0 0", _("^BGYou returned the ^TC^TT^BG flag!"), "") \
422         MSG_CENTER_NOTIF(1, CENTER_CTF_STALEMATE_CARRIER,       0, 0, "",             CPID_STALEMATE,      "0 0", _("^BGStalemate! Enemies can now see you on radar!"), "") \
423         MSG_CENTER_NOTIF(1, CENTER_CTF_STALEMATE_OTHER,         0, 0, "",             CPID_STALEMATE,      "0 0", _("^BGStalemate! Flag carriers can now be seen by enemies on radar!"), "") \
424         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAG,                 1, 1, "spree_cen s1",             NO_CPID, "0 0", _("^K3%sYou fragged ^BG%s"), _("^K3%sYou scored against ^BG%s")) \
425         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAGGED,              1, 1, "spree_cen s1",             NO_CPID, "0 0", _("^K1%sYou were fragged by ^BG%s"), _("^K1%sYou were scored against by ^BG%s")) \
426         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAGGED_VERBOSE,      1, 4, "spree_cen s1 frag_stats",  NO_CPID, "0 0", _("^K1%sYou were fragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^BG%s")) \
427         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAG_VERBOSE,         1, 2, "spree_cen s1 frag_ping",   NO_CPID, "0 0", _("^K3%sYou fragged ^BG%s^BG%s"), _("^K3%sYou scored against ^BG%s^BG%s")) \
428         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAG,             1, 1, "spree_cen s1",             NO_CPID, "0 0", _("^K1%sYou typefragged ^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing")) \
429         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAGGED,          1, 1, "spree_cen s1",             NO_CPID, "0 0", _("^K1%sYou were typefragged by ^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing!")) \
430         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE,  1, 4, "spree_cen s1 frag_stats",  NO_CPID, "0 0", _("^K1%sYou were typefragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing^BG%s")) \
431         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE,     1, 2, "spree_cen s1 frag_ping",   NO_CPID, "0 0", _("^K1%sYou typefragged ^BG%s^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing^BG%s")) \
432         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_AUTOTEAMCHANGE,   0, 1, "death_team",   NO_CPID,             "0 0", _("^BGYou have been moved into a different team\nYou are now on: %s"), "") \
433         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_BETRAYAL,         0, 0, "",             NO_CPID,             "0 0", _("^K1Don't shoot your team mates!"), _("^K1Don't go against your team mates!")) \
434         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CAMP,             0, 0, "",             NO_CPID,             "0 0", _("^K1Die camper!"), _("^K1Reconsider your tactics, camper!")) \
435         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CHEAT,            0, 0, "",             NO_CPID,             "0 0", _("^K1You unfairly eliminated yourself!"), "") \
436         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CUSTOM,           2, 0, "s2",           NO_CPID,             "0 0", _("^K1You were %s"), "") \
437         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_DROWN,            0, 0, "",             NO_CPID,             "0 0", _("^K1You couldn't catch your breath!"), "") \
438         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_FALL,             0, 0, "",             NO_CPID,             "0 0", _("^K1You hit the ground with a crunch!"), "") \
439         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_FIRE,             0, 0, "",             NO_CPID,             "0 0", _("^K1You got a little bit too crispy!"), _("^K1You felt a little too hot!")) \
440         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_GENERIC,          0, 0, "",             NO_CPID,             "0 0", _("^K1You killed your own dumb self!"), _("^K1You need to be more careful!")) \
441         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_LAVA,             0, 0, "",             NO_CPID,             "0 0", _("^K1You couldn't stand the heat!"), "") \
442         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NOAMMO,           0, 0, "",             NO_CPID,             "0 0", _("^K1You were killed for running out of ammo..."), _("^K1You are respawning for running out of ammo...")) \
443         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_ROT,              0, 0, "",             NO_CPID,             "0 0", _("^K1You grew too old without taking your medicine"), _("^K1You need to preserve your health")) \
444         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SHOOTING_STAR,    0, 0, "",             NO_CPID,             "0 0", _("^K1You became a shooting star!"), "") \
445         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SLIME,            0, 0, "",             NO_CPID,             "0 0", _("^K1You melted away in slime!"), "") \
446         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SUICIDE,          0, 0, "",             NO_CPID,             "0 0", _("^K1You committed suicide!"), _("^K1You ended it all!")) \
447         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SWAMP,            0, 0, "",             NO_CPID,             "0 0", _("^K1You got stuck in a swamp!"), "") \
448         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TEAMCHANGE,       0, 1, "death_team",   NO_CPID,             "0 0", _("^BGYou are now on: %s"), "") \
449         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TOUCHEXPLODE,     0, 0, "",             NO_CPID,             "0 0", _("^K1You died in an accident!"), "") \
450         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TURRET,           0, 0, "",             NO_CPID,             "0 0", _("^K1You were fragged by a turret!"), _("^K1You had an unfortunate run in with a turret!")) \
451         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TURRET_EWHEEL,    0, 0, "",             NO_CPID,             "0 0", _("^K1You were fragged by an eWheel turret!"), _("^K1You had an unfortunate run in with an eWheel turret!")) \
452         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TURRET_WALK,      0, 0, "",             NO_CPID,             "0 0", _("^K1You were fragged by a Walker turret!"), _("^K1You had an unfortunate run in with a Walker turret!")) \
453         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_BUMB_DEATH,    0, 0, "",             NO_CPID,             "0 0", _("^K1You got caught in the blast of a Bumblebee explosion!"), "") \
454         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_CRUSH,         0, 0, "",             NO_CPID,             "0 0", _("^K1You were crushed by a vehicle!"), "") \
455         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_RAPT_BOMB,     0, 0, "",             NO_CPID,             "0 0", _("^K1You were caught in a Raptor cluster bomb!"), "") \
456         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_RAPT_DEATH,    0, 0, "",             NO_CPID,             "0 0", _("^K1You got caught in the blast of a Raptor explosion!"), "") \
457         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_SPID_DEATH,    0, 0, "",             NO_CPID,             "0 0", _("^K1You got caught in the blast of a Spiderbot explosion!"), "") \
458         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_SPID_ROCKET,   0, 0, "",             NO_CPID,             "0 0", _("^K1You were blasted to bits by a Spiderbot rocket!"), "") \
459         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_WAKI_DEATH,    0, 0, "",             NO_CPID,             "0 0", _("^K1You got caught in the blast of a Racer explosion!"), "") \
460         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_WAKI_ROCKET,   0, 0, "",             NO_CPID,             "0 0", _("^K1You couldn't find shelter from a Racer rocket!"), "") \
461         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VOID,             0, 0, "",             NO_CPID,             "0 0", _("^K1Watch your step!"), "") \
462         MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAG,         1, 0, "s1",           NO_CPID,             "0 0", _("^K1Moron! You fragged ^BG%s^K1, a team mate!"), _("^K1Moron! You went against ^BG%s^K1, a team mate!")) \
463         MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAGGED,      1, 0, "s1",           NO_CPID,             "0 0", _("^K1You were fragged by ^BG%s^K1, a team mate"), _("^K1You were scored against by ^BG%s^K1, a team mate")) \
464         MSG_CENTER_NOTIF(1, CENTER_DISCONNECT_IDLING,           0, 1, "",             CPID_IDLING,         "1 f1", _("^K1Stop idling!\n^BGDisconnecting in ^COUNT..."), "") \
465         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FREEZE,            1, 0, "s1",           NO_CPID,             "0 0", _("^K3You froze ^BG%s"), "") \
466         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FROZEN,            1, 0, "s1",           NO_CPID,             "0 0", _("^K1You were frozen by ^BG%s"), "") \
467         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE,            1, 0, "s1",           NO_CPID,             "0 0", _("^K3You revived ^BG%s"), "") \
468         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVED,           1, 0, "s1",           NO_CPID,             "0 0", _("^K3You were revived by ^BG%s"), "") \
469         MULTITEAM_CENTER(1, CENTER_FREEZETAG_ROUND_WIN_, 4,     0, 0, "",             NO_CPID,             "0 0", _("^TC^TT^BG team wins the round, all other teams were frozen"), "") \
470         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SELF,              0, 0, "",             NO_CPID,             "0 0", _("^K1You froze yourself"), "") \
471         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SPAWN_LATE,        0, 0, "",             NO_CPID,             "0 0", _("^K1You spawned after the round started, you'll spawn as frozen"), "") \
472         MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_DONTHAVE,        0, 1, "item_wepname",                      CPID_ITEM, "item_centime 0", _("^BGYou do not have the ^F1%s"), "") \
473         MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_DROP,            1, 1, "item_wepname item_wepammo",         CPID_ITEM, "item_centime 0", _("^BGYou dropped the ^F1%s^BG%s"), "") \
474         MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_GOT,             0, 1, "item_wepname",                      CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1%s"), "") \
475         MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_NOAMMO,          0, 1, "item_wepname",                      CPID_ITEM, "item_centime 0", _("^BGYou don't have enough ammo for the ^F1%s"), "") \
476         MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_PRIMORSEC,       0, 3, "item_wepname f2primsec f3primsec",  CPID_ITEM, "item_centime 0", _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"), "") \
477         MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_UNAVAILABLE,     0, 1, "item_wepname",                      CPID_ITEM, "item_centime 0", _("^F1%s^BG is ^F4not available^BG on this map"), "") \
478         MSG_CENTER_NOTIF(1, CENTER_JOIN_NOSPAWNS,               0, 0, "",              CPID_PREVENT_JOIN,     "0 0", _("^K1No spawnpoints available!\nHope your team can fix it..."), "") \
479         MSG_CENTER_NOTIF(1, CENTER_JOIN_PREVENT,                0, 0, "",              CPID_PREVENT_JOIN,     "0 0", _("^K1You may not join the game at this time.\nThe player limit reached maximum capacity."), "") \
480         MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_DROPPED,            1, 0, "s1",            CPID_KEEPAWAY,         "0 0", _("^BG%s^BG has dropped the ball!"), "") \
481         MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_PICKUP,             1, 0, "s1",            CPID_KEEPAWAY,         "0 0", _("^BG%s^BG has picked up the ball!"), "") \
482         MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_WARN,               0, 0, "",              CPID_KEEPAWAY_WARN,    "0 0", _("^BGKilling people while you don't have the ball gives no points!"), "") \
483         MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_HELP,                0, 0, "",              CPID_KEYHUNT,          "0 0", _("^BGAll keys are in your team's hands!\nHelp the key carriers to meet!"), "") \
484         MULTITEAM_CENTER(1, CENTER_KEYHUNT_INTERFERE_, 4,       0, 0, "",              CPID_KEYHUNT,          "0 0", _("^BGAll keys are in ^TC^TT team^BG's hands!\nInterfere ^F4NOW^BG!"), "") \
485         MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_MEET,                0, 0, "",              CPID_KEYHUNT,          "0 0", _("^BGAll keys are in your team's hands!\nMeet the other key carriers ^F4NOW^BG!"), "") \
486         MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_SCAN,                0, 1, "",              CPID_KEYHUNT_OTHER,    "f1 0", _("^BGScanning frequency range..."), "") \
487         MULTITEAM_CENTER(1, CENTER_KEYHUNT_START_, 4,           0, 0, "",              CPID_KEYHUNT,          "0 0", _("^BGYou are starting with the ^TC^TT Key"), "") \
488         MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_WAIT,                0, 4, "kh_teams",      CPID_KEYHUNT_OTHER,    "0 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") \
489         MSG_CENTER_NOTIF(1, CENTER_LMS_CAMPCHECK,               0, 0, "",              CPID_LMS_CAMP,         "0 0", _("^F2Don't camp!"), "") \
490         MSG_CENTER_NOTIF(1, CENTER_MINSTA_FINDAMMO,             0, 0, "",              CPID_MINSTA_FINDAMMO,  "1 9", _("^F4^COUNT^BG left to find some ammo!"), "") \
491         MSG_CENTER_NOTIF(1, CENTER_MINSTA_FINDAMMO_FIRST,       0, 0, "",              CPID_MINSTA_FINDAMMO,  "1 10", _("^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"), _("^BGGet some ammo! ^F4^COUNT^BG left!")) \
492         MSG_CENTER_NOTIF(1, CENTER_MOTD,                        1, 0, "s1",            CPID_MOTD,             "-1 0", _("^BG%s"), "") \
493         MSG_CENTER_NOTIF(1, CENTER_NIX_COUNTDOWN,               0, 2, "item_wepname",  CPID_NIX,              "1 f2", _("^F2^COUNT^BG until weapon change...\nNext weapon: ^F1%s"), "") \
494         MSG_CENTER_NOTIF(1, CENTER_NIX_NEWWEAPON,               0, 1, "item_wepname",  CPID_NIX,              "0 0", _("^F2Active weapon: ^F1%s"), "") \
495         MSG_CENTER_NOTIF(1, CENTER_OVERTIME_FRAG,               0, 0, "",              CPID_OVERTIME,         "0 0", _("^F2Now playing ^F4OVERTIME^F2!\nKeep fragging until we have a winner!"), _("^F2Now playing ^F4OVERTIME^F2!\nKeep scoring until we have a winner!")) \
496         MSG_CENTER_NOTIF(1, CENTER_OVERTIME_TIME,               0, 1, "f1time",        CPID_OVERTIME,         "0 0", _("^F2Now playing ^F4OVERTIME^F2!\nAdded ^F4%s^F2 to the game!"), "") \
497         MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_INVISIBILITY,      0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Invisibility has worn off"), "") \
498         MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_SHIELD,            0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Shield has worn off"), "") \
499         MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_SPEED,             0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Speed has worn off"), "") \
500         MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_STRENGTH,          0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Strength has worn off"), "") \
501         MSG_CENTER_NOTIF(1, CENTER_POWERUP_INVISIBILITY,        0, 0, "",              CPID_POWERUP,          "0 0", _("^F2You are invisible"), "") \
502         MSG_CENTER_NOTIF(1, CENTER_POWERUP_SHIELD,              0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Shield surrounds you"), "") \
503         MSG_CENTER_NOTIF(1, CENTER_POWERUP_SPEED,               0, 0, "",              CPID_POWERUP,          "0 0", _("^F2You are on speed"), "") \
504         MSG_CENTER_NOTIF(1, CENTER_POWERUP_STRENGTH,            0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Strength infuses your weapons with devastating power"), "") \
505         MSG_CENTER_NOTIF(1, CENTER_RACE_FINISHLAP,              0, 0, "",              CPID_RACE_FINISHLAP,   "0 0", _("^F2The race is over, finish your lap!"), "") \
506         MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_BROKEN,          0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Superweapons have broken down"), "") \
507         MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_LOST,            0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Superweapons have been lost"), "") \
508         MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_PICKUP,          0, 0, "",              CPID_POWERUP,          "0 0", _("^F2You now have a superweapon"), "") \
509         MULTITEAM_CENTER(1, CENTER_TEAMCHANGE_, 4,              0, 1, "",              CPID_TEAMCHANGE,       "1 f1", _("^K1Changing to ^TC^TT^K1 in ^COUNT"), "") \
510         MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_AUTO,             0, 1, "",              CPID_TEAMCHANGE,       "1 f1", _("^K1Changing team in ^COUNT"), "") \
511         MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SPECTATE,         0, 1, "",              CPID_TEAMCHANGE,       "1 f1", _("^K1Spectating in ^COUNT"), "") \
512         MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SUICIDE,          0, 1, "",              CPID_TEAMCHANGE,       "1 f1", _("^K1Suicide in ^COUNT"), "") \
513         MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_BEGINNING,           0, 1, "",              CPID_TIMEOUT,          "1 f1", _("^F4Timeout begins in ^COUNT"), "") \
514         MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_ENDING,              0, 1, "",              CPID_TIMEOUT,          "1 f1", _("^F4Timeout ends in ^COUNT"), "")
515
516 #define MSG_MULTI_NOTIFICATIONS \
517         /*MSG_MULTI_NOTIF(1, FOOBAR,                               ANNOUNCE_FOOBAR,                           INFO_FOOBAR,                             CENTER_FOOBAR) \*/ \
518         MSG_MULTI_NOTIF(1, DEATH_MURDER_CHEAT,                   INFO_DEATH_MURDER_CHEAT,                   NO_MSG) \
519         MSG_MULTI_NOTIF(1, DEATH_MURDER_DROWN,                   INFO_DEATH_MURDER_DROWN,                   NO_MSG) \
520         MSG_MULTI_NOTIF(1, DEATH_MURDER_FALL,                    INFO_DEATH_MURDER_FALL,                    NO_MSG) \
521         MSG_MULTI_NOTIF(1, DEATH_MURDER_FIRE,                    INFO_DEATH_MURDER_FIRE,                    NO_MSG) \
522         MSG_MULTI_NOTIF(1, DEATH_MURDER_LAVA,                    INFO_DEATH_MURDER_LAVA,                    NO_MSG) \
523         MSG_MULTI_NOTIF(1, DEATH_MURDER_SHOOTING_STAR,           INFO_DEATH_MURDER_SHOOTING_STAR,           NO_MSG) \
524         MSG_MULTI_NOTIF(1, DEATH_MURDER_SLIME,                   INFO_DEATH_MURDER_SLIME,                   NO_MSG) \
525         MSG_MULTI_NOTIF(1, DEATH_MURDER_SWAMP,                   INFO_DEATH_MURDER_SWAMP,                   NO_MSG) \
526         MSG_MULTI_NOTIF(1, DEATH_MURDER_TELEFRAG,                INFO_DEATH_MURDER_TELEFRAG,                NO_MSG) \
527         MSG_MULTI_NOTIF(1, DEATH_MURDER_TOUCHEXPLODE,            INFO_DEATH_MURDER_TOUCHEXPLODE,            NO_MSG) \
528         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_BUMB_DEATH,           INFO_DEATH_MURDER_VH_BUMB_DEATH,           NO_MSG) \
529         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_BUMB_GUN,             INFO_DEATH_MURDER_VH_BUMB_GUN,             NO_MSG) \
530         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_CRUSH,                INFO_DEATH_MURDER_VH_CRUSH,                NO_MSG) \
531         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_BOMB,            INFO_DEATH_MURDER_VH_RAPT_BOMB,            NO_MSG) \
532         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_CANNON,          INFO_DEATH_MURDER_VH_RAPT_CANNON,          NO_MSG) \
533         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_DEATH,           INFO_DEATH_MURDER_VH_RAPT_DEATH,           NO_MSG) \
534         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_DEATH,           INFO_DEATH_MURDER_VH_SPID_DEATH,           NO_MSG) \
535         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_MINIGUN,         INFO_DEATH_MURDER_VH_SPID_MINIGUN,         NO_MSG) \
536         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_ROCKET,          INFO_DEATH_MURDER_VH_SPID_ROCKET,          NO_MSG) \
537         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_DEATH,           INFO_DEATH_MURDER_VH_WAKI_DEATH,           NO_MSG) \
538         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_GUN,             INFO_DEATH_MURDER_VH_WAKI_GUN,             NO_MSG) \
539         MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_ROCKET,          INFO_DEATH_MURDER_VH_WAKI_ROCKET,          NO_MSG) \
540         MSG_MULTI_NOTIF(1, DEATH_MURDER_VOID,                    INFO_DEATH_MURDER_VOID,                    NO_MSG) \
541         MSG_MULTI_NOTIF(1, DEATH_SELF_AUTOTEAMCHANGE,            INFO_DEATH_SELF_AUTOTEAMCHANGE,            CENTER_DEATH_SELF_AUTOTEAMCHANGE) \
542         MSG_MULTI_NOTIF(1, DEATH_SELF_BETRAYAL,                  INFO_DEATH_SELF_BETRAYAL,                  CENTER_DEATH_SELF_BETRAYAL) \
543         MSG_MULTI_NOTIF(1, DEATH_SELF_CAMP,                      INFO_DEATH_SELF_CAMP,                      CENTER_DEATH_SELF_CAMP) \
544         MSG_MULTI_NOTIF(1, DEATH_SELF_CHEAT,                     INFO_DEATH_SELF_CHEAT,                     CENTER_DEATH_SELF_CHEAT) \
545         MSG_MULTI_NOTIF(1, DEATH_SELF_CUSTOM,                    INFO_DEATH_SELF_GENERIC,                   CENTER_DEATH_SELF_CUSTOM) \
546         MSG_MULTI_NOTIF(1, DEATH_SELF_DROWN,                     INFO_DEATH_SELF_DROWN,                     CENTER_DEATH_SELF_DROWN) \
547         MSG_MULTI_NOTIF(1, DEATH_SELF_FALL,                      INFO_DEATH_SELF_FALL,                      CENTER_DEATH_SELF_FALL) \
548         MSG_MULTI_NOTIF(1, DEATH_SELF_FIRE,                      INFO_DEATH_SELF_FIRE,                      CENTER_DEATH_SELF_FIRE) \
549         MSG_MULTI_NOTIF(1, DEATH_SELF_GENERIC,                   INFO_DEATH_SELF_GENERIC,                   CENTER_DEATH_SELF_GENERIC) \
550         MSG_MULTI_NOTIF(1, DEATH_SELF_LAVA,                      INFO_DEATH_SELF_LAVA,                      CENTER_DEATH_SELF_LAVA) \
551         MSG_MULTI_NOTIF(1, DEATH_SELF_NOAMMO,                    INFO_DEATH_SELF_NOAMMO,                    CENTER_DEATH_SELF_NOAMMO) \
552         MSG_MULTI_NOTIF(1, DEATH_SELF_ROT,                       INFO_DEATH_SELF_ROT,                       CENTER_DEATH_SELF_ROT) \
553         MSG_MULTI_NOTIF(1, DEATH_SELF_SHOOTING_STAR,             INFO_DEATH_SELF_SHOOTING_STAR,             CENTER_DEATH_SELF_SHOOTING_STAR) \
554         MSG_MULTI_NOTIF(1, DEATH_SELF_SLIME,                     INFO_DEATH_SELF_SLIME,                     CENTER_DEATH_SELF_SLIME) \
555         MSG_MULTI_NOTIF(1, DEATH_SELF_SUICIDE,                   INFO_DEATH_SELF_SUICIDE,                   CENTER_DEATH_SELF_SUICIDE) \
556         MSG_MULTI_NOTIF(1, DEATH_SELF_SWAMP,                     INFO_DEATH_SELF_SWAMP,                     CENTER_DEATH_SELF_SWAMP) \
557         MSG_MULTI_NOTIF(1, DEATH_SELF_TEAMCHANGE,                INFO_DEATH_SELF_TEAMCHANGE,                CENTER_DEATH_SELF_TEAMCHANGE) \
558         MSG_MULTI_NOTIF(1, DEATH_SELF_TOUCHEXPLODE,              INFO_DEATH_SELF_TOUCHEXPLODE,              CENTER_DEATH_SELF_TOUCHEXPLODE) \
559         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET,                    INFO_DEATH_SELF_TURRET,                    CENTER_DEATH_SELF_TURRET) \
560         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_EWHEEL,             INFO_DEATH_SELF_TURRET_EWHEEL,             CENTER_DEATH_SELF_TURRET_EWHEEL) \
561         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_FLAC,               INFO_DEATH_SELF_TURRET_FLAC,               CENTER_DEATH_SELF_TURRET) \
562         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_HELLION,            INFO_DEATH_SELF_TURRET_HELLION,            CENTER_DEATH_SELF_TURRET) \
563         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_HK,                 INFO_DEATH_SELF_TURRET_HK,                 CENTER_DEATH_SELF_TURRET) \
564         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_MACHINEGUN,         INFO_DEATH_SELF_TURRET_MACHINEGUN,         CENTER_DEATH_SELF_TURRET) \
565         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_MLRS,               INFO_DEATH_SELF_TURRET_MLRS,               CENTER_DEATH_SELF_TURRET) \
566         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_PHASER,             INFO_DEATH_SELF_TURRET_PHASER,             CENTER_DEATH_SELF_TURRET) \
567         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_PLASMA,             INFO_DEATH_SELF_TURRET_PLASMA,             CENTER_DEATH_SELF_TURRET) \
568         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_TESLA,              INFO_DEATH_SELF_TURRET_TESLA,              CENTER_DEATH_SELF_TURRET) \
569         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_GUN,           INFO_DEATH_SELF_TURRET_WALK_GUN,           CENTER_DEATH_SELF_TURRET_WALK) \
570         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_MEELE,         INFO_DEATH_SELF_TURRET_WALK_MEELE,         CENTER_DEATH_SELF_TURRET_WALK) \
571         MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_ROCKET,        INFO_DEATH_SELF_TURRET_WALK_ROCKET,        CENTER_DEATH_SELF_TURRET_WALK) \
572         MSG_MULTI_NOTIF(1, DEATH_SELF_VH_BUMB_DEATH,             INFO_DEATH_SELF_VH_BUMB_DEATH,             CENTER_DEATH_SELF_VH_BUMB_DEATH) \
573         MSG_MULTI_NOTIF(1, DEATH_SELF_VH_CRUSH,                  INFO_DEATH_SELF_VH_CRUSH,                  CENTER_DEATH_SELF_VH_CRUSH) \
574         MSG_MULTI_NOTIF(1, DEATH_SELF_VH_RAPT_BOMB,              INFO_DEATH_SELF_VH_RAPT_BOMB,              CENTER_DEATH_SELF_VH_RAPT_BOMB) \
575         MSG_MULTI_NOTIF(1, DEATH_SELF_VH_RAPT_DEATH,             INFO_DEATH_SELF_VH_RAPT_DEATH,             CENTER_DEATH_SELF_VH_RAPT_DEATH) \
576         MSG_MULTI_NOTIF(1, DEATH_SELF_VH_SPID_DEATH,             INFO_DEATH_SELF_VH_SPID_DEATH,             CENTER_DEATH_SELF_VH_SPID_DEATH) \
577         MSG_MULTI_NOTIF(1, DEATH_SELF_VH_SPID_ROCKET,            INFO_DEATH_SELF_VH_SPID_ROCKET,            CENTER_DEATH_SELF_VH_SPID_ROCKET) \
578         MSG_MULTI_NOTIF(1, DEATH_SELF_VH_WAKI_DEATH,             INFO_DEATH_SELF_VH_WAKI_DEATH,             CENTER_DEATH_SELF_VH_WAKI_DEATH) \
579         MSG_MULTI_NOTIF(1, DEATH_SELF_VH_WAKI_ROCKET,            INFO_DEATH_SELF_VH_WAKI_ROCKET,            CENTER_DEATH_SELF_VH_WAKI_ROCKET) \
580         MSG_MULTI_NOTIF(1, DEATH_SELF_VOID,                      INFO_DEATH_SELF_VOID,                      CENTER_DEATH_SELF_VOID) \
581         MSG_MULTI_NOTIF(1, ITEM_WEAPON_DONTHAVE,                 INFO_ITEM_WEAPON_DONTHAVE,                 CENTER_ITEM_WEAPON_DONTHAVE) \
582         MSG_MULTI_NOTIF(1, ITEM_WEAPON_DROP,                     INFO_ITEM_WEAPON_DROP,                     CENTER_ITEM_WEAPON_DROP) \
583         MSG_MULTI_NOTIF(1, ITEM_WEAPON_GOT,                      INFO_ITEM_WEAPON_GOT,                      CENTER_ITEM_WEAPON_GOT) \
584         MSG_MULTI_NOTIF(1, ITEM_WEAPON_NOAMMO,                   INFO_ITEM_WEAPON_NOAMMO,                   CENTER_ITEM_WEAPON_NOAMMO) \
585         MSG_MULTI_NOTIF(1, ITEM_WEAPON_PRIMORSEC,                INFO_ITEM_WEAPON_PRIMORSEC,                CENTER_ITEM_WEAPON_PRIMORSEC) \
586         MSG_MULTI_NOTIF(1, ITEM_WEAPON_UNAVAILABLE,              INFO_ITEM_WEAPON_UNAVAILABLE,              CENTER_ITEM_WEAPON_UNAVAILABLE) \
587         MSG_MULTI_NOTIF(1, WEAPON_ACCORDEON_MURDER,              INFO_WEAPON_ACCORDEON_MURDER,              NO_MSG) \
588         MSG_MULTI_NOTIF(1, WEAPON_ACCORDEON_SUICIDE,             INFO_WEAPON_ACCORDEON_SUICIDE,             CENTER_DEATH_SELF_GENERIC) \
589         MSG_MULTI_NOTIF(1, WEAPON_CRYLINK_MURDER,                INFO_WEAPON_CRYLINK_MURDER,                NO_MSG) \
590         MSG_MULTI_NOTIF(1, WEAPON_CRYLINK_SUICIDE,               INFO_WEAPON_CRYLINK_SUICIDE,               CENTER_DEATH_SELF_GENERIC) \
591         MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_BOLT,           INFO_WEAPON_ELECTRO_MURDER_BOLT,           NO_MSG) \
592         MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_COMBO,          INFO_WEAPON_ELECTRO_MURDER_COMBO,          NO_MSG) \
593         MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_ORBS,           INFO_WEAPON_ELECTRO_MURDER_ORBS,           NO_MSG) \
594         MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_SUICIDE_BOLT,          INFO_WEAPON_ELECTRO_SUICIDE_BOLT,          CENTER_DEATH_SELF_GENERIC) \
595         MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_SUICIDE_ORBS,          INFO_WEAPON_ELECTRO_SUICIDE_ORBS,          CENTER_DEATH_SELF_GENERIC) \
596         MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_MURDER_BLAST,         INFO_WEAPON_FIREBALL_MURDER_BLAST,         NO_MSG) \
597         MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_MURDER_FIREMINE,      INFO_WEAPON_FIREBALL_MURDER_FIREMINE,      NO_MSG) \
598         MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_SUICIDE_BLAST,        INFO_WEAPON_FIREBALL_SUICIDE_BLAST,        CENTER_DEATH_SELF_GENERIC) \
599         MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_SUICIDE_FIREMINE,     INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE,     CENTER_DEATH_SELF_GENERIC) \
600         MSG_MULTI_NOTIF(1, WEAPON_HAGAR_MURDER_BURST,            INFO_WEAPON_HAGAR_MURDER_BURST,            NO_MSG) \
601         MSG_MULTI_NOTIF(1, WEAPON_HAGAR_MURDER_SPRAY,            INFO_WEAPON_HAGAR_MURDER_SPRAY,            NO_MSG) \
602         MSG_MULTI_NOTIF(1, WEAPON_HAGAR_SUICIDE,                 INFO_WEAPON_HAGAR_SUICIDE,                 CENTER_DEATH_SELF_GENERIC) \
603         MSG_MULTI_NOTIF(1, WEAPON_HLAC_MURDER,                   INFO_WEAPON_HLAC_MURDER,                   NO_MSG) \
604         MSG_MULTI_NOTIF(1, WEAPON_HLAC_SUICIDE,                  INFO_WEAPON_HLAC_SUICIDE,                  CENTER_DEATH_SELF_GENERIC) \
605         MSG_MULTI_NOTIF(1, WEAPON_HOOK_MURDER,                   INFO_WEAPON_HOOK_MURDER,                   NO_MSG) \
606         MSG_MULTI_NOTIF(1, WEAPON_KLEINBOTTLE_MURDER,            INFO_WEAPON_KLEINBOTTLE_MURDER,            NO_MSG) \
607         MSG_MULTI_NOTIF(1, WEAPON_KLEINBOTTLE_SUICIDE,           INFO_WEAPON_KLEINBOTTLE_SUICIDE,           CENTER_DEATH_SELF_GENERIC) \
608         MSG_MULTI_NOTIF(1, WEAPON_LASER_MURDER,                  INFO_WEAPON_LASER_MURDER,                  NO_MSG) \
609         MSG_MULTI_NOTIF(1, WEAPON_LASER_SUICIDE,                 INFO_WEAPON_LASER_SUICIDE,                 CENTER_DEATH_SELF_GENERIC) \
610         MSG_MULTI_NOTIF(1, WEAPON_MINELAYER_MURDER,              INFO_WEAPON_MINELAYER_MURDER,              NO_MSG) \
611         MSG_MULTI_NOTIF(1, WEAPON_MINELAYER_SUICIDE,             INFO_WEAPON_MINELAYER_SUICIDE,             CENTER_DEATH_SELF_GENERIC) \
612         MSG_MULTI_NOTIF(1, WEAPON_MINSTANEX_MURDER,              INFO_WEAPON_MINSTANEX_MURDER,              NO_MSG) \
613         MSG_MULTI_NOTIF(1, WEAPON_MORTAR_MURDER_BOUNCE,          INFO_WEAPON_MORTAR_MURDER_BOUNCE,          NO_MSG) \
614         MSG_MULTI_NOTIF(1, WEAPON_MORTAR_MURDER_EXPLODE,         INFO_WEAPON_MORTAR_MURDER_EXPLODE,         NO_MSG) \
615         MSG_MULTI_NOTIF(1, WEAPON_MORTAR_SUICIDE_BOUNCE,         INFO_WEAPON_MORTAR_SUICIDE_BOUNCE,         CENTER_DEATH_SELF_GENERIC) \
616         MSG_MULTI_NOTIF(1, WEAPON_MORTAR_SUICIDE_EXPLODE,        INFO_WEAPON_MORTAR_SUICIDE_EXPLODE,        CENTER_DEATH_SELF_GENERIC) \
617         MSG_MULTI_NOTIF(1, WEAPON_NEX_MURDER,                    INFO_WEAPON_NEX_MURDER,                    NO_MSG) \
618         MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER,                  INFO_WEAPON_RIFLE_MURDER,                  NO_MSG) \
619         MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL,             INFO_WEAPON_RIFLE_MURDER_HAIL,             NO_MSG) \
620         MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL_PIERCING,    INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING,    NO_MSG) \
621         MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_HEADSHOT,         INFO_WEAPON_RIFLE_MURDER_HEADSHOT,         NO_MSG) \
622         MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_PIERCING,         INFO_WEAPON_RIFLE_MURDER_PIERCING,         NO_MSG) \
623         MSG_MULTI_NOTIF(1, WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,  INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,  NO_MSG) \
624         MSG_MULTI_NOTIF(1, WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,  INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,  NO_MSG) \
625         MSG_MULTI_NOTIF(1, WEAPON_ROCKETLAUNCHER_SUICIDE,        INFO_WEAPON_ROCKETLAUNCHER_SUICIDE,        CENTER_DEATH_SELF_GENERIC) \
626         MSG_MULTI_NOTIF(1, WEAPON_SEEKER_MURDER_SPRAY,           INFO_WEAPON_SEEKER_MURDER_SPRAY,           NO_MSG) \
627         MSG_MULTI_NOTIF(1, WEAPON_SEEKER_MURDER_TAG,             INFO_WEAPON_SEEKER_MURDER_TAG,             NO_MSG) \
628         MSG_MULTI_NOTIF(1, WEAPON_SEEKER_SUICIDE,                INFO_WEAPON_SEEKER_SUICIDE,                CENTER_DEATH_SELF_GENERIC) \
629         MSG_MULTI_NOTIF(1, WEAPON_SHOTGUN_MURDER,                INFO_WEAPON_SHOTGUN_MURDER,                NO_MSG) \
630         MSG_MULTI_NOTIF(1, WEAPON_SHOTGUN_MURDER_SLAP,           INFO_WEAPON_SHOTGUN_MURDER_SLAP,           NO_MSG) \
631         MSG_MULTI_NOTIF(1, WEAPON_THINKING_WITH_PORTALS,         INFO_WEAPON_THINKING_WITH_PORTALS,         CENTER_DEATH_SELF_GENERIC) \
632         MSG_MULTI_NOTIF(1, WEAPON_TUBA_MURDER,                   INFO_WEAPON_TUBA_MURDER,                   NO_MSG) \
633         MSG_MULTI_NOTIF(1, WEAPON_TUBA_SUICIDE,                  INFO_WEAPON_TUBA_SUICIDE,                  CENTER_DEATH_SELF_GENERIC) \
634         MSG_MULTI_NOTIF(1, WEAPON_UZI_MURDER_SNIPE,              INFO_WEAPON_UZI_MURDER_SNIPE,              NO_MSG) \
635         MSG_MULTI_NOTIF(1, WEAPON_UZI_MURDER_SPRAY,              INFO_WEAPON_UZI_MURDER_SPRAY,              NO_MSG)
636
637
638 // ===========================
639 //  Special CVAR Declarations
640 // ===========================
641
642 // MAKE SURE THIS IS ALWAYS SYNCHRONIZED WITH THE DUMP
643 // NOTIFICATIONS FUNCTION IN THE .QC FILE!
644
645 #define NOTIF_ADD_AUTOCVAR(name,default) var float autocvar_notification_##name = default;
646
647 var float autocvar_notification_show_location = FALSE;
648 var string autocvar_notification_show_location_string = ""; //_(" at the %s");
649 var float autocvar_notification_show_sprees = TRUE;
650 var float autocvar_notification_show_sprees_info = 3; // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker
651 var float autocvar_notification_show_sprees_info_newline = TRUE;
652 var float autocvar_notification_show_sprees_info_specialonly = TRUE;
653 var float autocvar_notification_errors_are_fatal = TRUE;
654 var float autocvar_notification_lifetime_runtime = 0.5;
655 var float autocvar_notification_lifetime_mapload = 10;
656
657 #ifdef SVQC
658 .float FRAG_VERBOSE;
659 void Notification_GetCvars(void);
660 var float autocvar_notification_server_allows_frag_verbose = 1; // 0 = no, 1 = warmup only, 2 = all the time
661 var float autocvar_notification_server_allows_location = 1; // 0 = no, 1 = yes
662 #else
663 var float autocvar_notification_item_centerprinttime = 1.5;
664
665 // 0 = no, 1 = yes, 2 = forced on for all MSG_INFO notifs
666 // DISABLED IN CODE, BUT ENABLED IN CONFIG FOR COMPATIBILITY WITH OLD CLIENTS
667 var float autocvar_notification_allow_chatboxprint = 0; 
668
669 var float autocvar_notification_show_sprees_center = TRUE;
670 var float autocvar_notification_show_sprees_center_specialonly = TRUE;
671 var float autocvar_notification_frag_verbose = TRUE;
672 #endif
673
674
675 // ============================
676 //  Notification Argument List
677 // ============================
678 /*
679  These arguments get replaced with the Local_Notification_sprintf
680  and other such functions found in notifications.qc to supply data
681  from networked notifications to their usage in sprintf... It
682  allows for more dynamic data to be inferred by the local
683  notification parser, so that the server does not have to network
684  anything too crazy on a per-client/per-situation basis.
685  
686  Pay attention to the CSQC/SVQC relations, some of these are redefined
687  in slightly different ways for different programs, this is because the
688  server does a more conservative approach to the notifs than the client.
689  
690  All arguments are swapped into strings, so be sure that your
691  sprintf usage matches with proper %s placement.
692  
693  Argument descriptions:
694     s1-s4: string arguments to be literally swapped into sprintf
695     s2loc: s2 string of locations of deaths or other events
696     s3loc: s3 string of locations of deaths or other events
697     f1-f4: float arguments expanded into strings to be swapped into sprintf
698     f1p2dec: f1 float to string with 2 decimal places
699     f2p2dec: f2 float to string with 2 decimal places
700     f2primsec: f2 float primary or secondary selection for weapons
701     f3primsec: f3 float primary or secondary selection for weapons
702     f1secs: count_seconds of f1
703     f1ord: count_ordinal of f1
704     f1time: process_time of f1
705     f1race_time: mmssss of f1
706     f2race_time: mmssss of f2
707     race_col: color of race time/position (i.e. good or bad)
708     race_diff: show time difference between f2 and f3
709     kh_teams: show which teams still need players in keyhunt centerprint
710     pass_key: find the keybind for "passing" or "dropping" in CTF game mode
711     frag_ping: show the ping of a player
712     frag_stats: show health/armor/ping of a player
713     frag_pos: show score status and position in the match of a player
714     spree_cen: centerprint notif for kill spree/how many kills they have
715     spree_inf: info notif for kill spree/how many kills they have
716     spree_end: placed at the end of murder messages to show ending of sprees
717     spree_lost: placed at the end of suicide messages to show losing of sprees
718     item_wepname: return full name of a weapon from weaponid
719     item_wepammo: ammo display for weapon from string
720     item_centime: amount of time to display weapon message in centerprint
721     death_team: show the full name of the team a player is switching from
722 */
723
724 #define NOTIF_MAX_ARGS 7
725 #define NOTIF_MAX_HUDARGS 2
726 #define NOTIF_MAX_DURCNT 2
727
728 string arg_slot[NOTIF_MAX_ARGS];
729
730 #define ARG_CS_SV_HA 1 // enabled on CSQC, SVQC, and Hudargs
731 #define ARG_CS_SV_DC 2 // enabled on CSQC, SVQC, and durcnt centerprint
732 #define ARG_CS_SV 3 // enabled on CSQC and SVQC
733 #define ARG_CS 4 // unique result to CSQC
734 #define ARG_SV 5 // unique result to SVQC
735 #define ARG_DC 6 // unique result to durcnt/centerprint
736
737 // todo possible idea.... declare how many floats/strings each arg needs, and then dynamically increment the input
738 // this way, we don't need to have duplicates like i.e. s2loc and s3loc?
739
740 #define NOTIF_ARGUMENT_LIST \
741     ARG_CASE(ARG_CS_SV_HA,  "s1",            s1) \
742     ARG_CASE(ARG_CS_SV_HA,  "s2",            s2) \
743     ARG_CASE(ARG_CS_SV_HA,  "s3",            s3) \
744     ARG_CASE(ARG_CS_SV_HA,  "s4",            s4) \
745     ARG_CASE(ARG_CS_SV,     "s2loc",         ((autocvar_notification_show_location && (s2 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s2) : "")) \
746     ARG_CASE(ARG_CS_SV,     "s3loc",         ((autocvar_notification_show_location && (s3 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s3) : "")) \
747     ARG_CASE(ARG_CS_SV_DC,  "f1",            ftos(f1)) \
748     ARG_CASE(ARG_CS_SV_DC,  "f2",            ftos(f2)) \
749     ARG_CASE(ARG_CS_SV,     "f3",            ftos(f3)) \
750     ARG_CASE(ARG_CS_SV,     "f4",            ftos(f4)) \
751     ARG_CASE(ARG_CS_SV,     "f1p2dec",       ftos_decimals(f1/100, 2)) \
752     ARG_CASE(ARG_CS_SV,     "f2p2dec",       ftos_decimals(f2/100, 2)) \
753     ARG_CASE(ARG_CS,        "f2primsec",     (f2 ? _("secondary") : _("primary"))) \
754     ARG_CASE(ARG_CS,        "f3primsec",     (f3 ? _("secondary") : _("primary"))) \
755     ARG_CASE(ARG_CS,        "f1secs",        count_seconds(f1)) \
756     ARG_CASE(ARG_CS_SV,     "f1ord",         count_ordinal(f1)) \
757     ARG_CASE(ARG_CS,        "f1time",        process_time(2, f1)) \
758     ARG_CASE(ARG_CS_SV,     "f1race_time",   mmssss(f1)) \
759     ARG_CASE(ARG_CS_SV,     "f2race_time",   mmssss(f2)) \
760     ARG_CASE(ARG_CS_SV,     "race_col",      CCR(((f1 == 1) ? "^F1" : "^F2"))) \
761     ARG_CASE(ARG_CS_SV,     "race_diff",     ((f2 > f3) ? sprintf(CCR("^1[+%s]"), mmssss(f2 - f3)) : sprintf(CCR("^2[-%s]"), mmssss(f3 - f2)))) \
762     ARG_CASE(ARG_CS,        "kh_teams",      notif_arg_kh_teams(f1, f2, f3, f4)) \
763     ARG_CASE(ARG_CS,        "pass_key",      ((((tmp_s = getcommandkey("pass", "+use")) != "pass") && !(strstrofs(tmp_s, "not bound", 0) >= 0)) ? sprintf(CCR(_(" ^F1(Press %s)")), tmp_s) : "")) \
764     ARG_CASE(ARG_CS,        "frag_ping",     notif_arg_frag_ping(TRUE, f2)) \
765     ARG_CASE(ARG_CS,        "frag_stats",    notif_arg_frag_stats(f2, f3, f4)) \
766     /*ARG_CASE(ARG_CS,      "frag_pos",      ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \
767     ARG_CASE(ARG_CS,        "spree_cen",     (autocvar_notification_show_sprees ? notif_arg_spree_cen(f1) : "")) \
768     ARG_CASE(ARG_CS_SV,     "spree_inf",     (autocvar_notification_show_sprees ? notif_arg_spree_inf(1, input, s2, f2) : "")) \
769     ARG_CASE(ARG_CS_SV,     "spree_end",     (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
770     ARG_CASE(ARG_CS_SV,     "spree_lost",    (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \
771     ARG_CASE(ARG_CS_SV,     "item_wepname",  W_Name(f1)) \
772     ARG_CASE(ARG_CS_SV,     "item_wepammo",  (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \
773     ARG_CASE(ARG_DC,        "item_centime",  ftos(autocvar_notification_item_centerprinttime)) \
774     ARG_CASE(ARG_SV,        "death_team",    Team_ColoredFullName(f1)) \
775     ARG_CASE(ARG_CS,        "death_team",    Team_ColoredFullName(f1 - 1))
776
777 #define NOTIF_HIT_MAX(count,funcname) if(sel_num == count) { backtrace(sprintf("%s: Hit maximum arguments!\n", funcname)); break; }
778 #define NOTIF_HIT_UNKNOWN(token,funcname) { backtrace(sprintf("%s: Hit unknown token in selected string! '%s'\n", funcname, selected)); break; }
779
780 #define KILL_SPREE_LIST \
781         SPREE_ITEM(3, 03, _("TRIPLE FRAG! "), _("%s^K1 made a TRIPLE FRAG! %s^BG"), _("%s^K1 made a TRIPLE SCORE! %s^BG")) \
782         SPREE_ITEM(5, 05, _("RAGE! "), _("%s^K1 unlocked RAGE! %s^BG"), _("%s^K1 made FIVE SCORES IN A ROW! %s^BG")) \
783         SPREE_ITEM(10, 10, _("MASSACRE! "), _("%s^K1 started a MASSACRE! %s^BG"), _("%s^K1 made TEN SCORES IN A ROW! %s^BG")) \
784         SPREE_ITEM(15, 15, _("MAYHEM! "), _("%s^K1 executed MAYHEM! %s^BG"), _("%s^K1 made FIFTEEN SCORES IN A ROW! %s^BG")) \
785         SPREE_ITEM(20, 20, _("BERSERKER! "), _("%s^K1 is a BERSERKER! %s^BG"), _("%s^K1 made TWENTY SCORES IN A ROW! %s^BG")) \
786         SPREE_ITEM(25, 25, _("CARNAGE! "), _("%s^K1 inflicts CARNAGE! %s^BG"), _("%s^K1 made TWENTY FIVE SCORES IN A ROW! %s^BG")) \
787         SPREE_ITEM(30, 30, _("ARMAGEDDON! "), _("%s^K1 unleashes ARMAGEDDON! %s^BG"), _("%s^K1 made THIRTY SCORES IN A ROW! %s^BG"))
788
789 #ifdef CSQC
790 string notif_arg_frag_ping(float newline, float fping)
791 {
792         if(fping == NO_MSG)
793                 return sprintf(CCR(_("%s(^F1Bot^BG)")), (newline ? "\n" : " "));
794         else
795                 return sprintf(CCR(_("%s(Ping ^F1%d^BG)")), (newline ? "\n" : " "), fping);
796 }
797
798 string notif_arg_frag_stats(float fhealth, float farmor, float fping)
799 {
800         if not(fhealth < 1)
801                 return sprintf(CCR(_("\n(Health ^1%d^BG / Armor ^2%d^BG)%s")), fhealth, farmor, notif_arg_frag_ping(FALSE, fping));
802         else
803                 return sprintf(CCR(_("\n(^F4Dead^BG)%s")), notif_arg_frag_ping(FALSE, fping));
804 }
805
806 string notif_arg_kh_teams(float f1, float f2, float f3, float f4)
807 {
808         return sprintf("%s%s%s%s",
809                 (f1 ?
810                         sprintf("%s%s", Team_ColoredFullName(f1 - 1), ((f2 + f3 + f4) ? ", " : ""))
811                         :
812                         ""
813                 ),
814                 (f2 ?
815                         sprintf("%s%s", Team_ColoredFullName(f2 - 1), ((f3 + f4) ? ", " : ""))
816                         :
817                         ""
818                 ),
819                 (f3 ?
820                         sprintf("%s%s", Team_ColoredFullName(f3 - 1), (f4 ? ", " : ""))
821                         :
822                         ""
823                 ),
824                 (f4 ?
825                         Team_ColoredFullName(f4 - 1)
826                         :
827                         ""
828                 )
829         );
830 }
831
832 string notif_arg_spree_cen(float spree)
833 {
834         // 0 = off, 1 = target (but only for first victim) and attacker
835         if(autocvar_notification_show_sprees_center) 
836         {
837                 if(spree > 1)
838                 {
839                         #define SPREE_ITEM(counta,countb,center,normal,gentle) \
840                                 case counta: { return normal_or_gentle(center, sprintf(_("%d score spree! "), spree)); }
841                         
842                         switch(spree)
843                         {
844                                 KILL_SPREE_LIST
845                                 default:
846                                 {
847                                         if not(autocvar_notification_show_sprees_center_specialonly)
848                                         {
849                                                 return
850                                                         sprintf(
851                                                                 normal_or_gentle(
852                                                                         _("%d frag spree! "),
853                                                                         _("%d score spree! ")
854                                                                 ),
855                                                                 spree);
856                                         }
857                                         else { return ""; } // don't show spree information if it isn't an achievement 
858                                 }
859                         }
860
861                         #undef SPREE_ITEM
862                 }
863                 else if(spree == -1) // first blood
864                 {
865                         return normal_or_gentle(_("First blood! "), _("First score! "));
866                 }
867                 else if(spree == -2) // first victim
868                 {
869                         return normal_or_gentle(_("First victim! "), _("First casualty! "));
870                 }
871         }
872         return "";
873 }
874 #endif
875
876 string notif_arg_spree_inf(float type, string input, string player, float spree)
877 {
878         switch(type)
879         {
880                 case 1: // attacker kill spree
881                 {
882                         // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker
883                         // this conditional (& 2) is true for 2 and 3
884                         if(autocvar_notification_show_sprees_info & 2) 
885                         {
886                                 #ifdef CSQC
887                                 string spree_newline =
888                                         ( autocvar_notification_show_sprees_info_newline ?
889                                                 ((substring(input, 0, 1) == "\{3}") ? "\n\{3}" : "\n") : "" );
890                                 #else
891                                 string spree_newline =
892                                         (autocvar_notification_show_sprees_info_newline ? "\n" : "");
893                                 #endif
894                                 
895                                 if(spree > 1)
896                                 {
897                                         #define SPREE_ITEM(counta,countb,center,normal,gentle) \
898                                                 case counta: { return sprintf(CCR(normal_or_gentle(normal, gentle)), player, spree_newline); }
899                                         
900                                         switch(spree)
901                                         {
902                                                 KILL_SPREE_LIST
903                                                 default:
904                                                 {
905                                                         if not(autocvar_notification_show_sprees_info_specialonly)
906                                                         {
907                                                                 return
908                                                                         sprintf(
909                                                                                 CCR(normal_or_gentle(
910                                                                                         _("%s^K1 has %d frags in a row! %s^BG"),
911                                                                                         _("%s^K1 made %d scores in a row! %s^BG")
912                                                                                 )),
913                                                                                 player,
914                                                                                 spree,
915                                                                                 spree_newline
916                                                                         );
917                                                         }
918                                                         else { return ""; } // don't show spree information if it isn't an achievement 
919                                                 }
920                                         }
921
922                                         #undef SPREE_ITEM
923                                 }
924                                 else if(spree == -1) // firstblood
925                                 {
926                                         return
927                                                 sprintf(
928                                                         CCR(normal_or_gentle(
929                                                                 _("%s^K1 drew first blood! %s^BG"),
930                                                                 _("%s^K1 got the first score! %s^BG")
931                                                         )),
932                                                         player,
933                                                         spree_newline
934                                                 );
935                                 }
936                         }
937                         break;
938                 }
939
940                 case -1: // kill spree ended
941                 {
942                         if((spree > 1) && (autocvar_notification_show_sprees_info & 1))
943                         {
944                                 return
945                                         sprintf(normal_or_gentle(
946                                                 _(", ending their %d frag spree"),
947                                                 _(", ending their %d score spree")
948                                                 ),
949                                                 spree
950                                         );
951                         }
952                         break;
953                 }
954
955                 case -2: // kill spree lost
956                 {
957                         if((spree > 1) && (autocvar_notification_show_sprees_info & 1))
958                         {
959                                 return
960                                         sprintf(normal_or_gentle(
961                                                 _(", losing their %d frag spree"),
962                                                 _(", losing their %d score spree")
963                                                 ),
964                                                 spree
965                                         );
966                         }
967                         break;
968                 }
969         }
970         return "";
971 }
972
973
974 // ====================================
975 //  Initialization/Create Declarations
976 // ====================================
977
978 #define NOTIF_FIRST 1
979 #define NOTIF_MAX 1024 // limit of recursive functions with ACCUMULATE_FUNCTION
980
981 // error detection
982 float notif_error;
983 float notif_global_error;
984
985 // notification entities
986 entity msg_info_notifs[NOTIF_MAX];
987 entity msg_center_notifs[NOTIF_MAX];
988 entity msg_multi_notifs[NOTIF_MAX];
989
990 // notification counts
991 float NOTIF_INFO_COUNT;
992 float NOTIF_CENTER_COUNT;
993 float NOTIF_MULTI_COUNT;
994 float NOTIF_CPID_COUNT;
995
996 // notification entity values
997 .float nent_default;
998 .string nent_name;
999 .float nent_id;
1000 .float nent_enabled;
1001 .entity nent_msginfo;
1002 .entity nent_msgcenter;
1003 .float nent_stringcount;
1004 .float nent_floatcount; 
1005 .string nent_args;
1006 .string nent_hudargs;
1007 .string nent_icon;
1008 .float nent_cpid;
1009 .string nent_durcnt;
1010 .string nent_string;
1011
1012 // networked notification values
1013 .float nent_broadcast;
1014 .entity nent_client;
1015 .float nent_net_type;
1016 .float nent_net_name;
1017 .string nent_strings[4];
1018 .float nent_floats[4];
1019
1020 #define MSG_INFO_NOTIF(default,name,strnum,flnum,args,hudargs,icon,normal,gentle) \
1021         NOTIF_ADD_AUTOCVAR(name, default) \
1022         float name; \
1023         void RegisterNotification_##name() \
1024         { \
1025                 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \
1026                 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_INFO_COUNT, "notifications") \
1027                 Create_Notification_Entity( \
1028                         default,                       /* var_default */ \
1029                         autocvar_notification_##name,  /* var_cvar */ \
1030                         MSG_INFO,                      /* typeid */ \
1031                         name,                          /* nameid */ \
1032                         strtoupper(#name),             /* namestring */ \
1033                         NO_MSG,                        /* infoname */ \
1034                         NO_MSG,                        /* centername */ \
1035                         strnum,                        /* strnum */ \
1036                         flnum,                         /* flnum */ \
1037                         args,                          /* args */ \
1038                         hudargs,                       /* hudargs */ \
1039                         icon,                          /* icon */ \
1040                         NO_MSG,                        /* cpid */ \
1041                         "",                            /* durcnt */ \
1042                         normal,                        /* normal */ \
1043                         gentle,                        /* gentle */ \
1044                         TRUE,                          /* msg_is_info */ \
1045                         FALSE);                        /* msg_is_multi */ \
1046         } \
1047         ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
1048
1049 #define MSG_CENTER_NOTIF(default,name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
1050         NOTIF_ADD_AUTOCVAR(name, default) \
1051         float name; \
1052         float cpid; \
1053         void RegisterNotification_##name() \
1054         { \
1055                 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CENTER_COUNT) \
1056                 SET_FIELD_COUNT(cpid, NOTIF_FIRST, NOTIF_CPID_COUNT) \
1057                 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_CENTER_COUNT, "notifications") \
1058                 Create_Notification_Entity( \
1059                         default,                       /* var_default */ \
1060                         autocvar_notification_##name,  /* var_cvar */ \
1061                         MSG_CENTER,                    /* typeid */ \
1062                         name,                          /* nameid */ \
1063                         strtoupper(#name),             /* namestring */ \
1064                         NO_MSG,                        /* infoname */ \
1065                         NO_MSG,                        /* centername */ \
1066                         strnum,                        /* strnum */ \
1067                         flnum,                         /* flnum */ \
1068                         args,                          /* args */ \
1069                         "",                            /* hudargs */ \
1070                         "",                            /* icon */ \
1071                         cpid,                          /* cpid */ \
1072                         durcnt,                        /* durcnt */ \
1073                         normal,                        /* normal */ \
1074                         gentle,                        /* gentle */ \
1075                         FALSE,                         /* msg_is_info */ \
1076                         FALSE);                        /* msg_is_multi */ \
1077         } \
1078         ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
1079
1080 #define MSG_MULTI_NOTIF(default,name,infoname,centername) \
1081         NOTIF_ADD_AUTOCVAR(name, default) \
1082         float name; \
1083         void RegisterNotification_##name() \
1084         { \
1085                 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_MULTI_COUNT) \
1086                 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_MULTI_COUNT, "notifications") \
1087                 Create_Notification_Entity( \
1088                         default,                       /* var_default */ \
1089                         autocvar_notification_##name,  /* var_cvar */ \
1090                         MSG_MULTI,                     /* typeid */ \
1091                         name,                          /* nameid */ \
1092                         strtoupper(#name),             /* namestring */ \
1093                         infoname,                      /* infoname */ \
1094                         centername,                    /* centername */ \
1095                         NO_MSG,                        /* strnum */ \
1096                         NO_MSG,                        /* flnum */ \
1097                         "",                            /* args */ \
1098                         "",                            /* hudargs */ \
1099                         "",                            /* icon */ \
1100                         NO_MSG,                        /* cpid */ \
1101                         "",                            /* durcnt */ \
1102                         "",                            /* normal */ \
1103                         "",                            /* gentle */ \
1104                         FALSE,                         /* msg_is_info */ \
1105                         TRUE);                         /* msg_is_multi */ \
1106         } \
1107         ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
1108
1109 void RegisterNotifications_First()
1110 {
1111         notif_global_error = FALSE;
1112
1113         #ifdef SVQC
1114         #define dedi (server_is_dedicated ? "a dedicated " : "")
1115         #else
1116         #define dedi ""
1117         #endif
1118         
1119         print(sprintf("Beginning notification initialization on %s%s program...\n", dedi, PROGNAME));
1120         
1121         // maybe do another implementation of this with checksums? for now, we don't need versioning
1122         /*if(autocvar_notification_version != NOTIF_VERSION)
1123         {
1124                 #ifdef CSQC
1125                 if(autocvar_notification_version_mismatch_client_error)
1126                 #else
1127                 if(autocvar_notification_version_mismatch_server_error)
1128                 #endif
1129                         notif_global_error = TRUE;
1130
1131                 print(sprintf("^1NOTIFICATION VERSION MISMATCH: ^7program = %s, config = %d, code = %d.\n",
1132                         PROGNAME, autocvar_notification_version, NOTIF_VERSION));
1133         }*/
1134 }
1135
1136 void RegisterNotifications_Done()
1137 {
1138         if(notif_global_error)
1139         {
1140                 // shit happened... stop the loading of the program now if this is unacceptable
1141                 if(autocvar_notification_errors_are_fatal)
1142                         error("Notification initialization failed! Read above and fix the errors!\n");
1143                 else
1144                         print("Notification initialization failed! Read above and fix the errors!\n");
1145         }
1146         else { print("Notification initialization successful!\n"); }
1147 }
1148
1149 // NOW we actually activate the declarations
1150 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotifications_First)
1151 MSG_INFO_NOTIFICATIONS
1152 MSG_CENTER_NOTIFICATIONS
1153 MSG_MULTI_NOTIFICATIONS
1154 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotifications_Done)
1155 #undef MSG_INFO_NOTIF
1156 #undef MSG_CENTER_NOTIF
1157 #undef MSG_MULTI_NOTIF
1158
1159 #undef NOTIF_ADD_AUTOCVAR