From: TimePath Date: Sun, 6 Mar 2016 10:16:20 +0000 (+1100) Subject: Notifications: relocate X-Git-Tag: xonotic-v0.8.2~1132^2~1 X-Git-Url: https://de.git.xonotic.org/?a=commitdiff_plain;h=6e7fae90a84673482a986aa83a6b618fb23c7eb5;p=xonotic%2Fxonotic-data.pk3dir.git Notifications: relocate --- diff --git a/qcsrc/client/announcer.qc b/qcsrc/client/announcer.qc index dbf0cd807..12d07d150 100644 --- a/qcsrc/client/announcer.qc +++ b/qcsrc/client/announcer.qc @@ -2,7 +2,7 @@ #include "mutators/events.qh" -#include +#include #include bool announcer_1min; diff --git a/qcsrc/common/_all.inc b/qcsrc/common/_all.inc index 9c888b91a..5ebc52886 100644 --- a/qcsrc/common/_all.inc +++ b/qcsrc/common/_all.inc @@ -30,7 +30,7 @@ #include "deathtypes/all.qc" #include "effects/all.qc" #include "impulses/all.qc" -#include "notifications.qc" +#include "notifications/all.qc" #include "t_items.qc" #endif diff --git a/qcsrc/common/command/generic.qc b/qcsrc/common/command/generic.qc index 04fbc445d..a720796ce 100644 --- a/qcsrc/common/command/generic.qc +++ b/qcsrc/common/command/generic.qc @@ -6,7 +6,7 @@ #include "../mapinfo.qh" #ifndef MENUQC - #include "../notifications.qh" + #include "../notifications/all.qh" #endif #ifdef CSQC diff --git a/qcsrc/common/deathtypes/all.qh b/qcsrc/common/deathtypes/all.qh index 7dbbba87c..ae40ed811 100644 --- a/qcsrc/common/deathtypes/all.qh +++ b/qcsrc/common/deathtypes/all.qh @@ -1,7 +1,7 @@ #ifndef DEATHTYPES_ALL_H #define DEATHTYPES_ALL_H -#include "../notifications.qh" +#include "../notifications/all.qh" REGISTRY(Deathtypes, BITS(8)) #define Deathtypes_from(i) _Deathtypes_from(i, NULL) diff --git a/qcsrc/common/notifications.inc b/qcsrc/common/notifications.inc deleted file mode 100644 index e723b8933..000000000 --- a/qcsrc/common/notifications.inc +++ /dev/null @@ -1,926 +0,0 @@ -// ==================================== -// Notifications List and Information -// ==================================== -/* - List of all notifications (including identifiers and display information) - Possible Tokens: - default, name, strnum, flnum, - channel, sound, volume, position, - args, hudargs, icon, cpid, durcnt, normal, gentle, - anncename, infoname, centername, - challow, chtype, optiona, optionb - Format Specifications: - name: VAR: Name of notification - MSG_ANNCE: - default: FLOAT: Default setting for whether the notification is enabled or not - ^-> 0 = disabled, 1 = enabled if gentle is disabled, 2 = always enabled - sound: STRING: Filename for the announcement sound - channel: FLOAT: Sound channel to broadcast on to - volume: FLOAT: Volume setting for the announcement sound - position: FLOAT: Attenuation/positioning value - MSG_INFO: - default: FLOAT: Default setting for whether the notification is enabled or not - ^-> 0 = disabled, 1 = enabled, 2 = also print to chat box - strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive) - flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive) - args: STRING: Arguments for Local_Notification_sprintf() - hudargs: STRING: Arguments for Local_Notification_HUD_Notify_Push() - icon: STRING: icon string name for the hud notify panel, "" if no icon is used - normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled) - gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled) - MSG_CENTER: - default: FLOAT: Default setting for whether the notification is enabled or not - ^-> 0 = disabled, 1 = enabled - strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive) - flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive) - args: STRING: Arguments for Local_Notification_sprintf() - cpid: FLOAT: centerprint ID number (CPID_*), CPID_Null if no CPID is needed - durcnt: XPD(FLOAT, FLOAT): Duration/Countdown: extra arguments for centerprint messages - normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled) - gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled) - MSG_MULTI: - default: FLOAT: Default setting for whether the notification is enabled or not - ^-> 0 = disabled, 1 = enabled - anncename: VAR: Name of announcer notification for reference - infoname: VAR: Name of info notification for reference - centername: VAR: Name of centerprint notification for reference - MSG_CHOICE: - default: FLOAT: Default setting for whether the notification is enabled or not - ^-> 0 = disabled, 1 = select option A, 2 = selection option B - challow: FLOAT: Default setting for server allowing choices other than A - ^-> 0 = no choice, 1 = allowed in warmup, 2 = always allowed - chtype: VAR: Notification message type for options - optiona: VAR: Name of choice "A" notification for reference - optionb: VAR: Name of choice "B" notification for reference - - Messages with ^F1, ^BG, ^TC, etc etc in them will replace those strings - with colors according to the cvars the user has chosen. This allows for - users to create unique color profiles for their HUD, giving more customization - options to HUD designers and end users who want such a feature. - - Check out the definitions in util.qc/util.qh/teams.qh for string CCR(...) and - string TCR(...) to better understand how these code replacements work. - - Additionally, you can find all the definitions and explanations for - the argument values and what they return down below in this file. - - Guidlines for notification declaration (please try and follow these): - Specific rules: - - ALWAYS start the string with a color, preferably background. - - ALWAYS reset a color after a name (this way they don't set it for the whole string). - - NEVER add or remove tokens from the format, it SHOULD already work. - - MSG_INFO hudargs must always be ATTACKER -> VICTIM - - MSG_INFO and MSG_CENTER should NOT end with a new line - - General rules: - - Be clean and simple with your notification naming, - nothing too long for the name field... Abbreviations are your friend. :D - - Keep the spacing as clean as possible... if the arguments are abnormally long, - it's okay to go out of line a bit... but try and keep it clean still. - - Use ONLY spaces for spacing in the notification list, tabs are too inconsistent - with keeping alignment on different mediums. - - Sort the notifications in the most appropriate order for their tasks. - - Final note: DO NOT PROVIDE MORE ARGUMENTS THAN NECESSARY FOR THE NOTIFICATION YOU'RE CALLING! - The system is designed to save as much networking bandwidth as possible, - so please dynamically control your argument sending to fit *exactly* what is required. - If you send a notification with mismatching arguments, Send_Notification() will error. -*/ - -#define MULTITEAM_ANNCE2(prefix, default, sound, channel, volume, position) \ - MSG_ANNCE_NOTIF(prefix##RED, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), channel, volume, position) \ - MSG_ANNCE_NOTIF(prefix##BLUE, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_2)), channel, volume, position) -#define MULTITEAM_ANNCE3(prefix, default, sound, channel, volume, position) \ - MULTITEAM_ANNCE2(prefix, default, sound, channel, volume, position) \ - MSG_ANNCE_NOTIF(prefix##YELLOW, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_3)), channel, volume, position) -#define MULTITEAM_ANNCE4(prefix, default, sound, channel, volume, position) \ - MULTITEAM_ANNCE3(prefix, default, sound, channel, volume, position) \ - MSG_ANNCE_NOTIF(prefix##PINK, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_4)), channel, volume, position) -#define MULTITEAM_ANNCE(prefix, teams, default, sound, channel, volume, position) \ - MULTITEAM_ANNCE##teams(prefix, default, sound, channel, volume, position) - -// MSG_ANNCE_NOTIFICATIONS - MSG_ANNCE_NOTIF(ACHIEVEMENT_AIRSHOT, 1, "airshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_AMAZING, 1, "amazing", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME, 1, "awesome", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_BOTLIKE, 1, "botlike", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_ELECTROBITCH, 2, "electrobitch", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_IMPRESSIVE, 1, "impressive", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_YODA, 1, "yoda", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(BEGIN, 2, "begin", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(KILLSTREAK_03, 1, "03kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_05, 1, "05kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_10, 1, "10kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_15, 1, "15kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_20, 1, "20kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_25, 1, "25kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_30, 1, "30kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(INSTAGIB_LASTSECOND, 1, "lastsecond", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(INSTAGIB_NARROWLY, 1, "narrowly", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(INSTAGIB_TERMINATED, 1, "terminated", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(MULTIFRAG, 0, "multifrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(NUM_1, 2, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_2, 2, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_3, 2, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_4, 2, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_5, 2, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_6, 2, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_7, 2, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_8, 2, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_9, 2, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_10, 2, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(NUM_GAMESTART_1, 2, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_2, 2, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_3, 2, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_4, 2, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_5, 2, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(NUM_IDLE_1, 0, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_IDLE_2, 0, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_IDLE_3, 0, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_IDLE_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_IDLE_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_IDLE_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_IDLE_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_IDLE_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_IDLE_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_IDLE_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(NUM_KILL_1, 0, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_2, 0, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_3, 0, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(NUM_RESPAWN_1, 0, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_2, 0, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_3, 0, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_1, 2, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_2, 2, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_3, 2, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(PREPARE, 2, "prepareforbattle", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(REMAINING_FRAG_1, 1, "1fragleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(REMAINING_FRAG_2, 1, "2fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(REMAINING_FRAG_3, 1, "3fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(REMAINING_MIN_1, 2, "1minuteremains", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(REMAINING_MIN_5, 2, "5minutesremain", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(TIMEOUT, 2, "timeoutcalled", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(VOTE_ACCEPT, 2, "voteaccept", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(VOTE_CALL, 2, "votecall", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(VOTE_FAIL, 2, "votefail", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - -#define MULTITEAM_INFO2(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ - MSG_INFO_NOTIF(prefix##_RED, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ - MSG_INFO_NOTIF(prefix##_BLUE, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) -#define MULTITEAM_INFO3(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ - MULTITEAM_INFO2(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ - MSG_INFO_NOTIF(prefix##_YELLOW, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) -#define MULTITEAM_INFO4(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ - MULTITEAM_INFO3(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ - MSG_INFO_NOTIF(prefix##_PINK, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) -#define MULTITEAM_INFO(prefix, teams, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ - MULTITEAM_INFO##teams(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) - -// MSG_INFO_NOTIFICATIONS - MSG_INFO_NOTIF(CHAT_NOSPECTATORS, 2, 0, 0, "", "", "", _("^F4NOTE: ^BGSpectator chat is not sent to players during the match"), "") - - MULTITEAM_INFO(CTF_CAPTURE, 4, 1, 1, 0, "s1", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag"), "") - MULTITEAM_INFO(CTF_CAPTURE_BROKEN, 4, 1, 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"), "") - MSG_INFO_NOTIF(CTF_CAPTURE_NEUTRAL, 1, 1, 0, "s1", "s1", "notify_neutral_captured", _("^BG%s^BG captured the flag"), "") - MULTITEAM_INFO(CTF_CAPTURE_TIME, 4, 1, 1, 1, "s1 f1p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"), "") - MULTITEAM_INFO(CTF_CAPTURE_UNBROKEN, 4, 1, 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"), "") - MULTITEAM_INFO(CTF_FLAGRETURN_ABORTRUN, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner"), "") - MSG_INFO_NOTIF(CTF_FLAGRETURN_ABORTRUN_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag was returned by its owner"), "") - MULTITEAM_INFO(CTF_FLAGRETURN_DAMAGED, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base"), "") - MSG_INFO_NOTIF(CTF_FLAGRETURN_DAMAGED_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag was destroyed and returned to base"), "") - MULTITEAM_INFO(CTF_FLAGRETURN_DROPPED, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"), "") - MSG_INFO_NOTIF(CTF_FLAGRETURN_DROPPED_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag was dropped in the base and returned itself"), "") - MULTITEAM_INFO(CTF_FLAGRETURN_NEEDKILL, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base"), "") - MSG_INFO_NOTIF(CTF_FLAGRETURN_NEEDKILL_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag fell somewhere it couldn't be reached and returned to base"), "") - MULTITEAM_INFO(CTF_FLAGRETURN_SPEEDRUN, 4, 1, 0, 1, "f1p2dec", "", "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") - MSG_INFO_NOTIF(CTF_FLAGRETURN_SPEEDRUN_NEUTRAL, 1, 0, 1, "f1p2dec", "", "", _("^BGThe flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") - MULTITEAM_INFO(CTF_FLAGRETURN_TIMEOUT, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag has returned to the base"), "") - MSG_INFO_NOTIF(CTF_FLAGRETURN_TIMEOUT_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag has returned to the base"), "") - MULTITEAM_INFO(CTF_LOST, 4, 1, 1, 0, "s1", "s1", "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag"), "") - MSG_INFO_NOTIF(CTF_LOST_NEUTRAL, 1, 1, 0, "s1", "s1", "notify_neutral_lost", _("^BG%s^BG lost the flag"), "") - MULTITEAM_INFO(CTF_PICKUP, 4, 1, 1, 0, "s1", "s1", "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag"), "") - MSG_INFO_NOTIF(CTF_PICKUP_NEUTRAL, 1, 1, 0, "s1", "s1", "notify_neutral_taken", _("^BG%s^BG got the flag"), "") - MULTITEAM_INFO(CTF_RETURN, 4, 1, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") - MULTITEAM_INFO(CTF_RETURN_MONSTER, 4, 1, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") - - MSG_INFO_NOTIF(COINTOSS, 2, 1, 0, "s1", "", "", _("^F2Throwing coin... Result: %s^F2!"), "") - - MSG_INFO_NOTIF(JETPACK_NOFUEL, 1, 0, 0, "", "", "", _("^BGYou don't have any fuel for the ^F1Jetpack"), "") - - MSG_INFO_NOTIF(SUPERSPEC_MISSING_UID, 2, 0, 0, "", "", "", _("^F2You lack a UID, superspec options will not be saved/restored"), "") - - MSG_INFO_NOTIF(CA_JOIN_LATE, 1, 0, 0, "", "", "", _("^F1Round already started, you will join the game in the next round"), "") - MSG_INFO_NOTIF(CA_LEAVE, 1, 0, 0, "", "", "", _("^F2You will spectate in the next round"), "") - - MSG_INFO_NOTIF(DEATH_MURDER_BUFF, 1, 3, 3, "spree_inf s1 s2 f3buffname s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was killed by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"), _("^BG%s%s^K1 was scored against by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s")) - MSG_INFO_NOTIF(DEATH_MURDER_CHEAT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_DROWN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_water", _("^BG%s%s^K1 was drowned by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_FALL, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_fall", _("^BG%s%s^K1 was grounded by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_FIRE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s"), _("^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s")) - MSG_INFO_NOTIF(DEATH_MURDER_LAVA, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_lava", _("^BG%s%s^K1 was cooked by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_MONSTER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was pushed infront of a monster by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_NADE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_normal", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_NADE_NAPALM, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_napalm", _("^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"), _("^BG%s%s^K1 got too close to a napalm explosion%s%s")) - MSG_INFO_NOTIF(DEATH_MURDER_NADE_ICE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_ice", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Ice Nade%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_NADE_ICE_FREEZE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_ice", _("^BG%s%s^K1 was frozen to death by ^BG%s^K1's Ice Nade%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_NADE_HEAL, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_heal", _("^BG%s%s^K1 has not been healed by ^BG%s^K1's Healing Nade%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_SHOOTING_STAR, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_shootingstar", _("^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_SLIME, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was slimed by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_SWAMP, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was preserved by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_TELEFRAG, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_telefrag", _("^BG%s%s^K1 was telefragged by ^BG%s^K1%s%s"), _("^BG%s%s^K1 tried to occupy ^BG%s^K1's teleport destination space%s%s")) - MSG_INFO_NOTIF(DEATH_MURDER_TOUCHEXPLODE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 died in an accident with ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_BUMB_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Bumblebee exploded%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_BUMB_GUN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 saw the pretty lights of ^BG%s^K1's Bumblebee gun%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_CRUSH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was crushed by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_RAPT_BOMB, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was cluster bombed by ^BG%s^K1's Raptor%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_RAPT_CANNON, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 couldn't resist ^BG%s^K1's purple blobs%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_RAPT_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Raptor exploded%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_SPID_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Spiderbot exploded%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_SPID_MINIGUN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got shredded by ^BG%s^K1's Spiderbot%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_SPID_ROCKET, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was blasted to bits by ^BG%s^K1's Spiderbot%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_WAKI_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_WAKI_GUN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VH_WAKI_ROCKET, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s"), "") - MSG_INFO_NOTIF(DEATH_MURDER_VOID, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_void", _("^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s"), "") - - MSG_INFO_NOTIF(DEATH_SELF_AUTOTEAMCHANGE, 1, 2, 1, "s1 s2loc death_team", "", "", _("^BG%s^K1 was moved into the %s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_BETRAYAL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_teamkill_red", _("^BG%s^K1 became enemies with the Lord of Teamplay%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_CAMP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_camping", _("^BG%s^K1 thought they found a nice camping ground%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_CHEAT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 unfairly eliminated themself%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_CUSTOM, 1, 3, 1, "s1 s2 s3loc spree_lost", "s1", "notify_void", "^BG%s^K1 %s^K1%s%s", "") - MSG_INFO_NOTIF(DEATH_SELF_DROWN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_water", _("^BG%s^K1 couldn't catch their breath%s%s"), _("^BG%s^K1 was in the water for too long%s%s")) - MSG_INFO_NOTIF(DEATH_SELF_FALL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_fall", _("^BG%s^K1 hit the ground with a crunch%s%s"), _("^BG%s^K1 hit the ground with a bit too much force%s%s")) - MSG_INFO_NOTIF(DEATH_SELF_FIRE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 became a bit too crispy%s%s"), _("^BG%s^K1 felt a little hot%s%s")) - MSG_INFO_NOTIF(DEATH_SELF_GENERIC, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 died%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_LAVA, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_lava", _("^BG%s^K1 turned into hot slag%s%s"), _("^BG%s^K1 found a hot place%s%s")) - MSG_INFO_NOTIF(DEATH_SELF_MON_MAGE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was exploded by a Mage%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_MON_SHAMBLER_CLAW, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1's innards became outwards by a Shambler%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_MON_SHAMBLER_SMASH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was smashed by a Shambler%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_MON_SHAMBLER_ZAP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was zapped to death by a Shambler%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_MON_SPIDER, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was bitten by a Spider%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_MON_WYVERN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was fireballed by a Wyvern%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_MON_ZOMBIE_JUMP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 joins the Zombies%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_MON_ZOMBIE_MELEE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was given kung fu lessons by a Zombie%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_NADE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_normal", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_NADE_NAPALM, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_napalm", _("^BG%s^K1 was burned to death by their own Napalm Nade%s%s"), _("^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s")) - MSG_INFO_NOTIF(DEATH_SELF_NADE_ICE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_ice", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_NADE_ICE_FREEZE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_ice", _("^BG%s^K1 was frozen to death by their own Ice Nade%s%s"), _("^BG%s^K1 felt a little chilly%s%s")) - MSG_INFO_NOTIF(DEATH_SELF_NADE_HEAL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_heal", _("^BG%s^K1's Healing Nade didn't quite heal them%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_NOAMMO, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_outofammo", _("^BG%s^K1 died%s%s. What's the point of living without ammo?"), _("^BG%s^K1 ran out of ammo%s%s")) - MSG_INFO_NOTIF(DEATH_SELF_ROT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 rotted away%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_SHOOTING_STAR, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_shootingstar", _("^BG%s^K1 became a shooting star%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_SLIME, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_slime", _("^BG%s^K1 was slimed%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 couldn't take it anymore%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_SWAMP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_slime", _("^BG%s^K1 is now preserved for centuries to come%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TEAMCHANGE, 1, 2, 1, "s1 s2loc death_team", "", "", _("^BG%s^K1 switched to the %s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TOUCHEXPLODE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 died in an accident%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 ran into a turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_EWHEEL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by an eWheel turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_FLAC, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught up in the FLAC turret fire%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_HELLION, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by a Hellion turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_HK, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 could not hide from the Hunter turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_MACHINEGUN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was riddled full of holes by a Machinegun turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_MLRS, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got turned into smoldering gibs by an MLRS turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_PHASER, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was phased out by a turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_PLASMA, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got served some superheated plasma from a turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_TESLA, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was electrocuted by a Tesla turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_WALK_GUN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got served a lead enrichment by a Walker turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_WALK_MELEE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was impaled by a Walker turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_TURRET_WALK_ROCKET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by a Walker turret%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_VH_BUMB_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Bumblebee explosion%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_VH_CRUSH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was crushed by a vehicle%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_VH_RAPT_BOMB, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was caught in a Raptor cluster bomb%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_VH_RAPT_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Raptor explosion%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_VH_SPID_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Spiderbot explosion%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_VH_SPID_ROCKET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted to bits by a Spiderbot rocket%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_VH_WAKI_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Racer explosion%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_VH_WAKI_ROCKET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 couldn't find shelter from a Racer rocket%s%s"), "") - MSG_INFO_NOTIF(DEATH_SELF_VOID, 1, 3, 1, "s1 s2 s2loc spree_lost", "s1", "notify_void", "^BG%s^K1 %s^K1%s%s", "") - - MULTITEAM_INFO(DEATH_TEAMKILL, 4, 1, 3, 1, "s1 s2 s3loc spree_end", "s2 s1", "notify_teamkill_%s", _("^BG%s^K1 was betrayed by ^BG%s^K1%s%s"), "") - - MSG_INFO_NOTIF(DOMINATION_CAPTURE_TIME, 1, 2, 2, "s1 s2 f1 f1points f2", "", "", _("^BG%s^BG%s^BG (%s %s every %s seconds)"), "") - - MSG_INFO_NOTIF(FREEZETAG_FREEZE, 1, 2, 0, "s1 s2", "", "", _("^BG%s^K1 was frozen by ^BG%s"), "") - MSG_INFO_NOTIF(FREEZETAG_REVIVED, 1, 2, 0, "s1 s2", "", "", _("^BG%s^K3 was revived by ^BG%s"), "") - MSG_INFO_NOTIF(FREEZETAG_REVIVED_FALL, 1, 1, 0, "s1", "", "", _("^BG%s^K3 was revived by falling"), "") - MSG_INFO_NOTIF(FREEZETAG_REVIVED_NADE, 1, 1, 0, "s1", "", "", _("^BG%s^K3 was revived by their Nade explosion"), "") - MSG_INFO_NOTIF(FREEZETAG_AUTO_REVIVED, 1, 1, 1, "s1 f1", "", "", _("^BG%s^K3 was automatically revived after %s second(s)"), "") - MSG_INFO_NOTIF(FREEZETAG_SELF, 1, 1, 0, "s1", "", "", _("^BG%s^K1 froze themself"), "") - - MULTITEAM_INFO(ROUND_TEAM_WIN, 4, 1, 0, 0, "", "", "", _("^TC^TT^BG team wins the round"), "") - MSG_INFO_NOTIF(ROUND_PLAYER_WIN, 1, 1, 0, "s1", "", "", _("^BG%s^BG wins the round"), "") - MSG_INFO_NOTIF(ROUND_TIED, 1, 0, 0, "", "", "", _("^BGRound tied"), "") - MSG_INFO_NOTIF(ROUND_OVER, 1, 0, 0, "", "", "", _("^BGRound over, there's no winner"), "") - - MSG_INFO_NOTIF(GODMODE_OFF, 1, 0, 1, "f1", "", "", _("^BGGodmode saved you %s units of damage, cheater!"), "") - - MSG_INFO_NOTIF(ITEM_BUFF, 1, 1, 1, "s1 item_buffname", "", "", _("^BG%s^BG got the %s^BG buff!"), "") - MSG_INFO_NOTIF(ITEM_BUFF_LOST, 1, 1, 1, "s1 item_buffname", "", "", _("^BG%s^BG lost the %s^BG buff!"), "") - MSG_INFO_NOTIF(ITEM_BUFF_DROP, 1, 0, 1, "item_buffname", "", "", _("^BGYou dropped the %s^BG buff!"), "") - MSG_INFO_NOTIF(ITEM_BUFF_GOT, 1, 0, 1, "item_buffname", "", "", _("^BGYou got the %s^BG buff!"), "") - - MSG_INFO_NOTIF(ITEM_WEAPON_DONTHAVE, 0, 0, 1, "item_wepname", "", "", _("^BGYou do not have the ^F1%s"), "") - MSG_INFO_NOTIF(ITEM_WEAPON_DROP, 0, 1, 1, "item_wepname item_wepammo", "", "", _("^BGYou dropped the ^F1%s^BG%s"), "") - MSG_INFO_NOTIF(ITEM_WEAPON_GOT, 0, 0, 1, "item_wepname", "", "", _("^BGYou got the ^F1%s"), "") - MSG_INFO_NOTIF(ITEM_WEAPON_NOAMMO, 0, 0, 1, "item_wepname", "", "", _("^BGYou don't have enough ammo for the ^F1%s"), "") - MSG_INFO_NOTIF(ITEM_WEAPON_PRIMORSEC, 0, 0, 3, "item_wepname f2primsec f3primsec", "", "", _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"), "") - MSG_INFO_NOTIF(ITEM_WEAPON_UNAVAILABLE, 0, 0, 1, "item_wepname", "", "", _("^F1%s^BG is ^F4not available^BG on this map"), "") - - MSG_INFO_NOTIF(CONNECTING, 1, 1, 0, "s1", "", "", _("^BG%s^BG is connecting..."), "") - MSG_INFO_NOTIF(JOIN_CONNECT, 2, 1, 0, "s1", "", "", _("^BG%s^F3 connected"), "") - MULTITEAM_INFO(JOIN_CONNECT_TEAM, 4, 2, 1, 0, "s1", "", "", _("^BG%s^F3 connected and joined the ^TC^TT team"), "") - MSG_INFO_NOTIF(JOIN_PLAY, 1, 1, 0, "s1", "", "", _("^BG%s^F3 is now playing"), "") - MULTITEAM_INFO(JOIN_PLAY_TEAM, 4, 2, 1, 0, "s1", "", "", _("^BG%s^F3 is now playing on the ^TC^TT team"), "") - - MSG_INFO_NOTIF(KEEPAWAY_DROPPED, 1, 1, 0, "s1", "s1", "notify_balldropped", _("^BG%s^BG has dropped the ball!"), "") - MSG_INFO_NOTIF(KEEPAWAY_PICKUP, 1, 1, 0, "s1", "s1", "notify_ballpickedup", _("^BG%s^BG has picked up the ball!"), "") - - MULTITEAM_INFO(KEYHUNT_CAPTURE, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG captured the keys for the ^TC^TT team"), "") - MULTITEAM_INFO(KEYHUNT_DROP, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG dropped the ^TC^TT Key"), "") - MULTITEAM_INFO(KEYHUNT_LOST, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG lost the ^TC^TT Key"), "") - MULTITEAM_INFO(KEYHUNT_PICKUP, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG picked up the ^TC^TT Key"), "") - - MSG_INFO_NOTIF(LMS_FORFEIT, 1, 1, 0, "s1", "", "", _("^BG%s^F3 forfeited"), "") - MSG_INFO_NOTIF(LMS_NOLIVES, 1, 1, 0, "s1", "", "", _("^BG%s^F3 has no more lives left"), "") - - MSG_INFO_NOTIF(MONSTERS_DISABLED, 1, 0, 0, "", "", "", _("^BGMonsters are currently disabled"), "") - - MSG_INFO_NOTIF(ONSLAUGHT_CAPTURE, 1, 2, 0, "s1 s2", "", "", _("^BG%s^BG captured %s^BG control point"), "") - MULTITEAM_INFO(ONSLAUGHT_CPDESTROYED, 4, 1, 2, 0, "s1 s2", "", "", _("^TC^TT^BG team %s^BG control point has been destroyed by %s"), "") - MULTITEAM_INFO(ONSLAUGHT_GENDESTROYED, 4, 1, 0, 0, "", "", "", _("^TC^TT^BG generator has been destroyed"), "") - MULTITEAM_INFO(ONSLAUGHT_GENDESTROYED_OVERTIME, 4, 1, 0, 0, "", "", "", _("^TC^TT^BG generator spontaneously combusted due to overtime!"), "") - - MSG_INFO_NOTIF(POWERUP_INVISIBILITY, 1, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Invisibility"), "") - MSG_INFO_NOTIF(POWERUP_SHIELD, 1, 1, 0, "s1", "s1", "shield", _("^BG%s^K1 picked up Shield"), "") - MSG_INFO_NOTIF(POWERUP_SPEED, 1, 1, 0, "s1", "s1", "shield", _("^BG%s^K1 picked up Speed"), "") - MSG_INFO_NOTIF(POWERUP_STRENGTH, 1, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Strength"), "") - - MSG_INFO_NOTIF(QUIT_DISCONNECT, 2, 1, 0, "s1", "", "", _("^BG%s^F3 disconnected"), "") - MSG_INFO_NOTIF(QUIT_KICK_IDLING, 2, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked for idling"), "") - MSG_INFO_NOTIF(QUIT_KICK_SPECTATING, 1, 0, 0, "", "", "", _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment."), "") - MSG_INFO_NOTIF(QUIT_SPECTATE, 1, 1, 0, "s1", "", "", _("^BG%s^F3 is now spectating"), "") - - MSG_INFO_NOTIF(RACE_ABANDONED, 1, 1, 0, "s1", "", "", _("^BG%s^BG has abandoned the race"), "") - MSG_INFO_NOTIF(RACE_FAIL_RANKED, 1, 1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1 f3race_time", "race_newfail", _("^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s"), "") - MSG_INFO_NOTIF(RACE_FAIL_UNRANKED, 1, 1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1 f3race_time", "race_newfail", _("^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s"), "") - MSG_INFO_NOTIF(RACE_FINISHED, 1, 1, 0, "s1", "", "", _("^BG%s^BG has finished the race"), "") - MSG_INFO_NOTIF(RACE_NEW_BROKEN, 1, 2, 3, "s1 s2 race_col f1ord race_col f2race_time race_diff", "s1 f2race_time", "race_newrankyellow", _("^BG%s^BG broke %s^BG's %s%s^BG place record with %s%s %s"), "") - MSG_INFO_NOTIF(RACE_NEW_IMPROVED, 1, 1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1 f2race_time", "race_newtime", _("^BG%s^BG improved their %s%s^BG place record with %s%s %s"), "") - MSG_INFO_NOTIF(RACE_NEW_MISSING_UID, 1, 1, 1, "s1 f1race_time", "s1 f1race_time", "race_newfail", _("^BG%s^BG scored a new record with ^F2%s^BG, but unfortunately lacks a UID and will be lost."), "") - MSG_INFO_NOTIF(RACE_NEW_SET, 1, 1, 2, "s1 race_col f1ord race_col f2race_time", "s1 f2race_time", "race_newrecordserver", _("^BG%s^BG set the %s%s^BG place record with %s%s"), "") - - MULTIICON_INFO(MINIGAME_INVITE, 1, 2, 0, "s2 minigame1_name s1", "s2", "minigame1_d", "minigames/%s/icon_notif", _("^F4You have been invited by ^BG%s^F4 to join their game of ^F2%s^F4 (^F1%s^F4)"), "") - - MULTITEAM_INFO(SCORES, 4, 1, 0, 0, "", "", "", _("^TC^TT ^BGteam scores!"), "") - - MSG_INFO_NOTIF(SPECTATE_WARNING, 1, 0, 1, "f1secs", "", "", _("^F2You have to become a player within the next %s, otherwise you will be kicked, because spectating isn't allowed at this time!"), "") - - MSG_INFO_NOTIF(SUPERWEAPON_PICKUP, 1, 1, 0, "s1", "s1", "superweapons", _("^BG%s^K1 picked up a Superweapon"), "") - - MSG_INFO_NOTIF(TEAMCHANGE_LARGERTEAM, 1, 0, 0, "", "", "", _("^BGYou cannot change to a larger team"), "") - MSG_INFO_NOTIF(TEAMCHANGE_NOTALLOWED, 1, 0, 0, "", "", "", _("^BGYou are not allowed to change teams"), "") - - MSG_INFO_NOTIF(VERSION_BETA, 2, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s"), "") - MSG_INFO_NOTIF(VERSION_OLD, 2, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s"), "") - MSG_INFO_NOTIF(VERSION_OUTDATED, 2, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get the update from ^F3http://www.xonotic.org/^BG!"), "") - - MSG_INFO_NOTIF(WATERMARK, 1, 1, 0, "s1", "", "", _("^F3SVQC Build information: ^F4%s"), "") - - MSG_INFO_NOTIF(WEAPON_ACCORDEON_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Accordeon%s%s"), "") - MSG_INFO_NOTIF(WEAPON_ACCORDEON_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s%s"), "") - MSG_INFO_NOTIF(WEAPON_ARC_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponarc", _("^BG%s%s^K1 was electrocuted by ^BG%s^K1's Arc%s%s"), "") - MSG_INFO_NOTIF(WEAPON_ARC_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponarc", _("^BG%s%s^K1 was blasted by ^BG%s^K1's Arc bolts%s%s"), "") - MSG_INFO_NOTIF(WEAPON_BLASTER_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponlaser", _("^BG%s%s^K1 was shot to death by ^BG%s^K1's Blaster%s%s"), "") - MSG_INFO_NOTIF(WEAPON_BLASTER_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponlaser", _("^BG%s^K1 shot themself to hell with their Blaster%s%s"), "") - MSG_INFO_NOTIF(WEAPON_CRYLINK_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponcrylink", _("^BG%s%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s%s"), "") - MSG_INFO_NOTIF(WEAPON_CRYLINK_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponcrylink", _("^BG%s^K1 felt the strong pull of their Crylink%s%s"), "") - MSG_INFO_NOTIF(WEAPON_DEVASTATOR_MURDER_DIRECT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrocketlauncher", _("^BG%s%s^K1 ate ^BG%s^K1's rocket%s%s"), "") - MSG_INFO_NOTIF(WEAPON_DEVASTATOR_MURDER_SPLASH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrocketlauncher", _("^BG%s%s^K1 got too close ^BG%s^K1's rocket%s%s"), "") - MSG_INFO_NOTIF(WEAPON_DEVASTATOR_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrocketlauncher", _("^BG%s^K1 blew themself up with their Devastator%s%s"), "") - MSG_INFO_NOTIF(WEAPON_ELECTRO_MURDER_BOLT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 was blasted by ^BG%s^K1's Electro bolt%s%s"), "") - MSG_INFO_NOTIF(WEAPON_ELECTRO_MURDER_COMBO, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 felt the electrifying air of ^BG%s^K1's Electro combo%s%s"), "") - MSG_INFO_NOTIF(WEAPON_ELECTRO_MURDER_ORBS, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 got too close to ^BG%s^K1's Electro orb%s%s"), "") - MSG_INFO_NOTIF(WEAPON_ELECTRO_SUICIDE_BOLT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponelectro", _("^BG%s^K1 played with Electro bolts%s%s"), "") - MSG_INFO_NOTIF(WEAPON_ELECTRO_SUICIDE_ORBS, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponelectro", _("^BG%s^K1 could not remember where they put their Electro orb%s%s"), "") - MSG_INFO_NOTIF(WEAPON_FIREBALL_MURDER_BLAST, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponfireball", _("^BG%s%s^K1 got too close to ^BG%s^K1's fireball%s%s"), "") - MSG_INFO_NOTIF(WEAPON_FIREBALL_MURDER_FIREMINE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponfireball", _("^BG%s%s^K1 got burnt by ^BG%s^K1's firemine%s%s"), "") - MSG_INFO_NOTIF(WEAPON_FIREBALL_SUICIDE_BLAST, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponfireball", _("^BG%s^K1 should have used a smaller gun%s%s"), "") - MSG_INFO_NOTIF(WEAPON_FIREBALL_SUICIDE_FIREMINE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponfireball", _("^BG%s^K1 forgot about their firemine%s%s"), "") - MSG_INFO_NOTIF(WEAPON_HAGAR_MURDER_BURST, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhagar", _("^BG%s%s^K1 was pummeled by a burst of ^BG%s^K1's Hagar rockets%s%s"), "") - MSG_INFO_NOTIF(WEAPON_HAGAR_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhagar", _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Hagar rockets%s%s"), "") - MSG_INFO_NOTIF(WEAPON_HAGAR_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponhagar", _("^BG%s^K1 played with tiny Hagar rockets%s%s"), "") - MSG_INFO_NOTIF(WEAPON_HLAC_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhlac", _("^BG%s%s^K1 was cut down with ^BG%s^K1's HLAC%s%s"), "") - MSG_INFO_NOTIF(WEAPON_HLAC_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponhlac", _("^BG%s^K1 got a little jumpy with their HLAC%s%s"), "") - MSG_INFO_NOTIF(WEAPON_HMG_MURDER_SNIPE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhmg", _("^BG%s%s^K1 was sniped by ^BG%s^K1's Heavy Machine Gun%s%s"), "") - MSG_INFO_NOTIF(WEAPON_HMG_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhmg", _("^BG%s%s^K1 was torn to bits by ^BG%s^K1's Heavy Machine Gun%s%s"), "") - MSG_INFO_NOTIF(WEAPON_HOOK_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhook", _("^BG%s%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s%s"), "") - MSG_INFO_NOTIF(WEAPON_KLEINBOTTLE_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s%s"), "") - MSG_INFO_NOTIF(WEAPON_KLEINBOTTLE_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s%s"), "") - MSG_INFO_NOTIF(WEAPON_MACHINEGUN_MURDER_SNIPE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponuzi", _("^BG%s%s^K1 was sniped by ^BG%s^K1's Machine Gun%s%s"), "") - MSG_INFO_NOTIF(WEAPON_MACHINEGUN_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponuzi", _("^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s"), "") - MSG_INFO_NOTIF(WEAPON_MINELAYER_LIMIT, 1, 0, 1, "f1", "", "", _("^BGYou cannot place more than ^F2%s^BG mines at a time"), "") - MSG_INFO_NOTIF(WEAPON_MINELAYER_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponminelayer", _("^BG%s%s^K1 got too close to ^BG%s^K1's mine%s%s"), "") - MSG_INFO_NOTIF(WEAPON_MINELAYER_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponminelayer", _("^BG%s^K1 forgot about their mine%s%s"), "") - MSG_INFO_NOTIF(WEAPON_MORTAR_MURDER_BOUNCE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapongrenadelauncher", _("^BG%s%s^K1 got too close to ^BG%s^K1's Mortar grenade%s%s"), "") - MSG_INFO_NOTIF(WEAPON_MORTAR_MURDER_EXPLODE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapongrenadelauncher", _("^BG%s%s^K1 ate ^BG%s^K1's Mortar grenade%s%s"), "") - MSG_INFO_NOTIF(WEAPON_MORTAR_SUICIDE_BOUNCE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapongrenadelauncher", _("^BG%s^K1 didn't see their own Mortar grenade%s%s"), "") - MSG_INFO_NOTIF(WEAPON_MORTAR_SUICIDE_EXPLODE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapongrenadelauncher", _("^BG%s^K1 blew themself up with their own Mortar%s%s"), "") - MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 was sniped with a Rifle by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER_HAIL, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 died in ^BG%s^K1's Rifle bullet hail%s%s"), "") - MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER_HAIL_PIERCING, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s%s"), "") - MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER_PIERCING, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle%s%s"), "") - MSG_INFO_NOTIF(WEAPON_RPC_MURDER_DIRECT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrpc", _("^BG%s%s^K1 was sawn in half by ^BG%s^K1's Rocket Propelled Chainsaw%s%s"), "") - MSG_INFO_NOTIF(WEAPON_RPC_MURDER_SPLASH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrpc", _("^BG%s%s^K1 almost dodged ^BG%s^K1's Rocket Propelled Chainsaw%s%s"), "") - MSG_INFO_NOTIF(WEAPON_RPC_SUICIDE_DIRECT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrpc", _("^BG%s^K1 was sawn in half by their own Rocket Propelled Chainsaw%s%s"), "") - MSG_INFO_NOTIF(WEAPON_RPC_SUICIDE_SPLASH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrpc", _("^BG%s^K1 blew themself up with their Rocket Propelled Chainsaw%s%s"), "") - MSG_INFO_NOTIF(WEAPON_SEEKER_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponseeker", _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s"), "") - MSG_INFO_NOTIF(WEAPON_SEEKER_MURDER_TAG, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponseeker", _("^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s"), "") - MSG_INFO_NOTIF(WEAPON_SEEKER_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponseeker", _("^BG%s^K1 played with tiny Seeker rockets%s%s"), "") - MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponshotgun", _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shockwave%s%s"), "") - MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER_SLAP, 1, 3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1", "notify_melee_shotgun", _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shockwave%s%s"), "") - MSG_INFO_NOTIF(WEAPON_SHOTGUN_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponshotgun", _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s"), "") - MSG_INFO_NOTIF(WEAPON_SHOTGUN_MURDER_SLAP, 1, 3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1", "notify_melee_shotgun", _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s"), "") - MSG_INFO_NOTIF(WEAPON_THINKING_WITH_PORTALS, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 is now thinking with portals%s%s"), "") - MSG_INFO_NOTIF(WEAPON_TUBA_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s%s"), "") - MSG_INFO_NOTIF(WEAPON_TUBA_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s%s"), "") - MSG_INFO_NOTIF(WEAPON_VAPORIZER_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponminstanex", _("^BG%s%s^K1 has been sublimated by ^BG%s^K1's Vaporizer%s%s"), "") - MSG_INFO_NOTIF(WEAPON_VORTEX_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponnex", _("^BG%s%s^K1 has been vaporized by ^BG%s^K1's Vortex%s%s"), "") - -#define MULTITEAM_CENTER2(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ - MSG_CENTER_NOTIF(prefix##_RED, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ - MSG_CENTER_NOTIF(prefix##_BLUE, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) -#define MULTITEAM_CENTER3(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ - MULTITEAM_CENTER2(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ - MSG_CENTER_NOTIF(prefix##_YELLOW, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) -#define MULTITEAM_CENTER4(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ - MULTITEAM_CENTER3(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ - MSG_CENTER_NOTIF(prefix##_PINK, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) -#define MULTITEAM_CENTER(prefix, teams, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ - MULTITEAM_CENTER##teams(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) - -// MSG_CENTER_NOTIFICATIONS - MSG_CENTER_NOTIF(ALONE, 1, 0, 0, "", CPID_Null, "0 0", _("^F4You are now alone!"), "") - - MSG_CENTER_NOTIF(ASSAULT_ATTACKING, 1, 0, 0, "", CPID_ASSAULT_ROLE, "0 0", _("^BGYou are attacking!"), "") - MSG_CENTER_NOTIF(ASSAULT_DEFENDING, 1, 0, 0, "", CPID_ASSAULT_ROLE, "0 0", _("^BGYou are defending!"), "") - - MSG_CENTER_NOTIF(COUNTDOWN_BEGIN, 1, 0, 0, "", CPID_ROUND, "2 0", _("^F4Begin!"), "") - MSG_CENTER_NOTIF(COUNTDOWN_GAMESTART, 1, 0, 1, "", CPID_ROUND, "1 f1", _("^F4Game starts in ^COUNT"), "") - MSG_CENTER_NOTIF(COUNTDOWN_ROUNDSTART, 1, 0, 1, "", CPID_ROUND, "1 f1", _("^F4Round starts in ^COUNT"), "") - MSG_CENTER_NOTIF(COUNTDOWN_ROUNDSTOP, 1, 0, 0, "", CPID_ROUND, "2 0", _("^F4Round cannot start"), "") - - MSG_CENTER_NOTIF(ROUND_TIED, 1, 0, 0, "", CPID_ROUND, "0 0", _("^BGRound tied"), "") - MSG_CENTER_NOTIF(ROUND_OVER, 1, 0, 0, "", CPID_ROUND, "0 0", _("^BGRound over, there's no winner"), "") - - MSG_CENTER_NOTIF(CAMPCHECK, 1, 0, 0, "", CPID_CAMPCHECK, "0 0", _("^F2Don't camp!"), "") - - MSG_CENTER_NOTIF(COINTOSS, 1, 1, 0, "s1", CPID_Null, "0 0", _("^F2Throwing coin... Result: %s^F2!"), "") - - MSG_CENTER_NOTIF(CTF_CAPTURESHIELD_FREE, 1, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now free.\n^BGFeel free to ^F2try to capture^BG the flag again\n^BGif you think you will succeed."), "") - MSG_CENTER_NOTIF(CTF_CAPTURESHIELD_INACTIVE, 1, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGThis flag is currently inactive"), "") - MSG_CENTER_NOTIF(CTF_CAPTURESHIELD_SHIELDED, 1, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now ^F1shielded^BG from the flag(s)\n^BGfor ^F2too many unsuccessful attempts^BG to capture.\n^BGMake some defensive scores before trying again."), "") - MULTITEAM_CENTER(CTF_CAPTURE, 4, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the ^TC^TT^BG flag!"), "") - MSG_CENTER_NOTIF(CTF_CAPTURE_NEUTRAL, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the flag!"), "") - MSG_CENTER_NOTIF(CTF_FLAG_THROW_PUNISH, 1, 0, 1, "f1secs", CPID_CTF_LOWPRIO, "0 0", _("^BGToo many flag throws! Throwing disabled for %s."), "") - MULTITEAM_CENTER(CTF_PASS_OTHER, 4, 1, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") - MSG_CENTER_NOTIF(CTF_PASS_OTHER_NEUTRAL, 1, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the flag to %s"), "") - MULTITEAM_CENTER(CTF_PASS_RECEIVED, 4, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the ^TC^TT^BG flag from %s"), "") - MSG_CENTER_NOTIF(CTF_PASS_RECEIVED_NEUTRAL, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the flag from %s"), "") - MSG_CENTER_NOTIF(CTF_PASS_REQUESTED, 1, 1, 0, "s1 pass_key", CPID_CTF_PASS, "0 0", _("^BG%s^BG requests you to pass the flag%s"), "") - MSG_CENTER_NOTIF(CTF_PASS_REQUESTING, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGRequesting %s^BG to pass you the flag"), "") - MULTITEAM_CENTER(CTF_PASS_SENT, 4, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the ^TC^TT^BG flag to %s"), "") - MSG_CENTER_NOTIF(CTF_PASS_SENT_NEUTRAL, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the flag to %s"), "") - MULTITEAM_CENTER(CTF_PICKUP, 4, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the ^TC^TT^BG flag!"), "") - MSG_CENTER_NOTIF(CTF_PICKUP_NEUTRAL, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the flag!"), "") - MSG_CENTER_NOTIF(CTF_PICKUP_TEAM, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got your %steam^BG's flag, return it!"), "") - MSG_CENTER_NOTIF(CTF_PICKUP_TEAM_ENEMY, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the %senemy^BG's flag, return it!"), "") - MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") - MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_VERBOSE, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"), "") - MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_NEUTRAL, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got the flag! Retrieve it!"), "") - MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got the flag! Retrieve it!"), "") - MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_TEAM, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got their flag! Retrieve it!"), "") - MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_TEAM_VERBOSE, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"), "") - MULTITEAM_CENTER(CTF_PICKUP_TEAM, 4, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the ^TC^TT^BG flag! Protect them!"), "") - MULTITEAM_CENTER(CTF_PICKUP_TEAM_VERBOSE, 4, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the ^TC^TT^BG flag! Protect them!"), "") - MSG_CENTER_NOTIF(CTF_PICKUP_TEAM_NEUTRAL, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the flag! Protect them!"), "") - MSG_CENTER_NOTIF(CTF_PICKUP_TEAM_VERBOSE_NEUTRAL, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "") - MULTITEAM_CENTER(CTF_RETURN, 4, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou returned the ^TC^TT^BG flag!"), "") - MSG_CENTER_NOTIF(CTF_STALEMATE_CARRIER, 1, 0, 0, "", CPID_STALEMATE, "0 0", _("^BGStalemate! Enemies can now see you on radar!"), "") - MSG_CENTER_NOTIF(CTF_STALEMATE_OTHER, 1, 0, 0, "", CPID_STALEMATE, "0 0", _("^BGStalemate! Flag carriers can now be seen by enemies on radar!"), "") - - MSG_CENTER_NOTIF(DEATH_MURDER_FRAG, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K3%sYou fragged ^BG%s"), _("^K3%sYou scored against ^BG%s")) - MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K1%sYou were fragged by ^BG%s"), _("^K1%sYou were scored against by ^BG%s")) - MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED_VERBOSE, 1, 1, 4, "spree_cen s1 frag_stats", CPID_Null, "0 0", _("^K1%sYou were fragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^BG%s")) - MSG_CENTER_NOTIF(DEATH_MURDER_FRAG_VERBOSE, 1, 1, 2, "spree_cen s1 frag_ping", CPID_Null, "0 0", _("^K3%sYou fragged ^BG%s^BG%s"), _("^K3%sYou scored against ^BG%s^BG%s")) - MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAG, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K1%sYou typefragged ^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing")) - MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAGGED, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K1%sYou were typefragged by ^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing!")) - MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAGGED_VERBOSE, 1, 1, 4, "spree_cen s1 frag_stats", CPID_Null, "0 0", _("^K1%sYou were typefragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing^BG%s")) - MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAG_VERBOSE, 1, 1, 2, "spree_cen s1 frag_ping", CPID_Null, "0 0", _("^K1%sYou typefragged ^BG%s^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing^BG%s")) - - MSG_CENTER_NOTIF(NADE_THROW, 1, 0, 0, "", CPID_NADES, "0 0", _("^BGPress ^F2DROPWEAPON^BG again to toss the nade!"), "") - MSG_CENTER_NOTIF(NADE_BONUS, 1, 0, 0, "", CPID_NADES, "0 0", _("^F2You got a ^K1BONUS GRENADE^F2!"), "") - - MSG_CENTER_NOTIF(DEATH_SELF_AUTOTEAMCHANGE, 1, 0, 1, "death_team", CPID_Null, "0 0", _("^BGYou have been moved into a different team\nYou are now on: %s"), "") - MSG_CENTER_NOTIF(DEATH_SELF_BETRAYAL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Don't shoot your team mates!"), _("^K1Don't go against your team mates!")) - MSG_CENTER_NOTIF(DEATH_SELF_CAMP, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Die camper!"), _("^K1Reconsider your tactics, camper!")) - MSG_CENTER_NOTIF(DEATH_SELF_CHEAT, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You unfairly eliminated yourself!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_CUSTOM, 1, 2, 0, "s2", CPID_Null, "0 0", _("^K1You were %s"), "") - MSG_CENTER_NOTIF(DEATH_SELF_DROWN, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You couldn't catch your breath!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_FALL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You hit the ground with a crunch!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_FIRE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got a little bit too crispy!"), _("^K1You felt a little too hot!")) - MSG_CENTER_NOTIF(DEATH_SELF_GENERIC, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You killed your own dumb self!"), _("^K1You need to be more careful!")) - MSG_CENTER_NOTIF(DEATH_SELF_LAVA, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You couldn't stand the heat!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_MONSTER, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were killed by a monster!"), _("^K1You need to watch out for monsters!")) - MSG_CENTER_NOTIF(DEATH_SELF_NADE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You forgot to put the pin back in!"), _("^K1Tastes like chicken!")) - MSG_CENTER_NOTIF(DEATH_SELF_NADE_NAPALM, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Hanging around a napalm explosion is bad!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_NADE_ICE_FREEZE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got a little bit too cold!"), _("^K1You felt a little chilly!")) - MSG_CENTER_NOTIF(DEATH_SELF_NADE_HEAL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Your Healing Nade is a bit defective"), "") - MSG_CENTER_NOTIF(DEATH_SELF_NOAMMO, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were killed for running out of ammo..."), _("^K1You are respawning for running out of ammo...")) - MSG_CENTER_NOTIF(DEATH_SELF_ROT, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You grew too old without taking your medicine"), _("^K1You need to preserve your health")) - MSG_CENTER_NOTIF(DEATH_SELF_SHOOTING_STAR, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You became a shooting star!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_SLIME, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You melted away in slime!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_SUICIDE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You committed suicide!"), _("^K1You ended it all!")) - MSG_CENTER_NOTIF(DEATH_SELF_SWAMP, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got stuck in a swamp!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_TEAMCHANGE, 1, 0, 1, "death_team", CPID_Null, "0 0", _("^BGYou are now on: %s"), "") - MSG_CENTER_NOTIF(DEATH_SELF_TOUCHEXPLODE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You died in an accident!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_TURRET, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were fragged by a turret!"), _("^K1You had an unfortunate run in with a turret!")) - MSG_CENTER_NOTIF(DEATH_SELF_TURRET_EWHEEL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were fragged by an eWheel turret!"), _("^K1You had an unfortunate run in with an eWheel turret!")) - MSG_CENTER_NOTIF(DEATH_SELF_TURRET_WALK, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were fragged by a Walker turret!"), _("^K1You had an unfortunate run in with a Walker turret!")) - MSG_CENTER_NOTIF(DEATH_SELF_VH_BUMB_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Bumblebee explosion!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_VH_CRUSH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were crushed by a vehicle!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_VH_RAPT_BOMB, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were caught in a Raptor cluster bomb!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_VH_RAPT_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Raptor explosion!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_VH_SPID_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Spiderbot explosion!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_VH_SPID_ROCKET, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were blasted to bits by a Spiderbot rocket!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_VH_WAKI_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Racer explosion!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_VH_WAKI_ROCKET, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You couldn't find shelter from a Racer rocket!"), "") - MSG_CENTER_NOTIF(DEATH_SELF_VOID, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Watch your step!"), "") - - MSG_CENTER_NOTIF(DEATH_TEAMKILL_FRAG, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1Moron! You fragged ^BG%s^K1, a team mate!"), _("^K1Moron! You went against ^BG%s^K1, a team mate!")) - MSG_CENTER_NOTIF(DEATH_TEAMKILL_FRAGGED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1You were fragged by ^BG%s^K1, a team mate"), _("^K1You were scored against by ^BG%s^K1, a team mate")) - - MSG_CENTER_NOTIF(DISCONNECT_IDLING, 1, 0, 1, "", CPID_IDLING, "1 f1", _("^K1Stop idling!\n^BGDisconnecting in ^COUNT..."), "") - - MSG_CENTER_NOTIF(DOOR_LOCKED_NEED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^BGYou need %s^BG!"), "") - MSG_CENTER_NOTIF(DOOR_LOCKED_ALSONEED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^BGYou also need %s^BG!"), "") - MSG_CENTER_NOTIF(DOOR_UNLOCKED, 1, 0, 0, "", CPID_Null, "0 0", _("^BGDoor unlocked!"), "") - - MSG_CENTER_NOTIF(EXTRALIVES, 1, 0, 0, "", CPID_Null, "0 0", _("^F2You picked up some extra lives"), "") - - MSG_CENTER_NOTIF(FREEZETAG_FREEZE, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K3You froze ^BG%s"), "") - MSG_CENTER_NOTIF(FREEZETAG_FROZEN, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1You were frozen by ^BG%s"), "") - MSG_CENTER_NOTIF(FREEZETAG_REVIVE, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K3You revived ^BG%s"), "") - MSG_CENTER_NOTIF(FREEZETAG_REVIVE_SELF, 1, 0, 0, "", CPID_Null, "0 0", _("^K3You revived yourself"), "") - MSG_CENTER_NOTIF(FREEZETAG_REVIVED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K3You were revived by ^BG%s"), "") - MSG_CENTER_NOTIF(FREEZETAG_AUTO_REVIVED, 1, 0, 1, "f1", CPID_Null, "0 0", _("^K3You were automatically revived after %s second(s)"), "") - - MSG_CENTER_NOTIF(GENERATOR_UNDERATTACK, 1, 0, 0, "", CPID_Null, "0 0", _("^BGThe generator is under attack!"), "") - - MULTITEAM_CENTER(ROUND_TEAM_WIN, 4, 1, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team wins the round"), "") - MSG_CENTER_NOTIF(ROUND_PLAYER_WIN, 1, 1, 0, "s1", CPID_ROUND, "0 0", _("^BG%s^BG wins the round"), "") - - MSG_CENTER_NOTIF(FREEZETAG_SELF, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You froze yourself"), "") - MSG_CENTER_NOTIF(FREEZETAG_SPAWN_LATE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Round already started, you spawn as frozen"), "") - - MSG_CENTER_NOTIF(INVASION_SUPERMONSTER, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1A %s has arrived!"), "") - - MSG_CENTER_NOTIF(ITEM_BUFF_DROP, 1, 0, 1, "item_buffname", CPID_ITEM, "item_centime 0", _("^BGYou dropped the %s^BG buff!"), "") - MSG_CENTER_NOTIF(ITEM_BUFF_GOT, 1, 0, 1, "item_buffname", CPID_ITEM, "item_centime 0", _("^BGYou got the %s^BG buff!"), "") - MSG_CENTER_NOTIF(ITEM_FUELREGEN_GOT, 1, 0, 0, "", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1Fuel regenerator"), "") - MSG_CENTER_NOTIF(ITEM_JETPACK_GOT, 1, 0, 0, "", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1Jet pack"), "") - MSG_CENTER_NOTIF(ITEM_WEAPON_DONTHAVE, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou do not have the ^F1%s"), "") - MSG_CENTER_NOTIF(ITEM_WEAPON_DROP, 1, 1, 1, "item_wepname item_wepammo", CPID_ITEM, "item_centime 0", _("^BGYou dropped the ^F1%s^BG%s"), "") - MSG_CENTER_NOTIF(ITEM_WEAPON_GOT, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1%s"), "") - MSG_CENTER_NOTIF(ITEM_WEAPON_NOAMMO, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou don't have enough ammo for the ^F1%s"), "") - MSG_CENTER_NOTIF(ITEM_WEAPON_PRIMORSEC, 1, 0, 3, "item_wepname f2primsec f3primsec", CPID_ITEM, "item_centime 0", _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"), "") - MSG_CENTER_NOTIF(ITEM_WEAPON_UNAVAILABLE, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^F1%s^BG is ^F4not available^BG on this map"), "") - - MSG_CENTER_NOTIF(JOIN_NOSPAWNS, 1, 0, 0, "", CPID_PREVENT_JOIN, "0 0", _("^K1No spawnpoints available!\nHope your team can fix it..."), "") - MSG_CENTER_NOTIF(JOIN_PREVENT, 1, 0, 0, "", CPID_PREVENT_JOIN, "0 0", _("^K1You may not join the game at this time.\nThe player limit reached maximum capacity."), "") - - MSG_CENTER_NOTIF(KEEPAWAY_DROPPED, 1, 1, 0, "s1", CPID_KEEPAWAY, "0 0", _("^BG%s^BG has dropped the ball!"), "") - MSG_CENTER_NOTIF(KEEPAWAY_PICKUP, 1, 1, 0, "s1", CPID_KEEPAWAY, "0 0", _("^BG%s^BG has picked up the ball!"), "") - MSG_CENTER_NOTIF(KEEPAWAY_PICKUP_SELF, 1, 0, 0, "", CPID_KEEPAWAY, "0 0", _("^BGYou picked up the ball"), "") - MSG_CENTER_NOTIF(KEEPAWAY_WARN, 1, 0, 0, "", CPID_KEEPAWAY_WARN, "0 0", _("^BGKilling people while you don't have the ball gives no points!"), "") - - MSG_CENTER_NOTIF(KEYHUNT_HELP, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in your team's hands!\nHelp the key carriers to meet!"), "") - MULTITEAM_CENTER(KEYHUNT_INTERFERE, 4, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in ^TC^TT team^BG's hands!\nInterfere ^F4NOW^BG!"), "") - MSG_CENTER_NOTIF(KEYHUNT_MEET, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in your team's hands!\nMeet the other key carriers ^F4NOW^BG!"), "") - MSG_CENTER_NOTIF(KEYHUNT_ROUNDSTART, 1, 0, 1, "", CPID_KEYHUNT_OTHER, "1 f1", _("^F4Round will start in ^COUNT"), "") - MSG_CENTER_NOTIF(KEYHUNT_SCAN, 1, 0, 1, "", CPID_KEYHUNT_OTHER, "f1 0", _("^BGScanning frequency range..."), "") - MULTITEAM_CENTER(KEYHUNT_START, 4, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGYou are starting with the ^TC^TT Key"), "") - - MSG_CENTER_NOTIF(LMS_NOLIVES, 1, 0, 0, "", CPID_LMS, "0 0", _("^BGYou have no lives left, you must wait until the next match"), "") - - MSG_CENTER_NOTIF(MISSING_TEAMS, 1, 0, 1, "missing_teams", CPID_MISSING_TEAMS, "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") - MSG_CENTER_NOTIF(MISSING_PLAYERS, 1, 0, 1, "f1", CPID_MISSING_PLAYERS, "-1 0", _("^BGWaiting for %s player(s) to join..."), "") - - MSG_CENTER_NOTIF(INSTAGIB_DOWNGRADE, 1, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "5 0", _("^BGYour weapon has been downgraded until you find some ammo!"), "") - MSG_CENTER_NOTIF(INSTAGIB_FINDAMMO, 1, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "1 9", _("^F4^COUNT^BG left to find some ammo!"), "") - MSG_CENTER_NOTIF(INSTAGIB_FINDAMMO_FIRST, 1, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "1 10", _("^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"), _("^BGGet some ammo! ^F4^COUNT^BG left!")) - MSG_CENTER_NOTIF(INSTAGIB_LIVES_REMAINING, 1, 0, 1, "f1", CPID_Null, "0 0", _("^F2Extra lives remaining: ^K1%s"), "") - - MSG_CENTER_NOTIF(MOTD, 1, 1, 0, "s1", CPID_MOTD, "-1 0", "^BG%s", "") - - MSG_CENTER_NOTIF(NIX_COUNTDOWN, 1, 0, 2, "item_wepname", CPID_NIX, "1 f2", _("^F2^COUNT^BG until weapon change...\nNext weapon: ^F1%s"), "") - MSG_CENTER_NOTIF(NIX_NEWWEAPON, 1, 0, 1, "item_wepname", CPID_NIX, "0 0", _("^F2Active weapon: ^F1%s"), "") - - MSG_CENTER_NOTIF(NADE, 1, 0, 0, "", CPID_Null, "0 0", _("^BGPress ^F2DROPWEAPON^BG again to toss the grenade!"), "") - - MSG_CENTER_NOTIF(ONS_CAPTURE, 1, 1, 0, "s1", CPID_ONSLAUGHT, "0 0", _("^BGYou captured %s^BG control point"), "") - MULTITEAM_CENTER(ONS_CAPTURE, 4, 1, 1, 0, "s1", CPID_ONSLAUGHT, "0 0", _("^TC^TT^BG team captured %s^BG control point"), "") - MSG_CENTER_NOTIF(ONS_CONTROLPOINT_SHIELDED, 1, 0, 0, "", CPID_ONS_CAPSHIELD, "0 0", _("^BGThis control point currently cannot be captured"), "") - MSG_CENTER_NOTIF(ONS_GENERATOR_SHIELDED, 1, 0, 0, "", CPID_ONS_CAPSHIELD, "0 0", _("^BGThe enemy generator cannot be destroyed yet\n^F2Capture some control points to unshield it"), "") - MULTITEAM_CENTER(ONS_NOTSHIELDED, 4, 1, 0, 0, "", CPID_ONSLAUGHT, "0 0", _("^BGThe ^TCenemy^BG generator is no longer shielded!"), "") - MSG_CENTER_NOTIF(ONS_NOTSHIELDED_TEAM, 1, 0, 0, "", CPID_ONSLAUGHT, "0 0", _("^K1Your generator is NOT shielded!\n^BGRe-capture control points to shield it!"), "") - MSG_CENTER_NOTIF(ONS_TELEPORT, 1, 0, 0, "pass_key", CPID_ONSLAUGHT, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to teleport"), "") - MSG_CENTER_NOTIF(ONS_TELEPORT_ANTISPAM, 1, 0, 1, "f1secs", CPID_ONSLAUGHT, "0 0", _("^BGTeleporting disabled for %s"), "") - - MSG_CENTER_NOTIF(OVERTIME_FRAG, 1, 0, 0, "", CPID_OVERTIME, "0 0", _("^F2Now playing ^F4OVERTIME^F2!\nKeep fragging until we have a winner!"), _("^F2Now playing ^F4OVERTIME^F2!\nKeep scoring until we have a winner!")) - MSG_CENTER_NOTIF(OVERTIME_CONTROLPOINT, 1, 0, 0, "", CPID_OVERTIME, "5 0", _("^F2Now playing ^F4OVERTIME^F2!\n\nGenerators are now decaying.\nThe more control points your team holds,\nthe faster the enemy generator decays"), "") - MSG_CENTER_NOTIF(OVERTIME_TIME, 1, 0, 1, "f1time", CPID_OVERTIME, "0 0", _("^F2Now playing ^F4OVERTIME^F2!\n^BGAdded ^F4%s^BG to the game!"), "") - - MSG_CENTER_NOTIF(PORTO_CREATED_IN, 1, 0, 0, "", CPID_Null, "0 0", _("^K1In^BG-portal created"), "") - MSG_CENTER_NOTIF(PORTO_CREATED_OUT, 1, 0, 0, "", CPID_Null, "0 0", _("^F3Out^BG-portal created"), "") - MSG_CENTER_NOTIF(PORTO_FAILED, 1, 0, 0, "", CPID_Null, "0 0", _("^F1Portal creation failed"), "") - - MSG_CENTER_NOTIF(POWERUP_STRENGTH, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Strength infuses your weapons with devastating power"), "") - MSG_CENTER_NOTIF(POWERDOWN_STRENGTH, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Strength has worn off"), "") - - MSG_CENTER_NOTIF(POWERUP_SHIELD, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Shield surrounds you"), "") - MSG_CENTER_NOTIF(POWERDOWN_SHIELD, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Shield has worn off"), "") - - MSG_CENTER_NOTIF(POWERUP_SPEED, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You are on speed"), "") - MSG_CENTER_NOTIF(POWERDOWN_SPEED, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Speed has worn off"), "") - - MSG_CENTER_NOTIF(POWERUP_INVISIBILITY, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You are invisible"), "") - MSG_CENTER_NOTIF(POWERDOWN_INVISIBILITY, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Invisibility has worn off"), "") - - MSG_CENTER_NOTIF(RACE_FINISHLAP, 1, 0, 0, "", CPID_RACE_FINISHLAP, "0 0", _("^F2The race is over, finish your lap!"), "") - - MSG_CENTER_NOTIF(SECONDARY_NODAMAGE, 1, 0, 0, "", CPID_Null, "0 0", _("^BGSecondary fire inflicts no damage!"), "") - - MSG_CENTER_NOTIF(SEQUENCE_COMPLETED, 1, 0, 0, "", CPID_Null, "0 0", _("^BGSequence completed!"), "") - MSG_CENTER_NOTIF(SEQUENCE_COUNTER, 1, 0, 0, "", CPID_Null, "0 0", _("^BGThere are more to go..."), "") - MSG_CENTER_NOTIF(SEQUENCE_COUNTER_FEWMORE, 1, 0, 1, "f1", CPID_Null, "0 0", _("^BGOnly %s^BG more to go..."), "") - - MSG_CENTER_NOTIF(SUPERWEAPON_BROKEN, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Superweapons have broken down"), "") - MSG_CENTER_NOTIF(SUPERWEAPON_LOST, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Superweapons have been lost"), "") - MSG_CENTER_NOTIF(SUPERWEAPON_PICKUP, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You now have a superweapon"), "") - - MULTITEAM_CENTER(TEAMCHANGE, 4, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Changing to ^TC^TT^K1 in ^COUNT"), "") - MSG_CENTER_NOTIF(TEAMCHANGE_AUTO, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Changing team in ^COUNT"), "") - MSG_CENTER_NOTIF(TEAMCHANGE_SPECTATE, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Spectating in ^COUNT"), "") - MSG_CENTER_NOTIF(TEAMCHANGE_SUICIDE, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Suicide in ^COUNT"), "") - - MSG_CENTER_NOTIF(TIMEOUT_BEGINNING, 1, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout begins in ^COUNT"), "") - MSG_CENTER_NOTIF(TIMEOUT_ENDING, 1, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout ends in ^COUNT"), "") - - MSG_CENTER_NOTIF(JOIN_PREVENT_MINIGAME, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Cannot join given minigame session!"), "" ) - - MSG_CENTER_NOTIF(VEHICLE_ENTER, 1, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to enter/exit the vehicle"), "") - MSG_CENTER_NOTIF(VEHICLE_ENTER_GUNNER, 1, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to enter the vehicle gunner"), "") - MSG_CENTER_NOTIF(VEHICLE_ENTER_STEAL, 1, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to steal this vehicle"), "") - MSG_CENTER_NOTIF(VEHICLE_STEAL, 1, 0, 0, "", CPID_VEHICLES_OTHER, "0 0", _("^F2The enemy is stealing one of your vehicles!\n^F4Stop them!"), "") - MSG_CENTER_NOTIF(VEHICLE_STEAL_SELF, 1, 0, 0, "", CPID_VEHICLES_OTHER, "4 0", _("^F2You have stolen the enemy's vehicle, you are now visible on their radar!"), "") - - MSG_CENTER_NOTIF(WEAPON_MINELAYER_LIMIT, 1, 0, 1, "f1", CPID_Null, "0 0", _("^BGYou cannot place more than ^F2%s^BG mines at a time"), "") - -#define MULTITEAM_MULTI2(prefix, default, anncepre, infopre, centerpre) \ - MSG_MULTI_NOTIF(prefix##_RED, default, anncepre##_RED, infopre##_RED, centerpre##_RED) \ - MSG_MULTI_NOTIF(prefix##_BLUE, default, anncepre##_BLUE, infopre##_BLUE, centerpre##_BLUE) -#define MULTITEAM_MULTI3(prefix, default, anncepre, infopre, centerpre) \ - MULTITEAM_MULTI2(prefix, default, anncepre, infopre, centerpre) \ - MSG_MULTI_NOTIF(default, prefix##_YELLOW, anncepre##YELLOW, infopre##YELLOW, centerpre##YELLOW) -#define MULTITEAM_MULTI4(prefix, default, anncepre, infopre, centerpre) \ - MULTITEAM_MULTI3(prefix, default, anncepre, infopre, centerpre) \ - MSG_MULTI_NOTIF(prefix##_PINK, default, anncepre##PINK, infopre##PINK, centerpre##PINK) -#define MULTITEAM_MULTI(prefix, teams, default, anncepre, infopre, centerpre) \ - MULTITEAM_MULTI##teams(prefix, default, anncepre, infopre, centerpre) - -// MSG_MULTI_NOTIFICATIONS - MSG_MULTI_NOTIF(DEATH_MURDER_BUFF, 1, NULL, INFO_DEATH_MURDER_BUFF, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_CHEAT, 1, NULL, INFO_DEATH_MURDER_CHEAT, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_DROWN, 1, NULL, INFO_DEATH_MURDER_DROWN, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_FALL, 1, NULL, INFO_DEATH_MURDER_FALL, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_FIRE, 1, NULL, INFO_DEATH_MURDER_FIRE, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_LAVA, 1, NULL, INFO_DEATH_MURDER_LAVA, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_MONSTER, 1, NULL, INFO_DEATH_MURDER_MONSTER, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(DEATH_MURDER_NADE, 1, NULL, INFO_DEATH_MURDER_NADE, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_NADE_NAPALM, 1, NULL, INFO_DEATH_MURDER_NADE_NAPALM, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_NADE_ICE, 1, NULL, INFO_DEATH_MURDER_NADE_ICE, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_NADE_ICE_FREEZE, 1, NULL, INFO_DEATH_MURDER_NADE_ICE_FREEZE, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_NADE_HEAL, 1, NULL, INFO_DEATH_MURDER_NADE_HEAL, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_SHOOTING_STAR, 1, NULL, INFO_DEATH_MURDER_SHOOTING_STAR, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_SLIME, 1, NULL, INFO_DEATH_MURDER_SLIME, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_SWAMP, 1, NULL, INFO_DEATH_MURDER_SWAMP, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_TELEFRAG, 1, NULL, INFO_DEATH_MURDER_TELEFRAG, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_TOUCHEXPLODE, 1, NULL, INFO_DEATH_MURDER_TOUCHEXPLODE, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_BUMB_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_BUMB_DEATH, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_BUMB_GUN, 1, NULL, INFO_DEATH_MURDER_VH_BUMB_GUN, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_CRUSH, 1, NULL, INFO_DEATH_MURDER_VH_CRUSH, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_RAPT_BOMB, 1, NULL, INFO_DEATH_MURDER_VH_RAPT_BOMB, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_RAPT_CANNON, 1, NULL, INFO_DEATH_MURDER_VH_RAPT_CANNON, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_RAPT_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_RAPT_DEATH, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_SPID_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_SPID_DEATH, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_SPID_MINIGUN, 1, NULL, INFO_DEATH_MURDER_VH_SPID_MINIGUN, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_SPID_ROCKET, 1, NULL, INFO_DEATH_MURDER_VH_SPID_ROCKET, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_WAKI_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_WAKI_DEATH, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_WAKI_GUN, 1, NULL, INFO_DEATH_MURDER_VH_WAKI_GUN, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VH_WAKI_ROCKET, 1, NULL, INFO_DEATH_MURDER_VH_WAKI_ROCKET, NULL) - MSG_MULTI_NOTIF(DEATH_MURDER_VOID, 1, NULL, INFO_DEATH_MURDER_VOID, NULL) - - MSG_MULTI_NOTIF(DEATH_SELF_AUTOTEAMCHANGE, 1, NULL, INFO_DEATH_SELF_AUTOTEAMCHANGE, CENTER_DEATH_SELF_AUTOTEAMCHANGE) - MSG_MULTI_NOTIF(DEATH_SELF_BETRAYAL, 1, NULL, INFO_DEATH_SELF_BETRAYAL, CENTER_DEATH_SELF_BETRAYAL) - MSG_MULTI_NOTIF(DEATH_SELF_CAMP, 1, NULL, INFO_DEATH_SELF_CAMP, CENTER_DEATH_SELF_CAMP) - MSG_MULTI_NOTIF(DEATH_SELF_CHEAT, 1, NULL, INFO_DEATH_SELF_CHEAT, CENTER_DEATH_SELF_CHEAT) - MSG_MULTI_NOTIF(DEATH_SELF_CUSTOM, 1, NULL, INFO_DEATH_SELF_GENERIC, CENTER_DEATH_SELF_CUSTOM) - MSG_MULTI_NOTIF(DEATH_SELF_DROWN, 1, NULL, INFO_DEATH_SELF_DROWN, CENTER_DEATH_SELF_DROWN) - MSG_MULTI_NOTIF(DEATH_SELF_FALL, 1, NULL, INFO_DEATH_SELF_FALL, CENTER_DEATH_SELF_FALL) - MSG_MULTI_NOTIF(DEATH_SELF_FIRE, 1, NULL, INFO_DEATH_SELF_FIRE, CENTER_DEATH_SELF_FIRE) - MSG_MULTI_NOTIF(DEATH_SELF_GENERIC, 1, NULL, INFO_DEATH_SELF_GENERIC, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(DEATH_SELF_LAVA, 1, NULL, INFO_DEATH_SELF_LAVA, CENTER_DEATH_SELF_LAVA) - MSG_MULTI_NOTIF(DEATH_SELF_MON_MAGE, 1, NULL, INFO_DEATH_SELF_MON_MAGE, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(DEATH_SELF_MON_SHAMBLER_CLAW, 1, NULL, INFO_DEATH_SELF_MON_SHAMBLER_CLAW, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(DEATH_SELF_MON_SHAMBLER_SMASH, 1, NULL, INFO_DEATH_SELF_MON_SHAMBLER_SMASH, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(DEATH_SELF_MON_SHAMBLER_ZAP, 1, NULL, INFO_DEATH_SELF_MON_SHAMBLER_ZAP, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(DEATH_SELF_MON_SPIDER, 1, NULL, INFO_DEATH_SELF_MON_SPIDER, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(DEATH_SELF_MON_WYVERN, 1, NULL, INFO_DEATH_SELF_MON_WYVERN, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(DEATH_SELF_MON_ZOMBIE_JUMP, 1, NULL, INFO_DEATH_SELF_MON_ZOMBIE_JUMP, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(DEATH_SELF_MON_ZOMBIE_MELEE, 1, NULL, INFO_DEATH_SELF_MON_ZOMBIE_MELEE, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(DEATH_SELF_NADE, 1, NULL, INFO_DEATH_SELF_NADE, CENTER_DEATH_SELF_NADE) - MSG_MULTI_NOTIF(DEATH_SELF_NADE_NAPALM, 1, NULL, INFO_DEATH_SELF_NADE_NAPALM, CENTER_DEATH_SELF_NADE_NAPALM) - MSG_MULTI_NOTIF(DEATH_SELF_NADE_ICE, 1, NULL, INFO_DEATH_SELF_NADE_ICE, CENTER_DEATH_SELF_NADE_ICE_FREEZE) - MSG_MULTI_NOTIF(DEATH_SELF_NADE_ICE_FREEZE, 1, NULL, INFO_DEATH_SELF_NADE_ICE_FREEZE, CENTER_DEATH_SELF_NADE_ICE_FREEZE) - MSG_MULTI_NOTIF(DEATH_SELF_NADE_HEAL, 1, NULL, INFO_DEATH_SELF_NADE_HEAL, CENTER_DEATH_SELF_NADE_HEAL) - MSG_MULTI_NOTIF(DEATH_SELF_NOAMMO, 1, NULL, INFO_DEATH_SELF_NOAMMO, CENTER_DEATH_SELF_NOAMMO) - MSG_MULTI_NOTIF(DEATH_SELF_ROT, 1, NULL, INFO_DEATH_SELF_ROT, CENTER_DEATH_SELF_ROT) - MSG_MULTI_NOTIF(DEATH_SELF_SHOOTING_STAR, 1, NULL, INFO_DEATH_SELF_SHOOTING_STAR, CENTER_DEATH_SELF_SHOOTING_STAR) - MSG_MULTI_NOTIF(DEATH_SELF_SLIME, 1, NULL, INFO_DEATH_SELF_SLIME, CENTER_DEATH_SELF_SLIME) - MSG_MULTI_NOTIF(DEATH_SELF_SUICIDE, 1, NULL, INFO_DEATH_SELF_SUICIDE, CENTER_DEATH_SELF_SUICIDE) - MSG_MULTI_NOTIF(DEATH_SELF_SWAMP, 1, NULL, INFO_DEATH_SELF_SWAMP, CENTER_DEATH_SELF_SWAMP) - MSG_MULTI_NOTIF(DEATH_SELF_TEAMCHANGE, 1, NULL, INFO_DEATH_SELF_TEAMCHANGE, CENTER_DEATH_SELF_TEAMCHANGE) - MSG_MULTI_NOTIF(DEATH_SELF_TOUCHEXPLODE, 1, NULL, INFO_DEATH_SELF_TOUCHEXPLODE, CENTER_DEATH_SELF_TOUCHEXPLODE) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET, 1, NULL, INFO_DEATH_SELF_TURRET, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_EWHEEL, 1, NULL, INFO_DEATH_SELF_TURRET_EWHEEL, CENTER_DEATH_SELF_TURRET_EWHEEL) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_FLAC, 1, NULL, INFO_DEATH_SELF_TURRET_FLAC, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_HELLION, 1, NULL, INFO_DEATH_SELF_TURRET_HELLION, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_HK, 1, NULL, INFO_DEATH_SELF_TURRET_HK, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_MACHINEGUN, 1, NULL, INFO_DEATH_SELF_TURRET_MACHINEGUN, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_MLRS, 1, NULL, INFO_DEATH_SELF_TURRET_MLRS, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_PHASER, 1, NULL, INFO_DEATH_SELF_TURRET_PHASER, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_PLASMA, 1, NULL, INFO_DEATH_SELF_TURRET_PLASMA, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_TESLA, 1, NULL, INFO_DEATH_SELF_TURRET_TESLA, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_WALK_GUN, 1, NULL, INFO_DEATH_SELF_TURRET_WALK_GUN, CENTER_DEATH_SELF_TURRET_WALK) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_WALK_MELEE, 1, NULL, INFO_DEATH_SELF_TURRET_WALK_MELEE, CENTER_DEATH_SELF_TURRET_WALK) - MSG_MULTI_NOTIF(DEATH_SELF_TURRET_WALK_ROCKET, 1, NULL, INFO_DEATH_SELF_TURRET_WALK_ROCKET, CENTER_DEATH_SELF_TURRET_WALK) - MSG_MULTI_NOTIF(DEATH_SELF_VH_BUMB_DEATH, 1, NULL, INFO_DEATH_SELF_VH_BUMB_DEATH, CENTER_DEATH_SELF_VH_BUMB_DEATH) - MSG_MULTI_NOTIF(DEATH_SELF_VH_CRUSH, 1, NULL, INFO_DEATH_SELF_VH_CRUSH, CENTER_DEATH_SELF_VH_CRUSH) - MSG_MULTI_NOTIF(DEATH_SELF_VH_RAPT_BOMB, 1, NULL, INFO_DEATH_SELF_VH_RAPT_BOMB, CENTER_DEATH_SELF_VH_RAPT_BOMB) - MSG_MULTI_NOTIF(DEATH_SELF_VH_RAPT_DEATH, 1, NULL, INFO_DEATH_SELF_VH_RAPT_DEATH, CENTER_DEATH_SELF_VH_RAPT_DEATH) - MSG_MULTI_NOTIF(DEATH_SELF_VH_SPID_DEATH, 1, NULL, INFO_DEATH_SELF_VH_SPID_DEATH, CENTER_DEATH_SELF_VH_SPID_DEATH) - MSG_MULTI_NOTIF(DEATH_SELF_VH_SPID_ROCKET, 1, NULL, INFO_DEATH_SELF_VH_SPID_ROCKET, CENTER_DEATH_SELF_VH_SPID_ROCKET) - MSG_MULTI_NOTIF(DEATH_SELF_VH_WAKI_DEATH, 1, NULL, INFO_DEATH_SELF_VH_WAKI_DEATH, CENTER_DEATH_SELF_VH_WAKI_DEATH) - MSG_MULTI_NOTIF(DEATH_SELF_VH_WAKI_ROCKET, 1, NULL, INFO_DEATH_SELF_VH_WAKI_ROCKET, CENTER_DEATH_SELF_VH_WAKI_ROCKET) - MSG_MULTI_NOTIF(DEATH_SELF_VOID, 1, NULL, INFO_DEATH_SELF_VOID, CENTER_DEATH_SELF_VOID) - - MSG_MULTI_NOTIF(ITEM_BUFF_DROP, 1, NULL, INFO_ITEM_BUFF_DROP, CENTER_ITEM_BUFF_DROP) - MSG_MULTI_NOTIF(ITEM_BUFF_GOT, 1, NULL, INFO_ITEM_BUFF_GOT, CENTER_ITEM_BUFF_GOT) - MSG_MULTI_NOTIF(ITEM_WEAPON_DONTHAVE, 1, NULL, INFO_ITEM_WEAPON_DONTHAVE, CENTER_ITEM_WEAPON_DONTHAVE) - MSG_MULTI_NOTIF(ITEM_WEAPON_DROP, 1, NULL, INFO_ITEM_WEAPON_DROP, CENTER_ITEM_WEAPON_DROP) - MSG_MULTI_NOTIF(ITEM_WEAPON_GOT, 1, NULL, INFO_ITEM_WEAPON_GOT, CENTER_ITEM_WEAPON_GOT) - MSG_MULTI_NOTIF(ITEM_WEAPON_NOAMMO, 1, NULL, INFO_ITEM_WEAPON_NOAMMO, CENTER_ITEM_WEAPON_NOAMMO) - MSG_MULTI_NOTIF(ITEM_WEAPON_PRIMORSEC, 1, NULL, INFO_ITEM_WEAPON_PRIMORSEC, CENTER_ITEM_WEAPON_PRIMORSEC) - MSG_MULTI_NOTIF(ITEM_WEAPON_UNAVAILABLE, 1, NULL, INFO_ITEM_WEAPON_UNAVAILABLE, CENTER_ITEM_WEAPON_UNAVAILABLE) - - MSG_MULTI_NOTIF(MULTI_COINTOSS, 1, NULL, INFO_COINTOSS, CENTER_COINTOSS) - MSG_MULTI_NOTIF(MULTI_COUNTDOWN_BEGIN, 1, ANNCE_BEGIN, NULL, CENTER_COUNTDOWN_BEGIN) - MSG_MULTI_NOTIF(MULTI_INSTAGIB_FINDAMMO, 1, ANNCE_NUM_10, NULL, CENTER_INSTAGIB_FINDAMMO_FIRST) - - MSG_MULTI_NOTIF(WEAPON_ACCORDEON_MURDER, 1, NULL, INFO_WEAPON_ACCORDEON_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_ACCORDEON_SUICIDE, 1, NULL, INFO_WEAPON_ACCORDEON_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_ARC_MURDER, 1, NULL, INFO_WEAPON_ARC_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_ARC_MURDER_SPRAY, 1, NULL, INFO_WEAPON_ARC_MURDER_SPRAY, NULL) - MSG_MULTI_NOTIF(WEAPON_BLASTER_MURDER, 1, NULL, INFO_WEAPON_BLASTER_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_BLASTER_SUICIDE, 1, NULL, INFO_WEAPON_BLASTER_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_CRYLINK_MURDER, 1, NULL, INFO_WEAPON_CRYLINK_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_CRYLINK_SUICIDE, 1, NULL, INFO_WEAPON_CRYLINK_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_DEVASTATOR_MURDER_DIRECT, 1, NULL, INFO_WEAPON_DEVASTATOR_MURDER_DIRECT, NULL) - MSG_MULTI_NOTIF(WEAPON_DEVASTATOR_MURDER_SPLASH, 1, NULL, INFO_WEAPON_DEVASTATOR_MURDER_SPLASH, NULL) - MSG_MULTI_NOTIF(WEAPON_DEVASTATOR_SUICIDE, 1, NULL, INFO_WEAPON_DEVASTATOR_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_ELECTRO_MURDER_BOLT, 1, NULL, INFO_WEAPON_ELECTRO_MURDER_BOLT, NULL) - MSG_MULTI_NOTIF(WEAPON_ELECTRO_MURDER_COMBO, 1, NULL, INFO_WEAPON_ELECTRO_MURDER_COMBO, NULL) - MSG_MULTI_NOTIF(WEAPON_ELECTRO_MURDER_ORBS, 1, NULL, INFO_WEAPON_ELECTRO_MURDER_ORBS, NULL) - MSG_MULTI_NOTIF(WEAPON_ELECTRO_SUICIDE_BOLT, 1, NULL, INFO_WEAPON_ELECTRO_SUICIDE_BOLT, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_ELECTRO_SUICIDE_ORBS, 1, NULL, INFO_WEAPON_ELECTRO_SUICIDE_ORBS, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_FIREBALL_MURDER_BLAST, 1, NULL, INFO_WEAPON_FIREBALL_MURDER_BLAST, NULL) - MSG_MULTI_NOTIF(WEAPON_FIREBALL_MURDER_FIREMINE, 1, NULL, INFO_WEAPON_FIREBALL_MURDER_FIREMINE, NULL) - MSG_MULTI_NOTIF(WEAPON_FIREBALL_SUICIDE_BLAST, 1, NULL, INFO_WEAPON_FIREBALL_SUICIDE_BLAST, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_FIREBALL_SUICIDE_FIREMINE, 1, NULL, INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_HAGAR_MURDER_BURST, 1, NULL, INFO_WEAPON_HAGAR_MURDER_BURST, NULL) - MSG_MULTI_NOTIF(WEAPON_HAGAR_MURDER_SPRAY, 1, NULL, INFO_WEAPON_HAGAR_MURDER_SPRAY, NULL) - MSG_MULTI_NOTIF(WEAPON_HAGAR_SUICIDE, 1, NULL, INFO_WEAPON_HAGAR_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_HLAC_MURDER, 1, NULL, INFO_WEAPON_HLAC_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_HLAC_SUICIDE, 1, NULL, INFO_WEAPON_HLAC_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_HMG_MURDER_SNIPE, 1, NULL, INFO_WEAPON_HMG_MURDER_SNIPE, NULL) - MSG_MULTI_NOTIF(WEAPON_HMG_MURDER_SPRAY, 1, NULL, INFO_WEAPON_HMG_MURDER_SPRAY, NULL) - MSG_MULTI_NOTIF(WEAPON_HOOK_MURDER, 1, NULL, INFO_WEAPON_HOOK_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_KLEINBOTTLE_MURDER, 1, NULL, INFO_WEAPON_KLEINBOTTLE_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_KLEINBOTTLE_SUICIDE, 1, NULL, INFO_WEAPON_KLEINBOTTLE_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_MACHINEGUN_MURDER_SNIPE, 1, NULL, INFO_WEAPON_MACHINEGUN_MURDER_SNIPE, NULL) - MSG_MULTI_NOTIF(WEAPON_MACHINEGUN_MURDER_SPRAY, 1, NULL, INFO_WEAPON_MACHINEGUN_MURDER_SPRAY, NULL) - MSG_MULTI_NOTIF(WEAPON_MINELAYER_LIMIT, 1, NULL, INFO_WEAPON_MINELAYER_LIMIT, CENTER_WEAPON_MINELAYER_LIMIT) - MSG_MULTI_NOTIF(WEAPON_MINELAYER_MURDER, 1, NULL, INFO_WEAPON_MINELAYER_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_MINELAYER_SUICIDE, 1, NULL, INFO_WEAPON_MINELAYER_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_MORTAR_MURDER_BOUNCE, 1, NULL, INFO_WEAPON_MORTAR_MURDER_BOUNCE, NULL) - MSG_MULTI_NOTIF(WEAPON_MORTAR_MURDER_EXPLODE, 1, NULL, INFO_WEAPON_MORTAR_MURDER_EXPLODE, NULL) - MSG_MULTI_NOTIF(WEAPON_MORTAR_SUICIDE_BOUNCE, 1, NULL, INFO_WEAPON_MORTAR_SUICIDE_BOUNCE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_MORTAR_SUICIDE_EXPLODE, 1, NULL, INFO_WEAPON_MORTAR_SUICIDE_EXPLODE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER, 1, NULL, INFO_WEAPON_RIFLE_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER_HAIL, 1, NULL, INFO_WEAPON_RIFLE_MURDER_HAIL, NULL) - MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER_HAIL_PIERCING, 1, NULL, INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING, NULL) - MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER_PIERCING, 1, NULL, INFO_WEAPON_RIFLE_MURDER_PIERCING, NULL) - MSG_MULTI_NOTIF(WEAPON_RPC_MURDER_DIRECT, 1, NULL, INFO_WEAPON_RPC_MURDER_DIRECT, NULL) - MSG_MULTI_NOTIF(WEAPON_RPC_MURDER_SPLASH, 1, NULL, INFO_WEAPON_RPC_MURDER_SPLASH, NULL) - MSG_MULTI_NOTIF(WEAPON_RPC_SUICIDE_DIRECT, 1, NULL, INFO_WEAPON_RPC_SUICIDE_DIRECT, NULL) - MSG_MULTI_NOTIF(WEAPON_RPC_SUICIDE_SPLASH, 1, NULL, INFO_WEAPON_RPC_SUICIDE_SPLASH, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_SEEKER_MURDER_SPRAY, 1, NULL, INFO_WEAPON_SEEKER_MURDER_SPRAY, NULL) - MSG_MULTI_NOTIF(WEAPON_SEEKER_MURDER_TAG, 1, NULL, INFO_WEAPON_SEEKER_MURDER_TAG, NULL) - MSG_MULTI_NOTIF(WEAPON_SEEKER_SUICIDE, 1, NULL, INFO_WEAPON_SEEKER_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_SHOCKWAVE_MURDER, 1, NULL, INFO_WEAPON_SHOCKWAVE_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_SHOCKWAVE_MURDER_SLAP, 1, NULL, INFO_WEAPON_SHOCKWAVE_MURDER_SLAP, NULL) - MSG_MULTI_NOTIF(WEAPON_SHOTGUN_MURDER, 1, NULL, INFO_WEAPON_SHOTGUN_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_SHOTGUN_MURDER_SLAP, 1, NULL, INFO_WEAPON_SHOTGUN_MURDER_SLAP, NULL) - MSG_MULTI_NOTIF(WEAPON_THINKING_WITH_PORTALS, 1, NULL, INFO_WEAPON_THINKING_WITH_PORTALS, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_TUBA_MURDER, 1, NULL, INFO_WEAPON_TUBA_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_TUBA_SUICIDE, 1, NULL, INFO_WEAPON_TUBA_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(WEAPON_VAPORIZER_MURDER, 1, NULL, INFO_WEAPON_VAPORIZER_MURDER, NULL) - MSG_MULTI_NOTIF(WEAPON_VORTEX_MURDER, 1, NULL, INFO_WEAPON_VORTEX_MURDER, NULL) - -#define MULTITEAM_CHOICE2(prefix, default, challow, chtype, optiona, optionb) \ - MSG_CHOICE_NOTIF(prefix##_RED, default, challow, chtype, optiona##_RED, optionb##_RED) \ - MSG_CHOICE_NOTIF(prefix##_BLUE, default, challow, chtype, optiona##_BLUE, optionb##_BLUE) -#define MULTITEAM_CHOICE3(prefix, default, challow, chtype, optiona, optionb) \ - MULTITEAM_CHOICE2(prefix, default, challow, chtype, optiona, optionb) \ - MSG_CHOICE_NOTIF(prefix##_YELLOW, default, challow, chtype, optiona##_YELLOW, optionb##_YELLOW) -#define MULTITEAM_CHOICE4(prefix, default, challow, chtype, optiona, optionb) \ - MULTITEAM_CHOICE3(prefix, default, challow, chtype, optiona, optionb) \ - MSG_CHOICE_NOTIF(prefix##_PINK, default, challow, chtype, optiona##_PINK, optionb##_PINK) -#define MULTITEAM_CHOICE(prefix, teams, default, challow, chtype, optiona, optionb) \ - MULTITEAM_CHOICE##teams(prefix, default, challow, chtype, optiona, optionb) - -// MSG_CHOICE_NOTIFICATIONS - MULTITEAM_CHOICE(CTF_CAPTURE_BROKEN, 4, 1, 2, MSG_INFO, INFO_CTF_CAPTURE, INFO_CTF_CAPTURE_BROKEN) - MULTITEAM_CHOICE(CTF_CAPTURE_TIME, 4, 1, 2, MSG_INFO, INFO_CTF_CAPTURE, INFO_CTF_CAPTURE_TIME) - MULTITEAM_CHOICE(CTF_CAPTURE_UNBROKEN, 4, 1, 2, MSG_INFO, INFO_CTF_CAPTURE, INFO_CTF_CAPTURE_UNBROKEN) - MULTITEAM_CHOICE(CTF_PICKUP_TEAM, 4, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_TEAM, CENTER_CTF_PICKUP_TEAM_VERBOSE) - MSG_CHOICE_NOTIF(CTF_PICKUP_TEAM_NEUTRAL, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_TEAM_NEUTRAL, CENTER_CTF_PICKUP_TEAM_VERBOSE_NEUTRAL) - MSG_CHOICE_NOTIF(CTF_PICKUP_ENEMY, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY, CENTER_CTF_PICKUP_ENEMY_VERBOSE) - MSG_CHOICE_NOTIF(CTF_PICKUP_ENEMY_NEUTRAL, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_NEUTRAL, CENTER_CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE) - MSG_CHOICE_NOTIF(CTF_PICKUP_ENEMY_TEAM, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_TEAM, CENTER_CTF_PICKUP_ENEMY_TEAM_VERBOSE) - MSG_CHOICE_NOTIF(FRAG, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_FRAG, CENTER_DEATH_MURDER_FRAG_VERBOSE) - MSG_CHOICE_NOTIF(FRAGGED, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED, CENTER_DEATH_MURDER_FRAGGED_VERBOSE) - MSG_CHOICE_NOTIF(TYPEFRAG, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE) - MSG_CHOICE_NOTIF(TYPEFRAGGED, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAGGED, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE) diff --git a/qcsrc/common/notifications.qc b/qcsrc/common/notifications.qc deleted file mode 100644 index 5bfcfce5f..000000000 --- a/qcsrc/common/notifications.qc +++ /dev/null @@ -1,1775 +0,0 @@ -#if defined(CSQC) - #include "../client/announcer.qh" -#elif defined(MENUQC) -#elif defined(SVQC) - #include "constants.qh" - #include "teams.qh" - #include "../server/autocvars.qh" - #include "../server/constants.qh" - #include "../server/defs.qh" - #include "notifications.qh" - #include -#endif - -// ================================================ -// Unified notification system, written by Samual -// Last updated: August, 2013 -// ================================================ - -#ifdef SVQC -string Notification_CheckArgs( - NOTIF broadcast, entity client) -{ - // check supplied broadcast and target for errors - switch (broadcast) - { - case NOTIF_ONE: - case NOTIF_ONE_ONLY: - { - if (IS_NOT_A_CLIENT(client)) { - return "No client provided!"; - } - break; - } - - case NOTIF_ALL_EXCEPT: - { - if (IS_NOT_A_CLIENT(client)) { - return "Exception can't be a non-client!"; - } - break; - } - - case NOTIF_ALL: - { - if (client) { - return "Entity provided when world was required!"; - } - break; - } - - case NOTIF_TEAM: - { - if (!teamplay) { - return "Teamplay not active!"; - } else if (!client.team) { - // checkargs = sprintf("%sNo team provided!", checkargs); - } - break; - } - - case NOTIF_TEAM_EXCEPT: - { - if (!teamplay) { - return "Teamplay not active!"; - } else if (IS_NOT_A_CLIENT(client)) { - return "Exception can't be a non-client!"; - } - break; - } - - default: - { - return sprintf("Improper broadcast: %d!", broadcast); - } - } - return ""; -} - -bool Notification_ShouldSend(NOTIF broadcast, entity to_client, entity other_client) -{ - switch (broadcast) - { - case NOTIF_ONE: - return ( - (to_client == other_client) - || - ( - IS_SPEC(to_client) - && - (to_client.enemy == other_client) - ) - ); - case NOTIF_ONE_ONLY: - return (to_client == other_client); - case NOTIF_TEAM: - return ( - (to_client.team == other_client.team) - || - ( - IS_SPEC(to_client) - && - (to_client.enemy.team == other_client.team) - ) - ); - case NOTIF_TEAM_EXCEPT: - return ( - (to_client != other_client) - && - ( - (to_client.team == other_client.team) - || - ( - IS_SPEC(to_client) - && - ( - (to_client.enemy != other_client) - && - (to_client.enemy.team == other_client.team) - ) - ) - ) - ); - case NOTIF_ALL: - return true; - case NOTIF_ALL_EXCEPT: - return ( - (to_client != other_client) - && - !( - IS_SPEC(to_client) - && - (to_client.enemy == other_client) - ) - ); - default: - return false; - } -} - -#endif - -// =============================== -// Initialization Core Functions -// =============================== - -// used by restartnotifs command to initialize notifications -void Destroy_Notification_Entity(entity notif) -{ - if (notif.nent_name != "") strunzone(notif.nent_name); - if (notif.nent_snd != "") strunzone(notif.nent_snd); - if (notif.nent_args != "") strunzone(notif.nent_args); - if (notif.nent_hudargs != "") strunzone(notif.nent_hudargs); - if (notif.nent_icon != "") strunzone(notif.nent_icon); - if (notif.nent_durcnt != "") strunzone(notif.nent_durcnt); - if (notif.nent_string != "") strunzone(notif.nent_string); - remove(notif); -} - -void Destroy_All_Notifications() -{ - // kill all networked notifications and centerprints - #ifdef SVQC - Kill_Notification(NOTIF_ALL, NULL, MSG_Null, CPID_Null); - #else - reset_centerprint_messages(); - #endif - - // kill all real notification entities - FOREACH(Notifications, true, { Destroy_Notification_Entity(it); }); -} - -string Process_Notif_Line( - MSG typeId, - bool chat, - string input, - string notiftype, - string notifname, - string stringtype) -{ - #ifdef CSQC - if(typeId == MSG_INFO) - { - if((chat && autocvar_notification_allow_chatboxprint) - || (autocvar_notification_allow_chatboxprint == 2)) - { - // pass 1: add ETX char at beginning of line - input = strcat("\{3}", input); - - // pass 2: add ETX char at end of each new line (so that - // messages with multiple lines are put through chatbox too) - input = strreplace("\n", "\n\{3}", input); - - // pass 3: strip trailing ETX char - if(substring(input, (strlen(input) - 1), 1) == "\{3}") - { input = substring(input, 0, (strlen(input) - 1)); } - } - } - #endif - - // done to both MSG_INFO and MSG_CENTER - if(substring(input, (strlen(input) - 1), 1) == "\n") - { - LOG_INFOF( - ( - "^1TRAILING NEW LINE AT END OF NOTIFICATION: " - "^7net_type = %s, net_name = %s, string = %s.\n" - ), - notiftype, - notifname, - stringtype - ); - notif_error = true; - input = substring(input, 1, (strlen(input) - 1)); - } - - return input; -} - -string Process_Notif_Args( - float arg_type, - string args, - string notiftype, - string notifname) -{ - string selected, remaining = args; - float sel_num = 0; - - for (;(remaining != "");) - { - selected = car(remaining); remaining = cdr(remaining); - - switch(arg_type) - { - case 1: // normal args - { - if(sel_num == NOTIF_MAX_ARGS) - { - LOG_INFOF( - ( - "^1NOTIFICATION HAS TOO MANY ARGUMENTS: " - "^7net_type = %s, net_name = %s, max args = %d.\n" - ), - notiftype, - notifname, - NOTIF_MAX_ARGS - ); - notif_error = true; - break; - } - - switch(strtolower(selected)) - { - #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_CS(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_SV(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_DC(selected,result) - #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: - { - LOG_INFOF( - ( - "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: " - "^7net_type = %s, net_name = %s, args arg = '%s'.\n" - ), - notiftype, - notifname, - selected - ); - notif_error = true; - break; - } - } - break; - } - case 2: // hudargs - { - if(sel_num == NOTIF_MAX_HUDARGS) - { - LOG_INFOF( - ( - "^1NOTIFICATION HAS TOO MANY ARGUMENTS: " - "^7net_type = %s, net_name = %s, max hudargs = %d.\n" - ), - notiftype, - notifname, - NOTIF_MAX_HUDARGS - ); - notif_error = true; - break; - } - - switch(strtolower(selected)) - { - #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV_DC(selected,result) - #define ARG_CASE_ARG_CS_SV(selected,result) - #define ARG_CASE_ARG_CS(selected,result) - #define ARG_CASE_ARG_SV(selected,result) - #define ARG_CASE_ARG_DC(selected,result) - #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: - { - LOG_INFOF( - ( - "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: " - "^7net_type = %s, net_name = %s, hudargs arg = '%s'.\n" - ), - notiftype, - notifname, - selected - ); - notif_error = true; - break; - } - } - break; - } - case 3: // durcnt - { - if(sel_num == NOTIF_MAX_DURCNT) - { - LOG_INFOF( - ( - "^1NOTIFICATION HAS TOO MANY ARGUMENTS: " - "^7net_type = %s, net_name = %s, max durcnt = %d.\n" - ), - notiftype, - notifname, - NOTIF_MAX_DURCNT - ); - notif_error = true; - break; - } - - switch(strtolower(selected)) - { - #define ARG_CASE_ARG_CS_SV_HA(selected,result) - #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV(selected,result) - #define ARG_CASE_ARG_CS(selected,result) - #define ARG_CASE_ARG_SV(selected,result) - #define ARG_CASE_ARG_DC(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: - { - if(ftos(stof(selected)) != "") { ++sel_num; } - else - { - LOG_INFOF( - ( - "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: " - "^7net_type = %s, net_name = %s, durcnt arg = '%s'.\n" - ), - notiftype, - notifname, - selected - ); - notif_error = true; - } - break; - } - } - break; - } - } - } - return args; -} - -void Create_Notification_Entity(entity notif, - float var_default, - float var_cvar, - MSG typeId, - string namestring) -{ - // ===================== - // Global Entity Setup - // ===================== - notif.nent_default = var_default; - notif.nent_enabled = (var_cvar >= 1); - notif.nent_type = typeId; - notif.nent_name = strzone(namestring); - - // Other pre-notif-setup requisites - notif_error = false; - - switch (typeId) - { - case MSG_ANNCE: - case MSG_INFO: - case MSG_CENTER: - case MSG_MULTI: - case MSG_CHOICE: - break; - default: - LOG_INFOF( - ( - "^1NOTIFICATION WITH IMPROPER TYPE: " - "^7net_type = %d, net_name = %s.\n" - ), - typeId, - namestring - ); - notif_error = true; - break; - } - - // now check to see if any errors happened - if (notif_error) - { - notif.nent_enabled = false; // disable the notification so it can't cause trouble - notif_global_error = true; // throw the red flag that an error happened on init - } -} - -void Create_Notification_Entity_Annce(entity notif, - float var_cvar, - string namestring, - /* MSG_ANNCE */ - float channel, - string snd, - float vol, - float position) - { - // Set MSG_ANNCE information and handle precaching - #ifdef CSQC - MSG typeId = MSG_ANNCE; - if (!(GENTLE && (var_cvar == 1))) - { - if(snd != "") - { - if(notif.nent_enabled) - { - precache_sound(sprintf("announcer/%s/%s.wav", AnnouncerOption(), snd)); - notif.nent_channel = channel; - notif.nent_snd = strzone(snd); - notif.nent_vol = vol; - notif.nent_position = position; - } - } - else - { - string typestring = Get_Notif_TypeName(typeId); - LOG_INFOF( - ( - "^1NOTIFICATION WITH NO SOUND: " - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - } - else { notif.nent_enabled = false; } - #else - notif.nent_enabled = false; - #endif - - } - -void Create_Notification_Entity_InfoCenter(entity notif, - float var_cvar, - string namestring, - int strnum, - int flnum, - /* MSG_INFO & MSG_CENTER */ - string args, - string hudargs, - string icon, - CPID cpid, - string durcnt, - string normal, - string gentle) - { - MSG typeId = notif.nent_type; - // Set MSG_INFO and MSG_CENTER string/float counts - notif.nent_stringcount = strnum; - notif.nent_floatcount = flnum; - - // Only initialize arguments if we're either a client or on a dedicated server - #ifdef SVQC - float should_process_args = server_is_dedicated; - #else - float should_process_args = true; - #endif - string typestring = Get_Notif_TypeName(typeId); - if(should_process_args) - { - // ======================== - // Process Main Arguments - // ======================== - if(strnum + flnum) - { - if(args != "") - { - notif.nent_args = strzone( - Process_Notif_Args(1, args, typestring, namestring)); - } - else if((hudargs == "") && (durcnt =="")) - { - LOG_INFOF( - ( - "^1NOTIFICATION HAS ARG COUNTS BUT NO ARGS OR HUDARGS OR DURCNT: " - "^7net_type = %s, net_name = %s, strnum = %d, flnum = %d\n" - ), - typestring, - namestring, - strnum, - flnum - ); - notif_error = true; - } - } - else if(args != "") - { - notif.nent_args = strzone( - Process_Notif_Args(1, args, typestring, namestring)); - } - - - // ======================================= - // Process HUD and Centerprint Arguments - // Only processed on CSQC, as these - // args are only for HUD features. - // ======================================= - #ifdef CSQC - if(hudargs != "") - { - notif.nent_hudargs = strzone( - Process_Notif_Args(2, hudargs, typestring, namestring)); - - if(icon != "") { notif.nent_icon = strzone(icon); } - else - { - LOG_INFOF( - ( - "^1NOTIFICATION HAS HUDARGS BUT NO ICON: " - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - } - else if(icon != "") - { - LOG_WARNINGF( - ( - "^1NOTIFICATION HAS ICON BUT NO HUDARGS: " - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - - if (durcnt != "") - { - notif.nent_durcnt = strzone(Process_Notif_Args(3, durcnt, typestring, namestring)); - - if (cpid == CPID_Null && durcnt != "0 0") - { - LOG_WARNINGF( - ( - "Notification has durcnt but no cpid: " - "net_type = %s, net_name = %s." - ), - typestring, - namestring - ); - notif_error = true; - } - } - notif.nent_cpid = cpid; - #endif - - - // ====================== - // Process Notif String - // ====================== - #define SET_NOTIF_STRING(string,stringname) MACRO_BEGIN { \ - notif.nent_string = strzone(CCR( \ - Process_Notif_Line( \ - typeId, \ - (var_cvar > 1), \ - string, \ - typestring, \ - namestring, \ - stringname \ - )) \ - ); \ - } MACRO_END - - if(GENTLE) - { - if(gentle != "") { SET_NOTIF_STRING(gentle, "GENTLE"); } - else if(normal != "") { SET_NOTIF_STRING(normal, "NORMAL"); } - } - else if(normal != "") { SET_NOTIF_STRING(normal, "NORMAL"); } - #undef SET_NOTIF_STRING - - // Check to make sure a string was chosen - if(notif.nent_string == "") - { - LOG_INFOF( - ( - "^1EMPTY NOTIFICATION: " - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - } - } - -void Create_Notification_Entity_Multi(entity notif, - float var_cvar, - string namestring, - /* MSG_MULTI */ - Notification anncename, - Notification infoname, - Notification centername) - { - MSG typeId = MSG_MULTI; - // Set MSG_MULTI string/float counts - if (!anncename && !infoname && !centername) - { - string typestring = Get_Notif_TypeName(typeId); - LOG_INFOF( - ( - "^1NOTIFICATION WITH NO SUBCALLS: " - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - else - { - // announcements don't actually need any arguments, so lets not even count them. - if (anncename) { notif.nent_msgannce = anncename; } - - float infoname_stringcount = 0, infoname_floatcount = 0; - float centername_stringcount = 0, centername_floatcount = 0; - - if (infoname) - { - notif.nent_msginfo = infoname; - infoname_stringcount = notif.nent_msginfo.nent_stringcount; - infoname_floatcount = notif.nent_msginfo.nent_floatcount; - } - - if (centername) - { - notif.nent_msgcenter = centername; - centername_stringcount = notif.nent_msgcenter.nent_stringcount; - centername_floatcount = notif.nent_msgcenter.nent_floatcount; - } - - // set the requirements of THIS notification to the totals of its subcalls - notif.nent_stringcount = max(infoname_stringcount, centername_stringcount); - notif.nent_floatcount = max(infoname_floatcount, centername_floatcount); - } - } - -void Create_Notification_Entity_Choice(entity notif, - float var_cvar, - string namestring, - /* MSG_CHOICE */ - float challow_def, - float challow_var, - MSG chtype, - Notification optiona, - Notification optionb) - { - MSG typeId = MSG_CHOICE; - if (chtype == MSG_Null || !optiona || !optionb) - { - string typestring = Get_Notif_TypeName(typeId); - LOG_INFOF( - ( - "^1NOTIFICATION IS MISSING CHOICE PARAMS: " - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - else - { - notif.nent_optiona = optiona; - notif.nent_optionb = optionb; - notif.nent_challow_def = challow_def; // 0: never allowed, 1: allowed in warmup, 2: always allowed - notif.nent_challow_var = challow_var; // 0: never allowed, 1: allowed in warmup, 2: always allowed - notif.nent_stringcount = max(notif.nent_optiona.nent_stringcount, notif.nent_optionb.nent_stringcount); - notif.nent_floatcount = max(notif.nent_optiona.nent_floatcount, notif.nent_optionb.nent_floatcount); - - /*#ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Create_Notification_Entity(...): MSG_CHOICE: %s\n%s\n%s\n", - notif.nent_name, - sprintf( - "^ optiona: %s %s : %d %d", - Get_Notif_TypeName(notif.nent_optiona.nent_type), - notif.nent_optiona.nent_name, - notif.nent_optiona.nent_stringcount, - notif.nent_optiona.nent_floatcount - ), - sprintf( - "^ optionb: %s %s : %d %d", - Get_Notif_TypeName(notif.nent_optionb.nent_type), - notif.nent_optionb.nent_name, - notif.nent_optionb.nent_stringcount, - notif.nent_optionb.nent_floatcount - ) - )); - #endif*/ - } - } - - -// =============== -// Cvar Handling -// =============== - -// used by MSG_CHOICE to build list of choices -#ifdef SVQC -void Notification_GetCvars() -{ - int idx = 0; - FOREACH(Notifications, it.nent_type == MSG_CHOICE, { - GetCvars_handleFloat( - get_cvars_s, - get_cvars_f, - msg_choice_choices[idx++], - sprintf("notification_%s", it.nent_name) - ); - }); -} -#endif - -/** used to output notifications.cfg file */ -void Dump_Notifications(int fh, bool alsoprint) -{ - #define NOTIF_WRITE(a) MACRO_BEGIN { \ - fputs(fh, a); \ - if (alsoprint) LOG_INFO(a); \ - } MACRO_END - - #define NOTIF_WRITE_ENTITY(e, description) MACRO_BEGIN { \ - string notif_msg = sprintf( \ - "seta notification_%s \"%d\" \"%s\"\n", \ - e.nent_name, e.nent_default, description \ - ); \ - NOTIF_WRITE(notif_msg); \ - } MACRO_END - - #define NOTIF_WRITE_ENTITY_CHOICE(e, descriptiona, descriptionb) MACRO_BEGIN { \ - string notif_msg = sprintf( \ - "seta notification_%s \"%d\" \"%s\"\n" \ - "seta notification_%s_ALLOWED \"%d\" \"%s\"\n", \ - e.nent_name, e.nent_default, descriptiona, \ - e.nent_name, e.nent_challow_def, descriptionb \ - ); \ - NOTIF_WRITE(notif_msg); \ - } MACRO_END - - #define NOTIF_WRITE_HARDCODED(cvar, default, description) MACRO_BEGIN { \ - string notif_msg = sprintf( \ - "seta notification_%s \"%s\" \"%s\"\n", \ - cvar, default, description \ - ); \ - NOTIF_WRITE(notif_msg); \ - } MACRO_END - - // Note: This warning only applies to the notifications.cfg file that is output... - // You ARE supposed to manually edit this function to add i.e. hard coded - // notification variables for mutators or game modes or such and then - // regenerate the notifications.cfg file from the new code. - - NOTIF_WRITE("// ********************************************** //\n"); - NOTIF_WRITE("// ** WARNING - DO NOT MANUALLY EDIT THIS FILE ** //\n"); - NOTIF_WRITE("// ** ** //\n"); - NOTIF_WRITE("// ** This file is automatically generated ** //\n"); - NOTIF_WRITE("// ** by code with the command 'dumpnotifs'. ** //\n"); - NOTIF_WRITE("// ** ** //\n"); - NOTIF_WRITE("// ** If you add a new notification, please ** //\n"); - NOTIF_WRITE("// ** regenerate this file with that command ** //\n"); - NOTIF_WRITE("// ** making sure that the output matches ** //\n"); - NOTIF_WRITE("// ** with the lists and defaults in code. ** //\n"); - NOTIF_WRITE("// ** ** //\n"); - NOTIF_WRITE("// ********************************************** //\n"); - - // These notifications will also append their string as a comment... - // This is not necessary, and does not matter if they vary between config versions, - // it is just a semi-helpful tool for those who want to manually change their user settings. - - int NOTIF_ANNCE_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_ANNCE, { ++NOTIF_ANNCE_COUNT; }); - NOTIF_WRITE(sprintf("\n// MSG_ANNCE notifications (count = %d):\n", NOTIF_ANNCE_COUNT)); - FOREACH(Notifications, it.nent_type == MSG_ANNCE, { - NOTIF_WRITE_ENTITY(it, - "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" - ); - }); - - int NOTIF_INFO_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_INFO, { ++NOTIF_INFO_COUNT; }); - NOTIF_WRITE(sprintf("\n// MSG_INFO notifications (count = %d):\n", NOTIF_INFO_COUNT)); - FOREACH(Notifications, it.nent_type == MSG_INFO, { - NOTIF_WRITE_ENTITY(it, - "0 = off, 1 = print to console, " - "2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" - ); - }); - - int NOTIF_CENTER_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_CENTER, { ++NOTIF_CENTER_COUNT; }); - NOTIF_WRITE(sprintf("\n// MSG_CENTER notifications (count = %d):\n", NOTIF_CENTER_COUNT)); - FOREACH(Notifications, it.nent_type == MSG_CENTER, { - NOTIF_WRITE_ENTITY(it, - "0 = off, 1 = centerprint" - ); - }); - - int NOTIF_MULTI_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_MULTI, { ++NOTIF_MULTI_COUNT; }); - NOTIF_WRITE(sprintf("\n// MSG_MULTI notifications (count = %d):\n", NOTIF_MULTI_COUNT)); - FOREACH(Notifications, it.nent_type == MSG_MULTI, { - NOTIF_WRITE_ENTITY(it, - "Enable this multiple notification" - ); - }); - - int NOTIF_CHOICE_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_CHOICE, { ++NOTIF_CHOICE_COUNT; }); - NOTIF_WRITE(sprintf("\n// MSG_CHOICE notifications (count = %d):\n", NOTIF_CHOICE_COUNT)); - FOREACH(Notifications, it.nent_type == MSG_CHOICE, { - NOTIF_WRITE_ENTITY_CHOICE(it, - "Choice for this notification 0 = off, 1 = default message, 2 = verbose message", - "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" - ); - }); - - // edit these to match whichever cvars are used for specific notification options - NOTIF_WRITE("\n// HARD CODED notification variables:\n"); - - NOTIF_WRITE_HARDCODED( - "allow_chatboxprint", "1", - "Allow INFO notifications to be printed to chat box" - "0 = do not allow, " - "1 = allow only if allowed by individual notification_INFO* cvars, " - "2 = force all INFO notifications to be printed to the chatbox" - ); - - NOTIF_WRITE_HARDCODED( - "debug", "0", - "Print extra debug information on all notification function calls " - "(Requires -DNOTIFICATIONS_DEBUG flag to be enabled on QCSRC compilation)... " - "0 = disabled, 1 = dprint, 2 = print" - ); - - NOTIF_WRITE_HARDCODED( - "errors_are_fatal", "1", - "If a notification fails upon initialization, cause a Host_Error to stop the program" - ); - - NOTIF_WRITE_HARDCODED( - "item_centerprinttime", "1.5", - "How long to show item information centerprint messages (like 'You got the Electro' or such)" - ); - - NOTIF_WRITE_HARDCODED( - "lifetime_mapload", "10", - "Amount of time that notification entities last immediately at mapload (in seconds) " - "to help prevent notifications from being lost on early init (like gamestart countdown)" - ); - - NOTIF_WRITE_HARDCODED( - "lifetime_runtime", "0.5", - "Amount of time that notification entities last on the server during runtime (In seconds)" - ); - - NOTIF_WRITE_HARDCODED( - "server_allows_location", "1", - "Server side cvar for allowing death messages to show location information too" - ); - - NOTIF_WRITE_HARDCODED( - "show_location", "0", - "Append location information to MSG_INFO death/kill messages" - ); - - NOTIF_WRITE_HARDCODED( - "show_location_string", "", - "Replacement string piped into sprintf, " - "so you can do different messages like this: ' at the %s' or ' (near %s)'" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees", "1", - "Print information about sprees in death/kill messages" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees_center", "1", - "Show spree information in MSG_CENTER messages... " - "0 = off, 1 = target (but only for first victim) and attacker" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees_center_specialonly", "1", - "Don't show spree information in MSG_CENTER messages if it isn't an achievement" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees_info", "3", - "Show spree information in MSG_INFO messages... " - "0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees_info_newline", "1", - "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees_info_specialonly", "1", - "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement" - ); - - NOTIF_WRITE(sprintf( - ( - "\n// Notification counts (total = %d): " - "MSG_ANNCE = %d, MSG_INFO = %d, MSG_CENTER = %d, MSG_MULTI = %d, MSG_CHOICE = %d\n" - ), - ( - NOTIF_ANNCE_COUNT + - NOTIF_INFO_COUNT + - NOTIF_CENTER_COUNT + - NOTIF_MULTI_COUNT + - NOTIF_CHOICE_COUNT - ), - NOTIF_ANNCE_COUNT, - NOTIF_INFO_COUNT, - NOTIF_CENTER_COUNT, - NOTIF_MULTI_COUNT, - NOTIF_CHOICE_COUNT - )); - #undef NOTIF_WRITE_HARDCODED - #undef NOTIF_WRITE_ENTITY - #undef NOTIF_WRITE -} - - -// =============================== -// Frontend Notification Pushing -// =============================== - -string Local_Notification_sprintf( - string input, string args, - string s1, string s2, string s3, string s4, - int f1, float f2, float f3, float f4) -{ - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification_sprintf('%s^7', '%s', %s, %s);\n", - MakeConsoleSafe(input), - args, - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4) - )); - #endif - - for (int sel_num = 0; sel_num < NOTIF_MAX_ARGS; ++sel_num) { arg_slot[sel_num] = ""; } - - for (int sel_num = 0; (args != ""); ) - { - string selected = car(args); args = cdr(args); - NOTIF_HIT_MAX(NOTIF_MAX_ARGS, "Local_Notification_sprintf"); - string tmp_s; // used by NOTIF_ARGUMENT_LIST - switch (strtolower(selected)) - { - #define ARG_CASE_ARG_CS_SV_HA(selected, result) case selected: { arg_slot[sel_num++] = result; break; } - #define ARG_CASE_ARG_CS_SV_DC(selected, result) case selected: { arg_slot[sel_num++] = result; break; } - #define ARG_CASE_ARG_CS_SV(selected, result) case selected: { arg_slot[sel_num++] = result; break; } -#ifdef CSQC - #define ARG_CASE_ARG_CS(selected, result) case selected: { arg_slot[sel_num++] = result; break; } - #define ARG_CASE_ARG_SV(selected, result) -#else - #define ARG_CASE_ARG_CS(selected, result) - #define ARG_CASE_ARG_SV(selected, result) case selected: { arg_slot[sel_num++] = result; break; } -#endif - #define ARG_CASE_ARG_DC(selected, result) - #define ARG_CASE(prog, selected, result) ARG_CASE_##prog(selected, result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: NOTIF_HIT_UNKNOWN(NOTIF_MAX_ARGS, "Local_Notification_sprintf") - } - } - return sprintf( - strcat(input, "\n"), - arg_slot[0], - arg_slot[1], - arg_slot[2], - arg_slot[3], - arg_slot[4], - arg_slot[5], - arg_slot[6] - ); -} - -#ifdef CSQC -void Local_Notification_sound( - int soundchannel, string soundfile, - float soundvolume, float soundposition) -{ - if ((soundfile != prev_soundfile) || (time >= (prev_soundtime + autocvar_cl_announcer_antispam))) - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification_sound(%f, '%s', %f, %f);\n", - soundchannel, - sprintf( - "announcer/%s/%s.wav", - AnnouncerOption(), - soundfile - ), - soundvolume, - soundposition - )); - #endif - - _sound( - NULL, - soundchannel, - sprintf( - "announcer/%s/%s.wav", - AnnouncerOption(), - soundfile - ), - soundvolume, - soundposition - ); - - if (prev_soundfile) strunzone(prev_soundfile); - prev_soundfile = strzone(soundfile); - prev_soundtime = time; - } - else - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - ( - "Local_Notification_sound(world, %f, '%s', %f, %f) " - "^1BLOCKED BY ANTISPAM:^7 prevsnd: '%s', timediff: %f, limit: %f\n" - ), - soundchannel, - sprintf( - "announcer/%s/%s.wav", - AnnouncerOption(), - soundfile - ), - soundvolume, - soundposition, - prev_soundfile, - (time - prev_soundtime), - autocvar_cl_announcer_antispam - )); - #endif - } -} - -void Local_Notification_HUD_Notify_Push( - string icon, string hudargs, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4) -{ - arg_slot[0] = ""; arg_slot[1] = ""; - - for (int sel_num = 0; (hudargs != ""); ) - { - string selected = car(hudargs); hudargs = cdr(hudargs); - NOTIF_HIT_MAX(NOTIF_MAX_HUDARGS, "Local_Notification_HUD_Notify_Push"); - switch (strtolower(selected)) - { - #define ARG_CASE_ARG_CS_SV_HA(selected, result) case selected: { arg_slot[sel_num++] = result; break; } - #define ARG_CASE_ARG_CS_SV_DC(selected, result) - #define ARG_CASE_ARG_CS_SV(selected, result) - #define ARG_CASE_ARG_CS(selected, result) - #define ARG_CASE_ARG_SV(selected, result) - #define ARG_CASE_ARG_DC(selected, result) - #define ARG_CASE(prog, selected, result) ARG_CASE_##prog(selected, result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: NOTIF_HIT_UNKNOWN(NOTIF_MAX_HUDARGS, "Local_Notification_HUD_Notify_Push") - } - } - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification_HUD_Notify_Push('%s^7', '%s', %s, %s, %s);\n", - icon, - hudargs, - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4), - MakeConsoleSafe(sprintf("'%s^7', '%s^7'", stof(arg_slot[0]), stof(arg_slot[1]))) - )); - #endif - HUD_Notify_Push(icon, arg_slot[0], arg_slot[1]); -} - -void Local_Notification_centerprint_generic( - string input, string durcnt, - CPID cpid, float f1, float f2) -{ - arg_slot[0] = ""; arg_slot[1] = ""; - - for (int sel_num = 0; (durcnt != ""); ) - { - string selected = car(durcnt); durcnt = cdr(durcnt); - NOTIF_HIT_MAX(NOTIF_MAX_DURCNT, "Local_Notification_centerprint_generic"); - switch (strtolower(selected)) - { - #define ARG_CASE_ARG_CS_SV_HA(selected, result) - #define ARG_CASE_ARG_CS_SV_DC(selected, result) case selected: { arg_slot[sel_num++] = result; break; } - #define ARG_CASE_ARG_CS_SV(selected, result) - #define ARG_CASE_ARG_CS(selected, result) - #define ARG_CASE_ARG_SV(selected, result) - #define ARG_CASE_ARG_DC(selected, result) case selected: { arg_slot[sel_num++] = result; break; } - #define ARG_CASE(prog, selected, result) ARG_CASE_##prog(selected,result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: - { - if (/* wtf */ ftos(stof(selected)) != "") { arg_slot[sel_num++] = selected; } - else { NOTIF_HIT_UNKNOWN(NOTIF_MAX_DURCNT, "Local_Notification_centerprint_generic") } - break; - } - } - } - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification_centerprint_generic('%s^7', '%s', %d, %d, %d, %d);\n", - MakeConsoleSafe(input), - durcnt, - f1, f2, - stof(arg_slot[0]), - stof(arg_slot[1]) - )); - #endif - centerprint_generic(ORDINAL(cpid), input, stof(arg_slot[0]), stof(arg_slot[1])); -} -#endif - -void Local_Notification(MSG net_type, Notification net_name, ...count) -{ - // retreive entity of this notification - entity notif = net_name; - if (!notif) - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification(%s, NULL, ...);\n", - Get_Notif_TypeName(net_type) - )); - #endif - LOG_WARNINGF("Incorrect usage of Local_Notification: %s\n", "Null notification"); - return; - } - - // check if the notification is enabled - if (!notif.nent_enabled) - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification(%s, %s, ...): Entity was disabled...\n", - Get_Notif_TypeName(net_type), - notif.nent_name - )); - #endif - return; - } - - string s1 = ((notif.nent_stringcount > 0) ? ...(0, string) : ""); - string s2 = ((notif.nent_stringcount > 1) ? ...(1, string) : ""); - string s3 = ((notif.nent_stringcount > 2) ? ...(2, string) : ""); - string s4 = ((notif.nent_stringcount > 3) ? ...(3, string) : ""); - float f1 = ((notif.nent_floatcount > 0) ? ...((notif.nent_stringcount + 0), float) : 0); - float f2 = ((notif.nent_floatcount > 1) ? ...((notif.nent_stringcount + 1), float) : 0); - float f3 = ((notif.nent_floatcount > 2) ? ...((notif.nent_stringcount + 2), float) : 0); - float f4 = ((notif.nent_floatcount > 3) ? ...((notif.nent_stringcount + 3), float) : 0); - - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification(%s, %s, %s, %s);\n", - Get_Notif_TypeName(net_type), - notif.nent_name, - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4) - )); - #endif - - if ((notif.nent_stringcount + notif.nent_floatcount) != count) - { - backtrace(sprintf( - ( - "Arguments mismatch for Local_Notification(%s, %s, ...)! " - "stringcount(%d) + floatcount(%d) != count(%d)\n" - "Check the definition and function call for accuracy...?\n" - ), - Get_Notif_TypeName(net_type), - notif.nent_name, - notif.nent_stringcount, - notif.nent_floatcount, - count - )); - return; - } - - switch (net_type) - { - case MSG_ANNCE: - { - #ifdef CSQC - Local_Notification_sound( - notif.nent_channel, - notif.nent_snd, - notif.nent_vol, - notif.nent_position - ); - #else - backtrace("MSG_ANNCE on server?... Please notify Samual immediately!\n"); - #endif - break; - } - - case MSG_INFO: - { - print( - Local_Notification_sprintf( - notif.nent_string, - notif.nent_args, - s1, s2, s3, s4, - f1, f2, f3, f4) - ); - #ifdef CSQC - if (notif.nent_icon != "") - { - if (notif.nent_iconargs != "") - { - string s = Local_Notification_sprintf( - notif.nent_icon,notif.nent_iconargs, - s1, s2, s3, s4, f1, f2, f3, f4); - // remove the trailing newline - notif.nent_icon = strzone(substring(s, 0, -1)); - } - Local_Notification_HUD_Notify_Push( - notif.nent_icon, - notif.nent_hudargs, - s1, s2, s3, s4, - f1, f2, f3, f4); - } - #endif - break; - } - - #ifdef CSQC - case MSG_CENTER: - { - Local_Notification_centerprint_generic( - Local_Notification_sprintf( - notif.nent_string, - notif.nent_args, - s1, s2, s3, s4, - f1, f2, f3, f4), - notif.nent_durcnt, - notif.nent_cpid, - f1, f2); - break; - } - #endif - - case MSG_MULTI: - { - if (notif.nent_msginfo && notif.nent_msginfo.nent_enabled) - { - Local_Notification_WOVA( - MSG_INFO, - notif.nent_msginfo, - notif.nent_msginfo.nent_stringcount, - notif.nent_msginfo.nent_floatcount, - s1, s2, s3, s4, - f1, f2, f3, f4); - } - #ifdef CSQC - if (notif.nent_msgannce && notif.nent_msgannce.nent_enabled) - { - Local_Notification_WOVA( - MSG_ANNCE, - notif.nent_msgannce, - 0, 0, - "", "", "", "", - 0, 0, 0, 0); - } - if (notif.nent_msgcenter && notif.nent_msgcenter.nent_enabled) - { - Local_Notification_WOVA( - MSG_CENTER, - notif.nent_msgcenter, - notif.nent_msgcenter.nent_stringcount, - notif.nent_msgcenter.nent_floatcount, - s1, s2, s3, s4, - f1, f2, f3, f4); - } - #endif - break; - } - - case MSG_CHOICE: - { - entity found_choice = notif.nent_optiona; - if (notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) { - switch (cvar(sprintf("notification_%s", notif.nent_name))) - { - case 1: break; - case 2: found_choice = notif.nent_optionb; break; - default: return; // not enabled anyway - } - } - - Local_Notification_WOVA( - found_choice.nent_type, - found_choice, - found_choice.nent_stringcount, - found_choice.nent_floatcount, - s1, s2, s3, s4, - f1, f2, f3, f4); - } - } -} - -// WOVA = Without Variable Arguments -void Local_Notification_WOVA( - MSG net_type, Notification net_name, - float stringcount, float floatcount, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4) -{ - #define VARITEM(stringc, floatc, args) \ - if ((stringcount == stringc) && (floatcount == floatc)) \ - { Local_Notification(net_type, net_name, args); return; } - EIGHT_VARS_TO_VARARGS_VARLIST - #undef VARITEM - Local_Notification(net_type, net_name); // some notifications don't have any arguments at all -} - - -// ========================= -// Notification Networking -// ========================= - -/** networked as a linked entity to give newly connecting clients some notification context */ -REGISTER_NET_LINKED(ENT_CLIENT_NOTIFICATION) - -#ifdef CSQC -NET_HANDLE(ENT_CLIENT_NOTIFICATION, bool is_new) -{ - make_pure(this); - MSG net_type = ENUMCAST(MSG, ReadByte()); - int net_name = ReadShort(); - return = true; - - if (net_type == MSG_CENTER_KILL) - { - if (!is_new) return; - // killing - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Read_Notification(%d) at %f: net_type = %s, cpid = %d\n", - is_new, - time, - Get_Notif_TypeName(net_type), - net_name - )); - #endif - int _net_name = net_name; - CPID net_name = ENUMCAST(CPID, _net_name); - if (net_name == CPID_Null) { - // kill all - reset_centerprint_messages(); - } else { - // kill group - centerprint_generic(ORDINAL(net_name), "", 0, 0); - } - return; - } - - Notification notif = Get_Notif_Ent(net_type, net_name); - - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Read_Notification(%d) at %f: net_type = %s, net_name = %s (%d)\n", - is_new, - time, - Get_Notif_TypeName(net_type), - notif.registered_id, - net_name - )); - #endif - - if (!notif) { - backtrace("Read_Notification: Could not find notification entity!\n"); - return false; - } - - string s1 = ((notif.nent_stringcount > 0) ? ReadString() : ""); - string s2 = ((notif.nent_stringcount > 1) ? ReadString() : ""); - string s3 = ((notif.nent_stringcount > 2) ? ReadString() : ""); - string s4 = ((notif.nent_stringcount > 3) ? ReadString() : ""); - float f1 = ((notif.nent_floatcount > 0) ? ReadLong() : 0); - float f2 = ((notif.nent_floatcount > 1) ? ReadLong() : 0); - float f3 = ((notif.nent_floatcount > 2) ? ReadLong() : 0); - float f4 = ((notif.nent_floatcount > 3) ? ReadLong() : 0); - - if (!is_new) return; - Local_Notification_WOVA( - net_type, notif, - notif.nent_stringcount, - notif.nent_floatcount, - s1, s2, s3, s4, - f1, f2, f3, f4); -} -#endif - -#ifdef SVQC -void Net_Notification_Remove() -{ - SELFPARAM(); - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Net_Notification_Remove() at %f: %s '%s - %s' notification\n", - time, - ((this.nent_net_name == -1) ? "Killed" : "Removed"), - Get_Notif_TypeName(this.nent_net_type), - this.owner.nent_name - )); - #endif - for (int i = 0; i < this.nent_stringcount; ++i) { if (this.nent_strings[i]) strunzone(this.nent_strings[i]); } - remove(this); -} - -bool Net_Write_Notification(entity this, entity client, int sf) -{ - if (!Notification_ShouldSend(this.nent_broadcast, client, this.nent_client)) return false; - WriteHeader(MSG_ENTITY, ENT_CLIENT_NOTIFICATION); - WriteByte(MSG_ENTITY, ORDINAL(this.nent_net_type)); - WriteShort(MSG_ENTITY, this.nent_net_name); - for (int i = 0; i < this.nent_stringcount; ++i) { WriteString(MSG_ENTITY, this.nent_strings[i]); } - for (int i = 0; i < this.nent_floatcount; ++i) { WriteLong(MSG_ENTITY, this.nent_floats[i]); } - return true; -} - -void Kill_Notification( - NOTIF broadcast, entity client, - /** message group, MSG_Null for all */ - MSG net_type, - /** cpid group, CPID_Null for all */ - CPID net_cpid) -{ - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Kill_Notification(%s, '%s', %s, %d);\n", - Get_Notif_BroadcastName(broadcast), - client.netname, - (net_type ? Get_Notif_TypeName(net_type) : "0"), - net_cpid - )); - #endif - - string checkargs = Notification_CheckArgs(broadcast, client); - if (checkargs != "") { LOG_WARNINGF("Incorrect usage of Kill_Notification: %s", checkargs); return; } - - entity net_notif = new_pure(net_kill_notification); - net_notif.nent_broadcast = broadcast; - net_notif.nent_client = client; - net_notif.nent_net_type = MSG_CENTER_KILL; - net_notif.nent_net_name = ORDINAL(net_cpid); - Net_LinkEntity(net_notif, false, autocvar_notification_lifetime_runtime, Net_Write_Notification); - - FOREACH_ENTITY_CLASS( - "net_notification", - (it.owner.nent_type == net_type || net_type == MSG_Null) && (it.owner.nent_cpid == net_cpid || net_cpid == CPID_Null), - { - it.nent_net_name = -1; - it.nextthink = time; - } - ); -} - -void Send_Notification( - NOTIF broadcast, entity client, - MSG net_type, Notification net_name, - ...count) -{ - entity notif = net_name; - string parms = sprintf("%s, '%s', %s, %s", - Get_Notif_BroadcastName(broadcast), - client.classname, - Get_Notif_TypeName(net_type), - net_name.registered_id - ); - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf("Send_Notification(%s, ...%d);\n", parms, count)); - #endif - - if (!notif) - { - LOG_WARNING("Send_Notification: Could not find notification entity!"); - return; - } - - // check supplied broadcast, target, type, and name for errors - string checkargs = Notification_CheckArgs(broadcast, client); - if (!net_name) { checkargs = sprintf("No notification provided! %s", checkargs); } - if (checkargs != "") - { - LOG_WARNINGF("Incorrect usage of Send_Notification: %s", checkargs); - return; - } - - string s1 = ((0 < notif.nent_stringcount) ? ...(0, string) : ""); - string s2 = ((1 < notif.nent_stringcount) ? ...(1, string) : ""); - string s3 = ((2 < notif.nent_stringcount) ? ...(2, string) : ""); - string s4 = ((3 < notif.nent_stringcount) ? ...(3, string) : ""); - float f1 = ((0 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 0), float) : 0); - float f2 = ((1 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 1), float) : 0); - float f3 = ((2 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 2), float) : 0); - float f4 = ((3 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 3), float) : 0); - - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Send_Notification(%s, %s, %s);\n", - parms, - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4) - )); - #endif - - if ((notif.nent_stringcount + notif.nent_floatcount) != count) - { - LOG_WARNINGF( - "Argument mismatch for Send_Notification(%s, ...)! " - "stringcount(%d) + floatcount(%d) != count(%d)\n" - "Check the definition and function call for accuracy...?\n", - parms, - notif.nent_stringcount, - notif.nent_floatcount, - count - ); - return; - } - - if ( - server_is_dedicated - && - ( - broadcast == NOTIF_ALL - || - broadcast == NOTIF_ALL_EXCEPT - ) - && - !( - net_type == MSG_ANNCE - || - net_type == MSG_CENTER - ) - ) - { - Local_Notification_WOVA( - net_type, net_name, - notif.nent_stringcount, - notif.nent_floatcount, - s1, s2, s3, s4, - f1, f2, f3, f4); - } - - if (net_type == MSG_CHOICE) - { - // THIS GETS TRICKY... now we have to cycle through each possible player (checking broadcast) - // and then do an individual NOTIF_ONE_ONLY recursive call for each one depending on their option... - // It's slow, but it's better than the alternatives: - // 1. Constantly networking all info and letting client decide - // 2. Manually handling each separate call on per-usage basis (See old CTF usage of verbose) - entity found_choice; - - #define RECURSE_FROM_CHOICE(ent,action) MACRO_BEGIN { \ - if (notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) { \ - switch (ent.msg_choice_choices[net_name.nent_choice_idx]) \ - { \ - case 1: found_choice = notif.nent_optiona; break; \ - case 2: found_choice = notif.nent_optionb; break; \ - default: action; \ - } \ - } else { \ - found_choice = notif.nent_optiona; \ - } \ - Send_Notification_WOVA( \ - NOTIF_ONE_ONLY, \ - ent, \ - found_choice.nent_type, \ - found_choice, \ - found_choice.nent_stringcount, \ - found_choice.nent_floatcount, \ - s1, s2, s3, s4, \ - f1, f2, f3, f4); \ - } MACRO_END - - switch (broadcast) - { - case NOTIF_ONE_ONLY: // we can potentially save processing power with this broadcast method - { - if (IS_REAL_CLIENT(client)) { - RECURSE_FROM_CHOICE(client, return); - } - break; - } - default: - { - FOREACH_CLIENT(IS_REAL_CLIENT(it) && Notification_ShouldSend(broadcast, it, client), { - RECURSE_FROM_CHOICE(it, continue); - }); - break; - } - } - } - else - { - entity net_notif = new(net_notification); - make_pure(net_notif); - net_notif.owner = notif; - net_notif.nent_broadcast = broadcast; - net_notif.nent_client = client; - net_notif.nent_net_type = net_type; - net_notif.nent_net_name = notif.m_id; - net_notif.nent_stringcount = notif.nent_stringcount; - net_notif.nent_floatcount = notif.nent_floatcount; - - for (int i = 0; i < net_notif.nent_stringcount; ++i) { - net_notif.nent_strings[i] = strzone(...(i, string)); - } - for (int i = 0; i < net_notif.nent_floatcount; ++i) { - net_notif.nent_floats[i] = ...((net_notif.nent_stringcount + i), float); - } - - net_notif.think = Net_Notification_Remove; - net_notif.nextthink = (time > autocvar_notification_lifetime_mapload) - ? (time + autocvar_notification_lifetime_runtime) - : autocvar_notification_lifetime_mapload; - - Net_LinkEntity(net_notif, false, 0, Net_Write_Notification); - } -} - -// WOVA = Without Variable Arguments -void Send_Notification_WOVA( - NOTIF broadcast, entity client, - MSG net_type, Notification net_name, - float stringcount, float floatcount, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4) -{ - #ifdef NOTIFICATIONS_DEBUG - entity notif = net_name; - Debug_Notification(sprintf( - "Send_Notification_WOVA(%s, %d, %d, %s, %s);\n", - sprintf( - "%s, '%s', %s, %s", - Get_Notif_BroadcastName(broadcast), - client.classname, - Get_Notif_TypeName(net_type), - notif.nent_name - ), - stringcount, - floatcount, - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4) - )); - #endif - - #define VARITEM(stringc, floatc, args) \ - if ((stringcount == stringc) && (floatcount == floatc)) \ - { Send_Notification(broadcast, client, net_type, net_name, args); return; } - EIGHT_VARS_TO_VARARGS_VARLIST - #undef VARITEM - Send_Notification(broadcast, client, net_type, net_name); // some notifications don't have any arguments at all -} - -// WOCOVA = Without Counts Or Variable Arguments -void Send_Notification_WOCOVA( - NOTIF broadcast, entity client, - MSG net_type, Notification net_name, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4) -{ - entity notif = net_name; - - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Send_Notification_WOCOVA(%s, %s, %s);\n", - sprintf( - "%s, '%s', %s, %s", - Get_Notif_BroadcastName(broadcast), - client.classname, - Get_Notif_TypeName(net_type), - notif.nent_name - ), - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4) - )); - #endif - - #define VARITEM(stringc, floatc, args) \ - if ((notif.nent_stringcount == stringc) && (notif.nent_floatcount == floatc)) \ - { Send_Notification(broadcast, client, net_type, net_name, args); return; } - EIGHT_VARS_TO_VARARGS_VARLIST - #undef VARITEM - Send_Notification(broadcast, client, net_type, net_name); // some notifications don't have any arguments at all -} -#endif // ifdef SVQC diff --git a/qcsrc/common/notifications.qh b/qcsrc/common/notifications.qh deleted file mode 100644 index 40a72a349..000000000 --- a/qcsrc/common/notifications.qh +++ /dev/null @@ -1,804 +0,0 @@ -#ifndef NOTIFICATIONS_H -#define NOTIFICATIONS_H - -#include - -#include "constants.qh" -#include "teams.qh" -#include "util.qh" - -/** main types/groups of notifications */ -ENUMCLASS(MSG) - /** "Global" AND "personal" announcer messages */ - CASE(MSG, ANNCE) - /** "Global" information messages */ - CASE(MSG, INFO) - /** "Personal" centerprint messages */ - CASE(MSG, CENTER) - /** Subcall MSG_INFO and/or MSG_CENTER notifications */ - CASE(MSG, MULTI) - /** Choose which subcall wrapper to activate */ - CASE(MSG, CHOICE) - /** Kill centerprint message @deprecated */ - CASE(MSG, CENTER_KILL) -ENUMCLASS_END(MSG) - -string Get_Notif_TypeName(MSG net_type) -{ - switch (net_type) - { - case MSG_ANNCE: return "MSG_ANNCE"; - case MSG_INFO: return "MSG_INFO"; - case MSG_CENTER: return "MSG_CENTER"; - case MSG_MULTI: return "MSG_MULTI"; - case MSG_CHOICE: return "MSG_CHOICE"; - } - LOG_WARNINGF("Get_Notif_TypeName(%d): Improper net type!\n", ORDINAL(net_type)); - return ""; -} - -ENUMCLASS(CPID) - CASE(CPID, ASSAULT_ROLE) - CASE(CPID, ROUND) - CASE(CPID, CAMPCHECK) - CASE(CPID, CTF_CAPSHIELD) - CASE(CPID, CTF_LOWPRIO) - CASE(CPID, CTF_PASS) - CASE(CPID, STALEMATE) - CASE(CPID, NADES) - CASE(CPID, IDLING) - CASE(CPID, ITEM) - CASE(CPID, PREVENT_JOIN) - CASE(CPID, KEEPAWAY) - CASE(CPID, KEEPAWAY_WARN) - CASE(CPID, KEYHUNT) - CASE(CPID, KEYHUNT_OTHER) - CASE(CPID, LMS) - CASE(CPID, MISSING_TEAMS) - CASE(CPID, MISSING_PLAYERS) - CASE(CPID, INSTAGIB_FINDAMMO) - CASE(CPID, MOTD) - CASE(CPID, NIX) - CASE(CPID, ONSLAUGHT) - CASE(CPID, ONS_CAPSHIELD) - CASE(CPID, OVERTIME) - CASE(CPID, POWERUP) - CASE(CPID, RACE_FINISHLAP) - CASE(CPID, TEAMCHANGE) - CASE(CPID, TIMEOUT) - CASE(CPID, VEHICLES) - CASE(CPID, VEHICLES_OTHER) - /** always last */ - CASE(CPID, LAST) -ENUMCLASS_END(CPID) - -typedef entity Notification; - -// used for notification system multi-team identifiers -#define APP_TEAM_NUM(num, prefix) ((num == NUM_TEAM_1) ? prefix##_RED : ((num == NUM_TEAM_2) ? prefix##_BLUE : ((num == NUM_TEAM_3) ? prefix##_YELLOW : prefix##_PINK))) -/** @deprecated use APP_TEAM_NUM */ -#define APP_TEAM_ENT(ent, prefix) APP_TEAM_NUM(ent.team, prefix) - -#define EIGHT_VARS_TO_VARARGS_VARLIST \ - VARITEM(1, 0, s1) \ - VARITEM(2, 0, XPD(s1, s2)) \ - VARITEM(3, 0, XPD(s1, s2, s3)) \ - VARITEM(4, 0, XPD(s1, s2, s3, s4)) \ - VARITEM(0, 1, f1) \ - VARITEM(1, 1, XPD(s1, f1)) \ - VARITEM(2, 1, XPD(s1, s2, f1)) \ - VARITEM(3, 1, XPD(s1, s2, s3, f1)) \ - VARITEM(4, 1, XPD(s1, s2, s3, s4, f1)) \ - VARITEM(0, 2, XPD(f1, f2)) \ - VARITEM(1, 2, XPD(s1, f1, f2)) \ - VARITEM(2, 2, XPD(s1, s2, f1, f2)) \ - VARITEM(3, 2, XPD(s1, s2, s3, f1, f2)) \ - VARITEM(4, 2, XPD(s1, s2, s3, s4, f1, f2)) \ - VARITEM(0, 3, XPD(f1, f2, f3)) \ - VARITEM(1, 3, XPD(s1, f1, f2, f3)) \ - VARITEM(2, 3, XPD(s1, s2, f1, f2, f3)) \ - VARITEM(3, 3, XPD(s1, s2, s3, f1, f2, f3)) \ - VARITEM(4, 3, XPD(s1, s2, s3, s4, f1, f2, f3)) \ - VARITEM(0, 4, XPD(f1, f2, f3, f4)) \ - VARITEM(1, 4, XPD(s1, f1, f2, f3, f4)) \ - VARITEM(2, 4, XPD(s1, s2, f1, f2, f3, f4)) \ - VARITEM(3, 4, XPD(s1, s2, s3, f1, f2, f3, f4)) \ - VARITEM(4, 4, XPD(s1, s2, s3, s4, f1, f2, f3, f4)) - -void Destroy_All_Notifications(); -void Create_Notification_Entity(entity notif, - float var_default, - float var_cvar, - MSG typeId, - string namestring); -void Create_Notification_Entity_Annce(entity notif, - float var_cvar, - string namestring, - /* MSG_ANNCE */ - float channel, - string snd, - float vol, - float position); - -void Create_Notification_Entity_InfoCenter(entity notif, - float var_cvar, - string namestring, - int strnum, - int flnum, - /* MSG_INFO & MSG_CENTER */ - string args, - string hudargs, - string icon, - CPID cpid, - string durcnt, - string normal, - string gentle); - -void Create_Notification_Entity_Multi(entity notif, - float var_cvar, - string namestring, - /* MSG_MULTI */ - Notification anncename, - Notification infoname, - Notification centername); - -void Create_Notification_Entity_Choice(entity notif, - float var_cvar, - string namestring, - /* MSG_CHOICE */ - float challow_def, - float challow_var, - MSG chtype, - Notification optiona, - Notification optionb); - -void Dump_Notifications(int fh, bool alsoprint); - -GENERIC_COMMAND(dumpnotifs, "Dump all notifications into notifications_dump.txt") -{ - switch (request) - { - case CMD_REQUEST_COMMAND: - { - #ifndef MENUQC - string filename = argv(1); - bool alsoprint = false; - if (filename == "") - { - filename = "notifications_dump.cfg"; - alsoprint = false; - } - else if (filename == "-") - { - filename = "notifications_dump.cfg"; - alsoprint = true; - } - int fh = fopen(filename, FILE_WRITE); - if (fh >= 0) - { - Dump_Notifications(fh, alsoprint); - LOG_INFOF("Dumping notifications... File located in ^2data/data/%s^7.\n", filename); - fclose(fh); - } - else - { - LOG_INFOF("^1Error: ^7Could not open file '%s'!\n", filename); - } - #else - LOG_INFO(_("Notification dump command only works with cl_cmd and sv_cmd.\n")); - #endif - return; - } - default: - case CMD_REQUEST_USAGE: - { - LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpnotifs [filename]")); - LOG_INFO(" Where 'filename' is the file to write (default is notifications_dump.cfg),\n"); - LOG_INFO(" if supplied with '-' output to console as well as default,\n"); - LOG_INFO(" if left blank, it will only write to default.\n"); - return; - } - } -} - -#ifdef NOTIFICATIONS_DEBUG -void Debug_Notification(string input) -{ - switch (autocvar_notification_debug) - { - case 1: { LOG_TRACE(input); break; } - case 2: { LOG_INFO(input); break; } - } -} -#endif - -void Local_Notification(MSG net_type, Notification net_name, ...count); -/** glue for networking, forwards to `Local_Notification` */ -void Local_Notification_WOVA( - MSG net_type, Notification net_name, - float stringcount, float floatcount, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4); - -#ifdef CSQC -string prev_soundfile; -float prev_soundtime; -#endif - -#ifdef SVQC -ENUMCLASS(NOTIF) - /** send to one client and their spectators */ - CASE(NOTIF, ONE) - /** send ONLY to one client */ - CASE(NOTIF, ONE_ONLY) - /** send only to X team and their spectators */ - CASE(NOTIF, TEAM) - /** send only to X team and their spectators, except for Y person and their spectators */ - CASE(NOTIF, TEAM_EXCEPT) - /** send to everyone */ - CASE(NOTIF, ALL) - /** send to everyone except X person and their spectators */ - CASE(NOTIF, ALL_EXCEPT) -ENUMCLASS_END(NOTIF) - -string Get_Notif_BroadcastName(NOTIF broadcast) -{ - switch (broadcast) - { - case NOTIF_ONE: return "NOTIF_ONE"; - case NOTIF_ONE_ONLY: return "NOTIF_ONE_ONLY"; - case NOTIF_ALL_EXCEPT: return "NOTIF_ALL_EXCEPT"; - case NOTIF_ALL: return "NOTIF_ALL"; - case NOTIF_TEAM: return "NOTIF_TEAM"; - case NOTIF_TEAM_EXCEPT: return "NOTIF_TEAM_EXCEPT"; - } - LOG_WARNINGF("Get_Notif_BroadcastName(%d): Improper broadcast!\n", broadcast); - return ""; -} - -void Kill_Notification( - NOTIF broadcast, entity client, - MSG net_type, CPID net_name); -void Send_Notification( - NOTIF broadcast, entity client, - MSG net_type, Notification net_name, - ...count); -void Send_Notification_WOVA( - NOTIF broadcast, entity client, - MSG net_type, Notification net_name, - float stringcount, float floatcount, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4); -void Send_Notification_WOCOVA( - NOTIF broadcast, entity client, - MSG net_type, Notification net_name, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4); -#endif - -// =========================== -// Special CVAR Declarations -// =========================== - -// MAKE SURE THIS IS ALWAYS SYNCHRONIZED WITH THE DUMP -// NOTIFICATIONS FUNCTION IN THE .QC FILE! - -#define NOTIF_ADD_AUTOCVAR(name,default) float autocvar_notification_##name = default; - -float autocvar_notification_show_location = false; -string autocvar_notification_show_location_string = ""; //_(" at the %s"); -float autocvar_notification_show_sprees = true; -float autocvar_notification_show_sprees_info = 3; // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker -float autocvar_notification_show_sprees_info_newline = true; -float autocvar_notification_show_sprees_info_specialonly = true; -float autocvar_notification_errors_are_fatal = true; -float autocvar_notification_lifetime_runtime = 0.5; -float autocvar_notification_lifetime_mapload = 10; -float autocvar_notification_debug = false; - -#ifdef SVQC -.float FRAG_VERBOSE; -void Notification_GetCvars(); -float autocvar_notification_server_allows_location = 1; // 0 = no, 1 = yes -#else -float autocvar_notification_item_centerprinttime = 1.5; - -// 0 = no, 1 = yes, 2 = forced on for all MSG_INFO notifs -// DISABLED IN CODE, BUT ENABLED IN CONFIG FOR COMPATIBILITY WITH OLD CLIENTS -float autocvar_notification_allow_chatboxprint = 0; - -float autocvar_notification_show_sprees_center = true; -float autocvar_notification_show_sprees_center_specialonly = true; -#endif - - -// ============================ -// Notification Argument List -// ============================ -/* - These arguments get replaced with the Local_Notification_sprintf - and other such functions found in notifications.qc to supply data - from networked notifications to their usage in sprintf... It - allows for more dynamic data to be inferred by the local - notification parser, so that the server does not have to network - anything too crazy on a per-client/per-situation basis. - - Pay attention to the CSQC/SVQC relations, some of these are redefined - in slightly different ways for different programs, this is because the - server does a more conservative approach to the notifs than the client. - - All arguments are swapped into strings, so be sure that your - sprintf usage matches with proper %s placement. - - Argument descriptions: - s1-s4: string arguments to be literally swapped into sprintf - s2loc: s2 string of locations of deaths or other events - s3loc: s3 string of locations of deaths or other events - f1-f4: float arguments expanded into strings to be swapped into sprintf - f1p2dec: f1 float to string with 2 decimal places - f2p2dec: f2 float to string with 2 decimal places - f2primsec: f2 float primary or secondary selection for weapons - f3primsec: f3 float primary or secondary selection for weapons - f1secs: count_seconds of f1 - f1points: point or points depending on f1 - f1ord: count_ordinal of f1 - f1time: process_time of f1 - f1race_time: mmssss of f1 - f2race_time: mmssss of f2 - race_col: color of race time/position (i.e. good or bad) - race_diff: show time difference between f2 and f3 - missing_teams: show which teams still need players - pass_key: find the keybind for "passing" or "dropping" in CTF game mode - frag_ping: show the ping of a player - frag_stats: show health/armor/ping of a player - frag_pos: show score status and position in the match of a player - spree_cen: centerprint notif for kill spree/how many kills they have - spree_inf: info notif for kill spree/how many kills they have - spree_end: placed at the end of murder messages to show ending of sprees - spree_lost: placed at the end of suicide messages to show losing of sprees - item_wepname: return full name of a weapon from weaponid - item_wepammo: ammo display for weapon from string - item_centime: amount of time to display weapon message in centerprint - item_buffname: return full name of a buff from buffid - death_team: show the full name of the team a player is switching from - minigame1_name: return human readable name of a minigame from its id(s1) - minigame1_d: return descriptor name of a minigame from its id(s1) -*/ - -const float NOTIF_MAX_ARGS = 7; -const float NOTIF_MAX_HUDARGS = 2; -const float NOTIF_MAX_DURCNT = 2; - -string arg_slot[NOTIF_MAX_ARGS]; - -const float ARG_CS_SV_HA = 1; // enabled on CSQC, SVQC, and Hudargs -const float ARG_CS_SV_DC = 2; // enabled on CSQC, SVQC, and durcnt centerprint -const float ARG_CS_SV = 3; // enabled on CSQC and SVQC -const float ARG_CS = 4; // unique result to CSQC -const float ARG_SV = 5; // unique result to SVQC -const float ARG_DC = 6; // unique result to durcnt/centerprint - -// todo possible idea.... declare how many floats/strings each arg needs, and then dynamically increment the input -// this way, we don't need to have duplicates like i.e. s2loc and s3loc? - -string BUFF_NAME(int i); - -#define NOTIF_ARGUMENT_LIST \ - ARG_CASE(ARG_CS_SV_HA, "s1", s1) \ - ARG_CASE(ARG_CS_SV_HA, "s2", s2) \ - ARG_CASE(ARG_CS_SV_HA, "s3", s3) \ - ARG_CASE(ARG_CS_SV_HA, "s4", s4) \ - ARG_CASE(ARG_CS_SV, "s2loc", ((autocvar_notification_show_location && (s2 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s2) : "")) \ - ARG_CASE(ARG_CS_SV, "s3loc", ((autocvar_notification_show_location && (s3 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s3) : "")) \ - ARG_CASE(ARG_CS_SV_DC, "f1", ftos(f1)) \ - ARG_CASE(ARG_CS_SV_DC, "f2", ftos(f2)) \ - ARG_CASE(ARG_CS_SV, "f3", ftos(f3)) \ - ARG_CASE(ARG_CS_SV, "f4", ftos(f4)) \ - ARG_CASE(ARG_CS_SV, "f1p2dec", ftos_decimals(f1/100, 2)) \ - ARG_CASE(ARG_CS_SV, "f2p2dec", ftos_decimals(f2/100, 2)) \ - ARG_CASE(ARG_CS, "f2primsec", (f2 ? _("secondary") : _("primary"))) \ - ARG_CASE(ARG_CS, "f3primsec", (f3 ? _("secondary") : _("primary"))) \ - ARG_CASE(ARG_CS, "f1secs", count_seconds(f1)) \ - ARG_CASE(ARG_CS, "f1points", (f1 == 1 ? _("point") : _("points"))) \ - ARG_CASE(ARG_CS_SV, "f1ord", count_ordinal(f1)) \ - ARG_CASE(ARG_CS, "f1time", process_time(2, f1)) \ - ARG_CASE(ARG_CS_SV_HA, "f1race_time", mmssss(f1)) \ - ARG_CASE(ARG_CS_SV_HA, "f2race_time", mmssss(f2)) \ - ARG_CASE(ARG_CS_SV_HA, "f3race_time", mmssss(f3)) \ - ARG_CASE(ARG_CS_SV, "race_col", CCR(((f1 == 1) ? "^F1" : "^F2"))) \ - ARG_CASE(ARG_CS_SV, "race_diff", ((f2 > f3) ? sprintf(CCR("^1[+%s]"), mmssss(f2 - f3)) : sprintf(CCR("^2[-%s]"), mmssss(f3 - f2)))) \ - ARG_CASE(ARG_CS, "missing_teams", notif_arg_missing_teams(f1)) \ - ARG_CASE(ARG_CS, "pass_key", ((((tmp_s = getcommandkey("pass", "+use")) != "pass") && !(strstrofs(tmp_s, "not bound", 0) >= 0)) ? sprintf(CCR(_(" ^F1(Press %s)")), tmp_s) : "")) \ - ARG_CASE(ARG_CS, "frag_ping", notif_arg_frag_ping(true, f2)) \ - ARG_CASE(ARG_CS, "frag_stats", notif_arg_frag_stats(f2, f3, f4)) \ - /*ARG_CASE(ARG_CS, "frag_pos", ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \ - ARG_CASE(ARG_CS, "spree_cen", (autocvar_notification_show_sprees ? notif_arg_spree_cen(f1) : "")) \ - ARG_CASE(ARG_CS_SV, "spree_inf", (autocvar_notification_show_sprees ? notif_arg_spree_inf(1, input, s2, f2) : "")) \ - ARG_CASE(ARG_CS_SV, "spree_end", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \ - ARG_CASE(ARG_CS_SV, "spree_lost", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \ - ARG_CASE(ARG_CS_SV, "item_wepname", Weapons_from(f1).m_name) \ - ARG_CASE(ARG_CS_SV, "item_buffname", BUFF_NAME(f1)) \ - ARG_CASE(ARG_CS_SV, "f3buffname", BUFF_NAME(f3)) \ - ARG_CASE(ARG_CS_SV, "item_wepammo", (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \ - ARG_CASE(ARG_DC, "item_centime", ftos(autocvar_notification_item_centerprinttime)) \ - ARG_CASE(ARG_SV, "death_team", Team_ColoredFullName(f1)) \ - ARG_CASE(ARG_CS, "death_team", Team_ColoredFullName(f1 - 1)) \ - ARG_CASE(ARG_CS_SV_HA, "minigame1_name",find(world,netname,s1).descriptor.message) \ - ARG_CASE(ARG_CS_SV_HA, "minigame1_d", find(world,netname,s1).descriptor.netname) - -#define NOTIF_HIT_MAX(count,funcname) MACRO_BEGIN { \ - if(sel_num == count) { backtrace(sprintf("%s: Hit maximum arguments!\n", funcname)); break; } \ -} MACRO_END -#define NOTIF_HIT_UNKNOWN(token,funcname) { backtrace(sprintf("%s: Hit unknown token in selected string! '%s'\n", funcname, selected)); break; } - -#define KILL_SPREE_LIST \ - SPREE_ITEM(3, 03, _("TRIPLE FRAG! "), _("%s^K1 made a TRIPLE FRAG! %s^BG"), _("%s^K1 made a TRIPLE SCORE! %s^BG")) \ - SPREE_ITEM(5, 05, _("RAGE! "), _("%s^K1 unlocked RAGE! %s^BG"), _("%s^K1 made FIVE SCORES IN A ROW! %s^BG")) \ - SPREE_ITEM(10, 10, _("MASSACRE! "), _("%s^K1 started a MASSACRE! %s^BG"), _("%s^K1 made TEN SCORES IN A ROW! %s^BG")) \ - SPREE_ITEM(15, 15, _("MAYHEM! "), _("%s^K1 executed MAYHEM! %s^BG"), _("%s^K1 made FIFTEEN SCORES IN A ROW! %s^BG")) \ - SPREE_ITEM(20, 20, _("BERSERKER! "), _("%s^K1 is a BERSERKER! %s^BG"), _("%s^K1 made TWENTY SCORES IN A ROW! %s^BG")) \ - SPREE_ITEM(25, 25, _("CARNAGE! "), _("%s^K1 inflicts CARNAGE! %s^BG"), _("%s^K1 made TWENTY FIVE SCORES IN A ROW! %s^BG")) \ - SPREE_ITEM(30, 30, _("ARMAGEDDON! "), _("%s^K1 unleashes ARMAGEDDON! %s^BG"), _("%s^K1 made THIRTY SCORES IN A ROW! %s^BG")) - -#ifdef CSQC -string notif_arg_frag_ping(bool newline, float fping) -{ - string s = newline ? "\n" : " "; - if (fping < 0) - return sprintf(CCR(_("%s(^F1Bot^BG)")), s); - else - return sprintf(CCR(_("%s(Ping ^F1%d^BG)")), s, fping); -} - -string notif_arg_frag_stats(float fhealth, float farmor, float fping) -{ - string s = notif_arg_frag_ping(false, fping); - if (fhealth > 1) - return sprintf(CCR(_("\n(Health ^1%d^BG / Armor ^2%d^BG)%s")), fhealth, farmor, s); - else - return sprintf(CCR(_("\n(^F4Dead^BG)%s")), s); -} - -string notif_arg_missing_teams(float f1) -{ - return sprintf("%s%s%s%s", - ((f1 & BIT(0)) ? sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_1), (f1 & (BIT(1) | BIT(2) | BIT(3)) ? ", " : "")) : ""), - ((f1 & BIT(1)) ? sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_2), (f1 & ( BIT(2) | BIT(3)) ? ", " : "")) : ""), - ((f1 & BIT(2)) ? sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_3), (f1 & ( BIT(3)) ? ", " : "")) : ""), - ((f1 & BIT(3)) ? Team_ColoredFullName(NUM_TEAM_4) : "") - ); -} - -string notif_arg_spree_cen(float spree) -{ - // 0 = off, 1 = target (but only for first victim) and attacker - if(autocvar_notification_show_sprees_center) - { - if(spree > 1) - { - #define SPREE_ITEM(counta,countb,center,normal,gentle) \ - case counta: { return normal_or_gentle(center, sprintf(_("%d score spree! "), spree)); } - - switch(spree) - { - KILL_SPREE_LIST - default: - { - if (!autocvar_notification_show_sprees_center_specialonly) - { - return - sprintf( - normal_or_gentle( - _("%d frag spree! "), - _("%d score spree! ") - ), - spree); - } - else { return ""; } // don't show spree information if it isn't an achievement - } - } - - #undef SPREE_ITEM - } - else if(spree == -1) // first blood - { - return normal_or_gentle(_("First blood! "), _("First score! ")); - } - else if(spree == -2) // first victim - { - return normal_or_gentle(_("First victim! "), _("First casualty! ")); - } - } - return ""; -} -#endif - -string notif_arg_spree_inf(float type, string input, string player, float spree) -{ - switch(type) - { - case 1: // attacker kill spree - { - // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker - // this conditional (& 2) is true for 2 and 3 - if(autocvar_notification_show_sprees_info & 2) - { - #ifdef CSQC - string spree_newline = - ( autocvar_notification_show_sprees_info_newline ? - ((substring(input, 0, 1) == "\{3}") ? "\n\{3}" : "\n") : "" ); - #else - string spree_newline = - (autocvar_notification_show_sprees_info_newline ? "\n" : ""); - #endif - - if(spree > 1) - { - #define SPREE_ITEM(counta,countb,center,normal,gentle) \ - case counta: { return sprintf(CCR(normal_or_gentle(normal, gentle)), player, spree_newline); } - - switch(spree) - { - KILL_SPREE_LIST - default: - { - if (!autocvar_notification_show_sprees_info_specialonly) - { - return - sprintf( - CCR(normal_or_gentle( - _("%s^K1 has %d frags in a row! %s^BG"), - _("%s^K1 made %d scores in a row! %s^BG") - )), - player, - spree, - spree_newline - ); - } - else { return ""; } // don't show spree information if it isn't an achievement - } - } - - #undef SPREE_ITEM - } - else if(spree == -1) // firstblood - { - return - sprintf( - CCR(normal_or_gentle( - _("%s^K1 drew first blood! %s^BG"), - _("%s^K1 got the first score! %s^BG") - )), - player, - spree_newline - ); - } - } - break; - } - - case -1: // kill spree ended - { - if((spree > 1) && (autocvar_notification_show_sprees_info & 1)) - { - return - sprintf(normal_or_gentle( - _(", ending their %d frag spree"), - _(", ending their %d score spree") - ), - spree - ); - } - break; - } - - case -2: // kill spree lost - { - if((spree > 1) && (autocvar_notification_show_sprees_info & 1)) - { - return - sprintf(normal_or_gentle( - _(", losing their %d frag spree"), - _(", losing their %d score spree") - ), - spree - ); - } - break; - } - } - return ""; -} - - -// ==================================== -// Initialization/Create Declarations -// ==================================== - -// common notification entity values -.int nent_default; -.bool nent_enabled; -.MSG nent_type; -.string nent_name; -.int nent_stringcount; -.int nent_floatcount; - -// MSG_ANNCE entity values -.int nent_channel; -.string nent_snd; -.float nent_vol; -.float nent_position; - -// MSG_INFO and MSG_CENTER entity values -.string nent_args; // used by both -.string nent_hudargs; // used by info -.string nent_icon; // used by info -.CPID nent_cpid; // used by center -.string nent_durcnt; // used by center -.string nent_string; // used by both - -// MSG_MULTI entity values -.entity nent_msgannce; -.entity nent_msginfo; -.entity nent_msgcenter; - -// MSG_CHOICE entity values -.float nent_challow_def; -.float nent_challow_var; -.entity nent_optiona; -.entity nent_optionb; - -// networked notification entity values -#ifdef SVQC -.NOTIF nent_broadcast; -#endif -.entity nent_client; -.MSG nent_net_type; -.float nent_net_name; -.string nent_strings[4]; -.float nent_floats[4]; - -#define ACVNN(name) autocvar_notification_##name - -REGISTRY(Notifications, BITS(11)) -REGISTER_REGISTRY(Notifications) -REGISTRY_SORT(Notifications); STATIC_INIT(Notifications) { FOREACH(Notifications, true, LAMBDA(it.m_id = i)); } -REGISTRY_CHECK(Notifications) - -const int NOTIF_CHOICE_MAX = 50; -int nent_choice_count = 0; -.int nent_choice_idx; -.int msg_choice_choices[NOTIF_CHOICE_MAX]; // set on each player containing MSG_CHOICE choices -// initialization error detection -bool notif_error; -bool notif_global_error; - -STATIC_INIT_LATE(Notif_Choices) { - int c = 0; - FOREACH(Notifications, it.nent_type == MSG_CHOICE, { c++; }); - if (c > NOTIF_CHOICE_MAX) { - LOG_FATALF("Too many MSG_CHOICE notifications (%d)", c); - } -} - -Notification Get_Notif_Ent(MSG net_type, int net_name) -{ - Notification it = _Notifications_from(net_name, NULL); - if (it.nent_type != net_type) { - LOG_WARNINGF("Get_Notif_Ent(%s (%d), %s (%d)): Improper net type '%s'!\n", - Get_Notif_TypeName(net_type), net_type, - it.registered_id, net_name, - Get_Notif_TypeName(it.nent_type) - ); - return NULL; - } - return it; -} - -#define MSG_ANNCE_NOTIF(name, default, sound, channel, volume, position) \ - MSG_ANNCE_NOTIF_(ANNCE_##name, default, sound, channel, volume, position) -#define MSG_ANNCE_NOTIF_(name, default, sound, channel, volume, position) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - REGISTER(Notifications, name, m_id, new_pure(msg_annce_notification)) { \ - Create_Notification_Entity (this, default, ACVNN(name), MSG_ANNCE, strtoupper(#name)); \ - Create_Notification_Entity_Annce(this, ACVNN(name), strtoupper(#name), \ - channel, /* channel */ \ - sound, /* snd */ \ - volume, /* vol */ \ - position); /* position */ \ - } - -#define MSG_INFO_NOTIF(name, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ - MSG_INFO_NOTIF_(INFO_##name, default, strnum, flnum, args, hudargs, icon, normal, gentle) -#define MSG_INFO_NOTIF_(name, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) { \ - Create_Notification_Entity (this, default, ACVNN(name), MSG_INFO, strtoupper(#name)); \ - Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \ - args, /* args */ \ - hudargs, /* hudargs */ \ - icon, /* icon */ \ - CPID_Null,/* cpid */ \ - "", /* durcnt */ \ - normal, /* normal */ \ - gentle); /* gentle */ \ - } - -.string nent_iconargs; -#define MULTIICON_INFO(name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \ - MULTIICON_INFO_(INFO_##name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) -#define MULTIICON_INFO_(name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) { \ - Create_Notification_Entity (this, default, ACVNN(name), MSG_INFO, strtoupper(#name)); \ - Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \ - args, /* args */ \ - hudargs, /* hudargs */ \ - icon, /* icon */ \ - CPID_Null,/* cpid */ \ - "", /* durcnt */ \ - normal, /* normal */ \ - gentle); /* gentle */ \ - this.nent_iconargs = iconargs; \ - } - -#define MSG_CENTER_NOTIF(name, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ - MSG_CENTER_NOTIF_(CENTER_##name, default, strnum, flnum, args, cpid, durcnt, normal, gentle) -#define MSG_CENTER_NOTIF_(name, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - REGISTER(Notifications, name, m_id, new_pure(msg_center_notification)) { \ - Create_Notification_Entity (this, default, ACVNN(name), MSG_CENTER, strtoupper(#name)); \ - Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \ - args, /* args */ \ - "", /* hudargs */ \ - "", /* icon */ \ - cpid, /* cpid */ \ - durcnt, /* durcnt */ \ - normal, /* normal */ \ - gentle); /* gentle */ \ - } - -#define MSG_MULTI_NOTIF(name, default, anncename, infoname, centername) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - REGISTER(Notifications, name, m_id, new_pure(msg_multi_notification)) { \ - Create_Notification_Entity (this, default, ACVNN(name), MSG_MULTI, strtoupper(#name)); \ - Create_Notification_Entity_Multi(this, ACVNN(name), strtoupper(#name), \ - anncename, /* anncename */ \ - infoname, /* infoname */ \ - centername); /* centername */ \ - } - -#define MSG_CHOICE_NOTIF(name, default, challow, chtype, optiona, optionb) \ - MSG_CHOICE_NOTIF_(CHOICE_##name, default, challow, chtype, optiona, optionb) -#define MSG_CHOICE_NOTIF_(name, default, challow, chtype, optiona, optionb) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - NOTIF_ADD_AUTOCVAR(name##_ALLOWED, challow) \ - REGISTER(Notifications, name, m_id, new_pure(msg_choice_notification)) { \ - this.nent_choice_idx = nent_choice_count++; \ - Create_Notification_Entity (this, default, ACVNN(name), MSG_CHOICE, strtoupper(#name)); \ - Create_Notification_Entity_Choice(this, ACVNN(name), strtoupper(#name), \ - challow, /* challow_def */ \ - autocvar_notification_##name##_ALLOWED, /* challow_var */ \ - chtype, /* chtype */ \ - optiona, /* optiona */ \ - optionb); /* optionb */ \ - } - -REGISTRY_BEGIN(Notifications) -{ - notif_global_error = false; -} - -REGISTRY_END(Notifications) -{ - if (!notif_global_error) return; - // shit happened... stop the loading of the program now if this is unacceptable - if (autocvar_notification_errors_are_fatal) - LOG_FATAL("Notification initialization failed! Read above and fix the errors!"); - else - LOG_SEVERE("Notification initialization failed! Read above and fix the errors!"); -} - -#include "notifications.inc" - -#endif diff --git a/qcsrc/common/notifications/all.inc b/qcsrc/common/notifications/all.inc new file mode 100644 index 000000000..e723b8933 --- /dev/null +++ b/qcsrc/common/notifications/all.inc @@ -0,0 +1,926 @@ +// ==================================== +// Notifications List and Information +// ==================================== +/* + List of all notifications (including identifiers and display information) + Possible Tokens: + default, name, strnum, flnum, + channel, sound, volume, position, + args, hudargs, icon, cpid, durcnt, normal, gentle, + anncename, infoname, centername, + challow, chtype, optiona, optionb + Format Specifications: + name: VAR: Name of notification + MSG_ANNCE: + default: FLOAT: Default setting for whether the notification is enabled or not + ^-> 0 = disabled, 1 = enabled if gentle is disabled, 2 = always enabled + sound: STRING: Filename for the announcement sound + channel: FLOAT: Sound channel to broadcast on to + volume: FLOAT: Volume setting for the announcement sound + position: FLOAT: Attenuation/positioning value + MSG_INFO: + default: FLOAT: Default setting for whether the notification is enabled or not + ^-> 0 = disabled, 1 = enabled, 2 = also print to chat box + strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive) + flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive) + args: STRING: Arguments for Local_Notification_sprintf() + hudargs: STRING: Arguments for Local_Notification_HUD_Notify_Push() + icon: STRING: icon string name for the hud notify panel, "" if no icon is used + normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled) + gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled) + MSG_CENTER: + default: FLOAT: Default setting for whether the notification is enabled or not + ^-> 0 = disabled, 1 = enabled + strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive) + flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive) + args: STRING: Arguments for Local_Notification_sprintf() + cpid: FLOAT: centerprint ID number (CPID_*), CPID_Null if no CPID is needed + durcnt: XPD(FLOAT, FLOAT): Duration/Countdown: extra arguments for centerprint messages + normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled) + gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled) + MSG_MULTI: + default: FLOAT: Default setting for whether the notification is enabled or not + ^-> 0 = disabled, 1 = enabled + anncename: VAR: Name of announcer notification for reference + infoname: VAR: Name of info notification for reference + centername: VAR: Name of centerprint notification for reference + MSG_CHOICE: + default: FLOAT: Default setting for whether the notification is enabled or not + ^-> 0 = disabled, 1 = select option A, 2 = selection option B + challow: FLOAT: Default setting for server allowing choices other than A + ^-> 0 = no choice, 1 = allowed in warmup, 2 = always allowed + chtype: VAR: Notification message type for options + optiona: VAR: Name of choice "A" notification for reference + optionb: VAR: Name of choice "B" notification for reference + + Messages with ^F1, ^BG, ^TC, etc etc in them will replace those strings + with colors according to the cvars the user has chosen. This allows for + users to create unique color profiles for their HUD, giving more customization + options to HUD designers and end users who want such a feature. + + Check out the definitions in util.qc/util.qh/teams.qh for string CCR(...) and + string TCR(...) to better understand how these code replacements work. + + Additionally, you can find all the definitions and explanations for + the argument values and what they return down below in this file. + + Guidlines for notification declaration (please try and follow these): + Specific rules: + - ALWAYS start the string with a color, preferably background. + - ALWAYS reset a color after a name (this way they don't set it for the whole string). + - NEVER add or remove tokens from the format, it SHOULD already work. + - MSG_INFO hudargs must always be ATTACKER -> VICTIM + - MSG_INFO and MSG_CENTER should NOT end with a new line + + General rules: + - Be clean and simple with your notification naming, + nothing too long for the name field... Abbreviations are your friend. :D + - Keep the spacing as clean as possible... if the arguments are abnormally long, + it's okay to go out of line a bit... but try and keep it clean still. + - Use ONLY spaces for spacing in the notification list, tabs are too inconsistent + with keeping alignment on different mediums. + - Sort the notifications in the most appropriate order for their tasks. + + Final note: DO NOT PROVIDE MORE ARGUMENTS THAN NECESSARY FOR THE NOTIFICATION YOU'RE CALLING! + The system is designed to save as much networking bandwidth as possible, + so please dynamically control your argument sending to fit *exactly* what is required. + If you send a notification with mismatching arguments, Send_Notification() will error. +*/ + +#define MULTITEAM_ANNCE2(prefix, default, sound, channel, volume, position) \ + MSG_ANNCE_NOTIF(prefix##RED, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), channel, volume, position) \ + MSG_ANNCE_NOTIF(prefix##BLUE, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_2)), channel, volume, position) +#define MULTITEAM_ANNCE3(prefix, default, sound, channel, volume, position) \ + MULTITEAM_ANNCE2(prefix, default, sound, channel, volume, position) \ + MSG_ANNCE_NOTIF(prefix##YELLOW, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_3)), channel, volume, position) +#define MULTITEAM_ANNCE4(prefix, default, sound, channel, volume, position) \ + MULTITEAM_ANNCE3(prefix, default, sound, channel, volume, position) \ + MSG_ANNCE_NOTIF(prefix##PINK, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_4)), channel, volume, position) +#define MULTITEAM_ANNCE(prefix, teams, default, sound, channel, volume, position) \ + MULTITEAM_ANNCE##teams(prefix, default, sound, channel, volume, position) + +// MSG_ANNCE_NOTIFICATIONS + MSG_ANNCE_NOTIF(ACHIEVEMENT_AIRSHOT, 1, "airshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_AMAZING, 1, "amazing", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME, 1, "awesome", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_BOTLIKE, 1, "botlike", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_ELECTROBITCH, 2, "electrobitch", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_IMPRESSIVE, 1, "impressive", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_YODA, 1, "yoda", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(BEGIN, 2, "begin", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(KILLSTREAK_03, 1, "03kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_05, 1, "05kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_10, 1, "10kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_15, 1, "15kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_20, 1, "20kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_25, 1, "25kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_30, 1, "30kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(INSTAGIB_LASTSECOND, 1, "lastsecond", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(INSTAGIB_NARROWLY, 1, "narrowly", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(INSTAGIB_TERMINATED, 1, "terminated", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(MULTIFRAG, 0, "multifrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_1, 2, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_2, 2, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_3, 2, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_4, 2, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_5, 2, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_6, 2, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_7, 2, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_8, 2, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_9, 2, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_10, 2, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_GAMESTART_1, 2, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_2, 2, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_3, 2, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_4, 2, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_5, 2, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_IDLE_1, 0, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_2, 0, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_3, 0, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_KILL_1, 0, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_2, 0, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_3, 0, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_RESPAWN_1, 0, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_2, 0, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_3, 0, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_1, 2, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_2, 2, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_3, 2, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(PREPARE, 2, "prepareforbattle", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(REMAINING_FRAG_1, 1, "1fragleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(REMAINING_FRAG_2, 1, "2fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(REMAINING_FRAG_3, 1, "3fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(REMAINING_MIN_1, 2, "1minuteremains", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(REMAINING_MIN_5, 2, "5minutesremain", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(TIMEOUT, 2, "timeoutcalled", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(VOTE_ACCEPT, 2, "voteaccept", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(VOTE_CALL, 2, "votecall", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(VOTE_FAIL, 2, "votefail", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + +#define MULTITEAM_INFO2(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MSG_INFO_NOTIF(prefix##_RED, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ + MSG_INFO_NOTIF(prefix##_BLUE, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) +#define MULTITEAM_INFO3(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MULTITEAM_INFO2(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MSG_INFO_NOTIF(prefix##_YELLOW, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) +#define MULTITEAM_INFO4(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MULTITEAM_INFO3(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MSG_INFO_NOTIF(prefix##_PINK, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) +#define MULTITEAM_INFO(prefix, teams, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MULTITEAM_INFO##teams(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) + +// MSG_INFO_NOTIFICATIONS + MSG_INFO_NOTIF(CHAT_NOSPECTATORS, 2, 0, 0, "", "", "", _("^F4NOTE: ^BGSpectator chat is not sent to players during the match"), "") + + MULTITEAM_INFO(CTF_CAPTURE, 4, 1, 1, 0, "s1", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag"), "") + MULTITEAM_INFO(CTF_CAPTURE_BROKEN, 4, 1, 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"), "") + MSG_INFO_NOTIF(CTF_CAPTURE_NEUTRAL, 1, 1, 0, "s1", "s1", "notify_neutral_captured", _("^BG%s^BG captured the flag"), "") + MULTITEAM_INFO(CTF_CAPTURE_TIME, 4, 1, 1, 1, "s1 f1p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"), "") + MULTITEAM_INFO(CTF_CAPTURE_UNBROKEN, 4, 1, 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"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_ABORTRUN, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_ABORTRUN_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag was returned by its owner"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_DAMAGED, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_DAMAGED_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag was destroyed and returned to base"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_DROPPED, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_DROPPED_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag was dropped in the base and returned itself"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_NEEDKILL, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_NEEDKILL_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag fell somewhere it couldn't be reached and returned to base"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_SPEEDRUN, 4, 1, 0, 1, "f1p2dec", "", "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_SPEEDRUN_NEUTRAL, 1, 0, 1, "f1p2dec", "", "", _("^BGThe flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_TIMEOUT, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag has returned to the base"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_TIMEOUT_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag has returned to the base"), "") + MULTITEAM_INFO(CTF_LOST, 4, 1, 1, 0, "s1", "s1", "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag"), "") + MSG_INFO_NOTIF(CTF_LOST_NEUTRAL, 1, 1, 0, "s1", "s1", "notify_neutral_lost", _("^BG%s^BG lost the flag"), "") + MULTITEAM_INFO(CTF_PICKUP, 4, 1, 1, 0, "s1", "s1", "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag"), "") + MSG_INFO_NOTIF(CTF_PICKUP_NEUTRAL, 1, 1, 0, "s1", "s1", "notify_neutral_taken", _("^BG%s^BG got the flag"), "") + MULTITEAM_INFO(CTF_RETURN, 4, 1, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") + MULTITEAM_INFO(CTF_RETURN_MONSTER, 4, 1, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") + + MSG_INFO_NOTIF(COINTOSS, 2, 1, 0, "s1", "", "", _("^F2Throwing coin... Result: %s^F2!"), "") + + MSG_INFO_NOTIF(JETPACK_NOFUEL, 1, 0, 0, "", "", "", _("^BGYou don't have any fuel for the ^F1Jetpack"), "") + + MSG_INFO_NOTIF(SUPERSPEC_MISSING_UID, 2, 0, 0, "", "", "", _("^F2You lack a UID, superspec options will not be saved/restored"), "") + + MSG_INFO_NOTIF(CA_JOIN_LATE, 1, 0, 0, "", "", "", _("^F1Round already started, you will join the game in the next round"), "") + MSG_INFO_NOTIF(CA_LEAVE, 1, 0, 0, "", "", "", _("^F2You will spectate in the next round"), "") + + MSG_INFO_NOTIF(DEATH_MURDER_BUFF, 1, 3, 3, "spree_inf s1 s2 f3buffname s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was killed by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"), _("^BG%s%s^K1 was scored against by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s")) + MSG_INFO_NOTIF(DEATH_MURDER_CHEAT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_DROWN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_water", _("^BG%s%s^K1 was drowned by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_FALL, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_fall", _("^BG%s%s^K1 was grounded by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_FIRE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s"), _("^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s")) + MSG_INFO_NOTIF(DEATH_MURDER_LAVA, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_lava", _("^BG%s%s^K1 was cooked by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_MONSTER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was pushed infront of a monster by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_NADE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_normal", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_NADE_NAPALM, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_napalm", _("^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"), _("^BG%s%s^K1 got too close to a napalm explosion%s%s")) + MSG_INFO_NOTIF(DEATH_MURDER_NADE_ICE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_ice", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Ice Nade%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_NADE_ICE_FREEZE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_ice", _("^BG%s%s^K1 was frozen to death by ^BG%s^K1's Ice Nade%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_NADE_HEAL, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_heal", _("^BG%s%s^K1 has not been healed by ^BG%s^K1's Healing Nade%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_SHOOTING_STAR, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_shootingstar", _("^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_SLIME, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was slimed by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_SWAMP, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was preserved by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_TELEFRAG, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_telefrag", _("^BG%s%s^K1 was telefragged by ^BG%s^K1%s%s"), _("^BG%s%s^K1 tried to occupy ^BG%s^K1's teleport destination space%s%s")) + MSG_INFO_NOTIF(DEATH_MURDER_TOUCHEXPLODE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 died in an accident with ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_BUMB_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Bumblebee exploded%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_BUMB_GUN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 saw the pretty lights of ^BG%s^K1's Bumblebee gun%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_CRUSH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was crushed by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_RAPT_BOMB, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was cluster bombed by ^BG%s^K1's Raptor%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_RAPT_CANNON, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 couldn't resist ^BG%s^K1's purple blobs%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_RAPT_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Raptor exploded%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_SPID_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Spiderbot exploded%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_SPID_MINIGUN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got shredded by ^BG%s^K1's Spiderbot%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_SPID_ROCKET, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was blasted to bits by ^BG%s^K1's Spiderbot%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_WAKI_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_WAKI_GUN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_WAKI_ROCKET, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VOID, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_void", _("^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s"), "") + + MSG_INFO_NOTIF(DEATH_SELF_AUTOTEAMCHANGE, 1, 2, 1, "s1 s2loc death_team", "", "", _("^BG%s^K1 was moved into the %s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_BETRAYAL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_teamkill_red", _("^BG%s^K1 became enemies with the Lord of Teamplay%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_CAMP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_camping", _("^BG%s^K1 thought they found a nice camping ground%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_CHEAT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 unfairly eliminated themself%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_CUSTOM, 1, 3, 1, "s1 s2 s3loc spree_lost", "s1", "notify_void", "^BG%s^K1 %s^K1%s%s", "") + MSG_INFO_NOTIF(DEATH_SELF_DROWN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_water", _("^BG%s^K1 couldn't catch their breath%s%s"), _("^BG%s^K1 was in the water for too long%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_FALL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_fall", _("^BG%s^K1 hit the ground with a crunch%s%s"), _("^BG%s^K1 hit the ground with a bit too much force%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_FIRE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 became a bit too crispy%s%s"), _("^BG%s^K1 felt a little hot%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_GENERIC, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 died%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_LAVA, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_lava", _("^BG%s^K1 turned into hot slag%s%s"), _("^BG%s^K1 found a hot place%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_MON_MAGE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was exploded by a Mage%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_SHAMBLER_CLAW, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1's innards became outwards by a Shambler%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_SHAMBLER_SMASH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was smashed by a Shambler%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_SHAMBLER_ZAP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was zapped to death by a Shambler%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_SPIDER, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was bitten by a Spider%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_WYVERN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was fireballed by a Wyvern%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_ZOMBIE_JUMP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 joins the Zombies%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_ZOMBIE_MELEE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was given kung fu lessons by a Zombie%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_NADE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_normal", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_NADE_NAPALM, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_napalm", _("^BG%s^K1 was burned to death by their own Napalm Nade%s%s"), _("^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_NADE_ICE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_ice", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_NADE_ICE_FREEZE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_ice", _("^BG%s^K1 was frozen to death by their own Ice Nade%s%s"), _("^BG%s^K1 felt a little chilly%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_NADE_HEAL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_heal", _("^BG%s^K1's Healing Nade didn't quite heal them%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_NOAMMO, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_outofammo", _("^BG%s^K1 died%s%s. What's the point of living without ammo?"), _("^BG%s^K1 ran out of ammo%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_ROT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 rotted away%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_SHOOTING_STAR, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_shootingstar", _("^BG%s^K1 became a shooting star%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_SLIME, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_slime", _("^BG%s^K1 was slimed%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 couldn't take it anymore%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_SWAMP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_slime", _("^BG%s^K1 is now preserved for centuries to come%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TEAMCHANGE, 1, 2, 1, "s1 s2loc death_team", "", "", _("^BG%s^K1 switched to the %s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TOUCHEXPLODE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 died in an accident%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 ran into a turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_EWHEEL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by an eWheel turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_FLAC, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught up in the FLAC turret fire%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_HELLION, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by a Hellion turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_HK, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 could not hide from the Hunter turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_MACHINEGUN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was riddled full of holes by a Machinegun turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_MLRS, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got turned into smoldering gibs by an MLRS turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_PHASER, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was phased out by a turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_PLASMA, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got served some superheated plasma from a turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_TESLA, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was electrocuted by a Tesla turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_WALK_GUN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got served a lead enrichment by a Walker turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_WALK_MELEE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was impaled by a Walker turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_WALK_ROCKET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by a Walker turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_BUMB_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Bumblebee explosion%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_CRUSH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was crushed by a vehicle%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_RAPT_BOMB, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was caught in a Raptor cluster bomb%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_RAPT_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Raptor explosion%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_SPID_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Spiderbot explosion%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_SPID_ROCKET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted to bits by a Spiderbot rocket%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_WAKI_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Racer explosion%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_WAKI_ROCKET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 couldn't find shelter from a Racer rocket%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VOID, 1, 3, 1, "s1 s2 s2loc spree_lost", "s1", "notify_void", "^BG%s^K1 %s^K1%s%s", "") + + MULTITEAM_INFO(DEATH_TEAMKILL, 4, 1, 3, 1, "s1 s2 s3loc spree_end", "s2 s1", "notify_teamkill_%s", _("^BG%s^K1 was betrayed by ^BG%s^K1%s%s"), "") + + MSG_INFO_NOTIF(DOMINATION_CAPTURE_TIME, 1, 2, 2, "s1 s2 f1 f1points f2", "", "", _("^BG%s^BG%s^BG (%s %s every %s seconds)"), "") + + MSG_INFO_NOTIF(FREEZETAG_FREEZE, 1, 2, 0, "s1 s2", "", "", _("^BG%s^K1 was frozen by ^BG%s"), "") + MSG_INFO_NOTIF(FREEZETAG_REVIVED, 1, 2, 0, "s1 s2", "", "", _("^BG%s^K3 was revived by ^BG%s"), "") + MSG_INFO_NOTIF(FREEZETAG_REVIVED_FALL, 1, 1, 0, "s1", "", "", _("^BG%s^K3 was revived by falling"), "") + MSG_INFO_NOTIF(FREEZETAG_REVIVED_NADE, 1, 1, 0, "s1", "", "", _("^BG%s^K3 was revived by their Nade explosion"), "") + MSG_INFO_NOTIF(FREEZETAG_AUTO_REVIVED, 1, 1, 1, "s1 f1", "", "", _("^BG%s^K3 was automatically revived after %s second(s)"), "") + MSG_INFO_NOTIF(FREEZETAG_SELF, 1, 1, 0, "s1", "", "", _("^BG%s^K1 froze themself"), "") + + MULTITEAM_INFO(ROUND_TEAM_WIN, 4, 1, 0, 0, "", "", "", _("^TC^TT^BG team wins the round"), "") + MSG_INFO_NOTIF(ROUND_PLAYER_WIN, 1, 1, 0, "s1", "", "", _("^BG%s^BG wins the round"), "") + MSG_INFO_NOTIF(ROUND_TIED, 1, 0, 0, "", "", "", _("^BGRound tied"), "") + MSG_INFO_NOTIF(ROUND_OVER, 1, 0, 0, "", "", "", _("^BGRound over, there's no winner"), "") + + MSG_INFO_NOTIF(GODMODE_OFF, 1, 0, 1, "f1", "", "", _("^BGGodmode saved you %s units of damage, cheater!"), "") + + MSG_INFO_NOTIF(ITEM_BUFF, 1, 1, 1, "s1 item_buffname", "", "", _("^BG%s^BG got the %s^BG buff!"), "") + MSG_INFO_NOTIF(ITEM_BUFF_LOST, 1, 1, 1, "s1 item_buffname", "", "", _("^BG%s^BG lost the %s^BG buff!"), "") + MSG_INFO_NOTIF(ITEM_BUFF_DROP, 1, 0, 1, "item_buffname", "", "", _("^BGYou dropped the %s^BG buff!"), "") + MSG_INFO_NOTIF(ITEM_BUFF_GOT, 1, 0, 1, "item_buffname", "", "", _("^BGYou got the %s^BG buff!"), "") + + MSG_INFO_NOTIF(ITEM_WEAPON_DONTHAVE, 0, 0, 1, "item_wepname", "", "", _("^BGYou do not have the ^F1%s"), "") + MSG_INFO_NOTIF(ITEM_WEAPON_DROP, 0, 1, 1, "item_wepname item_wepammo", "", "", _("^BGYou dropped the ^F1%s^BG%s"), "") + MSG_INFO_NOTIF(ITEM_WEAPON_GOT, 0, 0, 1, "item_wepname", "", "", _("^BGYou got the ^F1%s"), "") + MSG_INFO_NOTIF(ITEM_WEAPON_NOAMMO, 0, 0, 1, "item_wepname", "", "", _("^BGYou don't have enough ammo for the ^F1%s"), "") + MSG_INFO_NOTIF(ITEM_WEAPON_PRIMORSEC, 0, 0, 3, "item_wepname f2primsec f3primsec", "", "", _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"), "") + MSG_INFO_NOTIF(ITEM_WEAPON_UNAVAILABLE, 0, 0, 1, "item_wepname", "", "", _("^F1%s^BG is ^F4not available^BG on this map"), "") + + MSG_INFO_NOTIF(CONNECTING, 1, 1, 0, "s1", "", "", _("^BG%s^BG is connecting..."), "") + MSG_INFO_NOTIF(JOIN_CONNECT, 2, 1, 0, "s1", "", "", _("^BG%s^F3 connected"), "") + MULTITEAM_INFO(JOIN_CONNECT_TEAM, 4, 2, 1, 0, "s1", "", "", _("^BG%s^F3 connected and joined the ^TC^TT team"), "") + MSG_INFO_NOTIF(JOIN_PLAY, 1, 1, 0, "s1", "", "", _("^BG%s^F3 is now playing"), "") + MULTITEAM_INFO(JOIN_PLAY_TEAM, 4, 2, 1, 0, "s1", "", "", _("^BG%s^F3 is now playing on the ^TC^TT team"), "") + + MSG_INFO_NOTIF(KEEPAWAY_DROPPED, 1, 1, 0, "s1", "s1", "notify_balldropped", _("^BG%s^BG has dropped the ball!"), "") + MSG_INFO_NOTIF(KEEPAWAY_PICKUP, 1, 1, 0, "s1", "s1", "notify_ballpickedup", _("^BG%s^BG has picked up the ball!"), "") + + MULTITEAM_INFO(KEYHUNT_CAPTURE, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG captured the keys for the ^TC^TT team"), "") + MULTITEAM_INFO(KEYHUNT_DROP, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG dropped the ^TC^TT Key"), "") + MULTITEAM_INFO(KEYHUNT_LOST, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG lost the ^TC^TT Key"), "") + MULTITEAM_INFO(KEYHUNT_PICKUP, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG picked up the ^TC^TT Key"), "") + + MSG_INFO_NOTIF(LMS_FORFEIT, 1, 1, 0, "s1", "", "", _("^BG%s^F3 forfeited"), "") + MSG_INFO_NOTIF(LMS_NOLIVES, 1, 1, 0, "s1", "", "", _("^BG%s^F3 has no more lives left"), "") + + MSG_INFO_NOTIF(MONSTERS_DISABLED, 1, 0, 0, "", "", "", _("^BGMonsters are currently disabled"), "") + + MSG_INFO_NOTIF(ONSLAUGHT_CAPTURE, 1, 2, 0, "s1 s2", "", "", _("^BG%s^BG captured %s^BG control point"), "") + MULTITEAM_INFO(ONSLAUGHT_CPDESTROYED, 4, 1, 2, 0, "s1 s2", "", "", _("^TC^TT^BG team %s^BG control point has been destroyed by %s"), "") + MULTITEAM_INFO(ONSLAUGHT_GENDESTROYED, 4, 1, 0, 0, "", "", "", _("^TC^TT^BG generator has been destroyed"), "") + MULTITEAM_INFO(ONSLAUGHT_GENDESTROYED_OVERTIME, 4, 1, 0, 0, "", "", "", _("^TC^TT^BG generator spontaneously combusted due to overtime!"), "") + + MSG_INFO_NOTIF(POWERUP_INVISIBILITY, 1, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Invisibility"), "") + MSG_INFO_NOTIF(POWERUP_SHIELD, 1, 1, 0, "s1", "s1", "shield", _("^BG%s^K1 picked up Shield"), "") + MSG_INFO_NOTIF(POWERUP_SPEED, 1, 1, 0, "s1", "s1", "shield", _("^BG%s^K1 picked up Speed"), "") + MSG_INFO_NOTIF(POWERUP_STRENGTH, 1, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Strength"), "") + + MSG_INFO_NOTIF(QUIT_DISCONNECT, 2, 1, 0, "s1", "", "", _("^BG%s^F3 disconnected"), "") + MSG_INFO_NOTIF(QUIT_KICK_IDLING, 2, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked for idling"), "") + MSG_INFO_NOTIF(QUIT_KICK_SPECTATING, 1, 0, 0, "", "", "", _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment."), "") + MSG_INFO_NOTIF(QUIT_SPECTATE, 1, 1, 0, "s1", "", "", _("^BG%s^F3 is now spectating"), "") + + MSG_INFO_NOTIF(RACE_ABANDONED, 1, 1, 0, "s1", "", "", _("^BG%s^BG has abandoned the race"), "") + MSG_INFO_NOTIF(RACE_FAIL_RANKED, 1, 1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1 f3race_time", "race_newfail", _("^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s"), "") + MSG_INFO_NOTIF(RACE_FAIL_UNRANKED, 1, 1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1 f3race_time", "race_newfail", _("^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s"), "") + MSG_INFO_NOTIF(RACE_FINISHED, 1, 1, 0, "s1", "", "", _("^BG%s^BG has finished the race"), "") + MSG_INFO_NOTIF(RACE_NEW_BROKEN, 1, 2, 3, "s1 s2 race_col f1ord race_col f2race_time race_diff", "s1 f2race_time", "race_newrankyellow", _("^BG%s^BG broke %s^BG's %s%s^BG place record with %s%s %s"), "") + MSG_INFO_NOTIF(RACE_NEW_IMPROVED, 1, 1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1 f2race_time", "race_newtime", _("^BG%s^BG improved their %s%s^BG place record with %s%s %s"), "") + MSG_INFO_NOTIF(RACE_NEW_MISSING_UID, 1, 1, 1, "s1 f1race_time", "s1 f1race_time", "race_newfail", _("^BG%s^BG scored a new record with ^F2%s^BG, but unfortunately lacks a UID and will be lost."), "") + MSG_INFO_NOTIF(RACE_NEW_SET, 1, 1, 2, "s1 race_col f1ord race_col f2race_time", "s1 f2race_time", "race_newrecordserver", _("^BG%s^BG set the %s%s^BG place record with %s%s"), "") + + MULTIICON_INFO(MINIGAME_INVITE, 1, 2, 0, "s2 minigame1_name s1", "s2", "minigame1_d", "minigames/%s/icon_notif", _("^F4You have been invited by ^BG%s^F4 to join their game of ^F2%s^F4 (^F1%s^F4)"), "") + + MULTITEAM_INFO(SCORES, 4, 1, 0, 0, "", "", "", _("^TC^TT ^BGteam scores!"), "") + + MSG_INFO_NOTIF(SPECTATE_WARNING, 1, 0, 1, "f1secs", "", "", _("^F2You have to become a player within the next %s, otherwise you will be kicked, because spectating isn't allowed at this time!"), "") + + MSG_INFO_NOTIF(SUPERWEAPON_PICKUP, 1, 1, 0, "s1", "s1", "superweapons", _("^BG%s^K1 picked up a Superweapon"), "") + + MSG_INFO_NOTIF(TEAMCHANGE_LARGERTEAM, 1, 0, 0, "", "", "", _("^BGYou cannot change to a larger team"), "") + MSG_INFO_NOTIF(TEAMCHANGE_NOTALLOWED, 1, 0, 0, "", "", "", _("^BGYou are not allowed to change teams"), "") + + MSG_INFO_NOTIF(VERSION_BETA, 2, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s"), "") + MSG_INFO_NOTIF(VERSION_OLD, 2, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s"), "") + MSG_INFO_NOTIF(VERSION_OUTDATED, 2, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get the update from ^F3http://www.xonotic.org/^BG!"), "") + + MSG_INFO_NOTIF(WATERMARK, 1, 1, 0, "s1", "", "", _("^F3SVQC Build information: ^F4%s"), "") + + MSG_INFO_NOTIF(WEAPON_ACCORDEON_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Accordeon%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ACCORDEON_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ARC_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponarc", _("^BG%s%s^K1 was electrocuted by ^BG%s^K1's Arc%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ARC_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponarc", _("^BG%s%s^K1 was blasted by ^BG%s^K1's Arc bolts%s%s"), "") + MSG_INFO_NOTIF(WEAPON_BLASTER_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponlaser", _("^BG%s%s^K1 was shot to death by ^BG%s^K1's Blaster%s%s"), "") + MSG_INFO_NOTIF(WEAPON_BLASTER_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponlaser", _("^BG%s^K1 shot themself to hell with their Blaster%s%s"), "") + MSG_INFO_NOTIF(WEAPON_CRYLINK_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponcrylink", _("^BG%s%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s%s"), "") + MSG_INFO_NOTIF(WEAPON_CRYLINK_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponcrylink", _("^BG%s^K1 felt the strong pull of their Crylink%s%s"), "") + MSG_INFO_NOTIF(WEAPON_DEVASTATOR_MURDER_DIRECT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrocketlauncher", _("^BG%s%s^K1 ate ^BG%s^K1's rocket%s%s"), "") + MSG_INFO_NOTIF(WEAPON_DEVASTATOR_MURDER_SPLASH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrocketlauncher", _("^BG%s%s^K1 got too close ^BG%s^K1's rocket%s%s"), "") + MSG_INFO_NOTIF(WEAPON_DEVASTATOR_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrocketlauncher", _("^BG%s^K1 blew themself up with their Devastator%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ELECTRO_MURDER_BOLT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 was blasted by ^BG%s^K1's Electro bolt%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ELECTRO_MURDER_COMBO, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 felt the electrifying air of ^BG%s^K1's Electro combo%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ELECTRO_MURDER_ORBS, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 got too close to ^BG%s^K1's Electro orb%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ELECTRO_SUICIDE_BOLT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponelectro", _("^BG%s^K1 played with Electro bolts%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ELECTRO_SUICIDE_ORBS, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponelectro", _("^BG%s^K1 could not remember where they put their Electro orb%s%s"), "") + MSG_INFO_NOTIF(WEAPON_FIREBALL_MURDER_BLAST, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponfireball", _("^BG%s%s^K1 got too close to ^BG%s^K1's fireball%s%s"), "") + MSG_INFO_NOTIF(WEAPON_FIREBALL_MURDER_FIREMINE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponfireball", _("^BG%s%s^K1 got burnt by ^BG%s^K1's firemine%s%s"), "") + MSG_INFO_NOTIF(WEAPON_FIREBALL_SUICIDE_BLAST, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponfireball", _("^BG%s^K1 should have used a smaller gun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_FIREBALL_SUICIDE_FIREMINE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponfireball", _("^BG%s^K1 forgot about their firemine%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HAGAR_MURDER_BURST, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhagar", _("^BG%s%s^K1 was pummeled by a burst of ^BG%s^K1's Hagar rockets%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HAGAR_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhagar", _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Hagar rockets%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HAGAR_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponhagar", _("^BG%s^K1 played with tiny Hagar rockets%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HLAC_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhlac", _("^BG%s%s^K1 was cut down with ^BG%s^K1's HLAC%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HLAC_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponhlac", _("^BG%s^K1 got a little jumpy with their HLAC%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HMG_MURDER_SNIPE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhmg", _("^BG%s%s^K1 was sniped by ^BG%s^K1's Heavy Machine Gun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HMG_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhmg", _("^BG%s%s^K1 was torn to bits by ^BG%s^K1's Heavy Machine Gun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HOOK_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhook", _("^BG%s%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s%s"), "") + MSG_INFO_NOTIF(WEAPON_KLEINBOTTLE_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s%s"), "") + MSG_INFO_NOTIF(WEAPON_KLEINBOTTLE_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MACHINEGUN_MURDER_SNIPE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponuzi", _("^BG%s%s^K1 was sniped by ^BG%s^K1's Machine Gun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MACHINEGUN_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponuzi", _("^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MINELAYER_LIMIT, 1, 0, 1, "f1", "", "", _("^BGYou cannot place more than ^F2%s^BG mines at a time"), "") + MSG_INFO_NOTIF(WEAPON_MINELAYER_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponminelayer", _("^BG%s%s^K1 got too close to ^BG%s^K1's mine%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MINELAYER_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponminelayer", _("^BG%s^K1 forgot about their mine%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MORTAR_MURDER_BOUNCE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapongrenadelauncher", _("^BG%s%s^K1 got too close to ^BG%s^K1's Mortar grenade%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MORTAR_MURDER_EXPLODE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapongrenadelauncher", _("^BG%s%s^K1 ate ^BG%s^K1's Mortar grenade%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MORTAR_SUICIDE_BOUNCE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapongrenadelauncher", _("^BG%s^K1 didn't see their own Mortar grenade%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MORTAR_SUICIDE_EXPLODE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapongrenadelauncher", _("^BG%s^K1 blew themself up with their own Mortar%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 was sniped with a Rifle by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER_HAIL, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 died in ^BG%s^K1's Rifle bullet hail%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER_HAIL_PIERCING, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER_PIERCING, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RPC_MURDER_DIRECT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrpc", _("^BG%s%s^K1 was sawn in half by ^BG%s^K1's Rocket Propelled Chainsaw%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RPC_MURDER_SPLASH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrpc", _("^BG%s%s^K1 almost dodged ^BG%s^K1's Rocket Propelled Chainsaw%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RPC_SUICIDE_DIRECT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrpc", _("^BG%s^K1 was sawn in half by their own Rocket Propelled Chainsaw%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RPC_SUICIDE_SPLASH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrpc", _("^BG%s^K1 blew themself up with their Rocket Propelled Chainsaw%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SEEKER_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponseeker", _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SEEKER_MURDER_TAG, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponseeker", _("^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SEEKER_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponseeker", _("^BG%s^K1 played with tiny Seeker rockets%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponshotgun", _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shockwave%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER_SLAP, 1, 3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1", "notify_melee_shotgun", _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shockwave%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SHOTGUN_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponshotgun", _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SHOTGUN_MURDER_SLAP, 1, 3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1", "notify_melee_shotgun", _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_THINKING_WITH_PORTALS, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 is now thinking with portals%s%s"), "") + MSG_INFO_NOTIF(WEAPON_TUBA_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s%s"), "") + MSG_INFO_NOTIF(WEAPON_TUBA_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s%s"), "") + MSG_INFO_NOTIF(WEAPON_VAPORIZER_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponminstanex", _("^BG%s%s^K1 has been sublimated by ^BG%s^K1's Vaporizer%s%s"), "") + MSG_INFO_NOTIF(WEAPON_VORTEX_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponnex", _("^BG%s%s^K1 has been vaporized by ^BG%s^K1's Vortex%s%s"), "") + +#define MULTITEAM_CENTER2(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MSG_CENTER_NOTIF(prefix##_RED, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ + MSG_CENTER_NOTIF(prefix##_BLUE, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) +#define MULTITEAM_CENTER3(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MULTITEAM_CENTER2(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MSG_CENTER_NOTIF(prefix##_YELLOW, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) +#define MULTITEAM_CENTER4(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MULTITEAM_CENTER3(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MSG_CENTER_NOTIF(prefix##_PINK, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) +#define MULTITEAM_CENTER(prefix, teams, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MULTITEAM_CENTER##teams(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) + +// MSG_CENTER_NOTIFICATIONS + MSG_CENTER_NOTIF(ALONE, 1, 0, 0, "", CPID_Null, "0 0", _("^F4You are now alone!"), "") + + MSG_CENTER_NOTIF(ASSAULT_ATTACKING, 1, 0, 0, "", CPID_ASSAULT_ROLE, "0 0", _("^BGYou are attacking!"), "") + MSG_CENTER_NOTIF(ASSAULT_DEFENDING, 1, 0, 0, "", CPID_ASSAULT_ROLE, "0 0", _("^BGYou are defending!"), "") + + MSG_CENTER_NOTIF(COUNTDOWN_BEGIN, 1, 0, 0, "", CPID_ROUND, "2 0", _("^F4Begin!"), "") + MSG_CENTER_NOTIF(COUNTDOWN_GAMESTART, 1, 0, 1, "", CPID_ROUND, "1 f1", _("^F4Game starts in ^COUNT"), "") + MSG_CENTER_NOTIF(COUNTDOWN_ROUNDSTART, 1, 0, 1, "", CPID_ROUND, "1 f1", _("^F4Round starts in ^COUNT"), "") + MSG_CENTER_NOTIF(COUNTDOWN_ROUNDSTOP, 1, 0, 0, "", CPID_ROUND, "2 0", _("^F4Round cannot start"), "") + + MSG_CENTER_NOTIF(ROUND_TIED, 1, 0, 0, "", CPID_ROUND, "0 0", _("^BGRound tied"), "") + MSG_CENTER_NOTIF(ROUND_OVER, 1, 0, 0, "", CPID_ROUND, "0 0", _("^BGRound over, there's no winner"), "") + + MSG_CENTER_NOTIF(CAMPCHECK, 1, 0, 0, "", CPID_CAMPCHECK, "0 0", _("^F2Don't camp!"), "") + + MSG_CENTER_NOTIF(COINTOSS, 1, 1, 0, "s1", CPID_Null, "0 0", _("^F2Throwing coin... Result: %s^F2!"), "") + + MSG_CENTER_NOTIF(CTF_CAPTURESHIELD_FREE, 1, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now free.\n^BGFeel free to ^F2try to capture^BG the flag again\n^BGif you think you will succeed."), "") + MSG_CENTER_NOTIF(CTF_CAPTURESHIELD_INACTIVE, 1, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGThis flag is currently inactive"), "") + MSG_CENTER_NOTIF(CTF_CAPTURESHIELD_SHIELDED, 1, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now ^F1shielded^BG from the flag(s)\n^BGfor ^F2too many unsuccessful attempts^BG to capture.\n^BGMake some defensive scores before trying again."), "") + MULTITEAM_CENTER(CTF_CAPTURE, 4, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the ^TC^TT^BG flag!"), "") + MSG_CENTER_NOTIF(CTF_CAPTURE_NEUTRAL, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the flag!"), "") + MSG_CENTER_NOTIF(CTF_FLAG_THROW_PUNISH, 1, 0, 1, "f1secs", CPID_CTF_LOWPRIO, "0 0", _("^BGToo many flag throws! Throwing disabled for %s."), "") + MULTITEAM_CENTER(CTF_PASS_OTHER, 4, 1, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") + MSG_CENTER_NOTIF(CTF_PASS_OTHER_NEUTRAL, 1, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the flag to %s"), "") + MULTITEAM_CENTER(CTF_PASS_RECEIVED, 4, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the ^TC^TT^BG flag from %s"), "") + MSG_CENTER_NOTIF(CTF_PASS_RECEIVED_NEUTRAL, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the flag from %s"), "") + MSG_CENTER_NOTIF(CTF_PASS_REQUESTED, 1, 1, 0, "s1 pass_key", CPID_CTF_PASS, "0 0", _("^BG%s^BG requests you to pass the flag%s"), "") + MSG_CENTER_NOTIF(CTF_PASS_REQUESTING, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGRequesting %s^BG to pass you the flag"), "") + MULTITEAM_CENTER(CTF_PASS_SENT, 4, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the ^TC^TT^BG flag to %s"), "") + MSG_CENTER_NOTIF(CTF_PASS_SENT_NEUTRAL, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the flag to %s"), "") + MULTITEAM_CENTER(CTF_PICKUP, 4, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the ^TC^TT^BG flag!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_NEUTRAL, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the flag!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_TEAM, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got your %steam^BG's flag, return it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_TEAM_ENEMY, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the %senemy^BG's flag, return it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_VERBOSE, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_NEUTRAL, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got the flag! Retrieve it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got the flag! Retrieve it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_TEAM, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got their flag! Retrieve it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_TEAM_VERBOSE, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"), "") + MULTITEAM_CENTER(CTF_PICKUP_TEAM, 4, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the ^TC^TT^BG flag! Protect them!"), "") + MULTITEAM_CENTER(CTF_PICKUP_TEAM_VERBOSE, 4, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the ^TC^TT^BG flag! Protect them!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_TEAM_NEUTRAL, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the flag! Protect them!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_TEAM_VERBOSE_NEUTRAL, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "") + MULTITEAM_CENTER(CTF_RETURN, 4, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou returned the ^TC^TT^BG flag!"), "") + MSG_CENTER_NOTIF(CTF_STALEMATE_CARRIER, 1, 0, 0, "", CPID_STALEMATE, "0 0", _("^BGStalemate! Enemies can now see you on radar!"), "") + MSG_CENTER_NOTIF(CTF_STALEMATE_OTHER, 1, 0, 0, "", CPID_STALEMATE, "0 0", _("^BGStalemate! Flag carriers can now be seen by enemies on radar!"), "") + + MSG_CENTER_NOTIF(DEATH_MURDER_FRAG, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K3%sYou fragged ^BG%s"), _("^K3%sYou scored against ^BG%s")) + MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K1%sYou were fragged by ^BG%s"), _("^K1%sYou were scored against by ^BG%s")) + MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED_VERBOSE, 1, 1, 4, "spree_cen s1 frag_stats", CPID_Null, "0 0", _("^K1%sYou were fragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^BG%s")) + MSG_CENTER_NOTIF(DEATH_MURDER_FRAG_VERBOSE, 1, 1, 2, "spree_cen s1 frag_ping", CPID_Null, "0 0", _("^K3%sYou fragged ^BG%s^BG%s"), _("^K3%sYou scored against ^BG%s^BG%s")) + MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAG, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K1%sYou typefragged ^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing")) + MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAGGED, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K1%sYou were typefragged by ^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing!")) + MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAGGED_VERBOSE, 1, 1, 4, "spree_cen s1 frag_stats", CPID_Null, "0 0", _("^K1%sYou were typefragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing^BG%s")) + MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAG_VERBOSE, 1, 1, 2, "spree_cen s1 frag_ping", CPID_Null, "0 0", _("^K1%sYou typefragged ^BG%s^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing^BG%s")) + + MSG_CENTER_NOTIF(NADE_THROW, 1, 0, 0, "", CPID_NADES, "0 0", _("^BGPress ^F2DROPWEAPON^BG again to toss the nade!"), "") + MSG_CENTER_NOTIF(NADE_BONUS, 1, 0, 0, "", CPID_NADES, "0 0", _("^F2You got a ^K1BONUS GRENADE^F2!"), "") + + MSG_CENTER_NOTIF(DEATH_SELF_AUTOTEAMCHANGE, 1, 0, 1, "death_team", CPID_Null, "0 0", _("^BGYou have been moved into a different team\nYou are now on: %s"), "") + MSG_CENTER_NOTIF(DEATH_SELF_BETRAYAL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Don't shoot your team mates!"), _("^K1Don't go against your team mates!")) + MSG_CENTER_NOTIF(DEATH_SELF_CAMP, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Die camper!"), _("^K1Reconsider your tactics, camper!")) + MSG_CENTER_NOTIF(DEATH_SELF_CHEAT, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You unfairly eliminated yourself!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_CUSTOM, 1, 2, 0, "s2", CPID_Null, "0 0", _("^K1You were %s"), "") + MSG_CENTER_NOTIF(DEATH_SELF_DROWN, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You couldn't catch your breath!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_FALL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You hit the ground with a crunch!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_FIRE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got a little bit too crispy!"), _("^K1You felt a little too hot!")) + MSG_CENTER_NOTIF(DEATH_SELF_GENERIC, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You killed your own dumb self!"), _("^K1You need to be more careful!")) + MSG_CENTER_NOTIF(DEATH_SELF_LAVA, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You couldn't stand the heat!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_MONSTER, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were killed by a monster!"), _("^K1You need to watch out for monsters!")) + MSG_CENTER_NOTIF(DEATH_SELF_NADE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You forgot to put the pin back in!"), _("^K1Tastes like chicken!")) + MSG_CENTER_NOTIF(DEATH_SELF_NADE_NAPALM, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Hanging around a napalm explosion is bad!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_NADE_ICE_FREEZE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got a little bit too cold!"), _("^K1You felt a little chilly!")) + MSG_CENTER_NOTIF(DEATH_SELF_NADE_HEAL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Your Healing Nade is a bit defective"), "") + MSG_CENTER_NOTIF(DEATH_SELF_NOAMMO, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were killed for running out of ammo..."), _("^K1You are respawning for running out of ammo...")) + MSG_CENTER_NOTIF(DEATH_SELF_ROT, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You grew too old without taking your medicine"), _("^K1You need to preserve your health")) + MSG_CENTER_NOTIF(DEATH_SELF_SHOOTING_STAR, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You became a shooting star!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_SLIME, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You melted away in slime!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_SUICIDE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You committed suicide!"), _("^K1You ended it all!")) + MSG_CENTER_NOTIF(DEATH_SELF_SWAMP, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got stuck in a swamp!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_TEAMCHANGE, 1, 0, 1, "death_team", CPID_Null, "0 0", _("^BGYou are now on: %s"), "") + MSG_CENTER_NOTIF(DEATH_SELF_TOUCHEXPLODE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You died in an accident!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_TURRET, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were fragged by a turret!"), _("^K1You had an unfortunate run in with a turret!")) + MSG_CENTER_NOTIF(DEATH_SELF_TURRET_EWHEEL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were fragged by an eWheel turret!"), _("^K1You had an unfortunate run in with an eWheel turret!")) + MSG_CENTER_NOTIF(DEATH_SELF_TURRET_WALK, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were fragged by a Walker turret!"), _("^K1You had an unfortunate run in with a Walker turret!")) + MSG_CENTER_NOTIF(DEATH_SELF_VH_BUMB_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Bumblebee explosion!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_CRUSH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were crushed by a vehicle!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_RAPT_BOMB, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were caught in a Raptor cluster bomb!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_RAPT_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Raptor explosion!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_SPID_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Spiderbot explosion!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_SPID_ROCKET, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were blasted to bits by a Spiderbot rocket!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_WAKI_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Racer explosion!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_WAKI_ROCKET, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You couldn't find shelter from a Racer rocket!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VOID, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Watch your step!"), "") + + MSG_CENTER_NOTIF(DEATH_TEAMKILL_FRAG, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1Moron! You fragged ^BG%s^K1, a team mate!"), _("^K1Moron! You went against ^BG%s^K1, a team mate!")) + MSG_CENTER_NOTIF(DEATH_TEAMKILL_FRAGGED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1You were fragged by ^BG%s^K1, a team mate"), _("^K1You were scored against by ^BG%s^K1, a team mate")) + + MSG_CENTER_NOTIF(DISCONNECT_IDLING, 1, 0, 1, "", CPID_IDLING, "1 f1", _("^K1Stop idling!\n^BGDisconnecting in ^COUNT..."), "") + + MSG_CENTER_NOTIF(DOOR_LOCKED_NEED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^BGYou need %s^BG!"), "") + MSG_CENTER_NOTIF(DOOR_LOCKED_ALSONEED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^BGYou also need %s^BG!"), "") + MSG_CENTER_NOTIF(DOOR_UNLOCKED, 1, 0, 0, "", CPID_Null, "0 0", _("^BGDoor unlocked!"), "") + + MSG_CENTER_NOTIF(EXTRALIVES, 1, 0, 0, "", CPID_Null, "0 0", _("^F2You picked up some extra lives"), "") + + MSG_CENTER_NOTIF(FREEZETAG_FREEZE, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K3You froze ^BG%s"), "") + MSG_CENTER_NOTIF(FREEZETAG_FROZEN, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1You were frozen by ^BG%s"), "") + MSG_CENTER_NOTIF(FREEZETAG_REVIVE, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K3You revived ^BG%s"), "") + MSG_CENTER_NOTIF(FREEZETAG_REVIVE_SELF, 1, 0, 0, "", CPID_Null, "0 0", _("^K3You revived yourself"), "") + MSG_CENTER_NOTIF(FREEZETAG_REVIVED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K3You were revived by ^BG%s"), "") + MSG_CENTER_NOTIF(FREEZETAG_AUTO_REVIVED, 1, 0, 1, "f1", CPID_Null, "0 0", _("^K3You were automatically revived after %s second(s)"), "") + + MSG_CENTER_NOTIF(GENERATOR_UNDERATTACK, 1, 0, 0, "", CPID_Null, "0 0", _("^BGThe generator is under attack!"), "") + + MULTITEAM_CENTER(ROUND_TEAM_WIN, 4, 1, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team wins the round"), "") + MSG_CENTER_NOTIF(ROUND_PLAYER_WIN, 1, 1, 0, "s1", CPID_ROUND, "0 0", _("^BG%s^BG wins the round"), "") + + MSG_CENTER_NOTIF(FREEZETAG_SELF, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You froze yourself"), "") + MSG_CENTER_NOTIF(FREEZETAG_SPAWN_LATE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Round already started, you spawn as frozen"), "") + + MSG_CENTER_NOTIF(INVASION_SUPERMONSTER, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1A %s has arrived!"), "") + + MSG_CENTER_NOTIF(ITEM_BUFF_DROP, 1, 0, 1, "item_buffname", CPID_ITEM, "item_centime 0", _("^BGYou dropped the %s^BG buff!"), "") + MSG_CENTER_NOTIF(ITEM_BUFF_GOT, 1, 0, 1, "item_buffname", CPID_ITEM, "item_centime 0", _("^BGYou got the %s^BG buff!"), "") + MSG_CENTER_NOTIF(ITEM_FUELREGEN_GOT, 1, 0, 0, "", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1Fuel regenerator"), "") + MSG_CENTER_NOTIF(ITEM_JETPACK_GOT, 1, 0, 0, "", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1Jet pack"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_DONTHAVE, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou do not have the ^F1%s"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_DROP, 1, 1, 1, "item_wepname item_wepammo", CPID_ITEM, "item_centime 0", _("^BGYou dropped the ^F1%s^BG%s"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_GOT, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1%s"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_NOAMMO, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou don't have enough ammo for the ^F1%s"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_PRIMORSEC, 1, 0, 3, "item_wepname f2primsec f3primsec", CPID_ITEM, "item_centime 0", _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_UNAVAILABLE, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^F1%s^BG is ^F4not available^BG on this map"), "") + + MSG_CENTER_NOTIF(JOIN_NOSPAWNS, 1, 0, 0, "", CPID_PREVENT_JOIN, "0 0", _("^K1No spawnpoints available!\nHope your team can fix it..."), "") + MSG_CENTER_NOTIF(JOIN_PREVENT, 1, 0, 0, "", CPID_PREVENT_JOIN, "0 0", _("^K1You may not join the game at this time.\nThe player limit reached maximum capacity."), "") + + MSG_CENTER_NOTIF(KEEPAWAY_DROPPED, 1, 1, 0, "s1", CPID_KEEPAWAY, "0 0", _("^BG%s^BG has dropped the ball!"), "") + MSG_CENTER_NOTIF(KEEPAWAY_PICKUP, 1, 1, 0, "s1", CPID_KEEPAWAY, "0 0", _("^BG%s^BG has picked up the ball!"), "") + MSG_CENTER_NOTIF(KEEPAWAY_PICKUP_SELF, 1, 0, 0, "", CPID_KEEPAWAY, "0 0", _("^BGYou picked up the ball"), "") + MSG_CENTER_NOTIF(KEEPAWAY_WARN, 1, 0, 0, "", CPID_KEEPAWAY_WARN, "0 0", _("^BGKilling people while you don't have the ball gives no points!"), "") + + MSG_CENTER_NOTIF(KEYHUNT_HELP, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in your team's hands!\nHelp the key carriers to meet!"), "") + MULTITEAM_CENTER(KEYHUNT_INTERFERE, 4, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in ^TC^TT team^BG's hands!\nInterfere ^F4NOW^BG!"), "") + MSG_CENTER_NOTIF(KEYHUNT_MEET, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in your team's hands!\nMeet the other key carriers ^F4NOW^BG!"), "") + MSG_CENTER_NOTIF(KEYHUNT_ROUNDSTART, 1, 0, 1, "", CPID_KEYHUNT_OTHER, "1 f1", _("^F4Round will start in ^COUNT"), "") + MSG_CENTER_NOTIF(KEYHUNT_SCAN, 1, 0, 1, "", CPID_KEYHUNT_OTHER, "f1 0", _("^BGScanning frequency range..."), "") + MULTITEAM_CENTER(KEYHUNT_START, 4, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGYou are starting with the ^TC^TT Key"), "") + + MSG_CENTER_NOTIF(LMS_NOLIVES, 1, 0, 0, "", CPID_LMS, "0 0", _("^BGYou have no lives left, you must wait until the next match"), "") + + MSG_CENTER_NOTIF(MISSING_TEAMS, 1, 0, 1, "missing_teams", CPID_MISSING_TEAMS, "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") + MSG_CENTER_NOTIF(MISSING_PLAYERS, 1, 0, 1, "f1", CPID_MISSING_PLAYERS, "-1 0", _("^BGWaiting for %s player(s) to join..."), "") + + MSG_CENTER_NOTIF(INSTAGIB_DOWNGRADE, 1, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "5 0", _("^BGYour weapon has been downgraded until you find some ammo!"), "") + MSG_CENTER_NOTIF(INSTAGIB_FINDAMMO, 1, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "1 9", _("^F4^COUNT^BG left to find some ammo!"), "") + MSG_CENTER_NOTIF(INSTAGIB_FINDAMMO_FIRST, 1, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "1 10", _("^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"), _("^BGGet some ammo! ^F4^COUNT^BG left!")) + MSG_CENTER_NOTIF(INSTAGIB_LIVES_REMAINING, 1, 0, 1, "f1", CPID_Null, "0 0", _("^F2Extra lives remaining: ^K1%s"), "") + + MSG_CENTER_NOTIF(MOTD, 1, 1, 0, "s1", CPID_MOTD, "-1 0", "^BG%s", "") + + MSG_CENTER_NOTIF(NIX_COUNTDOWN, 1, 0, 2, "item_wepname", CPID_NIX, "1 f2", _("^F2^COUNT^BG until weapon change...\nNext weapon: ^F1%s"), "") + MSG_CENTER_NOTIF(NIX_NEWWEAPON, 1, 0, 1, "item_wepname", CPID_NIX, "0 0", _("^F2Active weapon: ^F1%s"), "") + + MSG_CENTER_NOTIF(NADE, 1, 0, 0, "", CPID_Null, "0 0", _("^BGPress ^F2DROPWEAPON^BG again to toss the grenade!"), "") + + MSG_CENTER_NOTIF(ONS_CAPTURE, 1, 1, 0, "s1", CPID_ONSLAUGHT, "0 0", _("^BGYou captured %s^BG control point"), "") + MULTITEAM_CENTER(ONS_CAPTURE, 4, 1, 1, 0, "s1", CPID_ONSLAUGHT, "0 0", _("^TC^TT^BG team captured %s^BG control point"), "") + MSG_CENTER_NOTIF(ONS_CONTROLPOINT_SHIELDED, 1, 0, 0, "", CPID_ONS_CAPSHIELD, "0 0", _("^BGThis control point currently cannot be captured"), "") + MSG_CENTER_NOTIF(ONS_GENERATOR_SHIELDED, 1, 0, 0, "", CPID_ONS_CAPSHIELD, "0 0", _("^BGThe enemy generator cannot be destroyed yet\n^F2Capture some control points to unshield it"), "") + MULTITEAM_CENTER(ONS_NOTSHIELDED, 4, 1, 0, 0, "", CPID_ONSLAUGHT, "0 0", _("^BGThe ^TCenemy^BG generator is no longer shielded!"), "") + MSG_CENTER_NOTIF(ONS_NOTSHIELDED_TEAM, 1, 0, 0, "", CPID_ONSLAUGHT, "0 0", _("^K1Your generator is NOT shielded!\n^BGRe-capture control points to shield it!"), "") + MSG_CENTER_NOTIF(ONS_TELEPORT, 1, 0, 0, "pass_key", CPID_ONSLAUGHT, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to teleport"), "") + MSG_CENTER_NOTIF(ONS_TELEPORT_ANTISPAM, 1, 0, 1, "f1secs", CPID_ONSLAUGHT, "0 0", _("^BGTeleporting disabled for %s"), "") + + MSG_CENTER_NOTIF(OVERTIME_FRAG, 1, 0, 0, "", CPID_OVERTIME, "0 0", _("^F2Now playing ^F4OVERTIME^F2!\nKeep fragging until we have a winner!"), _("^F2Now playing ^F4OVERTIME^F2!\nKeep scoring until we have a winner!")) + MSG_CENTER_NOTIF(OVERTIME_CONTROLPOINT, 1, 0, 0, "", CPID_OVERTIME, "5 0", _("^F2Now playing ^F4OVERTIME^F2!\n\nGenerators are now decaying.\nThe more control points your team holds,\nthe faster the enemy generator decays"), "") + MSG_CENTER_NOTIF(OVERTIME_TIME, 1, 0, 1, "f1time", CPID_OVERTIME, "0 0", _("^F2Now playing ^F4OVERTIME^F2!\n^BGAdded ^F4%s^BG to the game!"), "") + + MSG_CENTER_NOTIF(PORTO_CREATED_IN, 1, 0, 0, "", CPID_Null, "0 0", _("^K1In^BG-portal created"), "") + MSG_CENTER_NOTIF(PORTO_CREATED_OUT, 1, 0, 0, "", CPID_Null, "0 0", _("^F3Out^BG-portal created"), "") + MSG_CENTER_NOTIF(PORTO_FAILED, 1, 0, 0, "", CPID_Null, "0 0", _("^F1Portal creation failed"), "") + + MSG_CENTER_NOTIF(POWERUP_STRENGTH, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Strength infuses your weapons with devastating power"), "") + MSG_CENTER_NOTIF(POWERDOWN_STRENGTH, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Strength has worn off"), "") + + MSG_CENTER_NOTIF(POWERUP_SHIELD, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Shield surrounds you"), "") + MSG_CENTER_NOTIF(POWERDOWN_SHIELD, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Shield has worn off"), "") + + MSG_CENTER_NOTIF(POWERUP_SPEED, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You are on speed"), "") + MSG_CENTER_NOTIF(POWERDOWN_SPEED, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Speed has worn off"), "") + + MSG_CENTER_NOTIF(POWERUP_INVISIBILITY, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You are invisible"), "") + MSG_CENTER_NOTIF(POWERDOWN_INVISIBILITY, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Invisibility has worn off"), "") + + MSG_CENTER_NOTIF(RACE_FINISHLAP, 1, 0, 0, "", CPID_RACE_FINISHLAP, "0 0", _("^F2The race is over, finish your lap!"), "") + + MSG_CENTER_NOTIF(SECONDARY_NODAMAGE, 1, 0, 0, "", CPID_Null, "0 0", _("^BGSecondary fire inflicts no damage!"), "") + + MSG_CENTER_NOTIF(SEQUENCE_COMPLETED, 1, 0, 0, "", CPID_Null, "0 0", _("^BGSequence completed!"), "") + MSG_CENTER_NOTIF(SEQUENCE_COUNTER, 1, 0, 0, "", CPID_Null, "0 0", _("^BGThere are more to go..."), "") + MSG_CENTER_NOTIF(SEQUENCE_COUNTER_FEWMORE, 1, 0, 1, "f1", CPID_Null, "0 0", _("^BGOnly %s^BG more to go..."), "") + + MSG_CENTER_NOTIF(SUPERWEAPON_BROKEN, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Superweapons have broken down"), "") + MSG_CENTER_NOTIF(SUPERWEAPON_LOST, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Superweapons have been lost"), "") + MSG_CENTER_NOTIF(SUPERWEAPON_PICKUP, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You now have a superweapon"), "") + + MULTITEAM_CENTER(TEAMCHANGE, 4, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Changing to ^TC^TT^K1 in ^COUNT"), "") + MSG_CENTER_NOTIF(TEAMCHANGE_AUTO, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Changing team in ^COUNT"), "") + MSG_CENTER_NOTIF(TEAMCHANGE_SPECTATE, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Spectating in ^COUNT"), "") + MSG_CENTER_NOTIF(TEAMCHANGE_SUICIDE, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Suicide in ^COUNT"), "") + + MSG_CENTER_NOTIF(TIMEOUT_BEGINNING, 1, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout begins in ^COUNT"), "") + MSG_CENTER_NOTIF(TIMEOUT_ENDING, 1, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout ends in ^COUNT"), "") + + MSG_CENTER_NOTIF(JOIN_PREVENT_MINIGAME, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Cannot join given minigame session!"), "" ) + + MSG_CENTER_NOTIF(VEHICLE_ENTER, 1, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to enter/exit the vehicle"), "") + MSG_CENTER_NOTIF(VEHICLE_ENTER_GUNNER, 1, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to enter the vehicle gunner"), "") + MSG_CENTER_NOTIF(VEHICLE_ENTER_STEAL, 1, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to steal this vehicle"), "") + MSG_CENTER_NOTIF(VEHICLE_STEAL, 1, 0, 0, "", CPID_VEHICLES_OTHER, "0 0", _("^F2The enemy is stealing one of your vehicles!\n^F4Stop them!"), "") + MSG_CENTER_NOTIF(VEHICLE_STEAL_SELF, 1, 0, 0, "", CPID_VEHICLES_OTHER, "4 0", _("^F2You have stolen the enemy's vehicle, you are now visible on their radar!"), "") + + MSG_CENTER_NOTIF(WEAPON_MINELAYER_LIMIT, 1, 0, 1, "f1", CPID_Null, "0 0", _("^BGYou cannot place more than ^F2%s^BG mines at a time"), "") + +#define MULTITEAM_MULTI2(prefix, default, anncepre, infopre, centerpre) \ + MSG_MULTI_NOTIF(prefix##_RED, default, anncepre##_RED, infopre##_RED, centerpre##_RED) \ + MSG_MULTI_NOTIF(prefix##_BLUE, default, anncepre##_BLUE, infopre##_BLUE, centerpre##_BLUE) +#define MULTITEAM_MULTI3(prefix, default, anncepre, infopre, centerpre) \ + MULTITEAM_MULTI2(prefix, default, anncepre, infopre, centerpre) \ + MSG_MULTI_NOTIF(default, prefix##_YELLOW, anncepre##YELLOW, infopre##YELLOW, centerpre##YELLOW) +#define MULTITEAM_MULTI4(prefix, default, anncepre, infopre, centerpre) \ + MULTITEAM_MULTI3(prefix, default, anncepre, infopre, centerpre) \ + MSG_MULTI_NOTIF(prefix##_PINK, default, anncepre##PINK, infopre##PINK, centerpre##PINK) +#define MULTITEAM_MULTI(prefix, teams, default, anncepre, infopre, centerpre) \ + MULTITEAM_MULTI##teams(prefix, default, anncepre, infopre, centerpre) + +// MSG_MULTI_NOTIFICATIONS + MSG_MULTI_NOTIF(DEATH_MURDER_BUFF, 1, NULL, INFO_DEATH_MURDER_BUFF, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_CHEAT, 1, NULL, INFO_DEATH_MURDER_CHEAT, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_DROWN, 1, NULL, INFO_DEATH_MURDER_DROWN, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_FALL, 1, NULL, INFO_DEATH_MURDER_FALL, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_FIRE, 1, NULL, INFO_DEATH_MURDER_FIRE, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_LAVA, 1, NULL, INFO_DEATH_MURDER_LAVA, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_MONSTER, 1, NULL, INFO_DEATH_MURDER_MONSTER, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_MURDER_NADE, 1, NULL, INFO_DEATH_MURDER_NADE, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_NADE_NAPALM, 1, NULL, INFO_DEATH_MURDER_NADE_NAPALM, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_NADE_ICE, 1, NULL, INFO_DEATH_MURDER_NADE_ICE, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_NADE_ICE_FREEZE, 1, NULL, INFO_DEATH_MURDER_NADE_ICE_FREEZE, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_NADE_HEAL, 1, NULL, INFO_DEATH_MURDER_NADE_HEAL, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_SHOOTING_STAR, 1, NULL, INFO_DEATH_MURDER_SHOOTING_STAR, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_SLIME, 1, NULL, INFO_DEATH_MURDER_SLIME, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_SWAMP, 1, NULL, INFO_DEATH_MURDER_SWAMP, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_TELEFRAG, 1, NULL, INFO_DEATH_MURDER_TELEFRAG, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_TOUCHEXPLODE, 1, NULL, INFO_DEATH_MURDER_TOUCHEXPLODE, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_BUMB_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_BUMB_DEATH, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_BUMB_GUN, 1, NULL, INFO_DEATH_MURDER_VH_BUMB_GUN, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_CRUSH, 1, NULL, INFO_DEATH_MURDER_VH_CRUSH, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_RAPT_BOMB, 1, NULL, INFO_DEATH_MURDER_VH_RAPT_BOMB, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_RAPT_CANNON, 1, NULL, INFO_DEATH_MURDER_VH_RAPT_CANNON, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_RAPT_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_RAPT_DEATH, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_SPID_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_SPID_DEATH, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_SPID_MINIGUN, 1, NULL, INFO_DEATH_MURDER_VH_SPID_MINIGUN, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_SPID_ROCKET, 1, NULL, INFO_DEATH_MURDER_VH_SPID_ROCKET, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_WAKI_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_WAKI_DEATH, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_WAKI_GUN, 1, NULL, INFO_DEATH_MURDER_VH_WAKI_GUN, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_WAKI_ROCKET, 1, NULL, INFO_DEATH_MURDER_VH_WAKI_ROCKET, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VOID, 1, NULL, INFO_DEATH_MURDER_VOID, NULL) + + MSG_MULTI_NOTIF(DEATH_SELF_AUTOTEAMCHANGE, 1, NULL, INFO_DEATH_SELF_AUTOTEAMCHANGE, CENTER_DEATH_SELF_AUTOTEAMCHANGE) + MSG_MULTI_NOTIF(DEATH_SELF_BETRAYAL, 1, NULL, INFO_DEATH_SELF_BETRAYAL, CENTER_DEATH_SELF_BETRAYAL) + MSG_MULTI_NOTIF(DEATH_SELF_CAMP, 1, NULL, INFO_DEATH_SELF_CAMP, CENTER_DEATH_SELF_CAMP) + MSG_MULTI_NOTIF(DEATH_SELF_CHEAT, 1, NULL, INFO_DEATH_SELF_CHEAT, CENTER_DEATH_SELF_CHEAT) + MSG_MULTI_NOTIF(DEATH_SELF_CUSTOM, 1, NULL, INFO_DEATH_SELF_GENERIC, CENTER_DEATH_SELF_CUSTOM) + MSG_MULTI_NOTIF(DEATH_SELF_DROWN, 1, NULL, INFO_DEATH_SELF_DROWN, CENTER_DEATH_SELF_DROWN) + MSG_MULTI_NOTIF(DEATH_SELF_FALL, 1, NULL, INFO_DEATH_SELF_FALL, CENTER_DEATH_SELF_FALL) + MSG_MULTI_NOTIF(DEATH_SELF_FIRE, 1, NULL, INFO_DEATH_SELF_FIRE, CENTER_DEATH_SELF_FIRE) + MSG_MULTI_NOTIF(DEATH_SELF_GENERIC, 1, NULL, INFO_DEATH_SELF_GENERIC, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(DEATH_SELF_LAVA, 1, NULL, INFO_DEATH_SELF_LAVA, CENTER_DEATH_SELF_LAVA) + MSG_MULTI_NOTIF(DEATH_SELF_MON_MAGE, 1, NULL, INFO_DEATH_SELF_MON_MAGE, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_SHAMBLER_CLAW, 1, NULL, INFO_DEATH_SELF_MON_SHAMBLER_CLAW, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_SHAMBLER_SMASH, 1, NULL, INFO_DEATH_SELF_MON_SHAMBLER_SMASH, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_SHAMBLER_ZAP, 1, NULL, INFO_DEATH_SELF_MON_SHAMBLER_ZAP, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_SPIDER, 1, NULL, INFO_DEATH_SELF_MON_SPIDER, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_WYVERN, 1, NULL, INFO_DEATH_SELF_MON_WYVERN, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_ZOMBIE_JUMP, 1, NULL, INFO_DEATH_SELF_MON_ZOMBIE_JUMP, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_ZOMBIE_MELEE, 1, NULL, INFO_DEATH_SELF_MON_ZOMBIE_MELEE, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_NADE, 1, NULL, INFO_DEATH_SELF_NADE, CENTER_DEATH_SELF_NADE) + MSG_MULTI_NOTIF(DEATH_SELF_NADE_NAPALM, 1, NULL, INFO_DEATH_SELF_NADE_NAPALM, CENTER_DEATH_SELF_NADE_NAPALM) + MSG_MULTI_NOTIF(DEATH_SELF_NADE_ICE, 1, NULL, INFO_DEATH_SELF_NADE_ICE, CENTER_DEATH_SELF_NADE_ICE_FREEZE) + MSG_MULTI_NOTIF(DEATH_SELF_NADE_ICE_FREEZE, 1, NULL, INFO_DEATH_SELF_NADE_ICE_FREEZE, CENTER_DEATH_SELF_NADE_ICE_FREEZE) + MSG_MULTI_NOTIF(DEATH_SELF_NADE_HEAL, 1, NULL, INFO_DEATH_SELF_NADE_HEAL, CENTER_DEATH_SELF_NADE_HEAL) + MSG_MULTI_NOTIF(DEATH_SELF_NOAMMO, 1, NULL, INFO_DEATH_SELF_NOAMMO, CENTER_DEATH_SELF_NOAMMO) + MSG_MULTI_NOTIF(DEATH_SELF_ROT, 1, NULL, INFO_DEATH_SELF_ROT, CENTER_DEATH_SELF_ROT) + MSG_MULTI_NOTIF(DEATH_SELF_SHOOTING_STAR, 1, NULL, INFO_DEATH_SELF_SHOOTING_STAR, CENTER_DEATH_SELF_SHOOTING_STAR) + MSG_MULTI_NOTIF(DEATH_SELF_SLIME, 1, NULL, INFO_DEATH_SELF_SLIME, CENTER_DEATH_SELF_SLIME) + MSG_MULTI_NOTIF(DEATH_SELF_SUICIDE, 1, NULL, INFO_DEATH_SELF_SUICIDE, CENTER_DEATH_SELF_SUICIDE) + MSG_MULTI_NOTIF(DEATH_SELF_SWAMP, 1, NULL, INFO_DEATH_SELF_SWAMP, CENTER_DEATH_SELF_SWAMP) + MSG_MULTI_NOTIF(DEATH_SELF_TEAMCHANGE, 1, NULL, INFO_DEATH_SELF_TEAMCHANGE, CENTER_DEATH_SELF_TEAMCHANGE) + MSG_MULTI_NOTIF(DEATH_SELF_TOUCHEXPLODE, 1, NULL, INFO_DEATH_SELF_TOUCHEXPLODE, CENTER_DEATH_SELF_TOUCHEXPLODE) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET, 1, NULL, INFO_DEATH_SELF_TURRET, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_EWHEEL, 1, NULL, INFO_DEATH_SELF_TURRET_EWHEEL, CENTER_DEATH_SELF_TURRET_EWHEEL) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_FLAC, 1, NULL, INFO_DEATH_SELF_TURRET_FLAC, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_HELLION, 1, NULL, INFO_DEATH_SELF_TURRET_HELLION, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_HK, 1, NULL, INFO_DEATH_SELF_TURRET_HK, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_MACHINEGUN, 1, NULL, INFO_DEATH_SELF_TURRET_MACHINEGUN, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_MLRS, 1, NULL, INFO_DEATH_SELF_TURRET_MLRS, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_PHASER, 1, NULL, INFO_DEATH_SELF_TURRET_PHASER, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_PLASMA, 1, NULL, INFO_DEATH_SELF_TURRET_PLASMA, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_TESLA, 1, NULL, INFO_DEATH_SELF_TURRET_TESLA, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_WALK_GUN, 1, NULL, INFO_DEATH_SELF_TURRET_WALK_GUN, CENTER_DEATH_SELF_TURRET_WALK) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_WALK_MELEE, 1, NULL, INFO_DEATH_SELF_TURRET_WALK_MELEE, CENTER_DEATH_SELF_TURRET_WALK) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_WALK_ROCKET, 1, NULL, INFO_DEATH_SELF_TURRET_WALK_ROCKET, CENTER_DEATH_SELF_TURRET_WALK) + MSG_MULTI_NOTIF(DEATH_SELF_VH_BUMB_DEATH, 1, NULL, INFO_DEATH_SELF_VH_BUMB_DEATH, CENTER_DEATH_SELF_VH_BUMB_DEATH) + MSG_MULTI_NOTIF(DEATH_SELF_VH_CRUSH, 1, NULL, INFO_DEATH_SELF_VH_CRUSH, CENTER_DEATH_SELF_VH_CRUSH) + MSG_MULTI_NOTIF(DEATH_SELF_VH_RAPT_BOMB, 1, NULL, INFO_DEATH_SELF_VH_RAPT_BOMB, CENTER_DEATH_SELF_VH_RAPT_BOMB) + MSG_MULTI_NOTIF(DEATH_SELF_VH_RAPT_DEATH, 1, NULL, INFO_DEATH_SELF_VH_RAPT_DEATH, CENTER_DEATH_SELF_VH_RAPT_DEATH) + MSG_MULTI_NOTIF(DEATH_SELF_VH_SPID_DEATH, 1, NULL, INFO_DEATH_SELF_VH_SPID_DEATH, CENTER_DEATH_SELF_VH_SPID_DEATH) + MSG_MULTI_NOTIF(DEATH_SELF_VH_SPID_ROCKET, 1, NULL, INFO_DEATH_SELF_VH_SPID_ROCKET, CENTER_DEATH_SELF_VH_SPID_ROCKET) + MSG_MULTI_NOTIF(DEATH_SELF_VH_WAKI_DEATH, 1, NULL, INFO_DEATH_SELF_VH_WAKI_DEATH, CENTER_DEATH_SELF_VH_WAKI_DEATH) + MSG_MULTI_NOTIF(DEATH_SELF_VH_WAKI_ROCKET, 1, NULL, INFO_DEATH_SELF_VH_WAKI_ROCKET, CENTER_DEATH_SELF_VH_WAKI_ROCKET) + MSG_MULTI_NOTIF(DEATH_SELF_VOID, 1, NULL, INFO_DEATH_SELF_VOID, CENTER_DEATH_SELF_VOID) + + MSG_MULTI_NOTIF(ITEM_BUFF_DROP, 1, NULL, INFO_ITEM_BUFF_DROP, CENTER_ITEM_BUFF_DROP) + MSG_MULTI_NOTIF(ITEM_BUFF_GOT, 1, NULL, INFO_ITEM_BUFF_GOT, CENTER_ITEM_BUFF_GOT) + MSG_MULTI_NOTIF(ITEM_WEAPON_DONTHAVE, 1, NULL, INFO_ITEM_WEAPON_DONTHAVE, CENTER_ITEM_WEAPON_DONTHAVE) + MSG_MULTI_NOTIF(ITEM_WEAPON_DROP, 1, NULL, INFO_ITEM_WEAPON_DROP, CENTER_ITEM_WEAPON_DROP) + MSG_MULTI_NOTIF(ITEM_WEAPON_GOT, 1, NULL, INFO_ITEM_WEAPON_GOT, CENTER_ITEM_WEAPON_GOT) + MSG_MULTI_NOTIF(ITEM_WEAPON_NOAMMO, 1, NULL, INFO_ITEM_WEAPON_NOAMMO, CENTER_ITEM_WEAPON_NOAMMO) + MSG_MULTI_NOTIF(ITEM_WEAPON_PRIMORSEC, 1, NULL, INFO_ITEM_WEAPON_PRIMORSEC, CENTER_ITEM_WEAPON_PRIMORSEC) + MSG_MULTI_NOTIF(ITEM_WEAPON_UNAVAILABLE, 1, NULL, INFO_ITEM_WEAPON_UNAVAILABLE, CENTER_ITEM_WEAPON_UNAVAILABLE) + + MSG_MULTI_NOTIF(MULTI_COINTOSS, 1, NULL, INFO_COINTOSS, CENTER_COINTOSS) + MSG_MULTI_NOTIF(MULTI_COUNTDOWN_BEGIN, 1, ANNCE_BEGIN, NULL, CENTER_COUNTDOWN_BEGIN) + MSG_MULTI_NOTIF(MULTI_INSTAGIB_FINDAMMO, 1, ANNCE_NUM_10, NULL, CENTER_INSTAGIB_FINDAMMO_FIRST) + + MSG_MULTI_NOTIF(WEAPON_ACCORDEON_MURDER, 1, NULL, INFO_WEAPON_ACCORDEON_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_ACCORDEON_SUICIDE, 1, NULL, INFO_WEAPON_ACCORDEON_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_ARC_MURDER, 1, NULL, INFO_WEAPON_ARC_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_ARC_MURDER_SPRAY, 1, NULL, INFO_WEAPON_ARC_MURDER_SPRAY, NULL) + MSG_MULTI_NOTIF(WEAPON_BLASTER_MURDER, 1, NULL, INFO_WEAPON_BLASTER_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_BLASTER_SUICIDE, 1, NULL, INFO_WEAPON_BLASTER_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_CRYLINK_MURDER, 1, NULL, INFO_WEAPON_CRYLINK_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_CRYLINK_SUICIDE, 1, NULL, INFO_WEAPON_CRYLINK_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_DEVASTATOR_MURDER_DIRECT, 1, NULL, INFO_WEAPON_DEVASTATOR_MURDER_DIRECT, NULL) + MSG_MULTI_NOTIF(WEAPON_DEVASTATOR_MURDER_SPLASH, 1, NULL, INFO_WEAPON_DEVASTATOR_MURDER_SPLASH, NULL) + MSG_MULTI_NOTIF(WEAPON_DEVASTATOR_SUICIDE, 1, NULL, INFO_WEAPON_DEVASTATOR_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_ELECTRO_MURDER_BOLT, 1, NULL, INFO_WEAPON_ELECTRO_MURDER_BOLT, NULL) + MSG_MULTI_NOTIF(WEAPON_ELECTRO_MURDER_COMBO, 1, NULL, INFO_WEAPON_ELECTRO_MURDER_COMBO, NULL) + MSG_MULTI_NOTIF(WEAPON_ELECTRO_MURDER_ORBS, 1, NULL, INFO_WEAPON_ELECTRO_MURDER_ORBS, NULL) + MSG_MULTI_NOTIF(WEAPON_ELECTRO_SUICIDE_BOLT, 1, NULL, INFO_WEAPON_ELECTRO_SUICIDE_BOLT, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_ELECTRO_SUICIDE_ORBS, 1, NULL, INFO_WEAPON_ELECTRO_SUICIDE_ORBS, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_FIREBALL_MURDER_BLAST, 1, NULL, INFO_WEAPON_FIREBALL_MURDER_BLAST, NULL) + MSG_MULTI_NOTIF(WEAPON_FIREBALL_MURDER_FIREMINE, 1, NULL, INFO_WEAPON_FIREBALL_MURDER_FIREMINE, NULL) + MSG_MULTI_NOTIF(WEAPON_FIREBALL_SUICIDE_BLAST, 1, NULL, INFO_WEAPON_FIREBALL_SUICIDE_BLAST, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_FIREBALL_SUICIDE_FIREMINE, 1, NULL, INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_HAGAR_MURDER_BURST, 1, NULL, INFO_WEAPON_HAGAR_MURDER_BURST, NULL) + MSG_MULTI_NOTIF(WEAPON_HAGAR_MURDER_SPRAY, 1, NULL, INFO_WEAPON_HAGAR_MURDER_SPRAY, NULL) + MSG_MULTI_NOTIF(WEAPON_HAGAR_SUICIDE, 1, NULL, INFO_WEAPON_HAGAR_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_HLAC_MURDER, 1, NULL, INFO_WEAPON_HLAC_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_HLAC_SUICIDE, 1, NULL, INFO_WEAPON_HLAC_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_HMG_MURDER_SNIPE, 1, NULL, INFO_WEAPON_HMG_MURDER_SNIPE, NULL) + MSG_MULTI_NOTIF(WEAPON_HMG_MURDER_SPRAY, 1, NULL, INFO_WEAPON_HMG_MURDER_SPRAY, NULL) + MSG_MULTI_NOTIF(WEAPON_HOOK_MURDER, 1, NULL, INFO_WEAPON_HOOK_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_KLEINBOTTLE_MURDER, 1, NULL, INFO_WEAPON_KLEINBOTTLE_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_KLEINBOTTLE_SUICIDE, 1, NULL, INFO_WEAPON_KLEINBOTTLE_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_MACHINEGUN_MURDER_SNIPE, 1, NULL, INFO_WEAPON_MACHINEGUN_MURDER_SNIPE, NULL) + MSG_MULTI_NOTIF(WEAPON_MACHINEGUN_MURDER_SPRAY, 1, NULL, INFO_WEAPON_MACHINEGUN_MURDER_SPRAY, NULL) + MSG_MULTI_NOTIF(WEAPON_MINELAYER_LIMIT, 1, NULL, INFO_WEAPON_MINELAYER_LIMIT, CENTER_WEAPON_MINELAYER_LIMIT) + MSG_MULTI_NOTIF(WEAPON_MINELAYER_MURDER, 1, NULL, INFO_WEAPON_MINELAYER_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_MINELAYER_SUICIDE, 1, NULL, INFO_WEAPON_MINELAYER_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_MORTAR_MURDER_BOUNCE, 1, NULL, INFO_WEAPON_MORTAR_MURDER_BOUNCE, NULL) + MSG_MULTI_NOTIF(WEAPON_MORTAR_MURDER_EXPLODE, 1, NULL, INFO_WEAPON_MORTAR_MURDER_EXPLODE, NULL) + MSG_MULTI_NOTIF(WEAPON_MORTAR_SUICIDE_BOUNCE, 1, NULL, INFO_WEAPON_MORTAR_SUICIDE_BOUNCE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_MORTAR_SUICIDE_EXPLODE, 1, NULL, INFO_WEAPON_MORTAR_SUICIDE_EXPLODE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER, 1, NULL, INFO_WEAPON_RIFLE_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER_HAIL, 1, NULL, INFO_WEAPON_RIFLE_MURDER_HAIL, NULL) + MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER_HAIL_PIERCING, 1, NULL, INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING, NULL) + MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER_PIERCING, 1, NULL, INFO_WEAPON_RIFLE_MURDER_PIERCING, NULL) + MSG_MULTI_NOTIF(WEAPON_RPC_MURDER_DIRECT, 1, NULL, INFO_WEAPON_RPC_MURDER_DIRECT, NULL) + MSG_MULTI_NOTIF(WEAPON_RPC_MURDER_SPLASH, 1, NULL, INFO_WEAPON_RPC_MURDER_SPLASH, NULL) + MSG_MULTI_NOTIF(WEAPON_RPC_SUICIDE_DIRECT, 1, NULL, INFO_WEAPON_RPC_SUICIDE_DIRECT, NULL) + MSG_MULTI_NOTIF(WEAPON_RPC_SUICIDE_SPLASH, 1, NULL, INFO_WEAPON_RPC_SUICIDE_SPLASH, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_SEEKER_MURDER_SPRAY, 1, NULL, INFO_WEAPON_SEEKER_MURDER_SPRAY, NULL) + MSG_MULTI_NOTIF(WEAPON_SEEKER_MURDER_TAG, 1, NULL, INFO_WEAPON_SEEKER_MURDER_TAG, NULL) + MSG_MULTI_NOTIF(WEAPON_SEEKER_SUICIDE, 1, NULL, INFO_WEAPON_SEEKER_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_SHOCKWAVE_MURDER, 1, NULL, INFO_WEAPON_SHOCKWAVE_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_SHOCKWAVE_MURDER_SLAP, 1, NULL, INFO_WEAPON_SHOCKWAVE_MURDER_SLAP, NULL) + MSG_MULTI_NOTIF(WEAPON_SHOTGUN_MURDER, 1, NULL, INFO_WEAPON_SHOTGUN_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_SHOTGUN_MURDER_SLAP, 1, NULL, INFO_WEAPON_SHOTGUN_MURDER_SLAP, NULL) + MSG_MULTI_NOTIF(WEAPON_THINKING_WITH_PORTALS, 1, NULL, INFO_WEAPON_THINKING_WITH_PORTALS, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_TUBA_MURDER, 1, NULL, INFO_WEAPON_TUBA_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_TUBA_SUICIDE, 1, NULL, INFO_WEAPON_TUBA_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_VAPORIZER_MURDER, 1, NULL, INFO_WEAPON_VAPORIZER_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_VORTEX_MURDER, 1, NULL, INFO_WEAPON_VORTEX_MURDER, NULL) + +#define MULTITEAM_CHOICE2(prefix, default, challow, chtype, optiona, optionb) \ + MSG_CHOICE_NOTIF(prefix##_RED, default, challow, chtype, optiona##_RED, optionb##_RED) \ + MSG_CHOICE_NOTIF(prefix##_BLUE, default, challow, chtype, optiona##_BLUE, optionb##_BLUE) +#define MULTITEAM_CHOICE3(prefix, default, challow, chtype, optiona, optionb) \ + MULTITEAM_CHOICE2(prefix, default, challow, chtype, optiona, optionb) \ + MSG_CHOICE_NOTIF(prefix##_YELLOW, default, challow, chtype, optiona##_YELLOW, optionb##_YELLOW) +#define MULTITEAM_CHOICE4(prefix, default, challow, chtype, optiona, optionb) \ + MULTITEAM_CHOICE3(prefix, default, challow, chtype, optiona, optionb) \ + MSG_CHOICE_NOTIF(prefix##_PINK, default, challow, chtype, optiona##_PINK, optionb##_PINK) +#define MULTITEAM_CHOICE(prefix, teams, default, challow, chtype, optiona, optionb) \ + MULTITEAM_CHOICE##teams(prefix, default, challow, chtype, optiona, optionb) + +// MSG_CHOICE_NOTIFICATIONS + MULTITEAM_CHOICE(CTF_CAPTURE_BROKEN, 4, 1, 2, MSG_INFO, INFO_CTF_CAPTURE, INFO_CTF_CAPTURE_BROKEN) + MULTITEAM_CHOICE(CTF_CAPTURE_TIME, 4, 1, 2, MSG_INFO, INFO_CTF_CAPTURE, INFO_CTF_CAPTURE_TIME) + MULTITEAM_CHOICE(CTF_CAPTURE_UNBROKEN, 4, 1, 2, MSG_INFO, INFO_CTF_CAPTURE, INFO_CTF_CAPTURE_UNBROKEN) + MULTITEAM_CHOICE(CTF_PICKUP_TEAM, 4, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_TEAM, CENTER_CTF_PICKUP_TEAM_VERBOSE) + MSG_CHOICE_NOTIF(CTF_PICKUP_TEAM_NEUTRAL, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_TEAM_NEUTRAL, CENTER_CTF_PICKUP_TEAM_VERBOSE_NEUTRAL) + MSG_CHOICE_NOTIF(CTF_PICKUP_ENEMY, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY, CENTER_CTF_PICKUP_ENEMY_VERBOSE) + MSG_CHOICE_NOTIF(CTF_PICKUP_ENEMY_NEUTRAL, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_NEUTRAL, CENTER_CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE) + MSG_CHOICE_NOTIF(CTF_PICKUP_ENEMY_TEAM, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_TEAM, CENTER_CTF_PICKUP_ENEMY_TEAM_VERBOSE) + MSG_CHOICE_NOTIF(FRAG, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_FRAG, CENTER_DEATH_MURDER_FRAG_VERBOSE) + MSG_CHOICE_NOTIF(FRAGGED, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED, CENTER_DEATH_MURDER_FRAGGED_VERBOSE) + MSG_CHOICE_NOTIF(TYPEFRAG, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE) + MSG_CHOICE_NOTIF(TYPEFRAGGED, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAGGED, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE) diff --git a/qcsrc/common/notifications/all.qc b/qcsrc/common/notifications/all.qc new file mode 100644 index 000000000..e52e9de09 --- /dev/null +++ b/qcsrc/common/notifications/all.qc @@ -0,0 +1,1775 @@ +#if defined(CSQC) + #include +#elif defined(MENUQC) +#elif defined(SVQC) + #include + #include + #include + #include + #include + #include "all.qh" + #include +#endif + +// ================================================ +// Unified notification system, written by Samual +// Last updated: August, 2013 +// ================================================ + +#ifdef SVQC +string Notification_CheckArgs( + NOTIF broadcast, entity client) +{ + // check supplied broadcast and target for errors + switch (broadcast) + { + case NOTIF_ONE: + case NOTIF_ONE_ONLY: + { + if (IS_NOT_A_CLIENT(client)) { + return "No client provided!"; + } + break; + } + + case NOTIF_ALL_EXCEPT: + { + if (IS_NOT_A_CLIENT(client)) { + return "Exception can't be a non-client!"; + } + break; + } + + case NOTIF_ALL: + { + if (client) { + return "Entity provided when world was required!"; + } + break; + } + + case NOTIF_TEAM: + { + if (!teamplay) { + return "Teamplay not active!"; + } else if (!client.team) { + // checkargs = sprintf("%sNo team provided!", checkargs); + } + break; + } + + case NOTIF_TEAM_EXCEPT: + { + if (!teamplay) { + return "Teamplay not active!"; + } else if (IS_NOT_A_CLIENT(client)) { + return "Exception can't be a non-client!"; + } + break; + } + + default: + { + return sprintf("Improper broadcast: %d!", broadcast); + } + } + return ""; +} + +bool Notification_ShouldSend(NOTIF broadcast, entity to_client, entity other_client) +{ + switch (broadcast) + { + case NOTIF_ONE: + return ( + (to_client == other_client) + || + ( + IS_SPEC(to_client) + && + (to_client.enemy == other_client) + ) + ); + case NOTIF_ONE_ONLY: + return (to_client == other_client); + case NOTIF_TEAM: + return ( + (to_client.team == other_client.team) + || + ( + IS_SPEC(to_client) + && + (to_client.enemy.team == other_client.team) + ) + ); + case NOTIF_TEAM_EXCEPT: + return ( + (to_client != other_client) + && + ( + (to_client.team == other_client.team) + || + ( + IS_SPEC(to_client) + && + ( + (to_client.enemy != other_client) + && + (to_client.enemy.team == other_client.team) + ) + ) + ) + ); + case NOTIF_ALL: + return true; + case NOTIF_ALL_EXCEPT: + return ( + (to_client != other_client) + && + !( + IS_SPEC(to_client) + && + (to_client.enemy == other_client) + ) + ); + default: + return false; + } +} + +#endif + +// =============================== +// Initialization Core Functions +// =============================== + +// used by restartnotifs command to initialize notifications +void Destroy_Notification_Entity(entity notif) +{ + if (notif.nent_name != "") strunzone(notif.nent_name); + if (notif.nent_snd != "") strunzone(notif.nent_snd); + if (notif.nent_args != "") strunzone(notif.nent_args); + if (notif.nent_hudargs != "") strunzone(notif.nent_hudargs); + if (notif.nent_icon != "") strunzone(notif.nent_icon); + if (notif.nent_durcnt != "") strunzone(notif.nent_durcnt); + if (notif.nent_string != "") strunzone(notif.nent_string); + remove(notif); +} + +void Destroy_All_Notifications() +{ + // kill all networked notifications and centerprints + #ifdef SVQC + Kill_Notification(NOTIF_ALL, NULL, MSG_Null, CPID_Null); + #else + reset_centerprint_messages(); + #endif + + // kill all real notification entities + FOREACH(Notifications, true, { Destroy_Notification_Entity(it); }); +} + +string Process_Notif_Line( + MSG typeId, + bool chat, + string input, + string notiftype, + string notifname, + string stringtype) +{ + #ifdef CSQC + if(typeId == MSG_INFO) + { + if((chat && autocvar_notification_allow_chatboxprint) + || (autocvar_notification_allow_chatboxprint == 2)) + { + // pass 1: add ETX char at beginning of line + input = strcat("\{3}", input); + + // pass 2: add ETX char at end of each new line (so that + // messages with multiple lines are put through chatbox too) + input = strreplace("\n", "\n\{3}", input); + + // pass 3: strip trailing ETX char + if(substring(input, (strlen(input) - 1), 1) == "\{3}") + { input = substring(input, 0, (strlen(input) - 1)); } + } + } + #endif + + // done to both MSG_INFO and MSG_CENTER + if(substring(input, (strlen(input) - 1), 1) == "\n") + { + LOG_INFOF( + ( + "^1TRAILING NEW LINE AT END OF NOTIFICATION: " + "^7net_type = %s, net_name = %s, string = %s.\n" + ), + notiftype, + notifname, + stringtype + ); + notif_error = true; + input = substring(input, 1, (strlen(input) - 1)); + } + + return input; +} + +string Process_Notif_Args( + float arg_type, + string args, + string notiftype, + string notifname) +{ + string selected, remaining = args; + float sel_num = 0; + + for (;(remaining != "");) + { + selected = car(remaining); remaining = cdr(remaining); + + switch(arg_type) + { + case 1: // normal args + { + if(sel_num == NOTIF_MAX_ARGS) + { + LOG_INFOF( + ( + "^1NOTIFICATION HAS TOO MANY ARGUMENTS: " + "^7net_type = %s, net_name = %s, max args = %d.\n" + ), + notiftype, + notifname, + NOTIF_MAX_ARGS + ); + notif_error = true; + break; + } + + switch(strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_SV(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_DC(selected,result) + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: + { + LOG_INFOF( + ( + "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: " + "^7net_type = %s, net_name = %s, args arg = '%s'.\n" + ), + notiftype, + notifname, + selected + ); + notif_error = true; + break; + } + } + break; + } + case 2: // hudargs + { + if(sel_num == NOTIF_MAX_HUDARGS) + { + LOG_INFOF( + ( + "^1NOTIFICATION HAS TOO MANY ARGUMENTS: " + "^7net_type = %s, net_name = %s, max hudargs = %d.\n" + ), + notiftype, + notifname, + NOTIF_MAX_HUDARGS + ); + notif_error = true; + break; + } + + switch(strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected,result) + #define ARG_CASE_ARG_CS_SV(selected,result) + #define ARG_CASE_ARG_CS(selected,result) + #define ARG_CASE_ARG_SV(selected,result) + #define ARG_CASE_ARG_DC(selected,result) + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: + { + LOG_INFOF( + ( + "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: " + "^7net_type = %s, net_name = %s, hudargs arg = '%s'.\n" + ), + notiftype, + notifname, + selected + ); + notif_error = true; + break; + } + } + break; + } + case 3: // durcnt + { + if(sel_num == NOTIF_MAX_DURCNT) + { + LOG_INFOF( + ( + "^1NOTIFICATION HAS TOO MANY ARGUMENTS: " + "^7net_type = %s, net_name = %s, max durcnt = %d.\n" + ), + notiftype, + notifname, + NOTIF_MAX_DURCNT + ); + notif_error = true; + break; + } + + switch(strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected,result) + #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV(selected,result) + #define ARG_CASE_ARG_CS(selected,result) + #define ARG_CASE_ARG_SV(selected,result) + #define ARG_CASE_ARG_DC(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: + { + if(ftos(stof(selected)) != "") { ++sel_num; } + else + { + LOG_INFOF( + ( + "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: " + "^7net_type = %s, net_name = %s, durcnt arg = '%s'.\n" + ), + notiftype, + notifname, + selected + ); + notif_error = true; + } + break; + } + } + break; + } + } + } + return args; +} + +void Create_Notification_Entity(entity notif, + float var_default, + float var_cvar, + MSG typeId, + string namestring) +{ + // ===================== + // Global Entity Setup + // ===================== + notif.nent_default = var_default; + notif.nent_enabled = (var_cvar >= 1); + notif.nent_type = typeId; + notif.nent_name = strzone(namestring); + + // Other pre-notif-setup requisites + notif_error = false; + + switch (typeId) + { + case MSG_ANNCE: + case MSG_INFO: + case MSG_CENTER: + case MSG_MULTI: + case MSG_CHOICE: + break; + default: + LOG_INFOF( + ( + "^1NOTIFICATION WITH IMPROPER TYPE: " + "^7net_type = %d, net_name = %s.\n" + ), + typeId, + namestring + ); + notif_error = true; + break; + } + + // now check to see if any errors happened + if (notif_error) + { + notif.nent_enabled = false; // disable the notification so it can't cause trouble + notif_global_error = true; // throw the red flag that an error happened on init + } +} + +void Create_Notification_Entity_Annce(entity notif, + float var_cvar, + string namestring, + /* MSG_ANNCE */ + float channel, + string snd, + float vol, + float position) + { + // Set MSG_ANNCE information and handle precaching + #ifdef CSQC + MSG typeId = MSG_ANNCE; + if (!(GENTLE && (var_cvar == 1))) + { + if(snd != "") + { + if(notif.nent_enabled) + { + precache_sound(sprintf("announcer/%s/%s.wav", AnnouncerOption(), snd)); + notif.nent_channel = channel; + notif.nent_snd = strzone(snd); + notif.nent_vol = vol; + notif.nent_position = position; + } + } + else + { + string typestring = Get_Notif_TypeName(typeId); + LOG_INFOF( + ( + "^1NOTIFICATION WITH NO SOUND: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + } + else { notif.nent_enabled = false; } + #else + notif.nent_enabled = false; + #endif + + } + +void Create_Notification_Entity_InfoCenter(entity notif, + float var_cvar, + string namestring, + int strnum, + int flnum, + /* MSG_INFO & MSG_CENTER */ + string args, + string hudargs, + string icon, + CPID cpid, + string durcnt, + string normal, + string gentle) + { + MSG typeId = notif.nent_type; + // Set MSG_INFO and MSG_CENTER string/float counts + notif.nent_stringcount = strnum; + notif.nent_floatcount = flnum; + + // Only initialize arguments if we're either a client or on a dedicated server + #ifdef SVQC + float should_process_args = server_is_dedicated; + #else + float should_process_args = true; + #endif + string typestring = Get_Notif_TypeName(typeId); + if(should_process_args) + { + // ======================== + // Process Main Arguments + // ======================== + if(strnum + flnum) + { + if(args != "") + { + notif.nent_args = strzone( + Process_Notif_Args(1, args, typestring, namestring)); + } + else if((hudargs == "") && (durcnt =="")) + { + LOG_INFOF( + ( + "^1NOTIFICATION HAS ARG COUNTS BUT NO ARGS OR HUDARGS OR DURCNT: " + "^7net_type = %s, net_name = %s, strnum = %d, flnum = %d\n" + ), + typestring, + namestring, + strnum, + flnum + ); + notif_error = true; + } + } + else if(args != "") + { + notif.nent_args = strzone( + Process_Notif_Args(1, args, typestring, namestring)); + } + + + // ======================================= + // Process HUD and Centerprint Arguments + // Only processed on CSQC, as these + // args are only for HUD features. + // ======================================= + #ifdef CSQC + if(hudargs != "") + { + notif.nent_hudargs = strzone( + Process_Notif_Args(2, hudargs, typestring, namestring)); + + if(icon != "") { notif.nent_icon = strzone(icon); } + else + { + LOG_INFOF( + ( + "^1NOTIFICATION HAS HUDARGS BUT NO ICON: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + } + else if(icon != "") + { + LOG_WARNINGF( + ( + "^1NOTIFICATION HAS ICON BUT NO HUDARGS: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + + if (durcnt != "") + { + notif.nent_durcnt = strzone(Process_Notif_Args(3, durcnt, typestring, namestring)); + + if (cpid == CPID_Null && durcnt != "0 0") + { + LOG_WARNINGF( + ( + "Notification has durcnt but no cpid: " + "net_type = %s, net_name = %s." + ), + typestring, + namestring + ); + notif_error = true; + } + } + notif.nent_cpid = cpid; + #endif + + + // ====================== + // Process Notif String + // ====================== + #define SET_NOTIF_STRING(string,stringname) MACRO_BEGIN { \ + notif.nent_string = strzone(CCR( \ + Process_Notif_Line( \ + typeId, \ + (var_cvar > 1), \ + string, \ + typestring, \ + namestring, \ + stringname \ + )) \ + ); \ + } MACRO_END + + if(GENTLE) + { + if(gentle != "") { SET_NOTIF_STRING(gentle, "GENTLE"); } + else if(normal != "") { SET_NOTIF_STRING(normal, "NORMAL"); } + } + else if(normal != "") { SET_NOTIF_STRING(normal, "NORMAL"); } + #undef SET_NOTIF_STRING + + // Check to make sure a string was chosen + if(notif.nent_string == "") + { + LOG_INFOF( + ( + "^1EMPTY NOTIFICATION: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + } + } + +void Create_Notification_Entity_Multi(entity notif, + float var_cvar, + string namestring, + /* MSG_MULTI */ + Notification anncename, + Notification infoname, + Notification centername) + { + MSG typeId = MSG_MULTI; + // Set MSG_MULTI string/float counts + if (!anncename && !infoname && !centername) + { + string typestring = Get_Notif_TypeName(typeId); + LOG_INFOF( + ( + "^1NOTIFICATION WITH NO SUBCALLS: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + else + { + // announcements don't actually need any arguments, so lets not even count them. + if (anncename) { notif.nent_msgannce = anncename; } + + float infoname_stringcount = 0, infoname_floatcount = 0; + float centername_stringcount = 0, centername_floatcount = 0; + + if (infoname) + { + notif.nent_msginfo = infoname; + infoname_stringcount = notif.nent_msginfo.nent_stringcount; + infoname_floatcount = notif.nent_msginfo.nent_floatcount; + } + + if (centername) + { + notif.nent_msgcenter = centername; + centername_stringcount = notif.nent_msgcenter.nent_stringcount; + centername_floatcount = notif.nent_msgcenter.nent_floatcount; + } + + // set the requirements of THIS notification to the totals of its subcalls + notif.nent_stringcount = max(infoname_stringcount, centername_stringcount); + notif.nent_floatcount = max(infoname_floatcount, centername_floatcount); + } + } + +void Create_Notification_Entity_Choice(entity notif, + float var_cvar, + string namestring, + /* MSG_CHOICE */ + float challow_def, + float challow_var, + MSG chtype, + Notification optiona, + Notification optionb) + { + MSG typeId = MSG_CHOICE; + if (chtype == MSG_Null || !optiona || !optionb) + { + string typestring = Get_Notif_TypeName(typeId); + LOG_INFOF( + ( + "^1NOTIFICATION IS MISSING CHOICE PARAMS: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + else + { + notif.nent_optiona = optiona; + notif.nent_optionb = optionb; + notif.nent_challow_def = challow_def; // 0: never allowed, 1: allowed in warmup, 2: always allowed + notif.nent_challow_var = challow_var; // 0: never allowed, 1: allowed in warmup, 2: always allowed + notif.nent_stringcount = max(notif.nent_optiona.nent_stringcount, notif.nent_optionb.nent_stringcount); + notif.nent_floatcount = max(notif.nent_optiona.nent_floatcount, notif.nent_optionb.nent_floatcount); + + /*#ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Create_Notification_Entity(...): MSG_CHOICE: %s\n%s\n%s\n", + notif.nent_name, + sprintf( + "^ optiona: %s %s : %d %d", + Get_Notif_TypeName(notif.nent_optiona.nent_type), + notif.nent_optiona.nent_name, + notif.nent_optiona.nent_stringcount, + notif.nent_optiona.nent_floatcount + ), + sprintf( + "^ optionb: %s %s : %d %d", + Get_Notif_TypeName(notif.nent_optionb.nent_type), + notif.nent_optionb.nent_name, + notif.nent_optionb.nent_stringcount, + notif.nent_optionb.nent_floatcount + ) + )); + #endif*/ + } + } + + +// =============== +// Cvar Handling +// =============== + +// used by MSG_CHOICE to build list of choices +#ifdef SVQC +void Notification_GetCvars() +{ + int idx = 0; + FOREACH(Notifications, it.nent_type == MSG_CHOICE, { + GetCvars_handleFloat( + get_cvars_s, + get_cvars_f, + msg_choice_choices[idx++], + sprintf("notification_%s", it.nent_name) + ); + }); +} +#endif + +/** used to output notifications.cfg file */ +void Dump_Notifications(int fh, bool alsoprint) +{ + #define NOTIF_WRITE(a) MACRO_BEGIN { \ + fputs(fh, a); \ + if (alsoprint) LOG_INFO(a); \ + } MACRO_END + + #define NOTIF_WRITE_ENTITY(e, description) MACRO_BEGIN { \ + string notif_msg = sprintf( \ + "seta notification_%s \"%d\" \"%s\"\n", \ + e.nent_name, e.nent_default, description \ + ); \ + NOTIF_WRITE(notif_msg); \ + } MACRO_END + + #define NOTIF_WRITE_ENTITY_CHOICE(e, descriptiona, descriptionb) MACRO_BEGIN { \ + string notif_msg = sprintf( \ + "seta notification_%s \"%d\" \"%s\"\n" \ + "seta notification_%s_ALLOWED \"%d\" \"%s\"\n", \ + e.nent_name, e.nent_default, descriptiona, \ + e.nent_name, e.nent_challow_def, descriptionb \ + ); \ + NOTIF_WRITE(notif_msg); \ + } MACRO_END + + #define NOTIF_WRITE_HARDCODED(cvar, default, description) MACRO_BEGIN { \ + string notif_msg = sprintf( \ + "seta notification_%s \"%s\" \"%s\"\n", \ + cvar, default, description \ + ); \ + NOTIF_WRITE(notif_msg); \ + } MACRO_END + + // Note: This warning only applies to the notifications.cfg file that is output... + // You ARE supposed to manually edit this function to add i.e. hard coded + // notification variables for mutators or game modes or such and then + // regenerate the notifications.cfg file from the new code. + + NOTIF_WRITE("// ********************************************** //\n"); + NOTIF_WRITE("// ** WARNING - DO NOT MANUALLY EDIT THIS FILE ** //\n"); + NOTIF_WRITE("// ** ** //\n"); + NOTIF_WRITE("// ** This file is automatically generated ** //\n"); + NOTIF_WRITE("// ** by code with the command 'dumpnotifs'. ** //\n"); + NOTIF_WRITE("// ** ** //\n"); + NOTIF_WRITE("// ** If you add a new notification, please ** //\n"); + NOTIF_WRITE("// ** regenerate this file with that command ** //\n"); + NOTIF_WRITE("// ** making sure that the output matches ** //\n"); + NOTIF_WRITE("// ** with the lists and defaults in code. ** //\n"); + NOTIF_WRITE("// ** ** //\n"); + NOTIF_WRITE("// ********************************************** //\n"); + + // These notifications will also append their string as a comment... + // This is not necessary, and does not matter if they vary between config versions, + // it is just a semi-helpful tool for those who want to manually change their user settings. + + int NOTIF_ANNCE_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_ANNCE, { ++NOTIF_ANNCE_COUNT; }); + NOTIF_WRITE(sprintf("\n// MSG_ANNCE notifications (count = %d):\n", NOTIF_ANNCE_COUNT)); + FOREACH(Notifications, it.nent_type == MSG_ANNCE, { + NOTIF_WRITE_ENTITY(it, + "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" + ); + }); + + int NOTIF_INFO_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_INFO, { ++NOTIF_INFO_COUNT; }); + NOTIF_WRITE(sprintf("\n// MSG_INFO notifications (count = %d):\n", NOTIF_INFO_COUNT)); + FOREACH(Notifications, it.nent_type == MSG_INFO, { + NOTIF_WRITE_ENTITY(it, + "0 = off, 1 = print to console, " + "2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" + ); + }); + + int NOTIF_CENTER_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_CENTER, { ++NOTIF_CENTER_COUNT; }); + NOTIF_WRITE(sprintf("\n// MSG_CENTER notifications (count = %d):\n", NOTIF_CENTER_COUNT)); + FOREACH(Notifications, it.nent_type == MSG_CENTER, { + NOTIF_WRITE_ENTITY(it, + "0 = off, 1 = centerprint" + ); + }); + + int NOTIF_MULTI_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_MULTI, { ++NOTIF_MULTI_COUNT; }); + NOTIF_WRITE(sprintf("\n// MSG_MULTI notifications (count = %d):\n", NOTIF_MULTI_COUNT)); + FOREACH(Notifications, it.nent_type == MSG_MULTI, { + NOTIF_WRITE_ENTITY(it, + "Enable this multiple notification" + ); + }); + + int NOTIF_CHOICE_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_CHOICE, { ++NOTIF_CHOICE_COUNT; }); + NOTIF_WRITE(sprintf("\n// MSG_CHOICE notifications (count = %d):\n", NOTIF_CHOICE_COUNT)); + FOREACH(Notifications, it.nent_type == MSG_CHOICE, { + NOTIF_WRITE_ENTITY_CHOICE(it, + "Choice for this notification 0 = off, 1 = default message, 2 = verbose message", + "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" + ); + }); + + // edit these to match whichever cvars are used for specific notification options + NOTIF_WRITE("\n// HARD CODED notification variables:\n"); + + NOTIF_WRITE_HARDCODED( + "allow_chatboxprint", "1", + "Allow INFO notifications to be printed to chat box" + "0 = do not allow, " + "1 = allow only if allowed by individual notification_INFO* cvars, " + "2 = force all INFO notifications to be printed to the chatbox" + ); + + NOTIF_WRITE_HARDCODED( + "debug", "0", + "Print extra debug information on all notification function calls " + "(Requires -DNOTIFICATIONS_DEBUG flag to be enabled on QCSRC compilation)... " + "0 = disabled, 1 = dprint, 2 = print" + ); + + NOTIF_WRITE_HARDCODED( + "errors_are_fatal", "1", + "If a notification fails upon initialization, cause a Host_Error to stop the program" + ); + + NOTIF_WRITE_HARDCODED( + "item_centerprinttime", "1.5", + "How long to show item information centerprint messages (like 'You got the Electro' or such)" + ); + + NOTIF_WRITE_HARDCODED( + "lifetime_mapload", "10", + "Amount of time that notification entities last immediately at mapload (in seconds) " + "to help prevent notifications from being lost on early init (like gamestart countdown)" + ); + + NOTIF_WRITE_HARDCODED( + "lifetime_runtime", "0.5", + "Amount of time that notification entities last on the server during runtime (In seconds)" + ); + + NOTIF_WRITE_HARDCODED( + "server_allows_location", "1", + "Server side cvar for allowing death messages to show location information too" + ); + + NOTIF_WRITE_HARDCODED( + "show_location", "0", + "Append location information to MSG_INFO death/kill messages" + ); + + NOTIF_WRITE_HARDCODED( + "show_location_string", "", + "Replacement string piped into sprintf, " + "so you can do different messages like this: ' at the %s' or ' (near %s)'" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees", "1", + "Print information about sprees in death/kill messages" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees_center", "1", + "Show spree information in MSG_CENTER messages... " + "0 = off, 1 = target (but only for first victim) and attacker" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees_center_specialonly", "1", + "Don't show spree information in MSG_CENTER messages if it isn't an achievement" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees_info", "3", + "Show spree information in MSG_INFO messages... " + "0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees_info_newline", "1", + "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees_info_specialonly", "1", + "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement" + ); + + NOTIF_WRITE(sprintf( + ( + "\n// Notification counts (total = %d): " + "MSG_ANNCE = %d, MSG_INFO = %d, MSG_CENTER = %d, MSG_MULTI = %d, MSG_CHOICE = %d\n" + ), + ( + NOTIF_ANNCE_COUNT + + NOTIF_INFO_COUNT + + NOTIF_CENTER_COUNT + + NOTIF_MULTI_COUNT + + NOTIF_CHOICE_COUNT + ), + NOTIF_ANNCE_COUNT, + NOTIF_INFO_COUNT, + NOTIF_CENTER_COUNT, + NOTIF_MULTI_COUNT, + NOTIF_CHOICE_COUNT + )); + #undef NOTIF_WRITE_HARDCODED + #undef NOTIF_WRITE_ENTITY + #undef NOTIF_WRITE +} + + +// =============================== +// Frontend Notification Pushing +// =============================== + +string Local_Notification_sprintf( + string input, string args, + string s1, string s2, string s3, string s4, + int f1, float f2, float f3, float f4) +{ + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification_sprintf('%s^7', '%s', %s, %s);\n", + MakeConsoleSafe(input), + args, + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4) + )); + #endif + + for (int sel_num = 0; sel_num < NOTIF_MAX_ARGS; ++sel_num) { arg_slot[sel_num] = ""; } + + for (int sel_num = 0; (args != ""); ) + { + string selected = car(args); args = cdr(args); + NOTIF_HIT_MAX(NOTIF_MAX_ARGS, "Local_Notification_sprintf"); + string tmp_s; // used by NOTIF_ARGUMENT_LIST + switch (strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE_ARG_CS_SV(selected, result) case selected: { arg_slot[sel_num++] = result; break; } +#ifdef CSQC + #define ARG_CASE_ARG_CS(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE_ARG_SV(selected, result) +#else + #define ARG_CASE_ARG_CS(selected, result) + #define ARG_CASE_ARG_SV(selected, result) case selected: { arg_slot[sel_num++] = result; break; } +#endif + #define ARG_CASE_ARG_DC(selected, result) + #define ARG_CASE(prog, selected, result) ARG_CASE_##prog(selected, result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: NOTIF_HIT_UNKNOWN(NOTIF_MAX_ARGS, "Local_Notification_sprintf") + } + } + return sprintf( + strcat(input, "\n"), + arg_slot[0], + arg_slot[1], + arg_slot[2], + arg_slot[3], + arg_slot[4], + arg_slot[5], + arg_slot[6] + ); +} + +#ifdef CSQC +void Local_Notification_sound( + int soundchannel, string soundfile, + float soundvolume, float soundposition) +{ + if ((soundfile != prev_soundfile) || (time >= (prev_soundtime + autocvar_cl_announcer_antispam))) + { + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification_sound(%f, '%s', %f, %f);\n", + soundchannel, + sprintf( + "announcer/%s/%s.wav", + AnnouncerOption(), + soundfile + ), + soundvolume, + soundposition + )); + #endif + + _sound( + NULL, + soundchannel, + sprintf( + "announcer/%s/%s.wav", + AnnouncerOption(), + soundfile + ), + soundvolume, + soundposition + ); + + if (prev_soundfile) strunzone(prev_soundfile); + prev_soundfile = strzone(soundfile); + prev_soundtime = time; + } + else + { + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + ( + "Local_Notification_sound(world, %f, '%s', %f, %f) " + "^1BLOCKED BY ANTISPAM:^7 prevsnd: '%s', timediff: %f, limit: %f\n" + ), + soundchannel, + sprintf( + "announcer/%s/%s.wav", + AnnouncerOption(), + soundfile + ), + soundvolume, + soundposition, + prev_soundfile, + (time - prev_soundtime), + autocvar_cl_announcer_antispam + )); + #endif + } +} + +void Local_Notification_HUD_Notify_Push( + string icon, string hudargs, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4) +{ + arg_slot[0] = ""; arg_slot[1] = ""; + + for (int sel_num = 0; (hudargs != ""); ) + { + string selected = car(hudargs); hudargs = cdr(hudargs); + NOTIF_HIT_MAX(NOTIF_MAX_HUDARGS, "Local_Notification_HUD_Notify_Push"); + switch (strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected, result) + #define ARG_CASE_ARG_CS_SV(selected, result) + #define ARG_CASE_ARG_CS(selected, result) + #define ARG_CASE_ARG_SV(selected, result) + #define ARG_CASE_ARG_DC(selected, result) + #define ARG_CASE(prog, selected, result) ARG_CASE_##prog(selected, result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: NOTIF_HIT_UNKNOWN(NOTIF_MAX_HUDARGS, "Local_Notification_HUD_Notify_Push") + } + } + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification_HUD_Notify_Push('%s^7', '%s', %s, %s, %s);\n", + icon, + hudargs, + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4), + MakeConsoleSafe(sprintf("'%s^7', '%s^7'", stof(arg_slot[0]), stof(arg_slot[1]))) + )); + #endif + HUD_Notify_Push(icon, arg_slot[0], arg_slot[1]); +} + +void Local_Notification_centerprint_generic( + string input, string durcnt, + CPID cpid, float f1, float f2) +{ + arg_slot[0] = ""; arg_slot[1] = ""; + + for (int sel_num = 0; (durcnt != ""); ) + { + string selected = car(durcnt); durcnt = cdr(durcnt); + NOTIF_HIT_MAX(NOTIF_MAX_DURCNT, "Local_Notification_centerprint_generic"); + switch (strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected, result) + #define ARG_CASE_ARG_CS_SV_DC(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE_ARG_CS_SV(selected, result) + #define ARG_CASE_ARG_CS(selected, result) + #define ARG_CASE_ARG_SV(selected, result) + #define ARG_CASE_ARG_DC(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE(prog, selected, result) ARG_CASE_##prog(selected,result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: + { + if (/* wtf */ ftos(stof(selected)) != "") { arg_slot[sel_num++] = selected; } + else { NOTIF_HIT_UNKNOWN(NOTIF_MAX_DURCNT, "Local_Notification_centerprint_generic") } + break; + } + } + } + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification_centerprint_generic('%s^7', '%s', %d, %d, %d, %d);\n", + MakeConsoleSafe(input), + durcnt, + f1, f2, + stof(arg_slot[0]), + stof(arg_slot[1]) + )); + #endif + centerprint_generic(ORDINAL(cpid), input, stof(arg_slot[0]), stof(arg_slot[1])); +} +#endif + +void Local_Notification(MSG net_type, Notification net_name, ...count) +{ + // retreive entity of this notification + entity notif = net_name; + if (!notif) + { + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification(%s, NULL, ...);\n", + Get_Notif_TypeName(net_type) + )); + #endif + LOG_WARNINGF("Incorrect usage of Local_Notification: %s\n", "Null notification"); + return; + } + + // check if the notification is enabled + if (!notif.nent_enabled) + { + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification(%s, %s, ...): Entity was disabled...\n", + Get_Notif_TypeName(net_type), + notif.nent_name + )); + #endif + return; + } + + string s1 = ((notif.nent_stringcount > 0) ? ...(0, string) : ""); + string s2 = ((notif.nent_stringcount > 1) ? ...(1, string) : ""); + string s3 = ((notif.nent_stringcount > 2) ? ...(2, string) : ""); + string s4 = ((notif.nent_stringcount > 3) ? ...(3, string) : ""); + float f1 = ((notif.nent_floatcount > 0) ? ...((notif.nent_stringcount + 0), float) : 0); + float f2 = ((notif.nent_floatcount > 1) ? ...((notif.nent_stringcount + 1), float) : 0); + float f3 = ((notif.nent_floatcount > 2) ? ...((notif.nent_stringcount + 2), float) : 0); + float f4 = ((notif.nent_floatcount > 3) ? ...((notif.nent_stringcount + 3), float) : 0); + + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification(%s, %s, %s, %s);\n", + Get_Notif_TypeName(net_type), + notif.nent_name, + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4) + )); + #endif + + if ((notif.nent_stringcount + notif.nent_floatcount) != count) + { + backtrace(sprintf( + ( + "Arguments mismatch for Local_Notification(%s, %s, ...)! " + "stringcount(%d) + floatcount(%d) != count(%d)\n" + "Check the definition and function call for accuracy...?\n" + ), + Get_Notif_TypeName(net_type), + notif.nent_name, + notif.nent_stringcount, + notif.nent_floatcount, + count + )); + return; + } + + switch (net_type) + { + case MSG_ANNCE: + { + #ifdef CSQC + Local_Notification_sound( + notif.nent_channel, + notif.nent_snd, + notif.nent_vol, + notif.nent_position + ); + #else + backtrace("MSG_ANNCE on server?... Please notify Samual immediately!\n"); + #endif + break; + } + + case MSG_INFO: + { + print( + Local_Notification_sprintf( + notif.nent_string, + notif.nent_args, + s1, s2, s3, s4, + f1, f2, f3, f4) + ); + #ifdef CSQC + if (notif.nent_icon != "") + { + if (notif.nent_iconargs != "") + { + string s = Local_Notification_sprintf( + notif.nent_icon,notif.nent_iconargs, + s1, s2, s3, s4, f1, f2, f3, f4); + // remove the trailing newline + notif.nent_icon = strzone(substring(s, 0, -1)); + } + Local_Notification_HUD_Notify_Push( + notif.nent_icon, + notif.nent_hudargs, + s1, s2, s3, s4, + f1, f2, f3, f4); + } + #endif + break; + } + + #ifdef CSQC + case MSG_CENTER: + { + Local_Notification_centerprint_generic( + Local_Notification_sprintf( + notif.nent_string, + notif.nent_args, + s1, s2, s3, s4, + f1, f2, f3, f4), + notif.nent_durcnt, + notif.nent_cpid, + f1, f2); + break; + } + #endif + + case MSG_MULTI: + { + if (notif.nent_msginfo && notif.nent_msginfo.nent_enabled) + { + Local_Notification_WOVA( + MSG_INFO, + notif.nent_msginfo, + notif.nent_msginfo.nent_stringcount, + notif.nent_msginfo.nent_floatcount, + s1, s2, s3, s4, + f1, f2, f3, f4); + } + #ifdef CSQC + if (notif.nent_msgannce && notif.nent_msgannce.nent_enabled) + { + Local_Notification_WOVA( + MSG_ANNCE, + notif.nent_msgannce, + 0, 0, + "", "", "", "", + 0, 0, 0, 0); + } + if (notif.nent_msgcenter && notif.nent_msgcenter.nent_enabled) + { + Local_Notification_WOVA( + MSG_CENTER, + notif.nent_msgcenter, + notif.nent_msgcenter.nent_stringcount, + notif.nent_msgcenter.nent_floatcount, + s1, s2, s3, s4, + f1, f2, f3, f4); + } + #endif + break; + } + + case MSG_CHOICE: + { + entity found_choice = notif.nent_optiona; + if (notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) { + switch (cvar(sprintf("notification_%s", notif.nent_name))) + { + case 1: break; + case 2: found_choice = notif.nent_optionb; break; + default: return; // not enabled anyway + } + } + + Local_Notification_WOVA( + found_choice.nent_type, + found_choice, + found_choice.nent_stringcount, + found_choice.nent_floatcount, + s1, s2, s3, s4, + f1, f2, f3, f4); + } + } +} + +// WOVA = Without Variable Arguments +void Local_Notification_WOVA( + MSG net_type, Notification net_name, + float stringcount, float floatcount, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4) +{ + #define VARITEM(stringc, floatc, args) \ + if ((stringcount == stringc) && (floatcount == floatc)) \ + { Local_Notification(net_type, net_name, args); return; } + EIGHT_VARS_TO_VARARGS_VARLIST + #undef VARITEM + Local_Notification(net_type, net_name); // some notifications don't have any arguments at all +} + + +// ========================= +// Notification Networking +// ========================= + +/** networked as a linked entity to give newly connecting clients some notification context */ +REGISTER_NET_LINKED(ENT_CLIENT_NOTIFICATION) + +#ifdef CSQC +NET_HANDLE(ENT_CLIENT_NOTIFICATION, bool is_new) +{ + make_pure(this); + MSG net_type = ENUMCAST(MSG, ReadByte()); + int net_name = ReadShort(); + return = true; + + if (net_type == MSG_CENTER_KILL) + { + if (!is_new) return; + // killing + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Read_Notification(%d) at %f: net_type = %s, cpid = %d\n", + is_new, + time, + Get_Notif_TypeName(net_type), + net_name + )); + #endif + int _net_name = net_name; + CPID net_name = ENUMCAST(CPID, _net_name); + if (net_name == CPID_Null) { + // kill all + reset_centerprint_messages(); + } else { + // kill group + centerprint_generic(ORDINAL(net_name), "", 0, 0); + } + return; + } + + Notification notif = Get_Notif_Ent(net_type, net_name); + + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Read_Notification(%d) at %f: net_type = %s, net_name = %s (%d)\n", + is_new, + time, + Get_Notif_TypeName(net_type), + notif.registered_id, + net_name + )); + #endif + + if (!notif) { + backtrace("Read_Notification: Could not find notification entity!\n"); + return false; + } + + string s1 = ((notif.nent_stringcount > 0) ? ReadString() : ""); + string s2 = ((notif.nent_stringcount > 1) ? ReadString() : ""); + string s3 = ((notif.nent_stringcount > 2) ? ReadString() : ""); + string s4 = ((notif.nent_stringcount > 3) ? ReadString() : ""); + float f1 = ((notif.nent_floatcount > 0) ? ReadLong() : 0); + float f2 = ((notif.nent_floatcount > 1) ? ReadLong() : 0); + float f3 = ((notif.nent_floatcount > 2) ? ReadLong() : 0); + float f4 = ((notif.nent_floatcount > 3) ? ReadLong() : 0); + + if (!is_new) return; + Local_Notification_WOVA( + net_type, notif, + notif.nent_stringcount, + notif.nent_floatcount, + s1, s2, s3, s4, + f1, f2, f3, f4); +} +#endif + +#ifdef SVQC +void Net_Notification_Remove() +{ + SELFPARAM(); + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Net_Notification_Remove() at %f: %s '%s - %s' notification\n", + time, + ((this.nent_net_name == -1) ? "Killed" : "Removed"), + Get_Notif_TypeName(this.nent_net_type), + this.owner.nent_name + )); + #endif + for (int i = 0; i < this.nent_stringcount; ++i) { if (this.nent_strings[i]) strunzone(this.nent_strings[i]); } + remove(this); +} + +bool Net_Write_Notification(entity this, entity client, int sf) +{ + if (!Notification_ShouldSend(this.nent_broadcast, client, this.nent_client)) return false; + WriteHeader(MSG_ENTITY, ENT_CLIENT_NOTIFICATION); + WriteByte(MSG_ENTITY, ORDINAL(this.nent_net_type)); + WriteShort(MSG_ENTITY, this.nent_net_name); + for (int i = 0; i < this.nent_stringcount; ++i) { WriteString(MSG_ENTITY, this.nent_strings[i]); } + for (int i = 0; i < this.nent_floatcount; ++i) { WriteLong(MSG_ENTITY, this.nent_floats[i]); } + return true; +} + +void Kill_Notification( + NOTIF broadcast, entity client, + /** message group, MSG_Null for all */ + MSG net_type, + /** cpid group, CPID_Null for all */ + CPID net_cpid) +{ + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Kill_Notification(%s, '%s', %s, %d);\n", + Get_Notif_BroadcastName(broadcast), + client.netname, + (net_type ? Get_Notif_TypeName(net_type) : "0"), + net_cpid + )); + #endif + + string checkargs = Notification_CheckArgs(broadcast, client); + if (checkargs != "") { LOG_WARNINGF("Incorrect usage of Kill_Notification: %s", checkargs); return; } + + entity net_notif = new_pure(net_kill_notification); + net_notif.nent_broadcast = broadcast; + net_notif.nent_client = client; + net_notif.nent_net_type = MSG_CENTER_KILL; + net_notif.nent_net_name = ORDINAL(net_cpid); + Net_LinkEntity(net_notif, false, autocvar_notification_lifetime_runtime, Net_Write_Notification); + + FOREACH_ENTITY_CLASS( + "net_notification", + (it.owner.nent_type == net_type || net_type == MSG_Null) && (it.owner.nent_cpid == net_cpid || net_cpid == CPID_Null), + { + it.nent_net_name = -1; + it.nextthink = time; + } + ); +} + +void Send_Notification( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + ...count) +{ + entity notif = net_name; + string parms = sprintf("%s, '%s', %s, %s", + Get_Notif_BroadcastName(broadcast), + client.classname, + Get_Notif_TypeName(net_type), + net_name.registered_id + ); + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf("Send_Notification(%s, ...%d);\n", parms, count)); + #endif + + if (!notif) + { + LOG_WARNING("Send_Notification: Could not find notification entity!"); + return; + } + + // check supplied broadcast, target, type, and name for errors + string checkargs = Notification_CheckArgs(broadcast, client); + if (!net_name) { checkargs = sprintf("No notification provided! %s", checkargs); } + if (checkargs != "") + { + LOG_WARNINGF("Incorrect usage of Send_Notification: %s", checkargs); + return; + } + + string s1 = ((0 < notif.nent_stringcount) ? ...(0, string) : ""); + string s2 = ((1 < notif.nent_stringcount) ? ...(1, string) : ""); + string s3 = ((2 < notif.nent_stringcount) ? ...(2, string) : ""); + string s4 = ((3 < notif.nent_stringcount) ? ...(3, string) : ""); + float f1 = ((0 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 0), float) : 0); + float f2 = ((1 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 1), float) : 0); + float f3 = ((2 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 2), float) : 0); + float f4 = ((3 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 3), float) : 0); + + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Send_Notification(%s, %s, %s);\n", + parms, + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4) + )); + #endif + + if ((notif.nent_stringcount + notif.nent_floatcount) != count) + { + LOG_WARNINGF( + "Argument mismatch for Send_Notification(%s, ...)! " + "stringcount(%d) + floatcount(%d) != count(%d)\n" + "Check the definition and function call for accuracy...?\n", + parms, + notif.nent_stringcount, + notif.nent_floatcount, + count + ); + return; + } + + if ( + server_is_dedicated + && + ( + broadcast == NOTIF_ALL + || + broadcast == NOTIF_ALL_EXCEPT + ) + && + !( + net_type == MSG_ANNCE + || + net_type == MSG_CENTER + ) + ) + { + Local_Notification_WOVA( + net_type, net_name, + notif.nent_stringcount, + notif.nent_floatcount, + s1, s2, s3, s4, + f1, f2, f3, f4); + } + + if (net_type == MSG_CHOICE) + { + // THIS GETS TRICKY... now we have to cycle through each possible player (checking broadcast) + // and then do an individual NOTIF_ONE_ONLY recursive call for each one depending on their option... + // It's slow, but it's better than the alternatives: + // 1. Constantly networking all info and letting client decide + // 2. Manually handling each separate call on per-usage basis (See old CTF usage of verbose) + entity found_choice; + + #define RECURSE_FROM_CHOICE(ent,action) MACRO_BEGIN { \ + if (notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) { \ + switch (ent.msg_choice_choices[net_name.nent_choice_idx]) \ + { \ + case 1: found_choice = notif.nent_optiona; break; \ + case 2: found_choice = notif.nent_optionb; break; \ + default: action; \ + } \ + } else { \ + found_choice = notif.nent_optiona; \ + } \ + Send_Notification_WOVA( \ + NOTIF_ONE_ONLY, \ + ent, \ + found_choice.nent_type, \ + found_choice, \ + found_choice.nent_stringcount, \ + found_choice.nent_floatcount, \ + s1, s2, s3, s4, \ + f1, f2, f3, f4); \ + } MACRO_END + + switch (broadcast) + { + case NOTIF_ONE_ONLY: // we can potentially save processing power with this broadcast method + { + if (IS_REAL_CLIENT(client)) { + RECURSE_FROM_CHOICE(client, return); + } + break; + } + default: + { + FOREACH_CLIENT(IS_REAL_CLIENT(it) && Notification_ShouldSend(broadcast, it, client), { + RECURSE_FROM_CHOICE(it, continue); + }); + break; + } + } + } + else + { + entity net_notif = new(net_notification); + make_pure(net_notif); + net_notif.owner = notif; + net_notif.nent_broadcast = broadcast; + net_notif.nent_client = client; + net_notif.nent_net_type = net_type; + net_notif.nent_net_name = notif.m_id; + net_notif.nent_stringcount = notif.nent_stringcount; + net_notif.nent_floatcount = notif.nent_floatcount; + + for (int i = 0; i < net_notif.nent_stringcount; ++i) { + net_notif.nent_strings[i] = strzone(...(i, string)); + } + for (int i = 0; i < net_notif.nent_floatcount; ++i) { + net_notif.nent_floats[i] = ...((net_notif.nent_stringcount + i), float); + } + + net_notif.think = Net_Notification_Remove; + net_notif.nextthink = (time > autocvar_notification_lifetime_mapload) + ? (time + autocvar_notification_lifetime_runtime) + : autocvar_notification_lifetime_mapload; + + Net_LinkEntity(net_notif, false, 0, Net_Write_Notification); + } +} + +// WOVA = Without Variable Arguments +void Send_Notification_WOVA( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + float stringcount, float floatcount, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4) +{ + #ifdef NOTIFICATIONS_DEBUG + entity notif = net_name; + Debug_Notification(sprintf( + "Send_Notification_WOVA(%s, %d, %d, %s, %s);\n", + sprintf( + "%s, '%s', %s, %s", + Get_Notif_BroadcastName(broadcast), + client.classname, + Get_Notif_TypeName(net_type), + notif.nent_name + ), + stringcount, + floatcount, + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4) + )); + #endif + + #define VARITEM(stringc, floatc, args) \ + if ((stringcount == stringc) && (floatcount == floatc)) \ + { Send_Notification(broadcast, client, net_type, net_name, args); return; } + EIGHT_VARS_TO_VARARGS_VARLIST + #undef VARITEM + Send_Notification(broadcast, client, net_type, net_name); // some notifications don't have any arguments at all +} + +// WOCOVA = Without Counts Or Variable Arguments +void Send_Notification_WOCOVA( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4) +{ + entity notif = net_name; + + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Send_Notification_WOCOVA(%s, %s, %s);\n", + sprintf( + "%s, '%s', %s, %s", + Get_Notif_BroadcastName(broadcast), + client.classname, + Get_Notif_TypeName(net_type), + notif.nent_name + ), + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4) + )); + #endif + + #define VARITEM(stringc, floatc, args) \ + if ((notif.nent_stringcount == stringc) && (notif.nent_floatcount == floatc)) \ + { Send_Notification(broadcast, client, net_type, net_name, args); return; } + EIGHT_VARS_TO_VARARGS_VARLIST + #undef VARITEM + Send_Notification(broadcast, client, net_type, net_name); // some notifications don't have any arguments at all +} +#endif // ifdef SVQC diff --git a/qcsrc/common/notifications/all.qh b/qcsrc/common/notifications/all.qh new file mode 100644 index 000000000..ffadf6ec1 --- /dev/null +++ b/qcsrc/common/notifications/all.qh @@ -0,0 +1,804 @@ +#ifndef NOTIFICATIONS_H +#define NOTIFICATIONS_H + +#include + +#include +#include +#include + +/** main types/groups of notifications */ +ENUMCLASS(MSG) + /** "Global" AND "personal" announcer messages */ + CASE(MSG, ANNCE) + /** "Global" information messages */ + CASE(MSG, INFO) + /** "Personal" centerprint messages */ + CASE(MSG, CENTER) + /** Subcall MSG_INFO and/or MSG_CENTER notifications */ + CASE(MSG, MULTI) + /** Choose which subcall wrapper to activate */ + CASE(MSG, CHOICE) + /** Kill centerprint message @deprecated */ + CASE(MSG, CENTER_KILL) +ENUMCLASS_END(MSG) + +string Get_Notif_TypeName(MSG net_type) +{ + switch (net_type) + { + case MSG_ANNCE: return "MSG_ANNCE"; + case MSG_INFO: return "MSG_INFO"; + case MSG_CENTER: return "MSG_CENTER"; + case MSG_MULTI: return "MSG_MULTI"; + case MSG_CHOICE: return "MSG_CHOICE"; + } + LOG_WARNINGF("Get_Notif_TypeName(%d): Improper net type!\n", ORDINAL(net_type)); + return ""; +} + +ENUMCLASS(CPID) + CASE(CPID, ASSAULT_ROLE) + CASE(CPID, ROUND) + CASE(CPID, CAMPCHECK) + CASE(CPID, CTF_CAPSHIELD) + CASE(CPID, CTF_LOWPRIO) + CASE(CPID, CTF_PASS) + CASE(CPID, STALEMATE) + CASE(CPID, NADES) + CASE(CPID, IDLING) + CASE(CPID, ITEM) + CASE(CPID, PREVENT_JOIN) + CASE(CPID, KEEPAWAY) + CASE(CPID, KEEPAWAY_WARN) + CASE(CPID, KEYHUNT) + CASE(CPID, KEYHUNT_OTHER) + CASE(CPID, LMS) + CASE(CPID, MISSING_TEAMS) + CASE(CPID, MISSING_PLAYERS) + CASE(CPID, INSTAGIB_FINDAMMO) + CASE(CPID, MOTD) + CASE(CPID, NIX) + CASE(CPID, ONSLAUGHT) + CASE(CPID, ONS_CAPSHIELD) + CASE(CPID, OVERTIME) + CASE(CPID, POWERUP) + CASE(CPID, RACE_FINISHLAP) + CASE(CPID, TEAMCHANGE) + CASE(CPID, TIMEOUT) + CASE(CPID, VEHICLES) + CASE(CPID, VEHICLES_OTHER) + /** always last */ + CASE(CPID, LAST) +ENUMCLASS_END(CPID) + +typedef entity Notification; + +// used for notification system multi-team identifiers +#define APP_TEAM_NUM(num, prefix) ((num == NUM_TEAM_1) ? prefix##_RED : ((num == NUM_TEAM_2) ? prefix##_BLUE : ((num == NUM_TEAM_3) ? prefix##_YELLOW : prefix##_PINK))) +/** @deprecated use APP_TEAM_NUM */ +#define APP_TEAM_ENT(ent, prefix) APP_TEAM_NUM(ent.team, prefix) + +#define EIGHT_VARS_TO_VARARGS_VARLIST \ + VARITEM(1, 0, s1) \ + VARITEM(2, 0, XPD(s1, s2)) \ + VARITEM(3, 0, XPD(s1, s2, s3)) \ + VARITEM(4, 0, XPD(s1, s2, s3, s4)) \ + VARITEM(0, 1, f1) \ + VARITEM(1, 1, XPD(s1, f1)) \ + VARITEM(2, 1, XPD(s1, s2, f1)) \ + VARITEM(3, 1, XPD(s1, s2, s3, f1)) \ + VARITEM(4, 1, XPD(s1, s2, s3, s4, f1)) \ + VARITEM(0, 2, XPD(f1, f2)) \ + VARITEM(1, 2, XPD(s1, f1, f2)) \ + VARITEM(2, 2, XPD(s1, s2, f1, f2)) \ + VARITEM(3, 2, XPD(s1, s2, s3, f1, f2)) \ + VARITEM(4, 2, XPD(s1, s2, s3, s4, f1, f2)) \ + VARITEM(0, 3, XPD(f1, f2, f3)) \ + VARITEM(1, 3, XPD(s1, f1, f2, f3)) \ + VARITEM(2, 3, XPD(s1, s2, f1, f2, f3)) \ + VARITEM(3, 3, XPD(s1, s2, s3, f1, f2, f3)) \ + VARITEM(4, 3, XPD(s1, s2, s3, s4, f1, f2, f3)) \ + VARITEM(0, 4, XPD(f1, f2, f3, f4)) \ + VARITEM(1, 4, XPD(s1, f1, f2, f3, f4)) \ + VARITEM(2, 4, XPD(s1, s2, f1, f2, f3, f4)) \ + VARITEM(3, 4, XPD(s1, s2, s3, f1, f2, f3, f4)) \ + VARITEM(4, 4, XPD(s1, s2, s3, s4, f1, f2, f3, f4)) + +void Destroy_All_Notifications(); +void Create_Notification_Entity(entity notif, + float var_default, + float var_cvar, + MSG typeId, + string namestring); +void Create_Notification_Entity_Annce(entity notif, + float var_cvar, + string namestring, + /* MSG_ANNCE */ + float channel, + string snd, + float vol, + float position); + +void Create_Notification_Entity_InfoCenter(entity notif, + float var_cvar, + string namestring, + int strnum, + int flnum, + /* MSG_INFO & MSG_CENTER */ + string args, + string hudargs, + string icon, + CPID cpid, + string durcnt, + string normal, + string gentle); + +void Create_Notification_Entity_Multi(entity notif, + float var_cvar, + string namestring, + /* MSG_MULTI */ + Notification anncename, + Notification infoname, + Notification centername); + +void Create_Notification_Entity_Choice(entity notif, + float var_cvar, + string namestring, + /* MSG_CHOICE */ + float challow_def, + float challow_var, + MSG chtype, + Notification optiona, + Notification optionb); + +void Dump_Notifications(int fh, bool alsoprint); + +GENERIC_COMMAND(dumpnotifs, "Dump all notifications into notifications_dump.txt") +{ + switch (request) + { + case CMD_REQUEST_COMMAND: + { + #ifndef MENUQC + string filename = argv(1); + bool alsoprint = false; + if (filename == "") + { + filename = "notifications_dump.cfg"; + alsoprint = false; + } + else if (filename == "-") + { + filename = "notifications_dump.cfg"; + alsoprint = true; + } + int fh = fopen(filename, FILE_WRITE); + if (fh >= 0) + { + Dump_Notifications(fh, alsoprint); + LOG_INFOF("Dumping notifications... File located in ^2data/data/%s^7.\n", filename); + fclose(fh); + } + else + { + LOG_INFOF("^1Error: ^7Could not open file '%s'!\n", filename); + } + #else + LOG_INFO(_("Notification dump command only works with cl_cmd and sv_cmd.\n")); + #endif + return; + } + default: + case CMD_REQUEST_USAGE: + { + LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpnotifs [filename]")); + LOG_INFO(" Where 'filename' is the file to write (default is notifications_dump.cfg),\n"); + LOG_INFO(" if supplied with '-' output to console as well as default,\n"); + LOG_INFO(" if left blank, it will only write to default.\n"); + return; + } + } +} + +#ifdef NOTIFICATIONS_DEBUG +void Debug_Notification(string input) +{ + switch (autocvar_notification_debug) + { + case 1: { LOG_TRACE(input); break; } + case 2: { LOG_INFO(input); break; } + } +} +#endif + +void Local_Notification(MSG net_type, Notification net_name, ...count); +/** glue for networking, forwards to `Local_Notification` */ +void Local_Notification_WOVA( + MSG net_type, Notification net_name, + float stringcount, float floatcount, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4); + +#ifdef CSQC +string prev_soundfile; +float prev_soundtime; +#endif + +#ifdef SVQC +ENUMCLASS(NOTIF) + /** send to one client and their spectators */ + CASE(NOTIF, ONE) + /** send ONLY to one client */ + CASE(NOTIF, ONE_ONLY) + /** send only to X team and their spectators */ + CASE(NOTIF, TEAM) + /** send only to X team and their spectators, except for Y person and their spectators */ + CASE(NOTIF, TEAM_EXCEPT) + /** send to everyone */ + CASE(NOTIF, ALL) + /** send to everyone except X person and their spectators */ + CASE(NOTIF, ALL_EXCEPT) +ENUMCLASS_END(NOTIF) + +string Get_Notif_BroadcastName(NOTIF broadcast) +{ + switch (broadcast) + { + case NOTIF_ONE: return "NOTIF_ONE"; + case NOTIF_ONE_ONLY: return "NOTIF_ONE_ONLY"; + case NOTIF_ALL_EXCEPT: return "NOTIF_ALL_EXCEPT"; + case NOTIF_ALL: return "NOTIF_ALL"; + case NOTIF_TEAM: return "NOTIF_TEAM"; + case NOTIF_TEAM_EXCEPT: return "NOTIF_TEAM_EXCEPT"; + } + LOG_WARNINGF("Get_Notif_BroadcastName(%d): Improper broadcast!\n", broadcast); + return ""; +} + +void Kill_Notification( + NOTIF broadcast, entity client, + MSG net_type, CPID net_name); +void Send_Notification( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + ...count); +void Send_Notification_WOVA( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + float stringcount, float floatcount, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4); +void Send_Notification_WOCOVA( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4); +#endif + +// =========================== +// Special CVAR Declarations +// =========================== + +// MAKE SURE THIS IS ALWAYS SYNCHRONIZED WITH THE DUMP +// NOTIFICATIONS FUNCTION IN THE .QC FILE! + +#define NOTIF_ADD_AUTOCVAR(name,default) float autocvar_notification_##name = default; + +float autocvar_notification_show_location = false; +string autocvar_notification_show_location_string = ""; //_(" at the %s"); +float autocvar_notification_show_sprees = true; +float autocvar_notification_show_sprees_info = 3; // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker +float autocvar_notification_show_sprees_info_newline = true; +float autocvar_notification_show_sprees_info_specialonly = true; +float autocvar_notification_errors_are_fatal = true; +float autocvar_notification_lifetime_runtime = 0.5; +float autocvar_notification_lifetime_mapload = 10; +float autocvar_notification_debug = false; + +#ifdef SVQC +.float FRAG_VERBOSE; +void Notification_GetCvars(); +float autocvar_notification_server_allows_location = 1; // 0 = no, 1 = yes +#else +float autocvar_notification_item_centerprinttime = 1.5; + +// 0 = no, 1 = yes, 2 = forced on for all MSG_INFO notifs +// DISABLED IN CODE, BUT ENABLED IN CONFIG FOR COMPATIBILITY WITH OLD CLIENTS +float autocvar_notification_allow_chatboxprint = 0; + +float autocvar_notification_show_sprees_center = true; +float autocvar_notification_show_sprees_center_specialonly = true; +#endif + + +// ============================ +// Notification Argument List +// ============================ +/* + These arguments get replaced with the Local_Notification_sprintf + and other such functions found in all.qc to supply data + from networked notifications to their usage in sprintf... It + allows for more dynamic data to be inferred by the local + notification parser, so that the server does not have to network + anything too crazy on a per-client/per-situation basis. + + Pay attention to the CSQC/SVQC relations, some of these are redefined + in slightly different ways for different programs, this is because the + server does a more conservative approach to the notifs than the client. + + All arguments are swapped into strings, so be sure that your + sprintf usage matches with proper %s placement. + + Argument descriptions: + s1-s4: string arguments to be literally swapped into sprintf + s2loc: s2 string of locations of deaths or other events + s3loc: s3 string of locations of deaths or other events + f1-f4: float arguments expanded into strings to be swapped into sprintf + f1p2dec: f1 float to string with 2 decimal places + f2p2dec: f2 float to string with 2 decimal places + f2primsec: f2 float primary or secondary selection for weapons + f3primsec: f3 float primary or secondary selection for weapons + f1secs: count_seconds of f1 + f1points: point or points depending on f1 + f1ord: count_ordinal of f1 + f1time: process_time of f1 + f1race_time: mmssss of f1 + f2race_time: mmssss of f2 + race_col: color of race time/position (i.e. good or bad) + race_diff: show time difference between f2 and f3 + missing_teams: show which teams still need players + pass_key: find the keybind for "passing" or "dropping" in CTF game mode + frag_ping: show the ping of a player + frag_stats: show health/armor/ping of a player + frag_pos: show score status and position in the match of a player + spree_cen: centerprint notif for kill spree/how many kills they have + spree_inf: info notif for kill spree/how many kills they have + spree_end: placed at the end of murder messages to show ending of sprees + spree_lost: placed at the end of suicide messages to show losing of sprees + item_wepname: return full name of a weapon from weaponid + item_wepammo: ammo display for weapon from string + item_centime: amount of time to display weapon message in centerprint + item_buffname: return full name of a buff from buffid + death_team: show the full name of the team a player is switching from + minigame1_name: return human readable name of a minigame from its id(s1) + minigame1_d: return descriptor name of a minigame from its id(s1) +*/ + +const float NOTIF_MAX_ARGS = 7; +const float NOTIF_MAX_HUDARGS = 2; +const float NOTIF_MAX_DURCNT = 2; + +string arg_slot[NOTIF_MAX_ARGS]; + +const float ARG_CS_SV_HA = 1; // enabled on CSQC, SVQC, and Hudargs +const float ARG_CS_SV_DC = 2; // enabled on CSQC, SVQC, and durcnt centerprint +const float ARG_CS_SV = 3; // enabled on CSQC and SVQC +const float ARG_CS = 4; // unique result to CSQC +const float ARG_SV = 5; // unique result to SVQC +const float ARG_DC = 6; // unique result to durcnt/centerprint + +// todo possible idea.... declare how many floats/strings each arg needs, and then dynamically increment the input +// this way, we don't need to have duplicates like i.e. s2loc and s3loc? + +string BUFF_NAME(int i); + +#define NOTIF_ARGUMENT_LIST \ + ARG_CASE(ARG_CS_SV_HA, "s1", s1) \ + ARG_CASE(ARG_CS_SV_HA, "s2", s2) \ + ARG_CASE(ARG_CS_SV_HA, "s3", s3) \ + ARG_CASE(ARG_CS_SV_HA, "s4", s4) \ + ARG_CASE(ARG_CS_SV, "s2loc", ((autocvar_notification_show_location && (s2 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s2) : "")) \ + ARG_CASE(ARG_CS_SV, "s3loc", ((autocvar_notification_show_location && (s3 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s3) : "")) \ + ARG_CASE(ARG_CS_SV_DC, "f1", ftos(f1)) \ + ARG_CASE(ARG_CS_SV_DC, "f2", ftos(f2)) \ + ARG_CASE(ARG_CS_SV, "f3", ftos(f3)) \ + ARG_CASE(ARG_CS_SV, "f4", ftos(f4)) \ + ARG_CASE(ARG_CS_SV, "f1p2dec", ftos_decimals(f1/100, 2)) \ + ARG_CASE(ARG_CS_SV, "f2p2dec", ftos_decimals(f2/100, 2)) \ + ARG_CASE(ARG_CS, "f2primsec", (f2 ? _("secondary") : _("primary"))) \ + ARG_CASE(ARG_CS, "f3primsec", (f3 ? _("secondary") : _("primary"))) \ + ARG_CASE(ARG_CS, "f1secs", count_seconds(f1)) \ + ARG_CASE(ARG_CS, "f1points", (f1 == 1 ? _("point") : _("points"))) \ + ARG_CASE(ARG_CS_SV, "f1ord", count_ordinal(f1)) \ + ARG_CASE(ARG_CS, "f1time", process_time(2, f1)) \ + ARG_CASE(ARG_CS_SV_HA, "f1race_time", mmssss(f1)) \ + ARG_CASE(ARG_CS_SV_HA, "f2race_time", mmssss(f2)) \ + ARG_CASE(ARG_CS_SV_HA, "f3race_time", mmssss(f3)) \ + ARG_CASE(ARG_CS_SV, "race_col", CCR(((f1 == 1) ? "^F1" : "^F2"))) \ + ARG_CASE(ARG_CS_SV, "race_diff", ((f2 > f3) ? sprintf(CCR("^1[+%s]"), mmssss(f2 - f3)) : sprintf(CCR("^2[-%s]"), mmssss(f3 - f2)))) \ + ARG_CASE(ARG_CS, "missing_teams", notif_arg_missing_teams(f1)) \ + ARG_CASE(ARG_CS, "pass_key", ((((tmp_s = getcommandkey("pass", "+use")) != "pass") && !(strstrofs(tmp_s, "not bound", 0) >= 0)) ? sprintf(CCR(_(" ^F1(Press %s)")), tmp_s) : "")) \ + ARG_CASE(ARG_CS, "frag_ping", notif_arg_frag_ping(true, f2)) \ + ARG_CASE(ARG_CS, "frag_stats", notif_arg_frag_stats(f2, f3, f4)) \ + /*ARG_CASE(ARG_CS, "frag_pos", ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \ + ARG_CASE(ARG_CS, "spree_cen", (autocvar_notification_show_sprees ? notif_arg_spree_cen(f1) : "")) \ + ARG_CASE(ARG_CS_SV, "spree_inf", (autocvar_notification_show_sprees ? notif_arg_spree_inf(1, input, s2, f2) : "")) \ + ARG_CASE(ARG_CS_SV, "spree_end", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \ + ARG_CASE(ARG_CS_SV, "spree_lost", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \ + ARG_CASE(ARG_CS_SV, "item_wepname", Weapons_from(f1).m_name) \ + ARG_CASE(ARG_CS_SV, "item_buffname", BUFF_NAME(f1)) \ + ARG_CASE(ARG_CS_SV, "f3buffname", BUFF_NAME(f3)) \ + ARG_CASE(ARG_CS_SV, "item_wepammo", (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \ + ARG_CASE(ARG_DC, "item_centime", ftos(autocvar_notification_item_centerprinttime)) \ + ARG_CASE(ARG_SV, "death_team", Team_ColoredFullName(f1)) \ + ARG_CASE(ARG_CS, "death_team", Team_ColoredFullName(f1 - 1)) \ + ARG_CASE(ARG_CS_SV_HA, "minigame1_name",find(world,netname,s1).descriptor.message) \ + ARG_CASE(ARG_CS_SV_HA, "minigame1_d", find(world,netname,s1).descriptor.netname) + +#define NOTIF_HIT_MAX(count,funcname) MACRO_BEGIN { \ + if(sel_num == count) { backtrace(sprintf("%s: Hit maximum arguments!\n", funcname)); break; } \ +} MACRO_END +#define NOTIF_HIT_UNKNOWN(token,funcname) { backtrace(sprintf("%s: Hit unknown token in selected string! '%s'\n", funcname, selected)); break; } + +#define KILL_SPREE_LIST \ + SPREE_ITEM(3, 03, _("TRIPLE FRAG! "), _("%s^K1 made a TRIPLE FRAG! %s^BG"), _("%s^K1 made a TRIPLE SCORE! %s^BG")) \ + SPREE_ITEM(5, 05, _("RAGE! "), _("%s^K1 unlocked RAGE! %s^BG"), _("%s^K1 made FIVE SCORES IN A ROW! %s^BG")) \ + SPREE_ITEM(10, 10, _("MASSACRE! "), _("%s^K1 started a MASSACRE! %s^BG"), _("%s^K1 made TEN SCORES IN A ROW! %s^BG")) \ + SPREE_ITEM(15, 15, _("MAYHEM! "), _("%s^K1 executed MAYHEM! %s^BG"), _("%s^K1 made FIFTEEN SCORES IN A ROW! %s^BG")) \ + SPREE_ITEM(20, 20, _("BERSERKER! "), _("%s^K1 is a BERSERKER! %s^BG"), _("%s^K1 made TWENTY SCORES IN A ROW! %s^BG")) \ + SPREE_ITEM(25, 25, _("CARNAGE! "), _("%s^K1 inflicts CARNAGE! %s^BG"), _("%s^K1 made TWENTY FIVE SCORES IN A ROW! %s^BG")) \ + SPREE_ITEM(30, 30, _("ARMAGEDDON! "), _("%s^K1 unleashes ARMAGEDDON! %s^BG"), _("%s^K1 made THIRTY SCORES IN A ROW! %s^BG")) + +#ifdef CSQC +string notif_arg_frag_ping(bool newline, float fping) +{ + string s = newline ? "\n" : " "; + if (fping < 0) + return sprintf(CCR(_("%s(^F1Bot^BG)")), s); + else + return sprintf(CCR(_("%s(Ping ^F1%d^BG)")), s, fping); +} + +string notif_arg_frag_stats(float fhealth, float farmor, float fping) +{ + string s = notif_arg_frag_ping(false, fping); + if (fhealth > 1) + return sprintf(CCR(_("\n(Health ^1%d^BG / Armor ^2%d^BG)%s")), fhealth, farmor, s); + else + return sprintf(CCR(_("\n(^F4Dead^BG)%s")), s); +} + +string notif_arg_missing_teams(float f1) +{ + return sprintf("%s%s%s%s", + ((f1 & BIT(0)) ? sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_1), (f1 & (BIT(1) | BIT(2) | BIT(3)) ? ", " : "")) : ""), + ((f1 & BIT(1)) ? sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_2), (f1 & ( BIT(2) | BIT(3)) ? ", " : "")) : ""), + ((f1 & BIT(2)) ? sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_3), (f1 & ( BIT(3)) ? ", " : "")) : ""), + ((f1 & BIT(3)) ? Team_ColoredFullName(NUM_TEAM_4) : "") + ); +} + +string notif_arg_spree_cen(float spree) +{ + // 0 = off, 1 = target (but only for first victim) and attacker + if(autocvar_notification_show_sprees_center) + { + if(spree > 1) + { + #define SPREE_ITEM(counta,countb,center,normal,gentle) \ + case counta: { return normal_or_gentle(center, sprintf(_("%d score spree! "), spree)); } + + switch(spree) + { + KILL_SPREE_LIST + default: + { + if (!autocvar_notification_show_sprees_center_specialonly) + { + return + sprintf( + normal_or_gentle( + _("%d frag spree! "), + _("%d score spree! ") + ), + spree); + } + else { return ""; } // don't show spree information if it isn't an achievement + } + } + + #undef SPREE_ITEM + } + else if(spree == -1) // first blood + { + return normal_or_gentle(_("First blood! "), _("First score! ")); + } + else if(spree == -2) // first victim + { + return normal_or_gentle(_("First victim! "), _("First casualty! ")); + } + } + return ""; +} +#endif + +string notif_arg_spree_inf(float type, string input, string player, float spree) +{ + switch(type) + { + case 1: // attacker kill spree + { + // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker + // this conditional (& 2) is true for 2 and 3 + if(autocvar_notification_show_sprees_info & 2) + { + #ifdef CSQC + string spree_newline = + ( autocvar_notification_show_sprees_info_newline ? + ((substring(input, 0, 1) == "\{3}") ? "\n\{3}" : "\n") : "" ); + #else + string spree_newline = + (autocvar_notification_show_sprees_info_newline ? "\n" : ""); + #endif + + if(spree > 1) + { + #define SPREE_ITEM(counta,countb,center,normal,gentle) \ + case counta: { return sprintf(CCR(normal_or_gentle(normal, gentle)), player, spree_newline); } + + switch(spree) + { + KILL_SPREE_LIST + default: + { + if (!autocvar_notification_show_sprees_info_specialonly) + { + return + sprintf( + CCR(normal_or_gentle( + _("%s^K1 has %d frags in a row! %s^BG"), + _("%s^K1 made %d scores in a row! %s^BG") + )), + player, + spree, + spree_newline + ); + } + else { return ""; } // don't show spree information if it isn't an achievement + } + } + + #undef SPREE_ITEM + } + else if(spree == -1) // firstblood + { + return + sprintf( + CCR(normal_or_gentle( + _("%s^K1 drew first blood! %s^BG"), + _("%s^K1 got the first score! %s^BG") + )), + player, + spree_newline + ); + } + } + break; + } + + case -1: // kill spree ended + { + if((spree > 1) && (autocvar_notification_show_sprees_info & 1)) + { + return + sprintf(normal_or_gentle( + _(", ending their %d frag spree"), + _(", ending their %d score spree") + ), + spree + ); + } + break; + } + + case -2: // kill spree lost + { + if((spree > 1) && (autocvar_notification_show_sprees_info & 1)) + { + return + sprintf(normal_or_gentle( + _(", losing their %d frag spree"), + _(", losing their %d score spree") + ), + spree + ); + } + break; + } + } + return ""; +} + + +// ==================================== +// Initialization/Create Declarations +// ==================================== + +// common notification entity values +.int nent_default; +.bool nent_enabled; +.MSG nent_type; +.string nent_name; +.int nent_stringcount; +.int nent_floatcount; + +// MSG_ANNCE entity values +.int nent_channel; +.string nent_snd; +.float nent_vol; +.float nent_position; + +// MSG_INFO and MSG_CENTER entity values +.string nent_args; // used by both +.string nent_hudargs; // used by info +.string nent_icon; // used by info +.CPID nent_cpid; // used by center +.string nent_durcnt; // used by center +.string nent_string; // used by both + +// MSG_MULTI entity values +.entity nent_msgannce; +.entity nent_msginfo; +.entity nent_msgcenter; + +// MSG_CHOICE entity values +.float nent_challow_def; +.float nent_challow_var; +.entity nent_optiona; +.entity nent_optionb; + +// networked notification entity values +#ifdef SVQC +.NOTIF nent_broadcast; +#endif +.entity nent_client; +.MSG nent_net_type; +.float nent_net_name; +.string nent_strings[4]; +.float nent_floats[4]; + +#define ACVNN(name) autocvar_notification_##name + +REGISTRY(Notifications, BITS(11)) +REGISTER_REGISTRY(Notifications) +REGISTRY_SORT(Notifications); STATIC_INIT(Notifications) { FOREACH(Notifications, true, LAMBDA(it.m_id = i)); } +REGISTRY_CHECK(Notifications) + +const int NOTIF_CHOICE_MAX = 50; +int nent_choice_count = 0; +.int nent_choice_idx; +.int msg_choice_choices[NOTIF_CHOICE_MAX]; // set on each player containing MSG_CHOICE choices +// initialization error detection +bool notif_error; +bool notif_global_error; + +STATIC_INIT_LATE(Notif_Choices) { + int c = 0; + FOREACH(Notifications, it.nent_type == MSG_CHOICE, { c++; }); + if (c > NOTIF_CHOICE_MAX) { + LOG_FATALF("Too many MSG_CHOICE notifications (%d)", c); + } +} + +Notification Get_Notif_Ent(MSG net_type, int net_name) +{ + Notification it = _Notifications_from(net_name, NULL); + if (it.nent_type != net_type) { + LOG_WARNINGF("Get_Notif_Ent(%s (%d), %s (%d)): Improper net type '%s'!\n", + Get_Notif_TypeName(net_type), net_type, + it.registered_id, net_name, + Get_Notif_TypeName(it.nent_type) + ); + return NULL; + } + return it; +} + +#define MSG_ANNCE_NOTIF(name, default, sound, channel, volume, position) \ + MSG_ANNCE_NOTIF_(ANNCE_##name, default, sound, channel, volume, position) +#define MSG_ANNCE_NOTIF_(name, default, sound, channel, volume, position) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + REGISTER(Notifications, name, m_id, new_pure(msg_annce_notification)) { \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_ANNCE, strtoupper(#name)); \ + Create_Notification_Entity_Annce(this, ACVNN(name), strtoupper(#name), \ + channel, /* channel */ \ + sound, /* snd */ \ + volume, /* vol */ \ + position); /* position */ \ + } + +#define MSG_INFO_NOTIF(name, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MSG_INFO_NOTIF_(INFO_##name, default, strnum, flnum, args, hudargs, icon, normal, gentle) +#define MSG_INFO_NOTIF_(name, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) { \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_INFO, strtoupper(#name)); \ + Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \ + args, /* args */ \ + hudargs, /* hudargs */ \ + icon, /* icon */ \ + CPID_Null,/* cpid */ \ + "", /* durcnt */ \ + normal, /* normal */ \ + gentle); /* gentle */ \ + } + +.string nent_iconargs; +#define MULTIICON_INFO(name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \ + MULTIICON_INFO_(INFO_##name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) +#define MULTIICON_INFO_(name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) { \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_INFO, strtoupper(#name)); \ + Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \ + args, /* args */ \ + hudargs, /* hudargs */ \ + icon, /* icon */ \ + CPID_Null,/* cpid */ \ + "", /* durcnt */ \ + normal, /* normal */ \ + gentle); /* gentle */ \ + this.nent_iconargs = iconargs; \ + } + +#define MSG_CENTER_NOTIF(name, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MSG_CENTER_NOTIF_(CENTER_##name, default, strnum, flnum, args, cpid, durcnt, normal, gentle) +#define MSG_CENTER_NOTIF_(name, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + REGISTER(Notifications, name, m_id, new_pure(msg_center_notification)) { \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_CENTER, strtoupper(#name)); \ + Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \ + args, /* args */ \ + "", /* hudargs */ \ + "", /* icon */ \ + cpid, /* cpid */ \ + durcnt, /* durcnt */ \ + normal, /* normal */ \ + gentle); /* gentle */ \ + } + +#define MSG_MULTI_NOTIF(name, default, anncename, infoname, centername) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + REGISTER(Notifications, name, m_id, new_pure(msg_multi_notification)) { \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_MULTI, strtoupper(#name)); \ + Create_Notification_Entity_Multi(this, ACVNN(name), strtoupper(#name), \ + anncename, /* anncename */ \ + infoname, /* infoname */ \ + centername); /* centername */ \ + } + +#define MSG_CHOICE_NOTIF(name, default, challow, chtype, optiona, optionb) \ + MSG_CHOICE_NOTIF_(CHOICE_##name, default, challow, chtype, optiona, optionb) +#define MSG_CHOICE_NOTIF_(name, default, challow, chtype, optiona, optionb) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + NOTIF_ADD_AUTOCVAR(name##_ALLOWED, challow) \ + REGISTER(Notifications, name, m_id, new_pure(msg_choice_notification)) { \ + this.nent_choice_idx = nent_choice_count++; \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_CHOICE, strtoupper(#name)); \ + Create_Notification_Entity_Choice(this, ACVNN(name), strtoupper(#name), \ + challow, /* challow_def */ \ + autocvar_notification_##name##_ALLOWED, /* challow_var */ \ + chtype, /* chtype */ \ + optiona, /* optiona */ \ + optionb); /* optionb */ \ + } + +REGISTRY_BEGIN(Notifications) +{ + notif_global_error = false; +} + +REGISTRY_END(Notifications) +{ + if (!notif_global_error) return; + // shit happened... stop the loading of the program now if this is unacceptable + if (autocvar_notification_errors_are_fatal) + LOG_FATAL("Notification initialization failed! Read above and fix the errors!"); + else + LOG_SEVERE("Notification initialization failed! Read above and fix the errors!"); +} + +#include "all.inc" + +#endif diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc index 9c8c42115..534a22a21 100644 --- a/qcsrc/common/t_items.qc +++ b/qcsrc/common/t_items.qc @@ -15,7 +15,7 @@ #include "constants.qh" #include - #include + #include #include "triggers/subs.qh" #include "util.qh" diff --git a/qcsrc/common/util.qc b/qcsrc/common/util.qc index 7bafe2bc1..03ab8f6d5 100644 --- a/qcsrc/common/util.qc +++ b/qcsrc/common/util.qc @@ -5,7 +5,7 @@ #include "constants.qh" #include "../client/mutators/events.qh" #include "mapinfo.qh" - #include "notifications.qh" + #include "notifications/all.qh" #include #elif defined(MENUQC) #elif defined(SVQC) @@ -13,7 +13,7 @@ #include "../server/autocvars.qh" #include "../server/defs.qh" #include "../server/mutators/events.qh" - #include "notifications.qh" + #include "notifications/all.qh" #include #include "mapinfo.qh" #endif diff --git a/qcsrc/common/weapons/all.qc b/qcsrc/common/weapons/all.qc index 6232db886..c1a7e3023 100644 --- a/qcsrc/common/weapons/all.qc +++ b/qcsrc/common/weapons/all.qc @@ -35,7 +35,7 @@ #include #include #include - #include "../notifications.qh" + #include "../notifications/all.qh" #include "../deathtypes/all.qh" #include #include "../mapinfo.qh" diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc index 95f0556b3..9246f7aa1 100644 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/qcsrc/server/command/common.qc b/qcsrc/server/command/common.qc index 4c155d07d..d2a8f6ec9 100644 --- a/qcsrc/server/command/common.qc +++ b/qcsrc/server/command/common.qc @@ -4,7 +4,7 @@ #include "../scores.qh" #include -#include +#include #include diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc index 33e9273bb..369b3eaa9 100644 --- a/qcsrc/server/command/sv_cmd.qc +++ b/qcsrc/server/command/sv_cmd.qc @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include diff --git a/qcsrc/server/command/vote.qc b/qcsrc/server/command/vote.qc index 223bbeb09..c4303f479 100644 --- a/qcsrc/server/command/vote.qc +++ b/qcsrc/server/command/vote.qc @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 8a274a9a2..9258b3e82 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -14,7 +14,7 @@ #include "weapons/selection.qh" #include "../common/constants.qh" #include "../common/deathtypes/all.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/physics/movetypes/movetypes.qh" #include "../common/playerstats.qh" #include "../common/teams.qh" diff --git a/qcsrc/server/g_damage.qh b/qcsrc/server/g_damage.qh index 1f4f3b5d2..6a8ca99b4 100644 --- a/qcsrc/server/g_damage.qh +++ b/qcsrc/server/g_damage.qh @@ -16,7 +16,7 @@ #include "autocvars.qh" #include "constants.qh" #include "defs.qh" - #include "../common/notifications.qh" + #include "../common/notifications/all.qh" #include "../common/deathtypes/all.qh" #include "mutators/all.qh" #include "../common/turrets/sv_turrets.qh" diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index c1f0e48ac..416a1584c 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -24,7 +24,7 @@ #include "../common/monsters/all.qh" #include "../common/monsters/sv_monsters.qh" #include "../common/vehicles/all.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/physics/player.qh" #include "../common/playerstats.qh" #include "../common/stats.qh" diff --git a/qcsrc/server/item_key.qc b/qcsrc/server/item_key.qc index d1e1f32e4..0230a21cb 100644 --- a/qcsrc/server/item_key.qc +++ b/qcsrc/server/item_key.qc @@ -2,7 +2,7 @@ #include "../common/triggers/subs.qh" #include "../common/monsters/all.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/util.qh" #include "../lib/warpzone/util_server.qh" diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 2a3ef8734..74fa6399f 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -13,7 +13,7 @@ #include "../common/constants.qh" #include "../common/deathtypes/all.qh" #include "../common/mapinfo.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/playerstats.qh" #include "../common/teams.qh" #include "../common/triggers/subs.qh" diff --git a/qcsrc/server/mutators/all.qc b/qcsrc/server/mutators/all.qc index 5c6906b7c..2cca71c7c 100644 --- a/qcsrc/server/mutators/all.qc +++ b/qcsrc/server/mutators/all.qc @@ -34,7 +34,7 @@ #include "../autocvars.qh" #include "../constants.qh" #include "../defs.qh" - #include + #include #include #include "all.qh" #include diff --git a/qcsrc/server/mutators/gamemode.qh b/qcsrc/server/mutators/gamemode.qh index 5c17e9a17..b83704650 100644 --- a/qcsrc/server/mutators/gamemode.qh +++ b/qcsrc/server/mutators/gamemode.qh @@ -28,7 +28,7 @@ #include "../weapons/weaponsystem.qh" #include -#include +#include #include #include #include diff --git a/qcsrc/server/mutators/mutator.qh b/qcsrc/server/mutators/mutator.qh index c29e10eb8..485bce298 100644 --- a/qcsrc/server/mutators/mutator.qh +++ b/qcsrc/server/mutators/mutator.qh @@ -28,7 +28,7 @@ #include "../weapons/weaponsystem.qh" #include -#include +#include #include #include #include diff --git a/qcsrc/server/portals.qc b/qcsrc/server/portals.qc index 361abcd11..e3cba9383 100644 --- a/qcsrc/server/portals.qc +++ b/qcsrc/server/portals.qc @@ -4,7 +4,7 @@ #include "mutators/all.qh" #include "../common/constants.qh" #include "../common/deathtypes/all.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/triggers/teleporters.qh" #include "../common/triggers/subs.qh" #include "../common/util.qh" diff --git a/qcsrc/server/race.qc b/qcsrc/server/race.qc index 0cac389aa..dd3a11cc0 100644 --- a/qcsrc/server/race.qc +++ b/qcsrc/server/race.qc @@ -8,7 +8,7 @@ #include "bot/navigation.qh" #include "command/getreplies.qh" #include "../common/deathtypes/all.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/mapinfo.qh" #include "../common/triggers/subs.qh" #include "../lib/warpzone/util_server.qh" diff --git a/qcsrc/server/weapons/common.qc b/qcsrc/server/weapons/common.qc index c4a0daba4..85e8820f3 100644 --- a/qcsrc/server/weapons/common.qc +++ b/qcsrc/server/weapons/common.qc @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/qcsrc/server/weapons/throwing.qc b/qcsrc/server/weapons/throwing.qc index 14da0f14e..7ffc68105 100644 --- a/qcsrc/server/weapons/throwing.qc +++ b/qcsrc/server/weapons/throwing.qc @@ -6,7 +6,7 @@ #include "../g_damage.qh" #include #include -#include +#include #include #include #include diff --git a/qcsrc/server/weapons/weaponsystem.qc b/qcsrc/server/weapons/weaponsystem.qc index 1637d8676..62d54973c 100644 --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include