]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/notifications.qh
MOTD moved to notif system by mario
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / notifications.qh
1 // ================================================
2 //  Unified notification system, written by Samual
3 //  Last updated: February, 2013
4 // ================================================
5
6 // main types/groups of notifications
7 #define MSG_INFO 1 // "Global" information messages (sent to console, and notify panel if it has an icon)
8 #define MSG_CENTER 2 // "Personal" centerprint messages
9 #define MSG_CENTER_KILL 3 // Kill centerprint message
10 #define MSG_WEAPON 4 // "Global" weapon messages 
11 #define MSG_DEATH 5 // "Personal" AND "Global" death messages 
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 Dump_Notifications(float fh, float alsoprint);
42 void Local_Notification(float net_type, float net_name, ...count);
43 void Local_Notification_WOVA(float net_type, float net_name, float stringcount, float floatcount, string s1, string s2, string s3, string s4, float f1, float f2, float f3, float f4);
44
45 #ifdef CSQC // CLIENT ONLY
46 void Read_Notification(float is_new);
47 #endif
48
49 #ifdef SVQC // SERVER ONLY
50 #define NOTIF_ONE 1
51 #define NOTIF_ONE_ONLY 2
52 #define NOTIF_TEAM 3
53 #define NOTIF_TEAM_EXCEPT 4
54 #define NOTIF_ANY 5
55 #define NOTIF_ANY_EXCEPT 6
56
57 #define IFSTR(num) ((num < notif.nent_stringcount) ? ...(num, string) : "")
58 #define IFFL(num) ((((notif.nent_stringcount-1) + num) < count) ? ...(((notif.nent_stringcount-1) + num), float) : 0)
59
60 void Kill_Notification(float broadcast, entity client, float net_type, float net_name);
61 void Send_Notification(float broadcast, entity client, float net_type, float net_name, ...count);
62 void Send_Notification_WOVA(float broadcast, entity client, float net_type, float net_name, string s1, string s2, string s3, string s4, float f1, float f2, float f3, float f4);
63
64 // legacy stuff
65 void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num);
66 #define Send_CSQC_Centerprint_Generic_Expire(e,id) Send_CSQC_Centerprint_Generic(e, id, "", 1, 0)
67 float CPID_KH_MSG = 10;
68 #endif
69
70
71 // ====================================
72 //  Notifications List and Information
73 // ====================================
74 /*
75  List of all notifications (including identifiers and display information)
76  Possible Tokens: default, name, infoname, centername, strnum, flnum, args, hudargs, icon, cpid, durcnt, normal, gentle
77  Format Specifications:
78     MSG_INFO:
79       default: FLOAT: Default setting for whether the notification is enabled or not
80          ^-> 0 = disabled, 1 = enabled, 2 = also print to chat box
81       name: VAR: Name of notification
82       strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive)
83       flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive)
84       args: STRING: Arguments for Local_Notification_sprintf()
85       hudargs: STRING: Arguments for Local_Notification_HUD_Notify_Push()
86       icon: STRING: icon string name for the hud notify panel, "" if no icon is used
87       normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled)
88       gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled)
89     MSG_CENTER:
90       default: FLOAT: Default setting for whether the notification is enabled or not
91          ^-> 0 = disabled, 1 = enabled
92       name: VAR: Name of notification
93       strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive)
94       flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive)
95       args: STRING: Arguments for Local_Notification_sprintf()
96       cpid: FLOAT: centerprint ID number (CPID_*), NO_CPID if no CPID is needed
97       durcnt: XPD(FLOAT, FLOAT): Duration/Countdown: extra arguments for centerprint messages
98       normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled)
99       gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled)
100     MSG_WEAPON:
101     MSG_DEATH:
102       default: FLOAT: Default setting for whether the notification is enabled or not
103          ^-> 0 = disabled, 1 = enabled
104       name: VAR: Name of chaining notification
105       infoname: VAR: Name of info notification for reference
106       centername: VAR: Name of centerprint notification for reference
107
108  Messages with ^F1, ^BG, ^TC, etc etc in them will replace those strings
109  with colors according to the cvars the user has chosen. This allows for
110  users to create unique color profiles for their HUD, giving more customization
111  options to HUD designers and end users who want such a feature.
112
113  Check out the definitions in util.qc/util.qh/teams.qh for string CCR(...) and
114  string TCR(...) to better understand how these code replacements work.
115  
116  Additionally, you can find all the definitions and explanations for
117  the argument values and what they return down below in this file.
118
119  Guidlines for notification declaration (please try and follow these):
120   Specific rules:
121     -ALWAYS start the string with a color, preferably background.
122     -ALWAYS reset a color after a name (this way they don't set it for the whole string).
123     -NEVER re-declare an event twice.
124     -NEVER add or remove tokens from the format, it SHOULD already work.
125     -MSG_INFO messages must ALWAYS end with a new line: \n
126     -MSG_INFO hudargs must always be ATTACKER -> VICTIM
127     -MSG_CENTER should NOT end with a new line
128
129  General rules:
130     -Be clean and simple with your notification naming,
131      nothing too long for the name field... Abbreviations are your friend. :D
132     -Keep the spacing as clean as possible... if the arguments are abnormally long,
133       it's okay to go out of line a bit... but try and keep it clean still.
134     -Sort the notifications in the most appropriate order for their tasks.
135     -ARIRE unir frk jvgu lbhe bja zbgure. (gvc sbe zvxrrhfn) -- Don't pay attention to this ^_^
136
137  Final note: DO NOT PROVIDE MORE ARGUMENTS THAN NECESSARY FOR THE NOTIFICATION YOU'RE CALLING!
138       The system is designed to save as much networking bandwidth as possible,
139       so please dynamically control your argument sending to fit *exactly* what is required.
140       If you send a notification with mismatching arguments, Send_Notification() will error.
141 */
142
143 #define MULTITEAM_INFO(default,prefix,teams,strnum,flnum,args,hudargs,icon,normal,gentle) \
144         MSG_INFO_NOTIF(default, prefix##RED, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STR_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(STR_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(STR_TEAM_1))) \
145         MSG_INFO_NOTIF(default, prefix##BLUE, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STR_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(STR_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(STR_TEAM_2))) \
146         #if teams >= 3 \
147                 MSG_INFO_NOTIF(default, prefix##YELLOW, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STR_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(STR_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(STR_TEAM_3))) \
148         #endif \
149         #if teams >= 4 \
150                 MSG_INFO_NOTIF(default, prefix##PINK, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STR_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(STR_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(STR_TEAM_4))) \
151         #endif
152 #define MSG_INFO_NOTIFICATIONS \
153         /*MSG_INFO_NOTIF(1, INFO_EMPTY,                                                 0, 0, "", "",                                                   "",                                             "", "")*/ \
154         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DROPPED_, 2,              0, 0, "", "",                                                   "",                                             _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself\n"), "") \
155         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DAMAGED_, 2,              0, 0, "", "",                                                   "",                                             _("^BGThe ^TC^TT^BG flag was destroyed and returned to base\n"), "") \
156         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"), "") \
157         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"), "") \
158         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_ABORTRUN_, 2,             0, 0, "", "",                                                   "",                                             _("^BGThe ^TC^TT^BG flag was returned to base by its owner\n"), "") \
159         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_TIMEOUT_, 2,              0, 0, "", "",                                                   "",                                             _("^BGThe ^TC^TT^BG flag has returned to the base\n"), "") \
160         MULTITEAM_INFO(1, INFO_CTF_PICKUP_, 2,                                  1, 0, "s1", "s1",                                               "notify_%s_taken",              _("^BG%s^BG got the ^TC^TT^BG flag\n"), "") \
161         MULTITEAM_INFO(1, INFO_CTF_RETURN_, 2,                                  1, 0, "s1", "s1",                                               "notify_%s_returned",   _("^BG%s^BG returned the ^TC^TT^BG flag\n"), "") \
162         MULTITEAM_INFO(1, INFO_CTF_LOST_, 2,                                    1, 0, "s1", "s1",                                               "notify_%s_lost",               _("^BG%s^BG lost the ^TC^TT^BG flag\n"), "") \
163         MULTITEAM_INFO(1, INFO_CTF_CAPTURE_, 2,                                 1, 0, "s1", "s1",                                               "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag\n"), "") \
164         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"), "") \
165         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"), "") \
166         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"), "") \
167         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"), "") \
168         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"), "") \
169         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_GENERIC,                              2, 1, "s1 s2loc spree_lost", "s1",              "notify_selfkill",              _("^BG%s^K1 died%s%s\n"), "") \
170         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"), "") \
171         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"), "") \
172         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")) \
173         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"), "") \
174         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"), "") \
175         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"), "") \
176         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TEAMCHANGE,                   2, 1, "s1 s2loc death_team", "",                "",                                             _("^BG%s^K1 switched to the %s%s\n"), "") \
177         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_AUTOTEAMCHANGE,               2, 1, "s1 s2loc death_team", "",                "",                                             _("^BG%s^K1 was moved into the %s%s\n"), "") \
178         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")) \
179         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")) \
180         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")) \
181         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")) \
182         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"), "") \
183         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"), "") \
184         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"), "") \
185         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"), "") \
186         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"), "") \
187         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"), "") \
188         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"), "") \
189         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"), "") \
190         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"), "") \
191         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"), "") \
192         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"), "") \
193         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"), "") \
194         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"), "") \
195         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"), "") \
196         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"), "") \
197         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"), "") \
198         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"), "") \
199         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"), "") \
200         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"), "") \
201         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"), "") \
202         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"), "") \
203         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"), "") \
204         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"), "") \
205         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"), "") \
206         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"), "") \
207         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"), "") \
208         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")) \
209         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"), "") \
210         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"), "") \
211         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"), "") \
212         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"), "") \
213         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"), "") \
214         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"), "") \
215         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"), "") \
216         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"), "") \
217         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"), "") \
218         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")) \
219         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"), "") \
220         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"), "") \
221         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"), "") \
222         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"), "") \
223         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"), "") \
224         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"), "") \
225         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"), "") \
226         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"), "") \
227         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"), "") \
228         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"), "") \
229         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"), "") \
230         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"), "") \
231         MULTITEAM_INFO(1, INFO_FREEZETAG_ROUND_WIN_, 4,                 0, 0, "", "",                                                   "",                                             _("^TC^TT^BG team wins the round, all other teams were frozen\n"), "") \
232         MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVE,                                2, 0, "s1 s2", "",                                              "",                                             _("^BG%s^K3 was revived by ^BG%s\n"), "") \
233         MSG_INFO_NOTIF(1, INFO_FREEZETAG_FREEZE,                                2, 0, "s1 s2", "",                                              "",                                             _("^BG%s^K1 was frozen by ^BG%s\n"), "") \
234         MSG_INFO_NOTIF(1, INFO_FREEZETAG_SELF,                                  1, 0, "s1", "",                                                 "",                                             _("^BG%s^K1 froze themself\n"), "") \
235         MSG_INFO_NOTIF(1, INFO_GODMODE_OFF,                                             0, 1, "f1", "",                                                 "",                                             _("^BGGodmode saved you %s units of damage, cheater!\n"), "") \
236         MSG_INFO_NOTIF(2, INFO_JOIN_CONNECT,                                    1, 0, "s1", "",                                                 "",                                             _("^BG%s^F3 connected%s\n"), "") \
237         MULTITEAM_INFO(2, INFO_JOIN_CONNECT_TEAM_, 4,                   1, 0, "s1", "",                                                 "",                                             _("^BG%s^F3 connected and joined the ^TC^TT\n"), "") \
238         MSG_INFO_NOTIF(2, INFO_JOIN_PLAY,                                               1, 0, "s1", "",                                                 "",                                             _("^BG%s^F3 is now playing\n"), "") \
239         MSG_INFO_NOTIF(1, INFO_KEEPAWAY_DROPPED,                                1, 0, "s1", "s1",                                               "notify_balldropped",   _("^BG%s^BG has dropped the ball!\n"), "") \
240         MSG_INFO_NOTIF(1, INFO_KEEPAWAY_PICKUP,                                 1, 0, "s1", "s1",                                               "notify_ballpickedup",  _("^BG%s^BG has picked up the ball!\n"), "") \
241         MSG_INFO_NOTIF(1, INFO_LMS_NOLIVES,                                             1, 0, "s1", "",                                                 "",                                             _("^BG%s^F3 has no more lives left\n"), "") \
242         MSG_INFO_NOTIF(1, INFO_LMS_FORFEIT,                                             1, 0, "s1", "",                                                 "",                                             _("^BG%s^F3 forfeited\n"), "") \
243         MSG_INFO_NOTIF(1, INFO_POWERUP_INVISIBILITY,                    1, 0, "s1", "s1",                                               "strength",                             _("^BG%s^K1 picked up Invisibility\n"), "") \
244         MSG_INFO_NOTIF(1, INFO_POWERUP_SHIELD,                                  1, 0, "s1", "s1",                                               "shield",                               _("^BG%s^K1 picked up Shield\n"), "") \
245         MSG_INFO_NOTIF(1, INFO_POWERUP_SPEED,                                   1, 0, "s1", "s1",                                               "shield",                               _("^BG%s^K1 picked up Speed\n"), "") \
246         MSG_INFO_NOTIF(1, INFO_POWERUP_STRENGTH,                                1, 0, "s1", "s1",                                               "strength",                             _("^BG%s^K1 picked up Strength\n"), "") \
247         MSG_INFO_NOTIF(2, INFO_QUIT_DISCONNECT,                                 1, 0, "s1", "",                                                 "",                                             _("^BG%s^F3 disconnected\n"), "") \
248         MSG_INFO_NOTIF(2, INFO_QUIT_KICK_IDLING,                                1, 0, "s1", "",                                                 "",                                             _("^BG%s^F3 was kicked for idling\n"), "") \
249         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"), "") \
250         MSG_INFO_NOTIF(2, INFO_QUIT_SPECTATE,                                   1, 0, "s1", "",                                                 "",                                             _("^BG%s^F3 is now spectating\n"), "") \
251         MSG_INFO_NOTIF(1, INFO_RACE_FAIL_RANKED,                                1, 3, "s1 f1ord race_time race_diff", "s1",             "race_newfail", _("^BG%s^BG couldn't break their %s place record of %s %s\n"), "") \
252         MSG_INFO_NOTIF(1, INFO_RACE_FAIL_UNRANKED,                              1, 3, "s1 f1ord race_time race_diff", "s1",             "race_newfail", _("^BG%s^BG couldn't break the %s place record of %s %s\n"), "") \
253         MSG_INFO_NOTIF(1, INFO_RACE_NEW_RECORD,                                 2, 0, "s1 s2", "s1",                                    "race_newrecordserver", "TODO\n", "") \
254         MSG_INFO_NOTIF(1, INFO_RACE_NEW_TIME,                                   2, 0, "s1 s2", "s1",                                    "race_newtime",                 "TODO\n", "") \
255         MSG_INFO_NOTIF(1, INFO_RACE_NEW_RANK,                                   2, 0, "s1 s2", "s1",                                    "race_newrankyellow",   "TODO\n", "") \
256         MULTITEAM_INFO(1, INFO_SCORES_, 4,                                              0, 0, "", "",                                                   "",                                             _("^TC^TT ^BGteam scores!\n"), "") \
257         MSG_INFO_NOTIF(1, INFO_SPECTATE_WARNING,                                0, 1, "f1", "",                                                 "",                                             _("^F2You have to become a player within the next %s seconds, otherwise you will be kicked, because spectating isn't allowed at this time!\n"), "") \
258         MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP,                              0, 0, "s1", "s1",                                               "strength",                             _("^BG%s^K1 picked up a Superweapon\n"), "") \
259         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"), "") \
260         MSG_INFO_NOTIF(2, INFO_VERSION_OLD,                                             2, 0, "s1 s2", "",                                              "",                                             _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s\n"), "") \
261         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"), "") \
262         MSG_INFO_NOTIF(1, INFO_WATERMARK,                                               1, 0, "s1", "",                                                 "",                                             _("^F3SVQC Build information: ^F4%s\n"), "") \
263         MSG_INFO_NOTIF(0, INFO_WEAPON_GOTWEP,                                   0, 1, "item_wepname", "",                               "",                                     _("^BGYou got the ^F1%s\n"), "") \
264         MSG_INFO_NOTIF(0, INFO_WEAPON_DROPPED,                                  1, 1, "item_wepname item_wepammo", "",  "",                                     _("^BGYou dropped the ^F1%s^BG%s\n"), "") \
265         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"), "") \
266         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"), "") \
267         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"), "") \
268         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"), "") \
269         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"), "") \
270         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"), "") \
271         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"), "") \
272         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"), "") \
273         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"), "") \
274         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"), "") \
275         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"), "") \
276         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"), "") \
277         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"), "") \
278         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"), "") \
279         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"), "") \
280         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"), "") \
281         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"), "") \
282         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"), "") \
283         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"), "") \
284         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"), "") \
285         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"), "") \
286         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"), "") \
287         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"), "") \
288         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"), "") \
289         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"), "") \
290         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"), "") \
291         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"), "") \
292         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"), "") \
293         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"), "") \
294         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"), "") \
295         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"), "") \
296         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"), "") \
297         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"), "") \
298         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"), "") \
299         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"), "") \
300         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"), "") \
301         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"), "") \
302         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"), "") \
303         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"), "") \
304         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"), "") \
305         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"), "") \
306         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"), "") \
307         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"), "") \
308         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"), "") \
309         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"), "") \
310         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"), "") \
311         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"), "") \
312         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"), "") \
313         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"), "") 
314
315 #define MULTITEAM_CENTER(default,prefix,teams,strnum,flnum,args,cpid,durcnt,normal,gentle) \
316         MSG_CENTER_NOTIF(default, prefix##RED, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(STR_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(STR_TEAM_1))) \
317         MSG_CENTER_NOTIF(default, prefix##BLUE, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_2, strtoupper(STR_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(STR_TEAM_2))) \
318         #if teams >= 3 \
319                 MSG_CENTER_NOTIF(default, prefix##YELLOW, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_3, strtoupper(STR_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(STR_TEAM_3))) \
320         #endif \
321         #if teams >= 4 \
322                 MSG_CENTER_NOTIF(default, prefix##PINK, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_4, strtoupper(STR_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(STR_TEAM_4))) \
323         #endif
324 #define MSG_CENTER_NOTIFICATIONS \
325         /*MSG_CENTER_NOTIF(1, CENTER_EMPTY,                                                     0, 0, "",                               NO_CPID,                                "0 0", "null", "")*/ \
326         MSG_CENTER_NOTIF(1, CENTER_ASSAULT_ATTACKING,                           0, 0, "",                               CPID_ASSAULT_ROLE,              "0 0", _("^BGYou are attacking!"), "") \
327         MSG_CENTER_NOTIF(1, CENTER_ASSAULT_DEFENDING,                           0, 0, "",                               CPID_ASSAULT_ROLE,              "0 0", _("^BGYou are defending!"), "") \
328         MSG_CENTER_NOTIF(1, CENTER_ARENA_BEGIN,                                         0, 0, "",                               CPID_ARENA,                             "2 0", _("^F4Begin!"), "") \
329         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!"), "") \
330         MSG_CENTER_NOTIF(1, CENTER_ARENA_ROUNDSTART,                            0, 1, "",                               CPID_ARENA,                     "1 f1", _("^F4Round will start in ^COUNT"), "") \
331         MSG_CENTER_NOTIF(1, CENTER_COUNTDOWN_BEGIN,                                     0, 0, "",                               CPID_GAMESTART,                 "2 0", _("^F4Begin!"), "") \
332         MSG_CENTER_NOTIF(1, CENTER_COUNTDOWN_GAMESTART,                         0, 1, "",                               CPID_GAMESTART,                 "1 f1", _("^F4Game starts in ^COUNT"), "") \
333         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."), "") \
334         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."), "") \
335         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"), "") \
336         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"), "") \
337         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"), "") \
338         MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_REQUESTING,                         1, 0, "s1",                             CPID_CTF_PASS,                  "0 0", _("^BGRequesting %s^BG to pass you the flag"), "") \
339         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"), "") \
340         MULTITEAM_CENTER(1, CENTER_CTF_RETURN_, 2,                                      0, 0, "",                               CPID_CTF_LOWPRIO,               "0 0", _("^BGYou returned the ^TC^TT^BG flag!"), "") \
341         MULTITEAM_CENTER(1, CENTER_CTF_CAPTURE_, 2,                                     0, 0, "",                               CPID_CTF_LOWPRIO,               "0 0", _("^BGYou captured the ^TC^TT^BG flag!"), "") \
342         MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_, 2,                                      0, 0, "",                               CPID_CTF_LOWPRIO,               "0 0", _("^BGYou got the ^TC^TT^BG flag!"), "") \
343         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!"), "") \
344         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!"), "") \
345         MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY,                            1, 0, "s1",                             CPID_CTF_LOWPRIO,               "0 0", _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") \
346         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!"), "") \
347         MSG_CENTER_NOTIF(1, CENTER_CTF_STALEMATE_CARRIER,                       0, 0, "",                               CPID_STALEMATE,                 "0 0", _("^BGStalemate! Enemies can now see you on radar!"), "") \
348         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!"), "") \
349         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."), "") \
350         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CUSTOM,                           2, 0, "s2",                             NO_CPID,                                "0 0", _("^K1You were %s"), "") \
351         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!")) \
352         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VOID,                                     0, 0, "",                               NO_CPID,                                "0 0", _("^K1Watch your step!"), "") \
353         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SUICIDE,                          0, 0, "",                               NO_CPID,                                "0 0", _("^K1You committed suicide!"), _("^K1You ended it all!")) \
354         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...")) \
355         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")) \
356         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CAMP,                                     0, 0, "",                               NO_CPID,                                "0 0", _("^K1Die camper!"), _("^K1Reconsider your tactics, camper!")) \
357         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!")) \
358         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TEAMCHANGE,                       0, 1, "death_team",             NO_CPID,                                "0 0", _("^BGYou are now on: %s"), "") \
359         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"), "") \
360         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_FALL,                                     0, 0, "",                               NO_CPID,                                "0 0", _("^K1You hit the ground with a crunch!"), "") \
361         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_DROWN,                            0, 0, "",                               NO_CPID,                                "0 0", _("^K1You couldn't catch your breath!"), "") \
362         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!")) \
363         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_LAVA,                                     0, 0, "",                               NO_CPID,                                "0 0", _("^K1You couldn't stand the heat!"), "") \
364         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SLIME,                            0, 0, "",                               NO_CPID,                                "0 0", _("^K1You melted away in slime!"), "") \
365         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SHOOTING_STAR,            0, 0, "",                               NO_CPID,                                "0 0", _("^K1You became a shooting star!"), "") \
366         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SWAMP,                            0, 0, "",                               NO_CPID,                                "0 0", _("^K1You got stuck in a swamp!"), "") \
367         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CHEAT,                            0, 0, "",                               NO_CPID,                                "0 0", _("^K1You unfairly eliminated yourself!"), "") \
368         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TOUCHEXPLODE,                     0, 0, "",                               NO_CPID,                                "0 0", _("^K1You died in an accident!"), "") \
369         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!")) \
370         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!")) \
371         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!")) \
372         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_CRUSH,                         0, 0, "",                               NO_CPID,                                "0 0", _("^K1You were crushed by a vehicle!"), "") \
373         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!"), "") \
374         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!"), "") \
375         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!"), "") \
376         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!"), "") \
377         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_RAPT_BOMB,                     0, 0, "",                               NO_CPID,                                "0 0", _("^K1You were caught in a Raptor cluster bomb!"), "") \
378         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!"), "") \
379         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!"), "") \
380         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")) \
381         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")) \
382         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")) \
383         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!")) \
384         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")) \
385         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")) \
386         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")) \
387         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")) \
388         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!")) \
389         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")) \
390         MSG_CENTER_NOTIF(1, CENTER_DISCONNECT_IDLING,                           0, 1, "",                               CPID_IDLING,                    "1 f1", _("^K1Stop idling!\n^BGDisconnecting in ^COUNT..."), "") \
391         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"), "") \
392         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"), "") \
393         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE,                            1, 0, "s1",                             NO_CPID,                                "0 0", _("^K3You revived ^BG%s"), "") \
394         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVED,                           1, 0, "s1",                             NO_CPID,                                "0 0", _("^K3You were revived by ^BG%s"), "") \
395         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SELF,                                      0, 0, "",                               NO_CPID,                                "0 0", _("^K1You froze yourself"), "") \
396         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FREEZE,                            1, 0, "s1",                             NO_CPID,                                "0 0", _("^K3You froze ^BG%s"), "") \
397         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FROZEN,                            1, 0, "s1",                             NO_CPID,                                "0 0", _("^K1You were frozen by ^BG%s"), "") \
398         MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_DROPPED,                            1, 0, "s1",                     CPID_KEEPAWAY,                  "0 0", _("^BG%s^BG has dropped the ball!"), "") \
399         MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_PICKUP,                                     1, 0, "s1",                     CPID_KEEPAWAY,                  "0 0", _("^BG%s^BG has picked up the ball!"), "") \
400         MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_WARN,                                       0, 0, "",                               CPID_KA_WARN,                   "0 0", _("^BGKilling people while you don't have the ball gives no points!"), "") \
401         MSG_CENTER_NOTIF(1, CENTER_LMS_CAMPCHECK,                                       0, 0, "",                               CPID_LMS_CAMP,                  "0 0", _("^F2Don't camp!"), "") \
402         MSG_CENTER_NOTIF(1, CENTER_MOTD,                                                        1, 0, "s1",                             CPID_MOTD,                              "-1 0", _("^BG%s"), "") \
403         MSG_CENTER_NOTIF(1, CENTER_MINSTA_FINDAMMO,                                     0, 0, "",                               CPID_MINSTA_FINDAMMO,   "1 9", _("^F4^COUNT^BG left to find some ammo!"), "") \
404         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!"), _("Get some ammo! ^F4^COUNT^BG left!")) \
405         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"), "") \
406         MSG_CENTER_NOTIF(1, CENTER_NIX_NEWWEAPON,                                       0, 1, "item_wepname",   CPID_NIX,                               "0 0", _("^F2Active weapon: ^F1%s"), "") \
407         MSG_CENTER_NOTIF(1, CENTER_JOIN_NOSPAWNS,                                       0, 0, "",                               CPID_PREVENT_JOIN,              "0 0", _("^K1No spawnpoints available!\nHope your team can fix it..."), "") \
408         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."), "") \
409         MSG_CENTER_NOTIF(1, CENTER_OVERTIME_TIME,                                       0, 1, "f1time",                 CPID_OVERTIME,                  "0 0", _("^F2Now playing ^F4OVERTIME^F2!\nAdded ^F4%s ^F2minute(s) to the game!"), "") \
410         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!")) \
411         MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_INVISIBILITY,                      0, 0, "",                               CPID_POWERUP,                   "0 0", _("^F2Invisibility has worn off"), "") \
412         MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_SHIELD,                            0, 0, "",                               CPID_POWERUP,                   "0 0", _("^F2Shield has worn off"), "") \
413         MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_SPEED,                                     0, 0, "",                               CPID_POWERUP,                   "0 0", _("^F2Speed has worn off"), "") \
414         MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_STRENGTH,                          0, 0, "",                               CPID_POWERUP,                   "0 0", _("^F2Strength has worn off"), "") \
415         MSG_CENTER_NOTIF(1, CENTER_POWERUP_INVISIBILITY,                        0, 0, "",                               CPID_POWERUP,                   "0 0", _("^F2You are invisible"), "") \
416         MSG_CENTER_NOTIF(1, CENTER_POWERUP_SHIELD,                                      0, 0, "",                               CPID_POWERUP,                   "0 0", _("^F2Shield surrounds you"), "") \
417         MSG_CENTER_NOTIF(1, CENTER_POWERUP_SPEED,                                       0, 0, "",                               CPID_POWERUP,                   "0 0", _("^F2You are on speed"), "") \
418         MSG_CENTER_NOTIF(1, CENTER_POWERUP_STRENGTH,                            0, 0, "",                               CPID_POWERUP,                   "0 0", _("^F2Strength infuses your weapons with devastating power"), "") \
419         MSG_CENTER_NOTIF(1, CENTER_RACE_FINISHLAP,                                      0, 0, "",                               CPID_RACE_FINISHLAP,    "0 0", _("^F2The race is over, finish your lap!"), "") \
420         MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_BROKEN,                          0, 0, "",                               CPID_POWERUP,                   "0 0", _("^F2Superweapons have broken down"), "") \
421         MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_PICKUP,                          0, 0, "",                               CPID_POWERUP,                   "0 0", _("^F2You now have a superweapon"), "") \
422         MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_LOST,                            0, 0, "",                               CPID_POWERUP,                   "0 0", _("^F2Superweapons have been lost"), "") \
423         MULTITEAM_CENTER(1, CENTER_TEAMCHANGE_, 4,                                      0, 1, "",                               CPID_TEAMCHANGE,                "1 f1", _("^BGChanging to ^TC^TT^BG in ^COUNT"), "") \
424         MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SPECTATE,                         0, 1, "",                               CPID_TEAMCHANGE,                "1 f1", _("^BGSpectating in ^COUNT"), "") \
425         MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_AUTO,                                     0, 1, "",                               CPID_TEAMCHANGE,                "1 f1", _("^BGChanging team in ^COUNT"), "") \
426         MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SUICIDE,                          0, 1, "",                               CPID_TEAMCHANGE,                "1 f1", _("^K1Suicide in ^COUNT"), "") \
427         MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_BEGINNING,                           0, 1, "",                               CPID_TIMEOUT,                   "1 f1", _("^F4Timeout begins in ^COUNT"), "") \
428         MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_ENDING,                                      0, 1, "",                               CPID_TIMEOUT,                   "1 f1", _("^F4Timeout ends in ^COUNT"), "") \
429         MSG_CENTER_NOTIF(1, CENTER_WEAPON_GOTWEP,                                       0, 1, "item_wepname",                           CPID_ITEM,      "item_centime 0", _("^BGYou got the ^F1%s"), "") \
430         MSG_CENTER_NOTIF(1, CENTER_WEAPON_DROPPED,                                      1, 1, "item_wepname item_wepammo",      CPID_ITEM,      "item_centime 0", _("^BGYou dropped the ^F1%s^BG%s"), "")
431
432 #define MSG_WEAPON_NOTIFICATIONS \
433         /*MSG_WEAPON_NOTIF(1, WEAPON_EMPTY,                                                     NO_MSG,                                                                         NO_MSG)*/ \
434         MSG_WEAPON_NOTIF(1, WEAPON_GOTWEP,                                                      INFO_WEAPON_GOTWEP,                                                     CENTER_WEAPON_GOTWEP) \
435         MSG_WEAPON_NOTIF(1, WEAPON_DROPPED,                                                     INFO_WEAPON_DROPPED,                                            CENTER_WEAPON_DROPPED) \
436         MSG_WEAPON_NOTIF(1, WEAPON_THINKING_WITH_PORTALS,                       INFO_WEAPON_THINKING_WITH_PORTALS,                      CENTER_DEATH_SELF_GENERIC) \
437         MSG_WEAPON_NOTIF(1, WEAPON_CRYLINK_SUICIDE,                             INFO_WEAPON_CRYLINK_SUICIDE,                            CENTER_DEATH_SELF_GENERIC) \
438         MSG_WEAPON_NOTIF(1, WEAPON_CRYLINK_MURDER,                                      INFO_WEAPON_CRYLINK_MURDER,                             NO_MSG) \
439         MSG_WEAPON_NOTIF(1, WEAPON_ELECTRO_SUICIDE_ORBS,                        INFO_WEAPON_ELECTRO_SUICIDE_ORBS,                       CENTER_DEATH_SELF_GENERIC) \
440         MSG_WEAPON_NOTIF(1, WEAPON_ELECTRO_SUICIDE_BOLT,                        INFO_WEAPON_ELECTRO_SUICIDE_BOLT,                       CENTER_DEATH_SELF_GENERIC) \
441         MSG_WEAPON_NOTIF(1, WEAPON_ELECTRO_MURDER_BOLT,                         INFO_WEAPON_ELECTRO_MURDER_BOLT,                        NO_MSG) \
442         MSG_WEAPON_NOTIF(1, WEAPON_ELECTRO_MURDER_ORBS,                         INFO_WEAPON_ELECTRO_MURDER_ORBS,                        NO_MSG) \
443         MSG_WEAPON_NOTIF(1, WEAPON_ELECTRO_MURDER_COMBO,                        INFO_WEAPON_ELECTRO_MURDER_COMBO,                       NO_MSG) \
444         MSG_WEAPON_NOTIF(1, WEAPON_FIREBALL_SUICIDE_FIREMINE,           INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE,          CENTER_DEATH_SELF_GENERIC) \
445         MSG_WEAPON_NOTIF(1, WEAPON_FIREBALL_SUICIDE_BLAST,                      INFO_WEAPON_FIREBALL_SUICIDE_BLAST,             CENTER_DEATH_SELF_GENERIC) \
446         MSG_WEAPON_NOTIF(1, WEAPON_FIREBALL_MURDER_FIREMINE,            INFO_WEAPON_FIREBALL_MURDER_FIREMINE,           NO_MSG) \
447         MSG_WEAPON_NOTIF(1, WEAPON_FIREBALL_MURDER_BLAST,                       INFO_WEAPON_FIREBALL_MURDER_BLAST,                      NO_MSG) \
448         MSG_WEAPON_NOTIF(1, WEAPON_MORTAR_SUICIDE_EXPLODE,                      INFO_WEAPON_MORTAR_SUICIDE_EXPLODE,             CENTER_DEATH_SELF_GENERIC) \
449         MSG_WEAPON_NOTIF(1, WEAPON_MORTAR_SUICIDE_BOUNCE,                       INFO_WEAPON_MORTAR_SUICIDE_BOUNCE,                      CENTER_DEATH_SELF_GENERIC) \
450         MSG_WEAPON_NOTIF(1, WEAPON_MORTAR_MURDER_EXPLODE,                       INFO_WEAPON_MORTAR_MURDER_EXPLODE,                      NO_MSG) \
451         MSG_WEAPON_NOTIF(1, WEAPON_MORTAR_MURDER_BOUNCE,                        INFO_WEAPON_MORTAR_MURDER_BOUNCE,                       NO_MSG) \
452         MSG_WEAPON_NOTIF(1, WEAPON_HAGAR_SUICIDE,                                       INFO_WEAPON_HAGAR_SUICIDE,                                      CENTER_DEATH_SELF_GENERIC) \
453         MSG_WEAPON_NOTIF(1, WEAPON_HAGAR_MURDER_BURST,                          INFO_WEAPON_HAGAR_MURDER_BURST,                         NO_MSG) \
454         MSG_WEAPON_NOTIF(1, WEAPON_HAGAR_MURDER_SPRAY,                          INFO_WEAPON_HAGAR_MURDER_SPRAY,                         NO_MSG) \
455         MSG_WEAPON_NOTIF(1, WEAPON_HLAC_SUICIDE,                                        INFO_WEAPON_HLAC_SUICIDE,                                       CENTER_DEATH_SELF_GENERIC) \
456         MSG_WEAPON_NOTIF(1, WEAPON_HLAC_MURDER,                                         INFO_WEAPON_HLAC_MURDER,                                        NO_MSG) \
457         MSG_WEAPON_NOTIF(1, WEAPON_HOOK_MURDER,                                         INFO_WEAPON_HOOK_MURDER,                                        NO_MSG) \
458         MSG_WEAPON_NOTIF(1, WEAPON_LASER_SUICIDE,                                       INFO_WEAPON_LASER_SUICIDE,                                      CENTER_DEATH_SELF_GENERIC) \
459         MSG_WEAPON_NOTIF(1, WEAPON_LASER_MURDER,                                        INFO_WEAPON_LASER_MURDER,                                       NO_MSG) \
460         MSG_WEAPON_NOTIF(1, WEAPON_MINELAYER_SUICIDE,                           INFO_WEAPON_MINELAYER_SUICIDE,                          CENTER_DEATH_SELF_GENERIC) \
461         MSG_WEAPON_NOTIF(1, WEAPON_MINELAYER_MURDER,                            INFO_WEAPON_MINELAYER_MURDER,                           NO_MSG) \
462         MSG_WEAPON_NOTIF(1, WEAPON_MINSTANEX_MURDER,                            INFO_WEAPON_MINSTANEX_MURDER,                           NO_MSG) \
463         MSG_WEAPON_NOTIF(1, WEAPON_NEX_MURDER,                                          INFO_WEAPON_NEX_MURDER,                                         NO_MSG) \
464         MSG_WEAPON_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL_PIERCING,          INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING,         NO_MSG) \
465         MSG_WEAPON_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL,                           INFO_WEAPON_RIFLE_MURDER_HAIL,                          NO_MSG) \
466         MSG_WEAPON_NOTIF(1, WEAPON_RIFLE_MURDER_PIERCING,                       INFO_WEAPON_RIFLE_MURDER_PIERCING,                      NO_MSG) \
467         MSG_WEAPON_NOTIF(1, WEAPON_RIFLE_MURDER,                                        INFO_WEAPON_RIFLE_MURDER,                                       NO_MSG) \
468         MSG_WEAPON_NOTIF(1, WEAPON_RIFLE_MURDER_HEADSHOT,                       INFO_WEAPON_RIFLE_MURDER_HEADSHOT,                      NO_MSG) \
469         MSG_WEAPON_NOTIF(1, WEAPON_ROCKETLAUNCHER_SUICIDE,                      INFO_WEAPON_ROCKETLAUNCHER_SUICIDE,             CENTER_DEATH_SELF_GENERIC) \
470         MSG_WEAPON_NOTIF(1, WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,        INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,       NO_MSG) \
471         MSG_WEAPON_NOTIF(1, WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,        INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,       NO_MSG) \
472         MSG_WEAPON_NOTIF(1, WEAPON_SEEKER_SUICIDE,                                      INFO_WEAPON_SEEKER_SUICIDE,                             CENTER_DEATH_SELF_GENERIC) \
473         MSG_WEAPON_NOTIF(1, WEAPON_SEEKER_MURDER_TAG,                           INFO_WEAPON_SEEKER_MURDER_TAG,                          NO_MSG) \
474         MSG_WEAPON_NOTIF(1, WEAPON_SEEKER_MURDER_SPRAY,                         INFO_WEAPON_SEEKER_MURDER_SPRAY,                        NO_MSG) \
475         MSG_WEAPON_NOTIF(1, WEAPON_SHOTGUN_MURDER_SLAP,                         INFO_WEAPON_SHOTGUN_MURDER_SLAP,                        NO_MSG) \
476         MSG_WEAPON_NOTIF(1, WEAPON_SHOTGUN_MURDER,                                      INFO_WEAPON_SHOTGUN_MURDER,                             NO_MSG) \
477         MSG_WEAPON_NOTIF(1, WEAPON_TUBA_SUICIDE,                                        INFO_WEAPON_TUBA_SUICIDE,                                       CENTER_DEATH_SELF_GENERIC) \
478         MSG_WEAPON_NOTIF(1, WEAPON_TUBA_MURDER,                                         INFO_WEAPON_TUBA_MURDER,                                        NO_MSG) \
479         MSG_WEAPON_NOTIF(1, WEAPON_ACCORDEON_SUICIDE,                           INFO_WEAPON_ACCORDEON_SUICIDE,                          CENTER_DEATH_SELF_GENERIC) \
480         MSG_WEAPON_NOTIF(1, WEAPON_ACCORDEON_MURDER,                            INFO_WEAPON_ACCORDEON_MURDER,                           NO_MSG) \
481         MSG_WEAPON_NOTIF(1, WEAPON_KLEINBOTTLE_SUICIDE,                         INFO_WEAPON_KLEINBOTTLE_SUICIDE,                        CENTER_DEATH_SELF_GENERIC) \
482         MSG_WEAPON_NOTIF(1, WEAPON_KLEINBOTTLE_MURDER,                          INFO_WEAPON_KLEINBOTTLE_MURDER,                         NO_MSG) \
483         MSG_WEAPON_NOTIF(1, WEAPON_UZI_MURDER_SNIPE,                            INFO_WEAPON_UZI_MURDER_SNIPE,                           NO_MSG) \
484         MSG_WEAPON_NOTIF(1, WEAPON_UZI_MURDER_SPRAY,                            INFO_WEAPON_UZI_MURDER_SPRAY,                           NO_MSG) 
485
486 #define MSG_DEATH_NOTIFICATIONS \
487         /*MSG_DEATH_NOTIF(1, DEATH_EMPTY,                                               NO_MSG,                                                                 NO_MSG)*/ \
488         MSG_DEATH_NOTIF(1, DEATH_SELF_CUSTOM,                                   INFO_DEATH_SELF_GENERIC,                                CENTER_DEATH_SELF_CUSTOM) \
489         MSG_DEATH_NOTIF(1, DEATH_SELF_GENERIC,                                  INFO_DEATH_SELF_GENERIC,                                CENTER_DEATH_SELF_GENERIC) \
490         MSG_DEATH_NOTIF(1, DEATH_SELF_VOID,                                             INFO_DEATH_SELF_VOID,                                   CENTER_DEATH_SELF_VOID) \
491         MSG_DEATH_NOTIF(1, DEATH_SELF_SUICIDE,                                  INFO_DEATH_SELF_SUICIDE,                                CENTER_DEATH_SELF_SUICIDE) \
492         MSG_DEATH_NOTIF(1, DEATH_SELF_NOAMMO,                                   INFO_DEATH_SELF_NOAMMO,                                 CENTER_DEATH_SELF_NOAMMO) \
493         MSG_DEATH_NOTIF(1, DEATH_SELF_ROT,                                              INFO_DEATH_SELF_ROT,                                    CENTER_DEATH_SELF_ROT) \
494         MSG_DEATH_NOTIF(1, DEATH_SELF_CAMP,                                             INFO_DEATH_SELF_CAMP,                                   CENTER_DEATH_SELF_CAMP) \
495         MSG_DEATH_NOTIF(1, DEATH_SELF_BETRAYAL,                                 INFO_DEATH_SELF_BETRAYAL,                               CENTER_DEATH_SELF_BETRAYAL) \
496         MSG_DEATH_NOTIF(1, DEATH_SELF_TEAMCHANGE,                               INFO_DEATH_SELF_TEAMCHANGE,                             CENTER_DEATH_SELF_TEAMCHANGE) \
497         MSG_DEATH_NOTIF(1, DEATH_SELF_AUTOTEAMCHANGE,                   INFO_DEATH_SELF_AUTOTEAMCHANGE,                 CENTER_DEATH_SELF_AUTOTEAMCHANGE) \
498         MSG_DEATH_NOTIF(1, DEATH_SELF_FALL,                                             INFO_DEATH_SELF_FALL,                                   CENTER_DEATH_SELF_FALL) \
499         MSG_DEATH_NOTIF(1, DEATH_SELF_DROWN,                                    INFO_DEATH_SELF_DROWN,                                  CENTER_DEATH_SELF_DROWN) \
500         MSG_DEATH_NOTIF(1, DEATH_SELF_FIRE,                                             INFO_DEATH_SELF_FIRE,                                   CENTER_DEATH_SELF_FIRE) \
501         MSG_DEATH_NOTIF(1, DEATH_SELF_LAVA,                                             INFO_DEATH_SELF_LAVA,                                   CENTER_DEATH_SELF_LAVA) \
502         MSG_DEATH_NOTIF(1, DEATH_SELF_SLIME,                                    INFO_DEATH_SELF_SLIME,                                  CENTER_DEATH_SELF_SLIME) \
503         MSG_DEATH_NOTIF(1, DEATH_SELF_SHOOTING_STAR,                    INFO_DEATH_SELF_SHOOTING_STAR,                  CENTER_DEATH_SELF_SHOOTING_STAR) \
504         MSG_DEATH_NOTIF(1, DEATH_SELF_SWAMP,                                    INFO_DEATH_SELF_SWAMP,                                  CENTER_DEATH_SELF_SWAMP) \
505         MSG_DEATH_NOTIF(1, DEATH_SELF_CHEAT,                                    INFO_DEATH_SELF_CHEAT,                                  CENTER_DEATH_SELF_CHEAT) \
506         MSG_DEATH_NOTIF(1, DEATH_SELF_TOUCHEXPLODE,                             INFO_DEATH_SELF_TOUCHEXPLODE,                   CENTER_DEATH_SELF_TOUCHEXPLODE) \
507         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET,                                   INFO_DEATH_SELF_TURRET,                                 CENTER_DEATH_SELF_TURRET) \
508         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_EWHEEL,                    INFO_DEATH_SELF_TURRET_EWHEEL,                  CENTER_DEATH_SELF_TURRET_EWHEEL) \
509         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_FLAC,                              INFO_DEATH_SELF_TURRET_FLAC,                    CENTER_DEATH_SELF_TURRET) \
510         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_MACHINEGUN,                INFO_DEATH_SELF_TURRET_MACHINEGUN,              CENTER_DEATH_SELF_TURRET) \
511         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_WALK_GUN,                  INFO_DEATH_SELF_TURRET_WALK_GUN,                CENTER_DEATH_SELF_TURRET_WALK) \
512         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_WALK_MEELE,                INFO_DEATH_SELF_TURRET_WALK_MEELE,              CENTER_DEATH_SELF_TURRET_WALK) \
513         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_WALK_ROCKET,               INFO_DEATH_SELF_TURRET_WALK_ROCKET,             CENTER_DEATH_SELF_TURRET_WALK) \
514         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_HELLION,                   INFO_DEATH_SELF_TURRET_HELLION,                 CENTER_DEATH_SELF_TURRET) \
515         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_HK,                                INFO_DEATH_SELF_TURRET_HK,                              CENTER_DEATH_SELF_TURRET) \
516         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_MLRS,                              INFO_DEATH_SELF_TURRET_MLRS,                    CENTER_DEATH_SELF_TURRET) \
517         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_PLASMA,                    INFO_DEATH_SELF_TURRET_PLASMA,                  CENTER_DEATH_SELF_TURRET) \
518         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_PHASER,                    INFO_DEATH_SELF_TURRET_PHASER,                  CENTER_DEATH_SELF_TURRET) \
519         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_TESLA,                             INFO_DEATH_SELF_TURRET_TESLA,                   CENTER_DEATH_SELF_TURRET) \
520         MSG_DEATH_NOTIF(1, DEATH_SELF_VH_CRUSH,                                 INFO_DEATH_SELF_VH_CRUSH,                               CENTER_DEATH_SELF_VH_CRUSH) \
521         MSG_DEATH_NOTIF(1, DEATH_SELF_VH_SPID_ROCKET,                   INFO_DEATH_SELF_VH_SPID_ROCKET,                 CENTER_DEATH_SELF_VH_SPID_ROCKET) \
522         MSG_DEATH_NOTIF(1, DEATH_SELF_VH_SPID_DEATH,                    INFO_DEATH_SELF_VH_SPID_DEATH,                  CENTER_DEATH_SELF_VH_SPID_DEATH) \
523         MSG_DEATH_NOTIF(1, DEATH_SELF_VH_WAKI_ROCKET,                   INFO_DEATH_SELF_VH_WAKI_ROCKET,                 CENTER_DEATH_SELF_VH_WAKI_ROCKET) \
524         MSG_DEATH_NOTIF(1, DEATH_SELF_VH_WAKI_DEATH,                    INFO_DEATH_SELF_VH_WAKI_DEATH,                  CENTER_DEATH_SELF_VH_WAKI_DEATH) \
525         MSG_DEATH_NOTIF(1, DEATH_SELF_VH_RAPT_BOMB,                             INFO_DEATH_SELF_VH_RAPT_BOMB,                   CENTER_DEATH_SELF_VH_RAPT_BOMB) \
526         MSG_DEATH_NOTIF(1, DEATH_SELF_VH_RAPT_DEATH,                    INFO_DEATH_SELF_VH_RAPT_DEATH,                  CENTER_DEATH_SELF_VH_RAPT_DEATH) \
527         MSG_DEATH_NOTIF(1, DEATH_SELF_VH_BUMB_DEATH,                    INFO_DEATH_SELF_VH_BUMB_DEATH,                  CENTER_DEATH_SELF_VH_BUMB_DEATH) \
528         MSG_DEATH_NOTIF(1, DEATH_MURDER_TELEFRAG,                               INFO_DEATH_MURDER_TELEFRAG,                             NO_MSG) \
529         MSG_DEATH_NOTIF(1, DEATH_MURDER_FALL,                                   INFO_DEATH_MURDER_FALL,                                 NO_MSG) \
530         MSG_DEATH_NOTIF(1, DEATH_MURDER_DROWN,                                  INFO_DEATH_MURDER_DROWN,                                NO_MSG) \
531         MSG_DEATH_NOTIF(1, DEATH_MURDER_LAVA,                                   INFO_DEATH_MURDER_LAVA,                                 NO_MSG) \
532         MSG_DEATH_NOTIF(1, DEATH_MURDER_SLIME,                                  INFO_DEATH_MURDER_SLIME,                                NO_MSG) \
533         MSG_DEATH_NOTIF(1, DEATH_MURDER_SHOOTING_STAR,                  INFO_DEATH_MURDER_SHOOTING_STAR,                NO_MSG) \
534         MSG_DEATH_NOTIF(1, DEATH_MURDER_SWAMP,                                  INFO_DEATH_MURDER_SWAMP,                                NO_MSG) \
535         MSG_DEATH_NOTIF(1, DEATH_MURDER_VOID,                                   INFO_DEATH_MURDER_VOID,                                 NO_MSG) \
536         MSG_DEATH_NOTIF(1, DEATH_MURDER_TOUCHEXPLODE,                   INFO_DEATH_MURDER_TOUCHEXPLODE,                 NO_MSG) \
537         MSG_DEATH_NOTIF(1, DEATH_MURDER_CHEAT,                                  INFO_DEATH_MURDER_CHEAT,                                NO_MSG) \
538         MSG_DEATH_NOTIF(1, DEATH_MURDER_FIRE,                                   INFO_DEATH_MURDER_FIRE,                                 NO_MSG) \
539         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_CRUSH,                               INFO_DEATH_MURDER_VH_CRUSH,                             NO_MSG) \
540         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_SPID_MINIGUN,                INFO_DEATH_MURDER_VH_SPID_MINIGUN,              NO_MSG) \
541         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_SPID_ROCKET,                 INFO_DEATH_MURDER_VH_SPID_ROCKET,               NO_MSG) \
542         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_SPID_DEATH,                  INFO_DEATH_MURDER_VH_SPID_DEATH,                NO_MSG) \
543         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_WAKI_GUN,                    INFO_DEATH_MURDER_VH_WAKI_GUN,                  NO_MSG) \
544         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_WAKI_ROCKET,                 INFO_DEATH_MURDER_VH_WAKI_ROCKET,               NO_MSG) \
545         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_WAKI_DEATH,                  INFO_DEATH_MURDER_VH_WAKI_DEATH,                NO_MSG) \
546         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_RAPT_CANNON,                 INFO_DEATH_MURDER_VH_RAPT_CANNON,               NO_MSG) \
547         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_RAPT_BOMB,                   INFO_DEATH_MURDER_VH_RAPT_BOMB,                 NO_MSG) \
548         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_RAPT_DEATH,                  INFO_DEATH_MURDER_VH_RAPT_DEATH,                NO_MSG) \
549         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_BUMB_GUN,                    INFO_DEATH_MURDER_VH_BUMB_GUN,                  NO_MSG) \
550         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_BUMB_DEATH,                  INFO_DEATH_MURDER_VH_BUMB_DEATH,                NO_MSG) 
551
552
553 // ===========================
554 //  Special CVAR Declarations
555 // ===========================
556
557 // MAKE SURE THIS IS ALWAYS SYNCHRONIZED WITH THE DUMP
558 // NOTIFICATIONS FUNCTION IN THE .QC FILE!
559
560 #define NOTIF_ADD_AUTOCVAR(name,default) var float autocvar_notification_##name = default;
561
562 var float autocvar_notification_show_location = FALSE;
563 var string autocvar_notification_show_location_string = ""; //_(" at the %s");
564 var float autocvar_notification_show_sprees = TRUE;
565 var float autocvar_notification_show_sprees_info = 3; // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker
566 var float autocvar_notification_show_sprees_info_newline = FALSE;
567 var float autocvar_notification_show_sprees_info_specialonly = TRUE;
568 var float autocvar_notification_errors_are_fatal = TRUE;
569 var float autocvar_notification_lifetime_runtime = 0.5;
570 var float autocvar_notification_lifetime_mapload = 10;
571
572 #ifdef SVQC
573 .float FRAG_VERBOSE;
574 void Notification_GetCvars(void);
575 #else
576 var float autocvar_notification_item_centerprinttime = 1.5;
577 var float autocvar_notification_allow_chatboxprint = 1; // 0 = no, 1 = yes, 2 = forced on for all MSG_INFO notifs // todo set back to 1 after testing
578 var float autocvar_notification_show_sprees_center = TRUE;
579 var float autocvar_notification_show_sprees_center_specialonly = TRUE;
580 var float autocvar_notification_frag_verbose = TRUE;
581 #endif
582
583 // ============================
584 //  Notification Argument List
585 // ============================ TODO UPDATE THIS
586 /*
587  These arguments get replaced with the Local_Notification_sprintf
588  and Local_Notification_HUD_Notify_Push functions to supply data
589  from networked notifications to their usage in sprintf... It
590  allows for more dynamic data to be inferred by the local
591  notification parser, so that the server does not have to network
592  anything too crazy on a per-client/per-situation basis.
593  
594  Pay attention to the CSQC/SVQC relations, some of these are redefined
595  in slightly different ways for different programs, this is because the
596  server does a more conservative approach to the notifs than the client.
597  
598  All arguments are swapped into strings, so be sure that your
599  sprintf usage matches with proper %s placement.
600  
601  Argument descriptions:
602     s1-s4: string arguments to be literally swapped into sprintf
603     f1-f4: float arguments expanded into strings to be swapped into sprintf
604     f1p2dec: f1 float to string with 2 decimal places
605     f2p2dec: f2 float to string with 2 decimal places
606     pass_key: find the keybind for "passing" or "dropping" in CTF game mode
607     frag_ping: show the ping of a player
608     frag_stats: show health/armor/ping of a player
609     frag_pos: show score status and position in the match of a player
610     spree_cen: centerprint notif for kill spree/how many kills they have
611     spree_inf: info notif for kill spree/how many kills they have
612     spree_end: placed at the end of murder messages to show ending of sprees
613     spree_lost: placed at the end of suicide messages to show losing of sprees
614     death_team: show the full name of the team a player is switching from
615     weapon_name: return the full name of a weapon from a weaponid
616 */
617
618 #define NOTIF_MAX_ARGS 7
619 #define NOTIF_MAX_HUDARGS 2
620 #define NOTIF_MAX_DURCNT 2
621
622 string arg_slot[NOTIF_MAX_ARGS];
623
624 #define ARG_CS_SV_HA 1 // enabled on CSQC, SVQC, and Hudargs
625 #define ARG_CS_SV_DC 2 // enabled on CSQC, SVQC, and durcnt centerprint
626 #define ARG_CS_SV 3 // enabled on CSQC and SVQC
627 #define ARG_CS 4 // unique result to CSQC
628 #define ARG_SV 5 // unique result to SVQC
629 #define ARG_DC 6 // unique result to durcnt/centerprint
630
631 // todo possible idea.... declare how many floats/strings each arg needs, and then dynamically increment the input
632 // this way, we don't need to have duplicates like i.e. s2loc and s3loc
633
634 #define NOTIF_ARGUMENT_LIST \
635         ARG_CASE(ARG_CS_SV_HA,          "s1",                           s1) \
636         ARG_CASE(ARG_CS_SV_HA,          "s2",                           s2) \
637         ARG_CASE(ARG_CS_SV_HA,          "s3",                           s3) \
638         ARG_CASE(ARG_CS_SV_HA,          "s4",                           s4) \
639         ARG_CASE(ARG_CS_SV,             "s2loc",                        (autocvar_notification_show_location ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s2) : "")) \
640         ARG_CASE(ARG_CS_SV,             "s3loc",                        (autocvar_notification_show_location ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s3) : "")) \
641         ARG_CASE(ARG_CS_SV_DC,          "f1",                           ftos(f1)) \
642         ARG_CASE(ARG_CS_SV_DC,          "f2",                           ftos(f2)) \
643         ARG_CASE(ARG_CS_SV,             "f3",                           ftos(f3)) \
644         ARG_CASE(ARG_CS_SV,             "f4",                           ftos(f4)) \
645         ARG_CASE(ARG_CS_SV,             "f1p2dec",                      ftos_decimals(f1/100, 2)) \
646         ARG_CASE(ARG_CS_SV,             "f2p2dec",                      ftos_decimals(f2/100, 2)) \
647         ARG_CASE(ARG_CS,                        "f1secs",                       count_seconds(f1)) \
648         ARG_CASE(ARG_CS_SV,                     "f1ord",                        count_ordinal(f1)) \
649         ARG_CASE(ARG_CS,                        "f1time",                       process_time("todo", f1)) \
650         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) : "")) \
651         ARG_CASE(ARG_CS,                        "frag_ping",            ((f2 != NO_MSG) ? sprintf(CCR(_("\n(Ping ^2%d^BG)")), f2) : "")) \
652         ARG_CASE(ARG_CS,                        "frag_stats",           sprintf(CCR(_("\n(Health ^1%d^BG / Armor ^2%d^BG)%s")), f2, f3, ((f4 != NO_MSG) ? sprintf(CCR(_(" (Ping ^2%d^BG)")), f4) : ""))) \
653         /*ARG_CASE(ARG_CS,                      "frag_pos",                     ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \
654         ARG_CASE(ARG_CS,                        "spree_cen",            (autocvar_notification_show_sprees ? notif_arg_spree_cen(f1) : "")) \
655         ARG_CASE(ARG_CS_SV,             "spree_inf",            (autocvar_notification_show_sprees ? notif_arg_spree_inf(1, input, s2, f2) : "")) \
656         ARG_CASE(ARG_CS_SV,             "spree_end",            (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
657         ARG_CASE(ARG_CS_SV,             "spree_lost",           (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \
658         ARG_CASE(ARG_CS_SV,             "item_wepname",         W_Name(f1)) \
659         ARG_CASE(ARG_CS_SV,                     "item_wepammo",         (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \
660         ARG_CASE(ARG_DC,                        "item_centime",         ftos(autocvar_notification_item_centerprinttime)) \
661         ARG_CASE(ARG_SV,                        "death_team",           Team_ColoredFullName(f1)) \
662         ARG_CASE(ARG_CS,                        "death_team",           Team_ColoredFullName(f1 - 1)) \
663         ARG_CASE(ARG_CS_SV,                     "race_time",            mmssss(f2)) \
664         ARG_CASE(ARG_CS_SV,             "race_diff",            ((f2 > f3) ? sprintf(CCR("^1[+%s]"), mmssss(f2 - f3)) : sprintf(CCR("^2[-%s]"), mmssss(f3 - f2))))
665
666 #define NOTIF_HIT_MAX(count,funcname) if(sel_num == count) { backtrace(sprintf("%s: Hit maximum arguments!\n", funcname)); break; }
667 #define NOTIF_HIT_UNKNOWN(token,funcname) { backtrace(sprintf("%s: Hit unknown token in selected string! '%s'\n", funcname, selected)); break; }
668
669 #define KILL_SPREE_LIST \
670         SPREE_ITEM(3, 03, _("TRIPLE FRAG! "), _("%s^K1 made a TRIPLE FRAG! %s^BG"), _("%s^K1 made a TRIPLE SCORE! %s^BG")) \
671         SPREE_ITEM(5, 05, _("RAGE! "), _("%s^K1 unlocked RAGE! %s^BG"), _("%s^K1 made FIVE SCORES IN A ROW! %s^BG")) \
672         SPREE_ITEM(10, 10, _("MASSACRE! "), _("%s^K1 started a MASSACRE! %s^BG"), _("%s^K1 made TEN SCORES IN A ROW! %s^BG")) \
673         SPREE_ITEM(15, 15, _("MAYHEM! "), _("%s^K1 executed MAYHEM! %s^BG"), _("%s^K1 made FIFTEEN SCORES IN A ROW! %s^BG")) \
674         SPREE_ITEM(20, 20, _("BERSERKER! "), _("%s^K1 is a BERSERKER! %s^BG"), _("%s^K1 made TWENTY SCORES IN A ROW! %s^BG")) \
675         SPREE_ITEM(25, 25, _("CARNAGE! "), _("%s^K1 inflicts CARNAGE! %s^BG"), _("%s^K1 made TWENTY FIVE SCORES IN A ROW! %s^BG")) \
676         SPREE_ITEM(30, 30, _("ARMAGEDDON! "), _("%s^K1 unleashes ARMAGEDDON! %s^BG"), _("%s^K1 made THIRTY SCORES IN A ROW! %s^BG"))
677
678 #ifdef CSQC
679 string notif_arg_spree_cen(float spree)
680 {
681         // 0 = off, 1 = target (but only for first victim) and attacker
682         if(autocvar_notification_show_sprees_center) 
683         {
684                 if(spree > 1)
685                 {
686                         #define SPREE_ITEM(counta,countb,center,normal,gentle) \
687                                 case counta: { return normal_or_gentle(center, sprintf(_("%d score spree! "), spree)); }
688                         
689                         switch(spree)
690                         {
691                                 KILL_SPREE_LIST
692                                 default:
693                                 {
694                                         if not(autocvar_notification_show_sprees_center_specialonly)
695                                         {
696                                                 return
697                                                         sprintf(
698                                                                 normal_or_gentle(
699                                                                         _("%d frag spree! "),
700                                                                         _("%d score spree! ")
701                                                                 ),
702                                                                 spree);
703                                         }
704                                         else { return ""; } // don't show spree information if it isn't an achievement 
705                                 }
706                         }
707
708                         #undef SPREE_ITEM
709                 }
710                 else if(spree == -1) // first blood
711                 {
712                         return normal_or_gentle(_("First blood! "), _("First score! "));
713                 }
714                 else if(spree == -2) // first victim
715                 {
716                         return normal_or_gentle(_("First victim! "), _("First casualty! "));
717                 }
718         }
719         return "";
720 }
721 #endif
722
723 string notif_arg_spree_inf(float type, string input, string player, float spree)
724 {
725         switch(type)
726         {
727                 case 1: // attacker kill spree
728                 {
729                         // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker
730                         // this conditional (& 2) is true for 2 and 3
731                         if(autocvar_notification_show_sprees_info & 2) 
732                         {
733                                 #ifdef CSQC
734                                 string spree_newline =
735                                         ( autocvar_notification_show_sprees_info_newline ?
736                                                 ((substring(input, 0, 1) == "\{3}") ? "\n\{3}" : "\n") : "" );
737                                 #else
738                                 string spree_newline =
739                                         (autocvar_notification_show_sprees_info_newline ? "\n" : "");
740                                 #endif
741                                 
742                                 if(spree > 1)
743                                 {
744                                         #define SPREE_ITEM(counta,countb,center,normal,gentle) \
745                                                 case counta: { return sprintf(CCR(normal_or_gentle(normal, gentle)), player, spree_newline); }
746                                         
747                                         switch(spree)
748                                         {
749                                                 KILL_SPREE_LIST
750                                                 default:
751                                                 {
752                                                         if not(autocvar_notification_show_sprees_info_specialonly)
753                                                         {
754                                                                 return
755                                                                         sprintf(
756                                                                                 CCR(normal_or_gentle(
757                                                                                         _("%s^K1 has %d frags in a row! %s^BG"),
758                                                                                         _("%s^K1 made %d scores in a row! %s^BG")
759                                                                                 )),
760                                                                                 player,
761                                                                                 spree,
762                                                                                 spree_newline
763                                                                         );
764                                                         }
765                                                         else { return ""; } // don't show spree information if it isn't an achievement 
766                                                 }
767                                         }
768
769                                         #undef SPREE_ITEM
770                                 }
771                                 else if(spree == -1) // firstblood
772                                 {
773                                         return
774                                                 sprintf(
775                                                         CCR(normal_or_gentle(
776                                                                 _("%s^K1 drew first blood! %s^BG"),
777                                                                 _("%s^K1 got the first score! %s^BG")
778                                                         )),
779                                                         player,
780                                                         spree_newline
781                                                 );
782                                 }
783                         }
784                         break;
785                 }
786
787                 case -1: // kill spree ended
788                 {
789                         if((spree > 1) && (autocvar_notification_show_sprees_info & 1))
790                         {
791                                 return
792                                         sprintf(normal_or_gentle(
793                                                 _(", ending their %d frag spree"),
794                                                 _(", ending their %d score spree")
795                                                 ),
796                                                 spree
797                                         );
798                         }
799                         break;
800                 }
801
802                 case -2: // kill spree lost
803                 {
804                         if((spree > 1) && (autocvar_notification_show_sprees_info & 1))
805                         {
806                                 return
807                                         sprintf(normal_or_gentle(
808                                                 _(", losing their %d frag spree"),
809                                                 _(", losing their %d score spree")
810                                                 ),
811                                                 spree
812                                         );
813                         }
814                         break;
815                 }
816         }
817         return "";
818 }
819
820
821 // ====================================
822 //  Initialization/Create Declarations
823 // ====================================
824
825 #define NOTIF_FIRST 1
826 #define NOTIF_MAX 1024 // limit of recursive functions with ACCUMULATE_FUNCTION
827
828 // error detection
829 float notif_error;
830 float notif_global_error;
831
832 // notification entities
833 entity msg_info_notifs[NOTIF_MAX];
834 entity msg_center_notifs[NOTIF_MAX];
835 entity msg_weapon_notifs[NOTIF_MAX];
836 entity msg_death_notifs[NOTIF_MAX];
837
838 // notification counts
839 float NOTIF_INFO_COUNT;
840 float NOTIF_CENTER_COUNT;
841 float NOTIF_WEAPON_COUNT;
842 float NOTIF_DEATH_COUNT;
843 float NOTIF_CPID_COUNT;
844
845 // notification entity values
846 .float nent_default;
847 .string nent_name;
848 .float nent_id;
849 .float nent_enabled;
850 .entity nent_msginfo;
851 .entity nent_msgcenter;
852 .float nent_stringcount;
853 .float nent_floatcount; 
854 .string nent_args;
855 .string nent_hudargs;
856 .string nent_icon;
857 .float nent_cpid;
858 .string nent_durcnt;
859 .string nent_string;
860
861 // networked notification values
862 .float nent_broadcast;
863 .entity nent_client;
864 .float nent_net_type;
865 .float nent_net_name;
866 .string nent_strings[4];
867 .float nent_floats[4];
868
869 string Process_Notif_Line(float check_newline, float chat, string input, string notiftype, string notifname, string stringtype)
870 {
871         if(check_newline)
872         {
873                 #ifdef CSQC
874                 if((chat && autocvar_notification_allow_chatboxprint)
875                         || (autocvar_notification_allow_chatboxprint == 2))
876                 {
877                         // pass 1: add ETX char at beginning of line
878                         input = strcat("\{3}", input);
879
880                         // pass 2: add ETX char at end of each new line (so that messages with multiple lines are put through chatbox too)
881                         input = strreplace("\n", "\n\{3}", input);
882
883                         // pass 3: strip trailing ETX char
884                         if(substring(input, (strlen(input) - 1), 1) == "\{3}")
885                                 { input = substring(input, 0, (strlen(input) - 1)); }
886                 }
887                 #endif
888                 if(substring(input, (strlen(input) - 1), 1) != "\n")
889                 {
890                         print(sprintf("^1MISSING/BROKEN NEW LINE AT END OF NOTIFICATION: ^7net_type = MSG_%s, net_name = %s, string = %s.\n", notiftype, notifname, stringtype));
891                         notif_error = TRUE;
892                         return strcat(input, "\n");
893                 }
894         }
895         return input;
896 }
897
898 string Process_Notif_Args(float arg_type, string args, string notiftype, string notifname)
899 {
900         string selected, remaining = args;
901         float sel_num = 0;
902
903         for(;(remaining != "");)
904         {
905                 selected = car(remaining); remaining = cdr(remaining);
906
907                 switch(arg_type)
908                 {
909                         case 1: // normal args
910                         {
911                                 if(sel_num == NOTIF_MAX_ARGS)
912                                 {
913                                         print(sprintf("^1NOTIFICATION HAS TOO MANY ARGUMENTS: ^7net_type = MSG_%s, net_name = %s, max args = %d.\n",
914                                                 notiftype, notifname, NOTIF_MAX_ARGS));
915                                         notif_error = TRUE;
916                                         break;
917                                 }
918
919                                 switch(strtolower(selected))
920                                 {
921                                         #define ARG_CASE(prog,selected,result) case selected: { ++sel_num; break; }
922                                         NOTIF_ARGUMENT_LIST
923                                         #undef ARG_CASE
924                                         default:
925                                         {
926                                                 print(sprintf("^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: ^7net_type = MSG_%s, net_name = %s, args arg = '%s'.\n",
927                                                         notiftype, notifname, selected));
928                                                 notif_error = TRUE;
929                                                 break;
930                                         }
931                                 }
932                                 break;
933                         }
934                         case 2: // hudargs
935                         {
936                                 if(sel_num == NOTIF_MAX_HUDARGS)
937                                 {
938                                         print(sprintf("^1NOTIFICATION HAS TOO MANY ARGUMENTS: ^7net_type = MSG_%s, net_name = %s, max hudargs = %d.\n",
939                                                 notiftype, notifname, NOTIF_MAX_HUDARGS));
940                                         notif_error = TRUE;
941                                         break;
942                                 }
943
944                                 switch(strtolower(selected))
945                                 {
946                                         #define ARG_CASE(prog,selected,result) \
947                                                 #if (prog == ARG_CS_SV_HA) \
948                                                         case selected: { ++sel_num; break; } \
949                                                 #endif
950                                         NOTIF_ARGUMENT_LIST
951                                         #undef ARG_CASE
952                                         default:
953                                         {
954                                                 print(sprintf("^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: ^7net_type = MSG_%s, net_name = %s, hudargs arg = '%s'.\n",
955                                                         notiftype, notifname, selected));
956                                                 notif_error = TRUE;
957                                                 break;
958                                         }
959                                 }
960                                 break;
961                         }
962                         case 3: // durcnt 
963                         {
964                                 if(sel_num == NOTIF_MAX_DURCNT)
965                                 {
966                                         print(sprintf("^1NOTIFICATION HAS TOO MANY ARGUMENTS: ^7net_type = MSG_%s, net_name = %s, max durcnt = %d.\n",
967                                                 notiftype, notifname, NOTIF_MAX_DURCNT));
968                                         notif_error = TRUE;
969                                         break;
970                                 }
971
972                                 switch(strtolower(selected))
973                                 {
974                                         #define ARG_CASE(prog,selected,result) \
975                                                 #if (prog == ARG_CS_SV_DC) || (prog == ARG_DC) \
976                                                         case selected: { ++sel_num; break; } \
977                                                 #endif
978                                         NOTIF_ARGUMENT_LIST
979                                         #undef ARG_CASE
980                                         default:
981                                         {
982                                                 if(ftos(stof(selected)) != "") { ++sel_num; }
983                                                 else
984                                                 {
985                                                         print(sprintf("^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: ^7net_type = MSG_%s, net_name = %s, durcnt arg = '%s'.\n",
986                                                                 notiftype, notifname, selected));
987                                                         notif_error = TRUE;
988                                                 }
989                                                 break;
990                                         }
991                                 }
992                                 break;
993                         }
994                 }
995         }
996         return args;
997 }
998
999 #define CREATE_NOTIF_ENTITY(default,type,name,infoname,centername,strnum,flnum,args,hudargs,icon,cpid,durcnt,normal,gentle,check_newline,subcalls) \
1000 { \
1001         notif_error = FALSE; \
1002         \
1003         /* global entity setup */ \
1004         entity notif = spawn(); \
1005         msg_##type##_notifs[name - 1] = notif; \
1006         notif.classname = "msg_#type#_notification"; \
1007         notif.nent_default = default; \
1008         notif.nent_name = strzone(#name); \
1009         notif.nent_id = name; \
1010         notif.nent_enabled = (1 <= autocvar_notification_##name); \
1011         \
1012         /* notification specific settings */ \
1013         #if subcalls /* MSG_DEATH and MSG_WEAPON */ \
1014                 #if (infoname == NO_MSG) && (centername == NO_MSG) \
1015                         print(sprintf("^1NOTIFICATION WITH NO SUBCALLS: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); \
1016                         notif_error = TRUE; \
1017                 #else \
1018                         float infoname_stringcount = 0, infoname_floatcount = 0, centername_stringcount = 0, centername_floatcount = 0; \
1019                         #if (infoname != NO_MSG) \
1020                                 notif.nent_msginfo = msg_info_notifs[infoname - 1]; \
1021                                 infoname_stringcount = notif.nent_msginfo.nent_stringcount; \
1022                                 infoname_floatcount = notif.nent_msginfo.nent_floatcount; \
1023                         #endif \
1024                         #if (centername != NO_MSG) \
1025                                 notif.nent_msgcenter = msg_center_notifs[centername - 1]; \
1026                                 centername_stringcount = notif.nent_msgcenter.nent_stringcount; \
1027                                 centername_floatcount = notif.nent_msgcenter.nent_floatcount; \
1028                         #endif \
1029                         /* set the requirements of THIS notification to the total requirements of its subcalls */ \
1030                         notif.nent_stringcount = max(infoname_stringcount, centername_stringcount); \
1031                         notif.nent_floatcount = max(infoname_floatcount, centername_floatcount); \
1032                 #endif \
1033         #else /* MSG_INFO and MSG_CENTER */ \
1034                 notif.nent_stringcount = strnum; \
1035                 notif.nent_floatcount = flnum; \
1036                 \
1037                 /* only initialize this information if we're on a client or a dedicated server */ \
1038                 #ifdef SVQC \
1039                 if(server_is_dedicated) { \
1040                 #endif \
1041                 \
1042                         if(strnum + flnum) \
1043                         { \
1044                                 if(args != "") { notif.nent_args = strzone(Process_Notif_Args(1, args, strtoupper(#type), #name)); } \
1045                                 else if((hudargs == "") && (durcnt =="")) { print(sprintf("^1NOTIFICATION HAS ARG COUNTS BUT NO ARGS OR HUDARGS OR DURCNT: ^7net_type = MSG_%s, net_name = %s, strnum = %d, flnum = %d\n", strtoupper(#type), #name, strnum, flnum)); notif_error = TRUE; } \
1046                         } \
1047                         else if(args != "") { notif.nent_args = strzone(Process_Notif_Args(1, args, strtoupper(#type), #name)); } \
1048                         \
1049                         #ifdef CSQC \
1050                                 /* MSG_INFO only */ \
1051                                 if(hudargs != "") \
1052                                 { \
1053                                         notif.nent_hudargs = strzone(Process_Notif_Args(2, hudargs, strtoupper(#type), #name)); \
1054                                         if(icon != "") { notif.nent_icon = strzone(icon); } \
1055                                         else { print(sprintf("^1NOTIFICATION HAS HUDARGS BUT NO ICON: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
1056                                 } \
1057                                 else if(icon != "") { print(sprintf("^1NOTIFICATION HAS ICON BUT NO HUDARGS: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
1058                                 \
1059                                 /* MSG_CENTER only */ \
1060                                 if(durcnt != "") \
1061                                 { \
1062                                         notif.nent_durcnt = strzone(Process_Notif_Args(3, durcnt, strtoupper(#type), #name)); \
1063                                         if(cpid != NO_MSG) { notif.nent_cpid = cpid; } \
1064                                         else { print(sprintf("^1NOTIFICATION HAS DURCNT BUT NO CPID: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
1065                                 } \
1066                                 else if(cpid != NO_MSG) { notif.nent_cpid = cpid; } \
1067                         #endif \
1068                         \
1069                         /* string setup */ \
1070                         /* select gentle/normal string and bake color codes in on init, this way it does not need to be re-processed at run time */ \
1071                         float nent_chat = (autocvar_notification_##name > 1); \
1072                         if(GENTLE) \
1073                         { \
1074                                 if(gentle != "") { notif.nent_string = strzone(CCR(Process_Notif_Line(check_newline, nent_chat, gentle, strtoupper(#type), #name, "GENTLE"))); } \
1075                                 else if(normal != "") { notif.nent_string = strzone(CCR(Process_Notif_Line(check_newline, nent_chat, normal, strtoupper(#type), #name, "NORMAL"))); } \
1076                         } \
1077                         else if(normal != "") { notif.nent_string = strzone(CCR(Process_Notif_Line(check_newline, nent_chat, normal, strtoupper(#type), #name, "NORMAL"))); } \
1078                         if(notif.nent_string == "") { print(sprintf("^1EMPTY NOTIFICATION: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
1079                 #ifdef SVQC \
1080                 } \
1081                 #endif \
1082         #endif \
1083         \
1084         /* now check to see if any errors happened */ \
1085         if(notif_error) \
1086         { \
1087                 notif.nent_enabled = FALSE; /* disable the notification so it can't cause trouble */ \
1088                 notif_global_error = TRUE; /* throw the red flag that an error happened on init */ \
1089         } \
1090 }
1091
1092 #define MSG_INFO_NOTIF(default,name,strnum,flnum,args,hudargs,icon,normal,gentle) \
1093         NOTIF_ADD_AUTOCVAR(name, default) \
1094         float name; \
1095         void RegisterNotification_##name() \
1096         { \
1097                 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \
1098                 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_INFO_COUNT, "notifications") \
1099                 CREATE_NOTIF_ENTITY( \
1100                         default,        /* default */ \
1101                         info,           /* type */ \
1102                         name,           /* name */ \
1103                         NO_MSG,         /* infoname */ \
1104                         NO_MSG,         /* centername */ \
1105                         strnum,         /* strnum */ \
1106                         flnum,          /* flnum */ \
1107                         args,           /* args */ \
1108                         hudargs,        /* hudargs */ \
1109                         icon,           /* icon */ \
1110                         NO_MSG,         /* cpid */ \
1111                         "",             /* durcnt */ \
1112                         normal,         /* normal */ \
1113                         gentle,         /* gentle */ \
1114                         1,                      /* check_newline */ \
1115                         0)                      /* subcalls */ \
1116         } \
1117         ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
1118
1119 #define MSG_CENTER_NOTIF(default,name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
1120         NOTIF_ADD_AUTOCVAR(name, default) \
1121         float name; \
1122         float cpid; \
1123         void RegisterNotification_##name() \
1124         { \
1125                 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CENTER_COUNT) \
1126                 SET_FIELD_COUNT(cpid, NOTIF_FIRST, NOTIF_CPID_COUNT) \
1127                 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_CENTER_COUNT, "notifications") \
1128                 CREATE_NOTIF_ENTITY( \
1129                         default,        /* default */ \
1130                         center,         /* type */ \
1131                         name,           /* name */ \
1132                         NO_MSG,         /* infoname */ \
1133                         NO_MSG,         /* centername */ \
1134                         strnum,         /* strnum */ \
1135                         flnum,          /* flnum */ \
1136                         args,           /* args */ \
1137                         "",             /* hudargs */ \
1138                         "",             /* icon */ \
1139                         cpid,           /* cpid */ \
1140                         durcnt,         /* durcnt */ \
1141                         normal,         /* normal */ \
1142                         gentle,         /* gentle */ \
1143                         0,                      /* check_newline */ \
1144                         0)                      /* subcalls */ \
1145         } \
1146         ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
1147
1148 #define MSG_WEAPON_NOTIF(default,name,infoname,centername) \
1149         NOTIF_ADD_AUTOCVAR(name, default) \
1150         float name; \
1151         void RegisterNotification_##name() \
1152         { \
1153                 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_WEAPON_COUNT) \
1154                 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_WEAPON_COUNT, "notifications") \
1155                 CREATE_NOTIF_ENTITY( \
1156                         default,        /* default */ \
1157                         weapon,         /* type */ \
1158                         name,           /* name */ \
1159                         infoname,       /* infoname */ \
1160                         centername, /* centername */ \
1161                         NO_MSG,         /* strnum */ \
1162                         NO_MSG,         /* flnum */ \
1163                         "",             /* args */ \
1164                         "",             /* hudargs */ \
1165                         "",             /* icon */ \
1166                         NO_MSG,         /* cpid */ \
1167                         "",             /* durcnt */ \
1168                         "",             /* normal */ \
1169                         "",             /* gentle */ \
1170                         0,                      /* check_newline */ \
1171                         1)                      /* subcalls */ \
1172         } \
1173         ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
1174
1175 #define MSG_DEATH_NOTIF(default,name,infoname,centername) \
1176         NOTIF_ADD_AUTOCVAR(name, default) \
1177         float name; \
1178         void RegisterNotification_##name() \
1179         { \
1180                 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_DEATH_COUNT) \
1181                 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_DEATH_COUNT, "notifications") \
1182                 CREATE_NOTIF_ENTITY( \
1183                         default,        /* default */ \
1184                         death,          /* type */ \
1185                         name,           /* name */ \
1186                         infoname,       /* infoname */ \
1187                         centername, /* centername */ \
1188                         NO_MSG,         /* strnum */ \
1189                         NO_MSG,         /* flnum */ \
1190                         "",             /* args */ \
1191                         "",             /* hudargs */ \
1192                         "",             /* icon */ \
1193                         NO_MSG,         /* cpid */ \
1194                         "",             /* durcnt */ \
1195                         "",             /* normal */ \
1196                         "",             /* gentle */ \
1197                         0,                      /* check_newline */ \
1198                         1)                      /* subcalls */ \
1199         } \
1200         ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
1201
1202 void RegisterNotifications_First()
1203 {
1204         notif_global_error = FALSE;
1205
1206         #ifdef SVQC
1207         #define dedi (server_is_dedicated ? "a dedicated " : "")
1208         #else
1209         #define dedi ""
1210         #endif
1211         
1212         print(sprintf("Beginning notification initialization on %s%s program...\n", dedi, PROGNAME));
1213         
1214         // maybe do another implementation of this with checksums? for now, we don't need versioning
1215         /*if(autocvar_notification_version != NOTIF_VERSION)
1216         {
1217                 #ifdef CSQC
1218                 if(autocvar_notification_version_mismatch_client_error)
1219                 #else
1220                 if(autocvar_notification_version_mismatch_server_error)
1221                 #endif
1222                         notif_global_error = TRUE;
1223
1224                 print(sprintf("^1NOTIFICATION VERSION MISMATCH: ^7program = %s, config = %d, code = %d.\n",
1225                         PROGNAME, autocvar_notification_version, NOTIF_VERSION));
1226         }*/
1227 }
1228
1229 void RegisterNotifications_Done()
1230 {
1231         if(notif_global_error)
1232         {
1233                 // shit happened... stop the loading of the program now if this is unacceptable
1234                 if(autocvar_notification_errors_are_fatal)
1235                         error("Notification initialization failed! Read above and fix the errors!\n");
1236                 else
1237                         print("Notification initialization failed! Read above and fix the errors!\n");
1238         }
1239         else { print("Notification initialization successful!\n"); }
1240 }
1241
1242 // NOW we actually activate the declarations
1243 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotifications_First)
1244 MSG_INFO_NOTIFICATIONS
1245 MSG_CENTER_NOTIFICATIONS
1246 MSG_WEAPON_NOTIFICATIONS
1247 MSG_DEATH_NOTIFICATIONS
1248 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotifications_Done)
1249 #undef MSG_INFO_NOTIF
1250 #undef MSG_CENTER_NOTIF
1251 #undef MSG_WEAPON_NOTIF
1252 #undef MSG_DEATH_NOTIF
1253
1254 #undef NOTIF_ADD_AUTOCVAR