]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/notifications.qh
Fix the check for hudargs, fix dumpnotifs command, add done function
[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_WEAPON 3 // "Personal" weapon messages (like "You got the Nex", sent to weapon notify panel)
10 #define MSG_DEATH 4 // "Personal" AND "Global" death messages 
11
12 // Current version number of the configuration file for notifications...
13 // This is used to check matches between the config file and the code,
14 // and should be incremented any time you add a new/remove or edit an notification
15 // or any time you change default values or add/edit/remove a special cvar.
16 #define NOTIF_VERSION 1
17
18 #define NOTIF_FIRST 1
19 #define NOTIF_MAX 1024 // limit of recursive functions with ACCUMULATE_FUNCTION
20
21 #define NO_MSG -12345 
22
23 // ping of bots defined for extra frag message notification information
24 #define BOT_PING -1
25
26 #define EIGHT_VARS_TO_VARARGS_VARLIST \
27         VARITEM(1, 0, s1) \
28         VARITEM(2, 0, XPD(s1, s2)) \
29         VARITEM(3, 0, XPD(s1, s2, s3)) \
30         VARITEM(4, 0, XPD(s1, s2, s3, s4)) \
31         VARITEM(0, 1, f1) \
32         VARITEM(1, 1, XPD(s1, f1)) \
33         VARITEM(2, 1, XPD(s1, s2, f1)) \
34         VARITEM(3, 1, XPD(s1, s2, s3, f1)) \
35         VARITEM(4, 1, XPD(s1, s2, s3, s4, f1)) \
36         VARITEM(0, 2, XPD(f1, f2)) \
37         VARITEM(1, 2, XPD(s1, f1, f2)) \
38         VARITEM(2, 2, XPD(s1, s2, f1, f2)) \
39         VARITEM(3, 2, XPD(s1, s2, s3, f1, f2)) \
40         VARITEM(4, 2, XPD(s1, s2, s3, s4, f1, f2)) \
41         VARITEM(0, 3, XPD(f1, f2, f3)) \
42         VARITEM(1, 3, XPD(s1, f1, f2, f3)) \
43         VARITEM(2, 3, XPD(s1, s2, f1, f2, f3)) \
44         VARITEM(3, 3, XPD(s1, s2, s3, f1, f2, f3)) \
45         VARITEM(4, 3, XPD(s1, s2, s3, s4, f1, f2, f3)) \
46         VARITEM(0, 4, XPD(f1, f2, f3, f4)) \
47         VARITEM(1, 4, XPD(s1, f1, f2, f3, f4)) \
48         VARITEM(2, 4, XPD(s1, s2, f1, f2, f3, f4)) \
49         VARITEM(3, 4, XPD(s1, s2, s3, f1, f2, f3, f4)) \
50         VARITEM(4, 4, XPD(s1, s2, s3, s4, f1, f2, f3, f4))
51
52 void Dump_Notifications(float fh, float alsoprint);
53
54 void Local_Notification(float net_type, float net_name, ...count);
55 void Local_Notification_Without_VarArgs(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);
56
57 #ifdef CSQC // CLIENT ONLY
58 #define KN_MAX_ENTRIES 10
59
60 float kn_index;
61 float killnotify_times[KN_MAX_ENTRIES];
62 string killnotify_icon[KN_MAX_ENTRIES];
63 string killnotify_attackers[KN_MAX_ENTRIES];
64 string killnotify_victims[KN_MAX_ENTRIES];
65 void HUD_Notify_Push(string icon, string attacker, string victim);
66 void Read_Notification(float is_new);
67 #endif // ifdef CSQC
68
69 #ifdef SVQC // SERVER ONLY
70 #define NOTIF_ONE 1
71 #define NOTIF_ONE_ONLY 2
72 #define NOTIF_TEAM 3
73 #define NOTIF_TEAM_EXCEPT 4
74 #define NOTIF_ANY 5
75 #define NOTIF_ANY_EXCEPT 6
76
77 #define IFSTR(num) ((num < notif.nent_stringcount) ? ...(num, string) : "")
78 #define IFFL(num) ((((notif.nent_stringcount-1) + num) < count) ? ...(((notif.nent_stringcount-1) + num), float) : 0)
79
80 void Send_Notification(float broadcast, entity client, float net_type, float net_name, ...count);
81 void Send_Notification_Without_VarArgs(float broadcast, entity client, 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);
82 void Send_Notification_Legacy_Wrapper(float broadcast, entity client, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3);
83
84 void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num);
85 void Send_CSQC_Centerprint_Generic_Expire(entity e, float id);
86 #endif // ifdef SVQC
87
88
89 // ====================================
90 //  Notifications List and Information
91 // ====================================
92 /*
93  List of all notifications (including identifiers and display information)
94  Possible Tokens: default, name, infoname, centername, strnum, flnum, args, hudargs, icon, cpid, durcnt, normal, gentle
95  Format Specifications:
96     MSG_INFO:
97       default: FLOAT: Default setting for whether the notification is enabled or not
98       name: VAR: Name of notification
99       strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive)
100       flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive)
101       args: STRING: Arguments for Local_Notification_sprintf()
102       hudargs: STRING: Arguments for Local_Notification_HUD_Notify_Push()
103       icon: STRING: icon string name for the hud notify panel, "" if no icon is used
104       normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled)
105       gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled)
106     MSG_CENTER:
107       default: FLOAT: Default setting for whether the notification is enabled or not
108       name: VAR: Name of notification
109       strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive)
110       flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive)
111       args: STRING: Arguments for Local_Notification_sprintf()
112       cpid: FLOAT: centerprint ID number (CPID_*), NO_CPID if no CPID is needed
113       durcnt: XPD(FLOAT, FLOAT): Duration/Countdown: extra arguments for centerprint messages
114       normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled)
115       gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled)
116     MSG_WEAPON:
117     MSG_DEATH:
118       default: FLOAT: Default setting for whether the notification is enabled or not
119       name: VAR: Name of chaining notification
120       infoname: VAR: Name of info notification for reference
121       centername: VAR: Name of centerprint notification for reference
122
123  Messages with ^F1, ^BG, ^TC, etc etc in them will replace those strings
124  with colors according to the cvars the user has chosen. This allows for
125  users to create unique color profiles for their HUD, giving more customization
126  options to HUD designers and end users who want such a feature.
127
128  Check out the definitions in util.qc/util.qh/teams.qh for string CCR(...) and
129  string TCR(...) to better understand how these code replacements work.
130
131  Guidlines for notification declaration (please try and follow these):
132   Specific rules:
133     -ALWAYS start the string with a color, preferably background.
134     -ALWAYS reset a color after a name (this way they don't set it for the whole string).
135     -NEVER re-declare an event twice.
136     -NEVER add or remove tokens from the format, it SHOULD already work.
137     -MSG_INFO messages must ALWAYS end with a new line: \n
138     -MSG_INFO hudargs must always be ATTACKER -> VICTIM
139     -MSG_CENTER should NOT end with a new line
140
141  General rules:
142     -Be clean and simple with your notification naming,
143      nothing too long for the name field... Abbreviations are your friend. :D
144     -Keep the spacing as clean as possible... if the arguments are abnormally long,
145       it's okay to go out of line a bit... but try and keep it clean still.
146     -Sort the notifications in the most appropriate order for their tasks.
147     -ARIRE unir frk jvgu lbhe bja zbgure. (gvc sbe zvxrrhfn) -- Don't pay attention to this ^_^
148
149  Final note: DO NOT PROVIDE MORE ARGUMENTS THAN NECESSARY FOR THE NOTIFICATION YOU'RE CALLING!
150       The system is designed to save as much networking bandwidth as possible,
151       so please dynamically control your argument sending to fit *exactly* what is required.
152       If you send a notification with mismatching arguments, Send_Notification() will error.
153 */
154
155 #define MULTITEAM_INFO(default,prefix,teams,strnum,flnum,args,hudargs,icon,normal,gentle) \
156         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))) \
157         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))) \
158         #if teams >= 3 \
159                 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))) \
160         #endif \
161         #if teams >= 4 \
162                 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))) \
163         #endif
164 #define MSG_INFO_NOTIFICATIONS \
165         /*MSG_INFO_NOTIF(INFO_EMPTY,                                            0, 0, "", "",                                                   "",                                             "", "")*/ \
166         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DROPPED_, 2,              0, 0, "", "",                                                   "",                                             _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself\n"), "") \
167         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DAMAGED_, 2,              0, 0, "", "",                                                   "",                                             _("^BGThe ^TC^TT^BG flag was destroyed and returned to base\n"), "") \
168         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"), "") \
169         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"), "") \
170         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_ABORTRUN_, 2,             0, 0, "", "",                                                   "",                                             _("^BGThe ^TC^TT^BG flag was returned to base by its owner\n"), "") \
171         MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_TIMEOUT_, 2,              0, 0, "", "",                                                   "",                                             _("^BGThe ^TC^TT^BG flag has returned to the base\n"), "") \
172         MULTITEAM_INFO(1, INFO_CTF_PICKUP_, 2,                                  1, 0, "s1", "s1",                                               "notify_%s_taken",              _("^BG%s^BG got the ^TC^TT^BG flag\n"), "") \
173         MULTITEAM_INFO(1, INFO_CTF_RETURN_, 2,                                  1, 0, "s1", "s1",                                               "notify_%s_returned",   _("^BG%s^BG returned the ^TC^TT^BG flag\n"), "") \
174         MULTITEAM_INFO(1, INFO_CTF_LOST_, 2,                                    1, 0, "s1", "s1",                                               "notify_%s_lost",               _("^BG%s^BG lost the ^TC^TT^BG flag\n"), "") \
175         MULTITEAM_INFO(1, INFO_CTF_CAPTURE_, 2,                                 1, 0, "s1", "s1",                                               "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag\n"), "") \
176         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"), "") \
177         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"), "") \
178         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"), "") \
179         MULTITEAM_INFO(1, INFO_DEATH_TEAMKILL_, 4,                              2, 1, "s1 s2 spree_end", "s2 s1",               "notify_teamkill_%s",   _("^BG%s^K1 was betrayed by ^BG%s^K1%s\n"), "") \
180         MSG_INFO_NOTIF(1, INFO_DEATH_FIRSTBLOOD,                                2, 0, "s2", "",                                                 "",                                             _("^BG%s^K1 drew first blood\n"), _("^F1%s^K1 got the first score\n")) \
181         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CUSTOM,                               2, 1, "s1 s2 spree_end", "s1",                  "notify_void",                  _("^BG%s^K1 %s^K1%s\n"), "") \
182         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_GENERIC,                              1, 1, "s1 spree_end", "s1",                             "notify_selfkill",              _("^BG%s^K1 died%s\n"), "") \
183         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VOID,                                 1, 1, "s1 spree_end", "s1",                             "notify_void",                  _("^BG%s^K1 was in the wrong place%s\n"), "") \
184         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SUICIDE,                              1, 1, "s1 spree_end", "s1",                             "notify_selfkill",              _("^BG%s^K1 couldn't take it anymore%s\n"), "") \
185         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NOAMMO,                               1, 1, "s1 spree_end", "s1",                             "notify_outofammo",             _("^BG%s^K1 died%s. What's the point of living without ammo?\n"), _("^F1%s^K1 ran out of ammo%s\n")) \
186         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_ROT,                                  1, 1, "s1 spree_end", "s1",                             "notify_death",                 _("^BG%s^K1 rotted away%s\n"), "") \
187         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CAMP,                                 1, 1, "s1 spree_end", "s1",                             "notify_camping",               _("^BG%s^K1 thought they found a nice camping ground%s\n"), "") \
188         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_BETRAYAL,                             1, 1, "s1 spree_end", "s1",                             "notify_teamkill_red",  _("^BG%s^K1 became enemies with the Lord of Teamplay%s\n"), "") \
189         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TEAMCHANGE,                   1, 1, "s1 death_team", "",                              "",                                             _("^BG%s^K1 switched to the %s\n"), "") \
190         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_AUTOTEAMCHANGE,               1, 1, "s1 death_team", "",                              "",                                             _("^BG%s^K1 was moved into the %s\n"), "") \
191         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FALL,                                 1, 1, "s1 spree_end", "s1",                             "notify_fall",                  _("^BG%s^K1 hit the ground with a crunch%s\n"), _("^F1%s^K1 hit the ground with a bit too much force%s\n")) \
192         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_DROWN,                                1, 1, "s1 spree_end", "s1",                             "notify_water",                 _("^BG%s^K1 couldn't catch their breath%s\n"), _("^F1%s^K1 was in the water for too long%s\n")) \
193         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FIRE,                                 1, 1, "s1 spree_end", "s1",                             "notify_death",                 _("^BG%s^K1 became a bit too crispy%s\n"), _("^F1%s^K1 felt a little hot%s\n")) \
194         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_LAVA,                                 1, 1, "s1 spree_end", "s1",                             "notify_lava",                  _("^BG%s^K1 turned into hot slag%s\n"), _("^F1%s^K1 found a hot place%s\n")) \
195         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SLIME,                                1, 1, "s1 spree_end", "s1",                             "notify_slime",                 _("^BG%s^K1 was slimed%s\n"), "") \
196         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SHOOTING_STAR,                1, 1, "s1 spree_end", "s1",                             "notify_shootingstar",  _("^BG%s^K1 became a shooting star%s\n"), "") \
197         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SWAMP,                                1, 1, "s1 spree_end", "s1",                             "notify_slime",                 _("^BG%s^K1 is now preserved for centuries to come%s\n"), "") \
198         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CHEAT,                                1, 1, "s1 spree_end", "s1",                             "notify_selfkill",              _("^BG%s^K1 unfairly eliminated themself%s\n"), "") \
199         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TOUCHEXPLODE,                 1, 1, "s1 spree_end", "s1",                             "notify_death",                 _("^BG%s^K1 died in an accident%s\n"), "") \
200         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET,                                       1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 ran into a turret%s\n"), "") \
201         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_EWHEEL,                        1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 was blasted away by an eWheel turret%s\n"), "") \
202         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_FLAC,                          1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 got caught up in the FLAC turret fire%s\n"), "") \
203         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_MACHINEGUN,            1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 was riddled full of holes by a Machinegun turret%s\n"), "") \
204         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALKER_GUN,            1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 got served a lead enrichment by a Walker turret%s\n"), "") \
205         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALKER_MEELE,          1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 was impaled by a Walker turret%s\n"), "") \
206         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALKER_ROCKET,         1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 was blasted away by a Walker turret%s\n"), "") \
207         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_HELLION,                       1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 was blasted away by a Hellion turret%s\n"), "") \
208         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_HK,                            1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 could not hide from the Hunter turret%s\n"), "") \
209         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_MLRS,                          1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 got turned into smoldering gibs by an MLRS turret%s\n"), "") \
210         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_PLASMA,                        1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 got served some superheated plasma from a turret%s\n"), "") \
211         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_PHASER,                        1, 1, "s1 spree_end", "s1",                     "notify_death",                 _("^BG%s^K1 was phased out by a turret%s\n"), "") \
212         MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_TESLA,                 1, 1, "s1 spree_end", "s1",                             "notify_death",                 _("^BG%s^K1 was electrocuted by a Tesla turret%s\n"), "") \
213         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_TELEFRAG,                   2, 1, "s1 s2 spree_end", "s2 s1",               "notify_telefrag",              _("^BG%s^K1 was telefragged by ^BG%s^K1%s\n"), _("^F1%s^K1 tried to occupy ^BG%s^K1's teleport destination space\n")) \
214         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FALL,                               2, 1, "s1 s2 spree_end", "s2 s1",               "notify_fall",                  _("^BG%s^K1 was grounded by ^BG%s^K1%s\n"), "") \
215         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_DROWN,                              2, 1, "s1 s2 spree_end", "s2 s1",               "notify_water",                 _("^BG%s^K1 was drowned by ^BG%s^K1%s\n"), "") \
216         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_LAVA,                               2, 1, "s1 s2 spree_end", "s2 s1",               "notify_lava",                  _("^BG%s^K1 was cooked by ^BG%s^K1%s\n"), "") \
217         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SLIME,                              2, 1, "s1 s2 spree_end", "s2 s1",               "notify_slime",                 _("^BG%s^K1 was slimed by ^BG%s^K1%s\n"), "") \
218         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SHOOTING_STAR,              2, 1, "s1 s2 spree_end", "s2 s1",               "notify_shootingstar",  _("^BG%s^K1 was shot into space by ^BG%s^K1%s\n"), "") \
219         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SWAMP,                              2, 1, "s1 s2 spree_end", "s2 s1",               "notify_slime",                 _("^BG%s^K1 was preserved by ^BG%s^K1%s\n"), "") \
220         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VOID,                               2, 1, "s1 s2 spree_end", "s2 s1",               "notify_void",                  _("^BG%s^K1 was thrown into a world of hurt by ^BG%s^K1%s\n"), "") \
221         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_TOUCHEXPLODE,               2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 died in an accident with ^BG%s^K1%s\n"), "") \
222         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_CHEAT,                              2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 was unfairly eliminated by ^BG%s^K1%s\n"), "") \
223         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FIRE,                               2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 was burnt up into a crisp by ^BG%s^K1%s\n"), _("^F1%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s\n")) \
224         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_CRUSH,                   2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 was crushed by ^BG%s^K1%s\n"), "") \
225         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_MINIGUN,    2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 got shredded by ^BG%s^K1%s\n"), "") \
226         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_ROCKET,             2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 was blasted to bits by ^BG%s^K1%s\n"), "") \
227         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_DEATH,              2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 got caught in the blast when ^BG%s^K1%s\n"), "") \
228         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_GUN,                2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 was bolted down by ^BG%s^K1%s\n"), "") \
229         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_ROCKET,             2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 couldn't find shelter from ^BG%s^K1%s\n"), "") \
230         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_DEATH,              2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 got caught in the blast when ^BG%s^K1%s\n"), "") \
231         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_CANNON,             2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 couldn't resist ^BG%s^K1 purple blobs%s\n"), "") \
232         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_BOMB,               2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 was cluster bombed by ^BG%s^K1%s\n"), "") \
233         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_FRAGMENT,   2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 was cluster bombed by ^BG%s^K1%s\n"), "") \
234         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_DEATH,              2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 got caught in the blast when ^BG%s^K1%s\n"), "") \
235         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_GUN,                2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 foobar by ^BG%s^K1%s\n"), "") \
236         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_RAY,                2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 foobar by ^BG%s^K1%s\n"), "") \
237         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_RAY_HEAL,   2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 foobar by ^BG%s^K1%s\n"), "") \
238         MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_DEATH,              2, 1, "s1 s2 spree_end", "s2 s1",               "notify_death",                 _("^BG%s^K1 foobar by ^BG%s^K1%s\n"), "") \
239         MULTITEAM_INFO(1, INFO_FREEZETAG_ROUND_WIN_, 4,                 0, 0, "", "",                                                   "",                                             _("^TC^TT^BG team wins the round, all other teams were frozen\n"), "") \
240         MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVE,                                2, 0, "s1 s2", "",                                              "",                                             _("^BG%s^K3 was revived by ^BG%s\n"), "") \
241         MSG_INFO_NOTIF(1, INFO_FREEZETAG_FREEZE,                                2, 0, "s1 s2", "",                                              "",                                             _("^BG%s^K1 was frozen by ^BG%s\n"), "") \
242         MSG_INFO_NOTIF(1, INFO_FREEZETAG_SELF,                                  1, 0, "s1", "",                                                 "",                                             _("^BG%s^K1 froze themself\n"), "") \
243         MSG_INFO_NOTIF(1, INFO_GODMODE_OFF,                                             0, 1, "f1", "",                                                 "",                                             _("^BGGodmode saved you %s units of damage, cheater!\n"), "") \
244         MSG_INFO_NOTIF(1, INFO_JOIN_CONNECT,                                    1, 0, "s1", "",                                                 "",                                             _("^BG%s^F3 connected%s\n"), "") \
245         MULTITEAM_INFO(1, INFO_JOIN_CONNECT_TEAM_, 4,                   1, 0, "s1", "",                                                 "",                                             _("^BG%s^F3 connected and joined the ^TC^TT\n"), "") \
246         MSG_INFO_NOTIF(1, INFO_JOIN_PLAY,                                               1, 0, "s1", "",                                                 "",                                             _("^BG%s^F3 is now playing\n"), "") \
247         MSG_INFO_NOTIF(1, INFO_KEEPAWAY_DROPPED,                                1, 0, "s1", "s1",                                               "notify_balldropped",   _("^BG%s^BG has dropped the ball!\n"), "") \
248         MSG_INFO_NOTIF(1, INFO_KEEPAWAY_PICKUP,                                 1, 0, "s1", "s1",                                               "notify_ballpickedup",  _("^BG%s^BG has picked up the ball!\n"), "") \
249         MSG_INFO_NOTIF(1, INFO_LMS_NOLIVES,                                             1, 0, "s1", "s1",                                               "",                                             _("^BG%s^F3 has no more lives left\n"), "") \
250         MSG_INFO_NOTIF(1, INFO_LMS_FORFEIT,                                             1, 0, "s1", "s1",                                               "",                                             _("^BG%s^F3 forfeited\n"), "") \
251         MSG_INFO_NOTIF(1, INFO_POWERDOWN_INVISIBILITY,                  0, 0, "", "",                                                   "",                                             _("^F2Invisibility has worn off\n"), "") \
252         MSG_INFO_NOTIF(1, INFO_POWERDOWN_SHIELD,                                0, 0, "", "",                                                   "",                                             _("^F2Shield has worn off\n"), "") \
253         MSG_INFO_NOTIF(1, INFO_POWERDOWN_SPEED,                                 0, 0, "", "",                                                   "",                                             _("^F2Speed has worn off\n"), "") \
254         MSG_INFO_NOTIF(1, INFO_POWERDOWN_STRENGTH,                              0, 0, "", "",                                                   "",                                             _("^F2Strength has worn off\n"), "") \
255         MSG_INFO_NOTIF(1, INFO_POWERUP_INVISIBILITY,                    0, 0, "", "",                                                   "",                                             _("^F2You are invisible\n"), "") \
256         MSG_INFO_NOTIF(1, INFO_POWERUP_SHIELD,                                  0, 0, "", "",                                                   "",                                             _("^F2Shield surrounds you\n"), "") \
257         MSG_INFO_NOTIF(1, INFO_POWERUP_SPEED,                                   0, 0, "", "",                                                   "",                                             _("^F2You are on speed\n"), "") \
258         MSG_INFO_NOTIF(1, INFO_POWERUP_STRENGTH,                                0, 0, "", "",                                                   "",                                             _("^F2Strength infuses your weapons with devastating power\n"), "") \
259         MSG_INFO_NOTIF(1, INFO_QUIT_DISCONNECT,                                 1, 0, "s1", "s1",                                               "",                                             _("^BG%s^F3 disconnected\n"), "") \
260         MSG_INFO_NOTIF(1, INFO_QUIT_KICK_IDLING,                                1, 0, "s1", "s1",                                               "",                                             _("^BG%s^F3 was kicked for idling\n"), "") \
261         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"), "") \
262         MSG_INFO_NOTIF(1, INFO_QUIT_SPECTATE,                                   1, 0, "s1", "s1",                                               "",                                             _("^BG%s^F3 is now spectating\n"), "") \
263         MSG_INFO_NOTIF(1, INFO_RACE_FAIL,                                               2, 0, "s1 s2", "s1",                                    "race_newfail",                 "TODO\n", "") \
264         MSG_INFO_NOTIF(1, INFO_RACE_NEW_RECORD,                                 2, 0, "s1 s2", "s1",                                    "race_newrecordserver", "TODO\n", "") \
265         MSG_INFO_NOTIF(1, INFO_RACE_NEW_TIME,                                   2, 0, "s1 s2", "s1",                                    "race_newtime",                 "TODO\n", "") \
266         MSG_INFO_NOTIF(1, INFO_RACE_NEW_RANK,                                   2, 0, "s1 s2", "s1",                                    "race_newrankyellow",   "TODO\n", "") \
267         MULTITEAM_INFO(1, INFO_SCORES_, 4,                                              0, 0, "", "",                                                   "",                                             _("^TC^TT ^BGteam scores!\n"), "") \
268         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"), "") \
269         MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_BROKEN,                              0, 0, "", "",                                                   "",                                             _("^F2Superweapons have broken down\n"), "") \
270         MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP,                              0, 0, "", "",                                                   "",                                             _("^F2You now have a superweapon\n"), "") \
271         MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_LOST,                                0, 0, "", "",                                                   "",                                             _("^F2Superweapons have been lost\n"), "") \
272         MSG_INFO_NOTIF(1, INFO_VERSION_BETA,                                    2, 0, "s1 s2", "",                                              "",                                             _("\{1}^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s\n"), "") \
273         MSG_INFO_NOTIF(1, INFO_VERSION_OLD,                                             2, 0, "s1 s2", "",                                              "",                                             _("\{1}^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s\n"), "") \
274         MSG_INFO_NOTIF(1, INFO_VERSION_OUTDATED,                                2, 0, "s1 s2", "",                                              "",                                             _("\{1}^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get the update from ^F3http://www.xonotic.org/^BG!\n"), "") \
275         MSG_INFO_NOTIF(1, INFO_WATERMARK,                                               1, 0, "s1", "",                                                 "",                                             _("^F3SVQC Build information: ^F4%s\n"), "") \
276         MSG_INFO_NOTIF(1, INFO_WEAPON_THINKING_WITH_PORTALS,                    1, 1, "s1 spree_end", "s1",             "notify_selfkill",                      _("^BG%s^K1 is now thinking with portals%s\n"), "") \
277         MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_SUICIDE,                                  1, 1, "s1 spree_end", "s1",             "weaponcrylink",                        _("^BG%s^K1 felt the strong pull of their Crylink%s\n"), "") \
278         MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_MURDER,                                   2, 1, "s1 s2 spree_end", "s2 s1",       "weaponcrylink",                        _("^BG%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s\n"), "") \
279         MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_SUICIDE_ORBS,                     1, 1, "s1 spree_end", "s1",             "weaponelectro",                        _("^BG%s^K1 could not remember where they put their Electro plasma%s\n"), "") \
280         MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_SUICIDE_BOLT,                     1, 1, "s1 spree_end", "s1",             "weaponelectro",                        _("^BG%s^K1 played with Electro plasma%s\n"), "") \
281         MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_BOLT,                              2, 1, "s1 s2 spree_end", "s2 s1",       "weaponelectro",                        _("^BG%s^K1 was blasted by ^BG%s^K1's Electro bolt%s\n"), "") \
282         MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_ORBS,                              2, 1, "s1 s2 spree_end", "s2 s1",       "weaponelectro",                        _("^BG%s^K1 got too close to ^BG%s^K1's Electro plasma%s\n"), "") \
283         MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_COMBO,                     2, 1, "s1 s2 spree_end", "s2 s1",       "weaponelectro",                        _("^BG%s^K1 felt the electrifying air of ^BG%s^K1's Electro combo%s\n"), "") \
284         MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE,                1, 1, "s1 spree_end", "s1",             "weaponfireball",                       _("^BG%s^K1 forgot about their firemine%s\n"), "") \
285         MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_SUICIDE_BLAST,                   1, 1, "s1 spree_end", "s1",             "weaponfireball",                       _("^BG%s^K1 should have used a smaller gun%s\n"), "") \
286         MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_MURDER_FIREMINE,                 2, 1, "s1 s2 spree_end", "s2 s1",       "weaponfireball",                       _("^BG%s^K1 got burnt by ^BG%s^K1's firemine%s\n"), "") \
287         MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_MURDER_BLAST,                    2, 1, "s1 s2 spree_end", "s2 s1",       "weaponfireball",                       _("^BG%s^K1 got too close to ^BG%s^K1's fireball%s\n"), "") \
288         MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_SUICIDE_EXPLODE,                   1, 1, "s1 spree_end", "s1",             "weapongrenadelauncher",        _("^BG%s^K1 blew themself up with their own Mortar%s\n"), "") \
289         MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_SUICIDE_BOUNCE,                    1, 1, "s1 spree_end", "s1",             "weapongrenadelauncher",        _("^BG%s^K1 didn't see their own Mortar grenade%s\n"), "") \
290         MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_MURDER_EXPLODE,                    2, 1, "s1 s2 spree_end", "s2 s1",       "weapongrenadelauncher",        _("^BG%s^K1 ate ^BG%s^K1's Mortar grenade%s\n"), "") \
291         MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_MURDER_BOUNCE,                     2, 1, "s1 s2 spree_end", "s2 s1",       "weapongrenadelauncher",        _("^BG%s^K1 got too close to ^BG%s^K1's Mortar grenade%s\n"), "") \
292         MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_SUICIDE,                                    1, 1, "s1 spree_end", "s1",             "weaponhagar",                          _("^BG%s^K1 played with tiny Hagar rockets%s\n"), "") \
293         MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_MURDER_BURST,                               2, 1, "s1 s2 spree_end", "s2 s1",       "weaponhagar",                          _("^BG%s^K1 was pummeled by a burst of ^BG%s^K1's Hagar rockets%s\n"), "") \
294         MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_MURDER_SPRAY,                               2, 1, "s1 s2 spree_end", "s2 s1",       "weaponhagar",                          _("^BG%s^K1 was pummeled by ^BG%s^K1's Hagar rockets%s\n"), "") \
295         MSG_INFO_NOTIF(1, INFO_WEAPON_HLAC_SUICIDE,                                     1, 1, "s1 spree_end", "s1",             "weaponhlac",                           _("^BG%s^K1 got a little jumpy with their HLAC%s\n"), "") \
296         MSG_INFO_NOTIF(1, INFO_WEAPON_HLAC_MURDER,                                              2, 1, "s1 s2 spree_end", "s2 s1",       "weaponhlac",                           _("^BG%s^K1 was cut down with ^BG%s^K1's HLAC%s\n"), "") \
297         MSG_INFO_NOTIF(1, INFO_WEAPON_HOOK_MURDER,                                              2, 1, "s1 s2 spree_end", "s2 s1",       "weaponhook",                           _("^BG%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s\n"), "") \
298         MSG_INFO_NOTIF(1, INFO_WEAPON_LASER_SUICIDE,                                    1, 1, "s1 spree_end", "s1",             "weaponlaser",                          _("^BG%s^K1 shot themself to hell with their Laser%s\n"), "") \
299         MSG_INFO_NOTIF(1, INFO_WEAPON_LASER_MURDER,                                     2, 1, "s1 s2 spree_end", "s2 s1",       "weaponlaser",                          _("^BG%s^K1 was shot to death by ^BG%s^K1's Laser%s\n"), "") \
300         MSG_INFO_NOTIF(1, INFO_WEAPON_MINELAYER_SUICIDE,                                1, 1, "s1 spree_end", "s1",             "weaponminelayer",                      _("^BG%s^K1 forgot about their mine%s\n"), "") \
301         MSG_INFO_NOTIF(1, INFO_WEAPON_MINELAYER_MURDER,                                 2, 1, "s1 s2 spree_end", "s2 s1",       "weaponminelayer",                      _("^BG%s^K1 got too close to ^BG%s^K1's mine%s\n"), "") \
302         MSG_INFO_NOTIF(1, INFO_WEAPON_MINSTANEX_MURDER,                                 2, 1, "s1 s2 spree_end", "s2 s1",       "weaponminstanex",                      _("^BG%s^K1 has been vaporized by ^BG%s^K1's Minstanex%s\n"), "") \
303         MSG_INFO_NOTIF(1, INFO_WEAPON_NEX_MURDER,                                               2, 1, "s1 s2 spree_end", "s2 s1",       "weaponnex",                            _("^BG%s^K1 has been vaporized by ^BG%s^K1's Nex%s\n"), "") \
304         MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING,               2, 1, "s1 s2 spree_end", "s2 s1",       "weaponrifle",                          _("^BG%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s\n"), "") \
305         MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL,                                2, 1, "s1 s2 spree_end", "s2 s1",       "weaponrifle",                          _("^BG%s^K1 died in ^BG%s^K1's Rifle bullet hail%s\n"), "") \
306         MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_PIERCING,                    2, 1, "s1 s2 spree_end", "s2 s1",       "weaponrifle",                          _("^BG%s^K1 failed to hide from ^BG%s^K1's Rifle%s\n"), "") \
307         MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER,                                     2, 1, "s1 s2 spree_end", "s2 s1",       "weaponrifle",                          _("^BG%s^K1 was sniped with a Rifle by ^BG%s^K1%s\n"), "") \
308         MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HEADSHOT,                    2, 1, "s1 s2 spree_end", "s2 s1",       "notify_headshot",                      _("^BG%s^K1 was shot in the head with a Rifle by ^BG%s^K1%s\n"), "") \
309         MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_SUICIDE,                   1, 1, "s1 spree_end", "s1",             "weaponrocketlauncher",         _("^BG%s^K1 blew themself up with their Rocketlauncher%s\n"), "") \
310         MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,     2, 1, "s1 s2 spree_end", "s2 s1",       "weaponrocketlauncher",         _("^BG%s^K1 ate ^BG%s^K1's rocket%s\n"), "") \
311         MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,     2, 1, "s1 s2 spree_end", "s2 s1",       "weaponrocketlauncher",         _("^BG%s^K1 got too close ^BG%s^K1's rocket%s\n"), "") \
312         MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_SUICIDE,                                   1, 1, "s1 spree_end", "s1",             "weaponseeker",                         _("^BG%s^K1 played with tiny Seeker rockets%s\n"), "") \
313         MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_MURDER_TAG,                                2, 1, "s1 s2 spree_end", "s2 s1",       "weaponseeker",                         _("^BG%s^K1 was tagged by ^BG%s^K1's Seeker%s\n"), "") \
314         MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_MURDER_SPRAY,                              2, 1, "s1 s2 spree_end", "s2 s1",       "weaponseeker",                         _("^BG%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s\n"), "") \
315         MSG_INFO_NOTIF(1, INFO_WEAPON_SHOTGUN_MURDER_SLAP,                              2, 1, "s2 s1 spree_end", "s2 s1",       "notify_melee_shotgun",         _("^BG%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s\n"), "") \
316         MSG_INFO_NOTIF(1, INFO_WEAPON_SHOTGUN_MURDER,                                   2, 1, "s1 s2 spree_end", "s2 s1",       "weaponshotgun",                        _("^BG%s^K1 was gunned down by ^BG%s^K1's Shotgun%s\n"), "") \
317         MSG_INFO_NOTIF(1, INFO_WEAPON_TUBA_SUICIDE,                                     1, 1, "s1 spree_end", "s1",             "weapontuba",                           _("^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s\n"), "") \
318         MSG_INFO_NOTIF(1, INFO_WEAPON_TUBA_MURDER,                                              2, 1, "s1 s2 spree_end", "s2 s1",       "weapontuba",                           _("^BG%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s\n"), "") \
319         MSG_INFO_NOTIF(1, INFO_WEAPON_ACCORDEON_SUICIDE,                                1, 1, "s1 spree_end", "s1",             "weapontuba",                           _("^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s\n"), "") \
320         MSG_INFO_NOTIF(1, INFO_WEAPON_ACCORDEON_MURDER,                                 2, 1, "s1 s2 spree_end", "s2 s1",       "weapontuba",                           _("^BG%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Accordeon%s\n"), "") \
321         MSG_INFO_NOTIF(1, INFO_WEAPON_KLEINBOTTLE_SUICIDE,                              1, 1, "s1 spree_end", "s1",             "weapontuba",                           _("^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s\n"), "") \
322         MSG_INFO_NOTIF(1, INFO_WEAPON_KLEINBOTTLE_MURDER,                               2, 1, "s1 s2 spree_end", "s2 s1",       "weapontuba",                           _("^BG%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s\n"), "") \
323         MSG_INFO_NOTIF(1, INFO_WEAPON_UZI_MURDER_SNIPE,                                 2, 1, "s1 s2 spree_end", "s2 s1",       "weaponuzi",                            _("^BG%s^K1 was sniped by ^BG%s^K1's Machine Gun%s\n"), "") \
324         MSG_INFO_NOTIF(1, INFO_WEAPON_UZI_MURDER_SPRAY,                                 2, 1, "s1 s2 spree_end", "s2 s1",       "weaponuzi",                            _("^BG%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s\n"), "") 
325
326 #define MULTITEAM_CENTER(default,prefix,teams,strnum,flnum,args,cpid,durcnt,normal,gentle) \
327         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))) \
328         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))) \
329         #if teams >= 3 \
330                 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))) \
331         #endif \
332         #if teams >= 4 \
333                 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))) \
334         #endif
335 #define MSG_CENTER_NOTIFICATIONS \
336         /*MSG_CENTER_NOTIF(CENTER_EMPTY,                                                0, 0, "",                               NO_CPID,                                XPD(0, 0), "null", "")*/ \
337         MSG_CENTER_NOTIF(1, CENTER_ASSAULT_ATTACKING,                           0, 0, "",                               CPID_ASSAULT_ROLE,              XPD(0, 0), _("^BGYou are attacking!"), "") \
338         MSG_CENTER_NOTIF(1, CENTER_ASSAULT_DEFENDING,                           0, 0, "",                               CPID_ASSAULT_ROLE,              XPD(0, 0), _("^BGYou are defending!"), "") \
339         MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_SHIELDED,          0, 0, "",                               CPID_CTF_CAPSHIELD,             XPD(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."), "") \
340         MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_FREE,                      0, 0, "",                               CPID_CTF_CAPSHIELD,             XPD(0, 0), _("^BGYou are now free.\n^BGFeel free to ^F2try to capture^BG the flag again\n^BGif you think you will succeed."), "") \
341         MULTITEAM_CENTER(1, CENTER_CTF_PASS_OTHER_, 2,                          2, 0, "s1 s2",                  CPID_CTF_PASS,                  XPD(0, 0), _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") \
342         MULTITEAM_CENTER(1, CENTER_CTF_PASS_SENT_, 2,                           1, 0, "s1",                     CPID_CTF_PASS,                  XPD(0, 0), _("^BGYou passed the ^TC^TT^BG flag to %s"), "") \
343         MULTITEAM_CENTER(1, CENTER_CTF_PASS_RECEIVED_, 2,                       1, 0, "s1",                     CPID_CTF_PASS,                  XPD(0, 0), _("^BGYou received the ^TC^TT^BG flag from %s"), "") \
344         MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_REQUESTING,                         1, 0, "s1",                             CPID_CTF_PASS,                  XPD(0, 0), _("^BGRequesting %s^BG to pass you the flag"), "") \
345         MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_REQUESTED,                          1, 0, "s1 pass_key",    CPID_CTF_PASS,                  XPD(0, 0), _("^BG%s^BG requests you to pass the flag%s"), "") \
346         MULTITEAM_CENTER(1, CENTER_CTF_RETURN_, 2,                                      0, 0, "",                               CPID_CTF_LOWPRIO,               XPD(0, 0), _("^BGYou returned the ^TC^TT^BG flag!"), "") \
347         MULTITEAM_CENTER(1, CENTER_CTF_CAPTURE_, 2,                                     0, 0, "",                               CPID_CTF_LOWPRIO,               XPD(0, 0), _("^BGYou captured the ^TC^TT^BG flag!"), "") \
348         MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_, 2,                                      0, 0, "",                               CPID_CTF_LOWPRIO,               XPD(0, 0), _("^BGYou got the ^TC^TT^BG flag!"), "") \
349         MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM,                                     1, 0, "s1",                             CPID_CTF_LOWPRIO,               XPD(0, 0), _("^BGYour %steam mate^BG got the flag! Protect them!"), "") \
350         MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_VERBOSE,                     2, 0, "s1 s2 s1",               CPID_CTF_LOWPRIO,               XPD(0, 0), _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "") \
351         MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY,                            1, 0, "s1",                             CPID_CTF_LOWPRIO,               XPD(0, 0), _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") \
352         MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_VERBOSE,            2, 0, "s1 s2 s1",               CPID_CTF_LOWPRIO,               XPD(0, 0), _("^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"), "") \
353         MSG_CENTER_NOTIF(1, CENTER_CTF_STALEMATE_CARRIER,                       0, 0, "",                               CPID_STALEMATE,                 XPD(0, 0), _("^BGStalemate! Enemies can now see you on radar!"), "") \
354         MSG_CENTER_NOTIF(1, CENTER_CTF_STALEMATE_OTHER,                         0, 0, "",                               CPID_STALEMATE,                 XPD(0, 0), _("^BGStalemate! Flag carriers can now be seen by enemies on radar!"), "") \
355         MSG_CENTER_NOTIF(1, CENTER_CTF_FLAG_THROW_PUNISH,                       0, 1, "f1",                             CPID_CTF_LOWPRIO,               XPD(0, 0), _("^BGToo many flag throws! Throwing disabled for %s seconds."), "") \
356         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CUSTOM,                           2, 0, "s2",                             NO_CPID,                                XPD(0, 0), _("^K1You were %s"), "") \
357         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_GENERIC,                          0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You killed your own dumb self!"), _("^K1You need to be more careful!")) \
358         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VOID,                                     0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1Watch your step!"), "") \
359         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SUICIDE,                          0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You committed suicide!"), _("^K1You ended it all!")) \
360         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NOAMMO,                           0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You were killed for running out of ammo..."), _("^K1You are respawning for running out of ammo...")) \
361         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_ROT,                                      0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You grew too old without taking your medicine"), _("^K1You need to preserve your health")) \
362         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CAMP,                                     0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1Die camper!"), _("^K1Reconsider your tactics, camper!")) \
363         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_BETRAYAL,                         0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1Don't shoot your team mates!"), _("^K1Don't go against your team mates!")) \
364         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TEAMCHANGE,                       0, 1, "death_team",             NO_CPID,                                XPD(0, 0), _("^BGYou are now on: %s"), "") \
365         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_AUTOTEAMCHANGE,           0, 1, "death_team",             NO_CPID,                                XPD(0, 0), _("^BGYou have been moved into a different team\nYou are now on: %s"), "") \
366         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_FALL,                                     0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You hit the ground with a crunch!"), "") \
367         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_DROWN,                            0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You couldn't catch your breath in time!"), "") \
368         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_FIRE,                                     0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You got a little bit too crispy!"), _("^K1You felt a little too hot!")) \
369         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_LAVA,                                     0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You couldn't stand the heat!"), "") \
370         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SLIME,                            0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You melted away in slime!"), "") \
371         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SHOOTING_STAR,            0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You became a shooting star!"), "") \
372         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SWAMP,                            0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You got stuck in a swamp!"), "") \
373         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CHEAT,                            0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You unfairly eliminated yourself!"), "") \
374         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TOUCHEXPLODE,                     0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You died in an accident!"), "") \
375         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TURRET,                           0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You were fragged by a turret!"), _("^K1You had an unfortunate run in with a turret!")) \
376         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TURRET_EWHEEL,            0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You were fragged by an eWheel turret!"), _("^K1You had an unfortunate run in with an eWheel turret!")) \
377         MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TURRET_WALKER,            0, 0, "",                               NO_CPID,                                XPD(0, 0), _("^K1You were fragged by a Walker turret!"), _("^K1You had an unfortunate run in with a Walker turret!")) \
378         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAG,                                           1, 1, "spree_cen s1",                           NO_CPID, XPD(0, 0), _("^K3%sYou fragged ^BG%s"), _("^K3%sYou scored against ^BG%s")) \
379         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAGGED,                                        1, 0, "s1",                                                     NO_CPID, XPD(0, 0), _("^K1You were fragged by ^BG%s"), _("^K1You were scored against by ^BG%s")) \
380         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAG,                                       1, 1, "spree_cen s1",                           NO_CPID, XPD(0, 0), _("^K1%sYou typefragged ^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing")) \
381         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAGGED,                            1, 0, "s1",                                                     NO_CPID, XPD(0, 0), _("^K1You were typefragged by ^BG%s"), _("^K1You were scored against by ^BG%s^K1 while typing!")) \
382         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAG_FIRST,                                     1, 0, "s1",                                                     NO_CPID, XPD(0, 0), _("^K3First blood! You fragged ^BG%s"), _("^K3First score! You scored against ^BG%s")) \
383         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAGGED_FIRST,                          1, 0, "s1",                                                     NO_CPID, XPD(0, 0), _("^K1First victim! You were fragged by ^BG%s"), _("^K1First casualty! You were scored against by ^BG%s")) \
384         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAG_FIRST,                         1, 0, "s1",                                                     NO_CPID, XPD(0, 0), _("^K1First blood! You typefragged ^BG%s"), _("^K1First score! You scored against ^BG%s^K1 while they were typing")) \
385         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAGGED_FIRST,                      1, 0, "s1",                                                     NO_CPID, XPD(0, 0), _("^K1First victim! You were typefragged by ^BG%s"), _("^K1First casualty! You were scored against by ^BG%s^K1 while typing!")) \
386         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAG_VERBOSE,                           1, 2, "spree_cen s1 frag_ping",         NO_CPID, XPD(0, 0), _("^K3%sYou fragged ^BG%s^BG%s"), _("^K3%sYou scored against ^BG%s^BG%s")) \
387         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAGGED_VERBOSE,                        1, 3, "s1 frag_stats",                          NO_CPID, XPD(0, 0), _("^K1You were fragged by ^BG%s^BG%s"), _("^K1You were scored against by ^BG%s^BG%s")) \
388         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE,                       1, 2, "spree_cen s1 frag_ping",         NO_CPID, XPD(0, 0), _("^K1%sYou typefragged ^BG%s^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing^BG%s")) \
389         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE,            1, 3, "s1 frag_stats",                          NO_CPID, XPD(0, 0), _("^K1You were typefragged by ^BG%s^BG%s"), _("^K1You were scored against by ^BG%s^K1 while typing^BG%s")) \
390         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAG_FIRST_VERBOSE,                     1, 1, "s1",                                                     NO_CPID, XPD(0, 0), _("^K3First blood! You fragged ^BG%s"), _("^K3First score! You scored against ^BG%s")) \
391         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAGGED_FIRST_VERBOSE,          1, 3, "s1",                                                     NO_CPID, XPD(0, 0), _("^K1First victim! You were fragged by ^BG%s"), _("^K1First casualty! You were scored against by ^BG%s")) \
392         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAG_FIRST_VERBOSE,         1, 1, "s1",                                                     NO_CPID, XPD(0, 0), _("^K1First blood! You typefragged ^BG%s"), _("^K1First score! You scored against ^BG%s^K1 while they were typing")) \
393         MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAGGED_FIRST_VERBOSE,      1, 3, "s1",                                                     NO_CPID, XPD(0, 0), _("^K1First victim! You were typefragged by ^BG%s"), _("^K1First casualty! You were scored against by ^BG%s^K1 while typing!")) \
394         MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAG,                                         1, 0, "s1",                                                     NO_CPID, XPD(0, 0), _("^K1Moron! You fragged ^BG%s^K1, a team mate!"), _("^K1Moron! You went against ^BG%s^K1, a team mate!")) \
395         MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAGGED,                                      1, 0, "s1",                                                     NO_CPID, XPD(0, 0), _("^K1You were fragged by ^BG%s^K1, a team mate"), _("^K1You were scored against by ^BG%s^K1, a team mate")) \
396         MSG_CENTER_NOTIF(1, CENTER_DISCONNECT_IDLING,                           0, 1, "",                                       CPID_IDLING,                    XPD(0, f1), _("^K1Stop idling!\n^BGDisconnecting in ^COUNT..."), "") \
397         MULTITEAM_CENTER(1, CENTER_FREEZETAG_ROUND_WIN_, 4,                     0, 0, "",                                       NO_CPID,                                XPD(0, 0), _("^TC^TT^BG team wins the round, all other teams were frozen"), "") \
398         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SPAWN_LATE,                        0, 0, "",                                       NO_CPID,                                XPD(0, 0), _("^K1You spawned after the round started, you'll spawn as frozen"), "") \
399         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE,                            1, 0, "s1",                                     NO_CPID,                                XPD(0, 0), _("^K3You revived ^BG%s"), "") \
400         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVED,                           1, 0, "s1",                                     NO_CPID,                                XPD(0, 0), _("^K3You were revived by ^BG%s"), "") \
401         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SELF,                                      0, 0, "",                                       NO_CPID,                                XPD(0, 0), _("^K1You froze yourself"), "") \
402         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FREEZE,                            1, 0, "s1",                                     NO_CPID,                                XPD(0, 0), _("^K3You froze ^BG%s"), "") \
403         MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FROZEN,                            1, 0, "s1",                                     NO_CPID,                                XPD(0, 0), _("^K1You were frozen by ^BG%s"), "") \
404         MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_DROPPED,                            1, 0, "s1",                             CPID_KEEPAWAY,                  XPD(0, 0), _("^BG%s^BG has dropped the ball!"), "") \
405         MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_PICKUP,                                     1, 0, "s1",                             CPID_KEEPAWAY,                  XPD(0, 0), _("^BG%s^BG has picked up the ball!"), "") \
406         MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_WARN,                                       0, 0, "",                                       CPID_KA_WARN,                   XPD(0, 0), _("^BGKilling people while you don't have the ball gives no points!"), "") \
407         MSG_CENTER_NOTIF(1, CENTER_LMS_CAMPCHECK,                                       0, 0, "",                                       CPID_LMS_CAMP,                  XPD(0, 0), _("^K1Don't camp!"), "") \
408         MSG_CENTER_NOTIF(1, CENTER_JOIN_NOSPAWNS,                                       0, 0, "",                                       CPID_PREVENT_JOIN,              XPD(0, 0), _("^K1No spawnpoints available!\nHope your team can fix it..."), "") \
409         MSG_CENTER_NOTIF(1, CENTER_JOIN_PREVENT,                                        0, 0, "",                                       CPID_PREVENT_JOIN,              XPD(0, 0), _("^K1You may not join the game at this time.\nThe player limit reached maximum capacity."), "") \
410         MSG_CENTER_NOTIF(1, CENTER_OVERTIME_TIME,                                       0, 1, "f1",                                     CPID_OVERTIME,                  XPD(0, 0), _("^F2Now playing ^F4OVERTIME^F2!\nAdded ^F4%s ^F2minute(s) to the game!"), "") \
411         MSG_CENTER_NOTIF(1, CENTER_OVERTIME_FRAG,                                       0, 0, "",                                       CPID_OVERTIME,                  XPD(0, 0), _("^F2Now playing ^F4OVERTIME^F2!\nKeep fragging until we have a winner!"), _("^F2Now playing ^F4OVERTIME^F2!\nKeep scoring until we have a winner!")) \
412         MSG_CENTER_NOTIF(1, CENTER_RACE_FINISHLAP,                                      0, 0, "",                                       CPID_RACE_FINISHLAP,    XPD(0, 0), _("^F2The race is over, finish your lap!"), "") \
413         MULTITEAM_CENTER(1, CENTER_TEAMCHANGE_, 4,                                      0, 1, "",                                       CPID_TEAMCHANGE,                XPD(0, f1), _("^BGChanging to ^TC^TT^BG in ^COUNT"), "") \
414         MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SPECTATE,                         0, 1, "",                                       CPID_TEAMCHANGE,                XPD(0, f1), _("^BGSpectating in ^COUNT"), "") \
415         MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_AUTO,                                     0, 1, "",                                       CPID_TEAMCHANGE,                XPD(0, f1), _("^BGChanging team in ^COUNT"), "") \
416         MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SUICIDE,                          0, 1, "",                                       CPID_TEAMCHANGE,                XPD(0, f1), _("^K1Suicide in ^COUNT"), "") \
417         MSG_CENTER_NOTIF(1, CENTER_WEAPON_MARBLES_LOST,                         1, 1, "s1 weapon_name",         NO_CPID,                                XPD(0, 0), _("^K1You lost your marbles against ^BG%s^K1 using the ^BG%s!"), "")
418
419 #define MSG_WEAPON_NOTIFICATIONS \
420         /*MSG_WEAPON_NOTIF(WEAPON_EMPTY,                                                NO_MSG,                                                                         NO_MSG)*/ \
421         MSG_WEAPON_NOTIF(1, WEAPON_THINKING_WITH_PORTALS,                       INFO_WEAPON_THINKING_WITH_PORTALS,                      CENTER_DEATH_SELF_GENERIC) \
422         MSG_WEAPON_NOTIF(1, WEAPON_CRYLINK_SUICIDE,                             INFO_WEAPON_CRYLINK_SUICIDE,                            CENTER_DEATH_SELF_GENERIC) \
423         MSG_WEAPON_NOTIF(1, WEAPON_CRYLINK_MURDER,                                      INFO_WEAPON_CRYLINK_MURDER,                             NO_MSG) \
424         MSG_WEAPON_NOTIF(1, WEAPON_ELECTRO_SUICIDE_ORBS,                        INFO_WEAPON_ELECTRO_SUICIDE_ORBS,                       CENTER_DEATH_SELF_GENERIC) \
425         MSG_WEAPON_NOTIF(1, WEAPON_ELECTRO_SUICIDE_BOLT,                        INFO_WEAPON_ELECTRO_SUICIDE_BOLT,                       CENTER_DEATH_SELF_GENERIC) \
426         MSG_WEAPON_NOTIF(1, WEAPON_ELECTRO_MURDER_BOLT,                         INFO_WEAPON_ELECTRO_MURDER_BOLT,                        NO_MSG) \
427         MSG_WEAPON_NOTIF(1, WEAPON_ELECTRO_MURDER_ORBS,                         INFO_WEAPON_ELECTRO_MURDER_ORBS,                        NO_MSG) \
428         MSG_WEAPON_NOTIF(1, WEAPON_ELECTRO_MURDER_COMBO,                        INFO_WEAPON_ELECTRO_MURDER_COMBO,                       NO_MSG) \
429         MSG_WEAPON_NOTIF(1, WEAPON_FIREBALL_SUICIDE_FIREMINE,           INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE,          CENTER_DEATH_SELF_GENERIC) \
430         MSG_WEAPON_NOTIF(1, WEAPON_FIREBALL_SUICIDE_BLAST,                      INFO_WEAPON_FIREBALL_SUICIDE_BLAST,             CENTER_DEATH_SELF_GENERIC) \
431         MSG_WEAPON_NOTIF(1, WEAPON_FIREBALL_MURDER_FIREMINE,            INFO_WEAPON_FIREBALL_MURDER_FIREMINE,           NO_MSG) \
432         MSG_WEAPON_NOTIF(1, WEAPON_FIREBALL_MURDER_BLAST,                       INFO_WEAPON_FIREBALL_MURDER_BLAST,                      NO_MSG) \
433         MSG_WEAPON_NOTIF(1, WEAPON_MORTAR_SUICIDE_EXPLODE,                      INFO_WEAPON_MORTAR_SUICIDE_EXPLODE,             CENTER_DEATH_SELF_GENERIC) \
434         MSG_WEAPON_NOTIF(1, WEAPON_MORTAR_SUICIDE_BOUNCE,                       INFO_WEAPON_MORTAR_SUICIDE_BOUNCE,                      CENTER_DEATH_SELF_GENERIC) \
435         MSG_WEAPON_NOTIF(1, WEAPON_MORTAR_MURDER_EXPLODE,                       INFO_WEAPON_MORTAR_MURDER_EXPLODE,                      NO_MSG) \
436         MSG_WEAPON_NOTIF(1, WEAPON_MORTAR_MURDER_BOUNCE,                        INFO_WEAPON_MORTAR_MURDER_BOUNCE,                       NO_MSG) \
437         MSG_WEAPON_NOTIF(1, WEAPON_HAGAR_SUICIDE,                                       INFO_WEAPON_HAGAR_SUICIDE,                                      CENTER_DEATH_SELF_GENERIC) \
438         MSG_WEAPON_NOTIF(1, WEAPON_HAGAR_MURDER_BURST,                          INFO_WEAPON_HAGAR_MURDER_BURST,                         NO_MSG) \
439         MSG_WEAPON_NOTIF(1, WEAPON_HAGAR_MURDER_SPRAY,                          INFO_WEAPON_HAGAR_MURDER_SPRAY,                         NO_MSG) \
440         MSG_WEAPON_NOTIF(1, WEAPON_HLAC_SUICIDE,                                        INFO_WEAPON_HLAC_SUICIDE,                                       CENTER_DEATH_SELF_GENERIC) \
441         MSG_WEAPON_NOTIF(1, WEAPON_HLAC_MURDER,                                         INFO_WEAPON_HLAC_MURDER,                                        NO_MSG) \
442         MSG_WEAPON_NOTIF(1, WEAPON_HOOK_MURDER,                                         INFO_WEAPON_HOOK_MURDER,                                        NO_MSG) \
443         MSG_WEAPON_NOTIF(1, WEAPON_LASER_SUICIDE,                                       INFO_WEAPON_LASER_SUICIDE,                                      CENTER_DEATH_SELF_GENERIC) \
444         MSG_WEAPON_NOTIF(1, WEAPON_LASER_MURDER,                                        INFO_WEAPON_LASER_MURDER,                                       NO_MSG) \
445         MSG_WEAPON_NOTIF(1, WEAPON_MINELAYER_SUICIDE,                           INFO_WEAPON_MINELAYER_SUICIDE,                          CENTER_DEATH_SELF_GENERIC) \
446         MSG_WEAPON_NOTIF(1, WEAPON_MINELAYER_MURDER,                            INFO_WEAPON_MINELAYER_MURDER,                           NO_MSG) \
447         MSG_WEAPON_NOTIF(1, WEAPON_MINSTANEX_MURDER,                            INFO_WEAPON_MINSTANEX_MURDER,                           NO_MSG) \
448         MSG_WEAPON_NOTIF(1, WEAPON_NEX_MURDER,                                          INFO_WEAPON_NEX_MURDER,                                         NO_MSG) \
449         MSG_WEAPON_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL_PIERCING,          INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING,         NO_MSG) \
450         MSG_WEAPON_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL,                           INFO_WEAPON_RIFLE_MURDER_HAIL,                          NO_MSG) \
451         MSG_WEAPON_NOTIF(1, WEAPON_RIFLE_MURDER_PIERCING,                       INFO_WEAPON_RIFLE_MURDER_PIERCING,                      NO_MSG) \
452         MSG_WEAPON_NOTIF(1, WEAPON_RIFLE_MURDER,                                        INFO_WEAPON_RIFLE_MURDER,                                       NO_MSG) \
453         MSG_WEAPON_NOTIF(1, WEAPON_RIFLE_MURDER_HEADSHOT,                       INFO_WEAPON_RIFLE_MURDER_HEADSHOT,                      NO_MSG) \
454         MSG_WEAPON_NOTIF(1, WEAPON_ROCKETLAUNCHER_SUICIDE,                      INFO_WEAPON_ROCKETLAUNCHER_SUICIDE,             CENTER_DEATH_SELF_GENERIC) \
455         MSG_WEAPON_NOTIF(1, WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,        INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,       NO_MSG) \
456         MSG_WEAPON_NOTIF(1, WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,        INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,       NO_MSG) \
457         MSG_WEAPON_NOTIF(1, WEAPON_SEEKER_SUICIDE,                                      INFO_WEAPON_SEEKER_SUICIDE,                             CENTER_DEATH_SELF_GENERIC) \
458         MSG_WEAPON_NOTIF(1, WEAPON_SEEKER_MURDER_TAG,                           INFO_WEAPON_SEEKER_MURDER_TAG,                          NO_MSG) \
459         MSG_WEAPON_NOTIF(1, WEAPON_SEEKER_MURDER_SPRAY,                         INFO_WEAPON_SEEKER_MURDER_SPRAY,                        NO_MSG) \
460         MSG_WEAPON_NOTIF(1, WEAPON_SHOTGUN_MURDER_SLAP,                         INFO_WEAPON_SHOTGUN_MURDER_SLAP,                        NO_MSG) \
461         MSG_WEAPON_NOTIF(1, WEAPON_SHOTGUN_MURDER,                                      INFO_WEAPON_SHOTGUN_MURDER,                             NO_MSG) \
462         MSG_WEAPON_NOTIF(1, WEAPON_TUBA_SUICIDE,                                        INFO_WEAPON_TUBA_SUICIDE,                                       CENTER_DEATH_SELF_GENERIC) \
463         MSG_WEAPON_NOTIF(1, WEAPON_TUBA_MURDER,                                         INFO_WEAPON_TUBA_MURDER,                                        NO_MSG) \
464         MSG_WEAPON_NOTIF(1, WEAPON_ACCORDEON_SUICIDE,                           INFO_WEAPON_ACCORDEON_SUICIDE,                          CENTER_DEATH_SELF_GENERIC) \
465         MSG_WEAPON_NOTIF(1, WEAPON_ACCORDEON_MURDER,                            INFO_WEAPON_ACCORDEON_MURDER,                           NO_MSG) \
466         MSG_WEAPON_NOTIF(1, WEAPON_KLEINBOTTLE_SUICIDE,                         INFO_WEAPON_KLEINBOTTLE_SUICIDE,                        CENTER_DEATH_SELF_GENERIC) \
467         MSG_WEAPON_NOTIF(1, WEAPON_KLEINBOTTLE_MURDER,                          INFO_WEAPON_KLEINBOTTLE_MURDER,                         NO_MSG) \
468         MSG_WEAPON_NOTIF(1, WEAPON_UZI_MURDER_SNIPE,                            INFO_WEAPON_UZI_MURDER_SNIPE,                           NO_MSG) \
469         MSG_WEAPON_NOTIF(1, WEAPON_UZI_MURDER_SPRAY,                            INFO_WEAPON_UZI_MURDER_SPRAY,                           NO_MSG) 
470
471 #define MSG_DEATH_NOTIFICATIONS \
472         /*MSG_DEATH_NOTIF(DEATH_EMPTY,                                          NO_MSG,                                                                 NO_MSG)*/ \
473         MSG_DEATH_NOTIF(1, DEATH_SELF_CUSTOM,                                   INFO_DEATH_SELF_GENERIC,                                CENTER_DEATH_SELF_CUSTOM) \
474         MSG_DEATH_NOTIF(1, DEATH_SELF_GENERIC,                                  INFO_DEATH_SELF_GENERIC,                                CENTER_DEATH_SELF_GENERIC) \
475         MSG_DEATH_NOTIF(1, DEATH_SELF_VOID,                                             INFO_DEATH_SELF_VOID,                                   CENTER_DEATH_SELF_VOID) \
476         MSG_DEATH_NOTIF(1, DEATH_SELF_SUICIDE,                                  INFO_DEATH_SELF_SUICIDE,                                CENTER_DEATH_SELF_SUICIDE) \
477         MSG_DEATH_NOTIF(1, DEATH_SELF_NOAMMO,                                   INFO_DEATH_SELF_NOAMMO,                                 CENTER_DEATH_SELF_NOAMMO) \
478         MSG_DEATH_NOTIF(1, DEATH_SELF_ROT,                                              INFO_DEATH_SELF_ROT,                                    CENTER_DEATH_SELF_ROT) \
479         MSG_DEATH_NOTIF(1, DEATH_SELF_CAMP,                                             INFO_DEATH_SELF_CAMP,                                   CENTER_DEATH_SELF_CAMP) \
480         MSG_DEATH_NOTIF(1, DEATH_SELF_BETRAYAL,                                 INFO_DEATH_SELF_BETRAYAL,                               CENTER_DEATH_SELF_BETRAYAL) \
481         MSG_DEATH_NOTIF(1, DEATH_SELF_TEAMCHANGE,                               INFO_DEATH_SELF_TEAMCHANGE,                             CENTER_DEATH_SELF_TEAMCHANGE) \
482         MSG_DEATH_NOTIF(1, DEATH_SELF_AUTOTEAMCHANGE,                   INFO_DEATH_SELF_AUTOTEAMCHANGE,                 CENTER_DEATH_SELF_AUTOTEAMCHANGE) \
483         MSG_DEATH_NOTIF(1, DEATH_SELF_FALL,                                             INFO_DEATH_SELF_FALL,                                   CENTER_DEATH_SELF_FALL) \
484         MSG_DEATH_NOTIF(1, DEATH_SELF_DROWN,                                    INFO_DEATH_SELF_DROWN,                                  CENTER_DEATH_SELF_DROWN) \
485         MSG_DEATH_NOTIF(1, DEATH_SELF_FIRE,                                             INFO_DEATH_SELF_FIRE,                                   CENTER_DEATH_SELF_FIRE) \
486         MSG_DEATH_NOTIF(1, DEATH_SELF_LAVA,                                             INFO_DEATH_SELF_LAVA,                                   CENTER_DEATH_SELF_LAVA) \
487         MSG_DEATH_NOTIF(1, DEATH_SELF_SLIME,                                    INFO_DEATH_SELF_SLIME,                                  CENTER_DEATH_SELF_SLIME) \
488         MSG_DEATH_NOTIF(1, DEATH_SELF_SHOOTING_STAR,                    INFO_DEATH_SELF_SHOOTING_STAR,                  CENTER_DEATH_SELF_SHOOTING_STAR) \
489         MSG_DEATH_NOTIF(1, DEATH_SELF_SWAMP,                                    INFO_DEATH_SELF_SWAMP,                                  CENTER_DEATH_SELF_SWAMP) \
490         MSG_DEATH_NOTIF(1, DEATH_SELF_CHEAT,                                    INFO_DEATH_SELF_CHEAT,                                  CENTER_DEATH_SELF_CHEAT) \
491         MSG_DEATH_NOTIF(1, DEATH_SELF_TOUCHEXPLODE,                             INFO_DEATH_SELF_TOUCHEXPLODE,                   CENTER_DEATH_SELF_TOUCHEXPLODE) \
492         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET,                                   INFO_DEATH_SELF_TURRET,                                 CENTER_DEATH_SELF_TURRET) \
493         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_EWHEEL,                    INFO_DEATH_SELF_TURRET_EWHEEL,                  CENTER_DEATH_SELF_TURRET_EWHEEL) \
494         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_FLAC,                              INFO_DEATH_SELF_TURRET_FLAC,                    CENTER_DEATH_SELF_TURRET) \
495         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_MACHINEGUN,                INFO_DEATH_SELF_TURRET_MACHINEGUN,              CENTER_DEATH_SELF_TURRET) \
496         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_WALKER_GUN,                INFO_DEATH_SELF_TURRET_WALKER_GUN,              CENTER_DEATH_SELF_TURRET_WALKER) \
497         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_WALKER_MEELE,              INFO_DEATH_SELF_TURRET_WALKER_MEELE,    CENTER_DEATH_SELF_TURRET_WALKER) \
498         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_WALKER_ROCKET,             INFO_DEATH_SELF_TURRET_WALKER_ROCKET,   CENTER_DEATH_SELF_TURRET_WALKER) \
499         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_HELLION,                   INFO_DEATH_SELF_TURRET_HELLION,                 CENTER_DEATH_SELF_TURRET) \
500         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_HK,                                INFO_DEATH_SELF_TURRET_HK,                              CENTER_DEATH_SELF_TURRET) \
501         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_MLRS,                              INFO_DEATH_SELF_TURRET_MLRS,                    CENTER_DEATH_SELF_TURRET) \
502         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_PLASMA,                    INFO_DEATH_SELF_TURRET_PLASMA,                  CENTER_DEATH_SELF_TURRET) \
503         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_PHASER,                    INFO_DEATH_SELF_TURRET_PHASER,                  CENTER_DEATH_SELF_TURRET) \
504         MSG_DEATH_NOTIF(1, DEATH_SELF_TURRET_TESLA,                             INFO_DEATH_SELF_TURRET_TESLA,                   CENTER_DEATH_SELF_TURRET) \
505         MSG_DEATH_NOTIF(1, DEATH_MURDER_TELEFRAG,                               INFO_DEATH_MURDER_TELEFRAG,                             NO_MSG) \
506         MSG_DEATH_NOTIF(1, DEATH_MURDER_FALL,                                   INFO_DEATH_MURDER_FALL,                                 NO_MSG) \
507         MSG_DEATH_NOTIF(1, DEATH_MURDER_DROWN,                                  INFO_DEATH_MURDER_DROWN,                                NO_MSG) \
508         MSG_DEATH_NOTIF(1, DEATH_MURDER_LAVA,                                   INFO_DEATH_MURDER_LAVA,                                 NO_MSG) \
509         MSG_DEATH_NOTIF(1, DEATH_MURDER_SLIME,                                  INFO_DEATH_MURDER_SLIME,                                NO_MSG) \
510         MSG_DEATH_NOTIF(1, DEATH_MURDER_SHOOTING_STAR,                  INFO_DEATH_MURDER_SHOOTING_STAR,                NO_MSG) \
511         MSG_DEATH_NOTIF(1, DEATH_MURDER_SWAMP,                                  INFO_DEATH_MURDER_SWAMP,                                NO_MSG) \
512         MSG_DEATH_NOTIF(1, DEATH_MURDER_VOID,                                   INFO_DEATH_MURDER_VOID,                                 NO_MSG) \
513         MSG_DEATH_NOTIF(1, DEATH_MURDER_TOUCHEXPLODE,                   INFO_DEATH_MURDER_TOUCHEXPLODE,                 NO_MSG) \
514         MSG_DEATH_NOTIF(1, DEATH_MURDER_CHEAT,                                  INFO_DEATH_MURDER_CHEAT,                                NO_MSG) \
515         MSG_DEATH_NOTIF(1, DEATH_MURDER_FIRE,                                   INFO_DEATH_MURDER_FIRE,                                 NO_MSG) \
516         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_CRUSH,                               INFO_DEATH_MURDER_VH_CRUSH,                             NO_MSG) \
517         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_SPID_MINIGUN,                INFO_DEATH_MURDER_VH_SPID_MINIGUN,              NO_MSG) \
518         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_SPID_ROCKET,                 INFO_DEATH_MURDER_VH_SPID_ROCKET,               NO_MSG) \
519         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_SPID_DEATH,                  INFO_DEATH_MURDER_VH_SPID_DEATH,                NO_MSG) \
520         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_WAKI_GUN,                    INFO_DEATH_MURDER_VH_WAKI_GUN,                  NO_MSG) \
521         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_WAKI_ROCKET,                 INFO_DEATH_MURDER_VH_WAKI_ROCKET,               NO_MSG) \
522         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_WAKI_DEATH,                  INFO_DEATH_MURDER_VH_WAKI_DEATH,                NO_MSG) \
523         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_RAPT_CANNON,                 INFO_DEATH_MURDER_VH_RAPT_CANNON,               NO_MSG) \
524         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_RAPT_BOMB,                   INFO_DEATH_MURDER_VH_RAPT_BOMB,                 NO_MSG) \
525         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_RAPT_FRAGMENT,               INFO_DEATH_MURDER_VH_RAPT_FRAGMENT,             NO_MSG) \
526         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_RAPT_DEATH,                  INFO_DEATH_MURDER_VH_RAPT_DEATH,                NO_MSG) \
527         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_BUMB_GUN,                    INFO_DEATH_MURDER_VH_BUMB_GUN,                  NO_MSG) \
528         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_BUMB_RAY,                    INFO_DEATH_MURDER_VH_BUMB_RAY,                  NO_MSG) \
529         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_BUMB_RAY_HEAL,               INFO_DEATH_MURDER_VH_BUMB_RAY_HEAL,             NO_MSG) \
530         MSG_DEATH_NOTIF(1, DEATH_MURDER_VH_BUMB_DEATH,                  INFO_DEATH_MURDER_VH_BUMB_DEATH,                NO_MSG) \
531         MSG_DEATH_NOTIF(1, DEATH_MURDER_FRAG,                                                   NO_MSG,                                                 CENTER_DEATH_MURDER_FRAG) \
532         MSG_DEATH_NOTIF(1, DEATH_MURDER_FRAGGED,                                                NO_MSG,                                                 CENTER_DEATH_MURDER_FRAGGED) \
533         MSG_DEATH_NOTIF(1, DEATH_MURDER_TYPEFRAG,                                               NO_MSG,                                                 CENTER_DEATH_MURDER_TYPEFRAG) \
534         MSG_DEATH_NOTIF(1, DEATH_MURDER_TYPEFRAGGED,                                    NO_MSG,                                                 CENTER_DEATH_MURDER_TYPEFRAGGED) \
535         MSG_DEATH_NOTIF(1, DEATH_MURDER_FRAG_FIRST,                                             INFO_DEATH_FIRSTBLOOD,                  CENTER_DEATH_MURDER_FRAG_FIRST) \
536         MSG_DEATH_NOTIF(1, DEATH_MURDER_FRAGGED_FIRST,                                  NO_MSG,                                                 CENTER_DEATH_MURDER_FRAGGED_FIRST) \
537         MSG_DEATH_NOTIF(1, DEATH_MURDER_TYPEFRAG_FIRST,                                 INFO_DEATH_FIRSTBLOOD,                  CENTER_DEATH_MURDER_TYPEFRAG_FIRST) \
538         MSG_DEATH_NOTIF(1, DEATH_MURDER_TYPEFRAGGED_FIRST,                              NO_MSG,                                                 CENTER_DEATH_MURDER_TYPEFRAGGED_FIRST) \
539         MSG_DEATH_NOTIF(1, DEATH_MURDER_FRAG_VERBOSE,                                   NO_MSG,                                                 CENTER_DEATH_MURDER_FRAG_VERBOSE) \
540         MSG_DEATH_NOTIF(1, DEATH_MURDER_FRAGGED_VERBOSE,                                NO_MSG,                                                 CENTER_DEATH_MURDER_FRAGGED_VERBOSE) \
541         MSG_DEATH_NOTIF(1, DEATH_MURDER_TYPEFRAG_VERBOSE,                               NO_MSG,                                                 CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE) \
542         MSG_DEATH_NOTIF(1, DEATH_MURDER_TYPEFRAGGED_VERBOSE,                    NO_MSG,                                                 CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE) \
543         MSG_DEATH_NOTIF(1, DEATH_MURDER_FRAG_FIRST_VERBOSE,                             INFO_DEATH_FIRSTBLOOD,                  CENTER_DEATH_MURDER_FRAG_FIRST_VERBOSE) \
544         MSG_DEATH_NOTIF(1, DEATH_MURDER_FRAGGED_FIRST_VERBOSE,                  NO_MSG,                                                 CENTER_DEATH_MURDER_FRAGGED_FIRST_VERBOSE) \
545         MSG_DEATH_NOTIF(1, DEATH_MURDER_TYPEFRAG_FIRST_VERBOSE,                 INFO_DEATH_FIRSTBLOOD,                  CENTER_DEATH_MURDER_TYPEFRAG_FIRST_VERBOSE) \
546         MSG_DEATH_NOTIF(1, DEATH_MURDER_TYPEFRAGGED_FIRST_VERBOSE,              NO_MSG,                                                 CENTER_DEATH_MURDER_TYPEFRAGGED_FIRST_VERBOSE) \
547         MSG_DEATH_NOTIF(1, DEATH_TEAMKILL_FRAG,                                                 NO_MSG,                                                 CENTER_DEATH_TEAMKILL_FRAG) \
548         MSG_DEATH_NOTIF(1, DEATH_TEAMKILL_FRAGGED,                                              NO_MSG,                                                 CENTER_DEATH_TEAMKILL_FRAGGED)
549
550
551 // ====================================
552 //  Initialization/Create Declarations
553 // ====================================
554
555 #define ARG_DOUBLE 1
556 #define ARG_TRIPLE 2 // also included with hudargs
557 #define ARG_CSQC 3
558 #define ARG_SVQC 4
559
560 #define NOTIF_MAX_ARGS 7
561 #define NOTIF_MAX_HUDARGS 2
562
563 #define NOTIF_HIT_MAX(count,funcname) if(sel_num == count) { backtrace(sprintf("%s: Hit maximum arguments!\n", funcname)); break; }
564 #define NOTIF_HIT_UNKNOWN(token,funcname) default: { backtrace(sprintf("%s: Hit unknown token in selected string! '%s'\n", funcname, selected)); break; }
565
566 #define NOTIF_ARGUMENT_LIST \
567         ARG_CASE(ARG_TRIPLE, "s1",                              s1) \
568         ARG_CASE(ARG_TRIPLE, "s2",                              s2) \
569         ARG_CASE(ARG_TRIPLE, "s3",                              s3) \
570         ARG_CASE(ARG_TRIPLE, "s4",                              s4) \
571         ARG_CASE(ARG_DOUBLE, "f1",                              ftos(f1)) \
572         ARG_CASE(ARG_DOUBLE, "f2",                              ftos(f2)) \
573         ARG_CASE(ARG_DOUBLE, "f3",                              ftos(f3)) \
574         ARG_CASE(ARG_DOUBLE, "f4",                              ftos(f4)) \
575         ARG_CASE(ARG_DOUBLE, "f1p2dec",                         ftos_decimals(f1/100, 2)) \
576         ARG_CASE(ARG_DOUBLE, "f2p2dec",                         ftos_decimals(f2/100, 2)) \
577         ARG_CASE(ARG_CSQC, "pass_key",                  ((((tmp_s = getcommandkey("pass", "+use")) != "pass") && !(strstrofs(tmp_s, "not bound", 0) >= 0)) ? sprintf(CCR(_(" ^F1(Press %s)")), tmp_s) : "")) \
578         ARG_CASE(ARG_CSQC, "frag_ping",                 ((f2 != BOT_PING) ? sprintf(CCR(_("\n(Ping ^2%d^BG)")), f2) : "")) \
579         ARG_CASE(ARG_CSQC, "frag_stats",                sprintf(CCR(_("\n(Health ^1%d^BG / Armor ^2%d^BG)%s")), f1, f2, ((f3 != BOT_PING) ? sprintf(CCR(_(" (Ping ^2%d^BG)")), f3) : ""))) \
580         ARG_CASE(ARG_CSQC, "spree_cen",                 (((f1 == 3) || (f1 == 5) || (f1 == 10) || (f1 == 15) || (f1 == 20) || (f1 == 25) || (f1 == 30)) ? sprintf(normal_or_gentle(_("%d frag spree! "), _("%d score spree! ")), f1) : "")) \
581         ARG_CASE(ARG_CSQC, "spree_inf",                 (((f1 == 3) || (f1 == 5) || (f1 == 10) || (f1 == 15) || (f1 == 20) || (f1 == 25) || (f1 == 30)) ? sprintf(normal_or_gentle(_("%d frag spree! "), _("%d score spree! ")), f1) : "")) \
582         ARG_CASE(ARG_CSQC, "spree_end",                 ((f1 >= 3) ? sprintf(normal_or_gentle(_(", ending their %d frag spree"), _(", ending their %d score spree")), f1) : "")) \
583         ARG_CASE(ARG_CSQC, "spree_lost",                ((f1 >= 3) ? sprintf(normal_or_gentle(_(", losing their %d frag spree"), _(", losing their %d score spree")), f1) : "")) \
584         ARG_CASE(ARG_CSQC, "death_team",                Team_ColoredFullName(f1 - 1)) \
585         ARG_CASE(ARG_CSQC, "weapon_name",               ftos(f1)) \
586         ARG_CASE(ARG_SVQC, "spree_inf",                 (((f1 == 3) || (f1 == 5) || (f1 == 10) || (f1 == 15) || (f1 == 20) || (f1 == 25) || (f1 == 30)) ? sprintf(normal_or_gentle(_("%d frag spree! "), _("%d score spree! ")), f1) : "")) \
587         ARG_CASE(ARG_SVQC, "spree_end",                 ((f1 >= 3) ? sprintf(normal_or_gentle(_(", ending their %d frag spree"), _(", ending their %d score spree")), f1) : "")) \
588         ARG_CASE(ARG_SVQC, "spree_lost",                ((f1 >= 3) ? sprintf(normal_or_gentle(_(", losing their %d frag spree"), _(", losing their %d score spree")), f1) : "")) \
589         ARG_CASE(ARG_SVQC, "death_team",                Team_ColoredFullName(f1)) \
590         ARG_CASE(ARG_SVQC, "weapon_name",               ftos(f1))
591
592 string arg_slot[NOTIF_MAX_ARGS];
593
594
595 var float notif_error = FALSE; // an error has occurred in this specific notification
596 var float notif_global_error = FALSE; // an error has occurred in the notification system
597
598 float NOTIF_INFO_COUNT;
599 float NOTIF_CENTER_COUNT;
600 float NOTIF_WEAPON_COUNT;
601 float NOTIF_DEATH_COUNT;
602 float NOTIF_CPID_COUNT;
603
604 entity msg_info_notifs[NOTIF_MAX];
605 entity msg_center_notifs[NOTIF_MAX];
606 entity msg_weapon_notifs[NOTIF_MAX];
607 entity msg_death_notifs[NOTIF_MAX];
608
609 .float nent_broadcast;
610 .entity nent_client;
611 .float nent_net_type;
612 .float nent_net_name;
613 .string nent_strings[4];
614 .float nent_floats[4];
615
616 .float nent_default;
617 .string nent_name;
618 .float nent_id;
619 .float nent_enabled; 
620 .entity nent_msginfo;
621 .entity nent_msgcenter;
622 .float nent_stringcount;
623 .float nent_floatcount; 
624 .string nent_args;
625 .string nent_hudargs;
626 .string nent_icon;
627 .float nent_cpid;
628 .string nent_durcnt;
629 .string nent_string;
630
631 // if(durcnt != "") { notif.nent_durcnt = durcnt; } \
632
633 string Process_Notif_Line(float check_newline, string input, string notiftype, string notifname, string stringtype)
634 {
635         if(check_newline) 
636         if(substring(input, (strlen(input) - 1), 1) != "\n")
637         {
638                 print(sprintf("^1MISSING/BROKEN NEW LINE AT END OF NOTIFICATION: ^7net_type = MSG_%s, net_name = %s, string = %s.\n", notiftype, notifname, stringtype));
639                 notif_error = TRUE;
640                 return strcat(input, "\n");
641         }
642         return input;
643 }
644
645 string Process_Notif_Args(float is_hudargs, string args, string notiftype, string notifname)
646 {
647         string selected, remaining = args;
648         float sel_num = 0;
649         float maxargs = (is_hudargs ? NOTIF_MAX_HUDARGS : NOTIF_MAX_ARGS);
650
651         for(;(remaining != "");)
652         {
653                 selected = car(remaining); remaining = cdr(remaining);
654
655                 if(sel_num == maxargs)
656                 {
657                         print(sprintf("^1NOTIFICATION HAS TOO MANY ARGUMENTS: ^7net_type = MSG_%s, net_name = %s, max %s = %d.\n",
658                                 notiftype, notifname, (is_hudargs ? "hudargs" : "args"), maxargs));
659                         notif_error = TRUE;
660                         break;
661                 }
662
663                 switch(strtolower(selected))
664                 {
665                         #define ARG_CASE(prog,selected,result) \
666                                 #if (prog == ARG_TRIPLE) \
667                                         case selected: { ++sel_num; break; } \
668                                 #else \
669                                         case selected: { if(!is_hudargs) { ++sel_num; break; } } \
670                                 #endif
671                         NOTIF_ARGUMENT_LIST
672                         #undef ARG_CASE
673                         default:
674                         {
675                                 print(sprintf("^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: ^7net_type = MSG_%s, net_name = %s, %s = '%s'.\n",
676                                         notiftype, notifname, (is_hudargs ? "hudargs" : "args"), selected));
677                                 notif_error = TRUE;
678                                 break;
679                         }
680                 }
681         }
682
683         return args;
684 }
685
686 #define CREATE_NOTIF_ENTITY(default,type,name,infoname,centername,strnum,flnum,args,hudargs,icon,cpid,durcnt,normal,gentle,check_newline,subcalls) \
687         notif_error = FALSE; \
688         entity notif = spawn(); \
689         msg_##type##_notifs[name - 1] = notif; \
690         notif.classname = "msg_#type#_notification"; \
691         notif.nent_default = default; \
692         notif.nent_name = strzone(#name); \
693         notif.nent_id = name; \
694         notif.nent_enabled = autocvar_notification_##name; \
695         #if subcalls \
696                 #if (infoname == NO_MSG) && (centername == NO_MSG) \
697                         print(sprintf("^1NOTIFICATION WITH NO SUBCALLS: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); \
698                         notif_error = TRUE; \
699                 #else \
700                         float infoname_stringcount = 0, infoname_floatcount = 0, centername_stringcount = 0, centername_floatcount = 0; \
701                         #if (infoname != NO_MSG) \
702                                 notif.nent_msginfo = msg_info_notifs[infoname - 1]; \
703                                 infoname_stringcount = notif.nent_msginfo.nent_stringcount; \
704                                 infoname_floatcount = notif.nent_msginfo.nent_floatcount; \
705                         #endif \
706                         #if (centername != NO_MSG) \
707                                 notif.nent_msgcenter = msg_center_notifs[centername - 1]; \
708                                 centername_stringcount = notif.nent_msgcenter.nent_stringcount; \
709                                 centername_floatcount = notif.nent_msgcenter.nent_floatcount; \
710                         #endif \
711                         notif.nent_stringcount = max(infoname_stringcount, centername_stringcount); \
712                         notif.nent_floatcount = max(infoname_floatcount, centername_floatcount); \
713                 #endif \
714         #else \
715                 notif.nent_stringcount = strnum; \
716                 notif.nent_floatcount = flnum; \
717                 if(args != "") { notif.nent_args = strzone(Process_Notif_Args(FALSE, args, strtoupper(#type), #name)); } \
718                 if(hudargs != "") { notif.nent_hudargs = strzone(Process_Notif_Args(TRUE, hudargs, strtoupper(#type), #name)); } \
719                 if(icon != "") { notif.nent_icon = strzone(icon); } \
720                 if(GENTLE) \
721                 { \
722                         if(gentle != "") { notif.nent_string = strzone(CCR(Process_Notif_Line(check_newline, gentle, strtoupper(#type), #name, "GENTLE"))); } \
723                         else if(normal != "") { notif.nent_string = strzone(CCR(Process_Notif_Line(check_newline, normal, strtoupper(#type), #name, "NORMAL"))); } \
724                 } \
725                 else if(normal != "") { notif.nent_string = strzone(CCR(Process_Notif_Line(check_newline, normal, strtoupper(#type), #name, "NORMAL"))); } \
726                 if(notif.nent_string == "") { print(sprintf("^1EMPTY NOTIFICATION: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
727         #endif \
728         if(notif_error) \
729         { \
730                 notif.nent_enabled = FALSE; \
731                 notif_global_error = TRUE; \
732         }
733
734 #define ADD_AUTOCVAR(name,default) var float autocvar_notification_##name = default;
735
736 #define MSG_INFO_NOTIF(default,name,strnum,flnum,args,hudargs,icon,normal,gentle) \
737         ADD_AUTOCVAR(name, default) \
738         float name; \
739         void RegisterNotification_##name() \
740         { \
741                 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \
742                 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_INFO_COUNT, "notifications") \
743                 CREATE_NOTIF_ENTITY( \
744                         default,        /* default */ \
745                         info,           /* type */ \
746                         name,           /* name */ \
747                         NO_MSG,         /* infoname */ \
748                         NO_MSG,         /* centername */ \
749                         strnum,         /* strnum */ \
750                         flnum,          /* flnum */ \
751                         args,           /* args */ \
752                         hudargs,        /* hudargs */ \
753                         icon,           /* icon */ \
754                         NO_MSG,         /* cpid */ \
755                         NO_MSG,         /* durcnt */ \
756                         normal,         /* normal */ \
757                         gentle,         /* gentle */ \
758                         1,                      /* check_newline */ \
759                         0)                      /* subcalls */ \
760         } \
761         ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
762
763 #define MSG_CENTER_NOTIF(default,name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
764         ADD_AUTOCVAR(name, default) \
765         float name; \
766         float cpid; \
767         void RegisterNotification_##name() \
768         { \
769                 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CENTER_COUNT) \
770                 SET_FIELD_COUNT(cpid, NOTIF_FIRST, NOTIF_CPID_COUNT) \
771                 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_CENTER_COUNT, "notifications") \
772                 CREATE_NOTIF_ENTITY( \
773                         default,        /* default */ \
774                         center,         /* type */ \
775                         name,           /* name */ \
776                         NO_MSG,         /* infoname */ \
777                         NO_MSG,         /* centername */ \
778                         strnum,         /* strnum */ \
779                         flnum,          /* flnum */ \
780                         args,           /* args */ \
781                         "",             /* hudargs */ \
782                         "",             /* icon */ \
783                         cpid,           /* cpid */ \
784                         durcnt,         /* durcnt */ \
785                         normal,         /* normal */ \
786                         gentle,         /* gentle */ \
787                         0,                      /* check_newline */ \
788                         0)                      /* subcalls */ \
789         } \
790         ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
791
792 #define MSG_WEAPON_NOTIF(default,name,infoname,centername) \
793         ADD_AUTOCVAR(name, default) \
794         float name; \
795         void RegisterNotification_##name() \
796         { \
797                 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_WEAPON_COUNT) \
798                 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_WEAPON_COUNT, "notifications") \
799                 CREATE_NOTIF_ENTITY( \
800                         default,        /* default */ \
801                         weapon,         /* type */ \
802                         name,           /* name */ \
803                         infoname,       /* infoname */ \
804                         centername, /* centername */ \
805                         NO_MSG,         /* strnum */ \
806                         NO_MSG,         /* flnum */ \
807                         "",             /* args */ \
808                         "",             /* hudargs */ \
809                         "",             /* icon */ \
810                         NO_MSG,         /* cpid */ \
811                         NO_MSG,         /* durcnt */ \
812                         "",             /* normal */ \
813                         "",             /* gentle */ \
814                         0,                      /* check_newline */ \
815                         1)                      /* subcalls */ \
816         } \
817         ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
818
819 #define MSG_DEATH_NOTIF(default,name,infoname,centername) \
820         ADD_AUTOCVAR(name, default) \
821         float name; \
822         void RegisterNotification_##name() \
823         { \
824                 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_DEATH_COUNT) \
825                 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_DEATH_COUNT, "notifications") \
826                 CREATE_NOTIF_ENTITY( \
827                         default,        /* default */ \
828                         death,          /* type */ \
829                         name,           /* name */ \
830                         infoname,       /* infoname */ \
831                         centername, /* centername */ \
832                         NO_MSG,         /* strnum */ \
833                         NO_MSG,         /* flnum */ \
834                         "",             /* args */ \
835                         "",             /* hudargs */ \
836                         "",             /* icon */ \
837                         NO_MSG,         /* cpid */ \
838                         NO_MSG,         /* durcnt */ \
839                         "",             /* normal */ \
840                         "",             /* gentle */ \
841                         0,                      /* check_newline */ \
842                         1)                      /* subcalls */ \
843         } \
844         ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
845
846 var float autocvar_notification_errors_are_fatal = TRUE;
847 void RegisterNotifications_Done()
848 {
849         if(notif_global_error && autocvar_notification_errors_are_fatal)
850         {
851                 // shit happened- stop the loading of the program
852                 error("Notification initialization failed!");
853         }
854 }
855
856 // NOW we actually activate the declarations
857 MSG_INFO_NOTIFICATIONS
858 MSG_CENTER_NOTIFICATIONS
859 MSG_WEAPON_NOTIFICATIONS
860 MSG_DEATH_NOTIFICATIONS
861 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotifications_Done)
862 #undef MSG_INFO_NOTIF
863 #undef MSG_CENTER_NOTIF
864 #undef MSG_WEAPON_NOTIF
865 #undef MSG_DEATH_NOTIF
866
867 #undef ADD_AUTOCVAR