1 // ================================================
2 // Unified notification system, written by Samual
3 // Last updated: September, 2012
4 // ================================================
6 // main types/groups of notifications
7 #define MSG_INFO 1 // "Global" information messages (sent to console, and notify panel if it has an icon)
8 #define MSG_CENTER 2 // "Personal" centerprint messages
9 #define MSG_WEAPON 3 // "Personal" weapon messages (like "You got the Nex", sent to weapon notify panel)
12 #define NO_FL_ARG -12345
18 // allow sending of notifications to also pass through to spectators (specifically for centerprints)
20 #define WRITESPECTATABLE_MSG_ONE_VARNAME(varname,statement) entity varname; varname = msg_entity; FOR_EACH_REALCLIENT(msg_entity) if(msg_entity == varname || (msg_entity.classname == STR_SPECTATOR && msg_entity.enemy == varname)) statement msg_entity = varname
21 #define WRITESPECTATABLE_MSG_ONE(statement) WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement)
22 #define WRITESPECTATABLE(msg,statement) if(msg == MSG_ONE) { WRITESPECTATABLE_MSG_ONE(statement); } else statement float WRITESPECTATABLE_workaround = 0
25 #define NOTIF_MATCH(a,b) if(min(NOTIF_MAX, a) == b)
27 string got_commandkey;
28 #define ADD_CSQC_AUTOCVAR(name) var float autocvar_notification_##name = TRUE;
29 var float autocvar_notification_ctf_capture_verbose = TRUE;
30 var float autocvar_notification_ctf_pickup_team_verbose = TRUE;
31 var float autocvar_notification_ctf_pickup_enemy_verbose = TRUE;
32 #define CHECK_AUTOCVAR(name) if(autocvar_notification_##name)
33 #define HANDLE_CPID(cpid) ((min(NOTIF_MAX, cpid) == NO_CPID) ? FALSE : cpid)
34 #define PASS_KEY ((((got_commandkey = getcommandkey("pass", "+use")) != "pass") && !(strstrofs(got_commandkey, "not bound", 0) >= 0)) ? sprintf(CCR(_(" ^F1(Press %s)")), got_commandkey) : "")
36 #define ADD_CSQC_AUTOCVAR(name)
40 // ====================================
41 // Notifications List and Information
42 // ====================================
44 List of all notifications (including identifiers and display information)
45 Format: name, strnum, flnum, args, *icon/CPID, *durcnt, normal, gentle
46 Asterisked fields are not present in all notification types.
49 Number of STRING arguments (so that networking knows how many to send/receive)
50 Number of FLOAT arguments (so that networking knows how many to send/receive)
51 Arguments for sprintf(string, args), if no args needed then use ""
53 MSG_INFO: STRING: icon string name for the hud notify panel, "" if no icon is used
54 MSG_CENTER: FLOAT: centerprint ID number (CPID_*), NO_CPID if no CPID is needed
56 MSG_CENTER: XPND2(FLOAT, FLOAT): extra arguments for centerprint messages
57 Normal message (string for sprintf when gentle messages are NOT enabled)
58 Gentle message (string for sprintf when gentle messages ARE enabled)
60 Messages have ^F1, ^F2, and ^BG in them-- these are replaced
61 with colors according to the cvars the user has chosen.
62 ^F1 = highest priority, "primary"
63 ^F2 = next highest priority, "secondary"
64 ^BG = normal/less important priority, "tertiary"
66 Guidlines (please try and follow these):
67 -ALWAYS start the string with a color, preferably background.
68 -ALWAYS reset a color after a name (this way they don't set it for the whole string).
69 -NEVER re-declare an event twice.
70 -NEVER add or remove fields from the format, it SHOULD already work.
71 -MSG_INFO messages must ALWAYS end with a new line: \n
72 -Be clean and simple with your notification naming,
73 nothing too long for the name field... Abbreviations are your friend. :D
74 -Keep the spacing as clean as possible... if the arguments are abnormally long,
75 it's okay to go out of line a bit... but try and keep it clean still.
76 -Keep the notifications in alphabetical order.
77 ARIRE unir frk jvgu lbhe bja zbgure. (gvc sbe zvxrrhfn) -- Don't pay attention to this ^_^
80 // flag.netname = ((teamnumber) ? "^1RED^7 flag" : "^4BLUE^7 flag");
81 // weaponorder[f1].netname
82 #define MSG_INFO_NOTIFICATIONS \
83 MSG_INFO_NOTIF(INFO_EMPTY, 0, 0, NO_STR_ARG, "", "", "") \
84 MSG_INFO_NOTIF(INFO_CTF_FLAGRETURN_DROPPED_RED, 0, 0, NO_STR_ARG, "", _("^BGThe ^1RED^BG flag was dropped in the base and returned itself\n"), "") \
85 MSG_INFO_NOTIF(INFO_CTF_FLAGRETURN_DROPPED_BLUE, 0, 0, NO_STR_ARG, "", _("^BGThe ^5BLUE^BG flag was dropped in the base and returned itself\n"), "") \
86 MSG_INFO_NOTIF(INFO_CTF_FLAGRETURN_DAMAGED_RED, 0, 0, NO_STR_ARG, "", _("^BGThe ^1RED^BG flag was destroyed and returned to base\n"), "") \
87 MSG_INFO_NOTIF(INFO_CTF_FLAGRETURN_DAMAGED_BLUE, 0, 0, NO_STR_ARG, "", _("^BGThe ^5BLUE^BG flag was destroyed and returned to base\n"), "") \
88 MSG_INFO_NOTIF(INFO_CTF_FLAGRETURN_SPEEDRUN_RED, 0, 1, f1/100, "", _("^BGThe ^1RED^BG flag became impatient after ^F1%.2f^BG seconds and returned itself\n"), "") \
89 MSG_INFO_NOTIF(INFO_CTF_FLAGRETURN_SPEEDRUN_BLUE, 0, 1, f1/100, "", _("^BGThe ^5BLUE^BG flag became impatient after ^F1%.2f^BG seconds and returned itself\n"), "") \
90 MSG_INFO_NOTIF(INFO_CTF_FLAGRETURN_NEEDKILL_RED, 0, 0, NO_STR_ARG, "", _("^BGThe ^1RED^BG flag fell somewhere it couldn't be reached and returned to base\n"), "") \
91 MSG_INFO_NOTIF(INFO_CTF_FLAGRETURN_NEEDKILL_BLUE, 0, 0, NO_STR_ARG, "", _("^BGThe ^5BLUE^BG flag fell somewhere it couldn't be reached and returned to base\n"), "") \
92 MSG_INFO_NOTIF(INFO_CTF_FLAGRETURN_ABORTRUN_RED, 0, 0, NO_STR_ARG, "", _("^BGThe ^1RED^BG flag was returned to base by its owner\n"), "") \
93 MSG_INFO_NOTIF(INFO_CTF_FLAGRETURN_ABORTRUN_BLUE, 0, 0, NO_STR_ARG, "", _("^BGThe ^5BLUE^BG flag was returned to base by its owner\n"), "") \
94 MSG_INFO_NOTIF(INFO_CTF_PICKUP_RED, 1, 0, s1, "notify_red_taken", _("^BG%s^BG got the ^1RED^BG flag\n"), "") \
95 MSG_INFO_NOTIF(INFO_CTF_PICKUP_BLUE, 1, 0, s1, "notify_blue_taken", _("^BG%s^BG got the ^5BLUE^BG flag\n"), "") \
96 MSG_INFO_NOTIF(INFO_CTF_RETURN_RED, 1, 0, s1, "notify_red_returned", _("^BG%s^BG returned the ^1RED^BG flag\n"), "") \
97 MSG_INFO_NOTIF(INFO_CTF_RETURN_BLUE, 1, 0, s1, "notify_blue_returned", _("^BG%s^BG returned the ^5BLUE^BG flag\n"), "") \
98 MSG_INFO_NOTIF(INFO_CTF_LOST_RED, 1, 0, s1, "notify_red_lost", _("^BG%s^BG lost the ^1RED^BG flag\n"), "") \
99 MSG_INFO_NOTIF(INFO_CTF_LOST_BLUE, 1, 0, s1, "notify_blue_lost", _("^BG%s^BG lost the ^5BLUE^BG flag\n"), "") \
100 MSG_INFO_NOTIF(INFO_CTF_CAPTURE_RED, 1, 0, s1, "notify_red_capture", _("^BG%s^BG captured the ^1RED^BG flag\n"), "") \
101 MSG_INFO_NOTIF(INFO_CTF_CAPTURE_BLUE, 1, 0, s1, "notify_blue_capture", _("^BG%s^BG captured the ^5BLUE^BG flag\n"), "") \
102 MSG_INFO_NOTIF(INFO_CTF_CAPTURE_TIME_RED, 1, 1, XPND2(s1, f1/100), "notify_red_capture", _("^BG%s^BG captured the ^1RED^BG flag in ^F1%.2f^BG seconds\n"), "") \
103 MSG_INFO_NOTIF(INFO_CTF_CAPTURE_TIME_BLUE, 1, 1, XPND2(s1, f1/100), "notify_blue_capture", _("^BG%s^BG captured the ^5BLUE^BG flag in ^F1%.2f^BG seconds\n"), "") \
104 MSG_INFO_NOTIF(INFO_CTF_CAPTURE_BROKEN_RED, 2, 2, XPND4(s1, f1/100, s2, f2/100), "notify_red_capture", _("^BG%s^BG captured the ^1RED^BG flag in ^F1%.2f^BG seconds, breaking ^BG%s^BG's previous record of ^F2%.2f^BG seconds\n"), "") \
105 MSG_INFO_NOTIF(INFO_CTF_CAPTURE_BROKEN_BLUE, 2, 2, XPND4(s1, f1/100, s2, f2/100), "notify_blue_capture", _("^BG%s^BG captured the ^5BLUE^BG flag in ^F1%.2f^BG seconds, breaking ^BG%s^BG's previous record of ^F2%.2f^BG seconds\n"), "") \
106 MSG_INFO_NOTIF(INFO_CTF_CAPTURE_UNBROKEN_RED, 2, 2, XPND4(s1, f1/100, s2, f2/100), "notify_red_capture", _("^BG%s^BG captured the ^1RED^BG flag in ^F2%.2f^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%.2f^BG seconds\n"), "") \
107 MSG_INFO_NOTIF(INFO_CTF_CAPTURE_UNBROKEN_BLUE, 2, 2, XPND4(s1, f1/100, s2, f2/100), "notify_blue_capture", _("^BG%s^BG captured the ^5BLUE^BG flag in ^F2%.2f^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%.2f^BG seconds\n"), "") \
108 #undef MSG_INFO_NOTIF
110 #define MSG_CENTER_NOTIFICATIONS \
111 MSG_CENTER_NOTIF(CENTER_EMPTY, 0, 0, NO_STR_ARG, NO_CPID, XPND2(0, 0), "", "") \
112 MSG_CENTER_NOTIF(CENTER_CTF_CAPTURESHIELD_SHIELDED, 0, 0, NO_STR_ARG, CPID_CTF_CAPTURESHIELD, XPND2(0, 0), _("^BGYou are now ^F1shielded^BG from the flag\n^BGfor ^F2too many unsuccessful attempts^BG to capture.\n^BGMake some defensive scores before trying again."), "") \
113 MSG_CENTER_NOTIF(CENTER_CTF_CAPTURESHIELD_FREE, 0, 0, NO_STR_ARG, CPID_CTF_CAPTURESHIELD, XPND2(0, 0), _("^BGYou are now free.\n^BGFeel free to ^F2try to capture^BG the flag again\n^BGif you think you will succeed."), "") \
114 MSG_CENTER_NOTIF(CENTER_CTF_PASS_OTHER_RED, 2, 0, XPND2(s1, s2), CPID_CTF_PASS, XPND2(0, 0), _("^BG%s^BG passed the ^1RED^BG flag to %s"), "") \
115 MSG_CENTER_NOTIF(CENTER_CTF_PASS_OTHER_BLUE, 2, 0, XPND2(s1, s2), CPID_CTF_PASS, XPND2(0, 0), _("^BG%s^BG passed the ^4BLUE^BG flag to %s"), "") \
116 MSG_CENTER_NOTIF(CENTER_CTF_PASS_SENT_RED, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGYou passed the ^1RED^BG flag to %s"), "") \
117 MSG_CENTER_NOTIF(CENTER_CTF_PASS_SENT_BLUE, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGYou passed the ^4BLUE^BG flag to %s"), "") \
118 MSG_CENTER_NOTIF(CENTER_CTF_PASS_RECEIVED_RED, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGYou received the ^1RED^BG flag from %s"), "") \
119 MSG_CENTER_NOTIF(CENTER_CTF_PASS_RECEIVED_BLUE, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGYou received the ^4BLUE^BG flag from %s"), "") \
120 MSG_CENTER_NOTIF(CENTER_CTF_PASS_REQUESTING, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGRequesting %s^BG to pass you the flag"), "") \
121 MSG_CENTER_NOTIF(CENTER_CTF_PASS_REQUESTED, 1, 0, XPND2(s1, PASS_KEY), CPID_CTF_PASS, XPND2(0, 0), _("^BG%s^BG requests you to pass the flag%s"), "") \
122 MSG_CENTER_NOTIF(CENTER_CTF_RETURN_RED, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou returned the ^1RED^BG flag"), "") \
123 MSG_CENTER_NOTIF(CENTER_CTF_RETURN_BLUE, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou returned the ^4BLUE^BG flag"), "") \
124 MSG_CENTER_NOTIF(CENTER_CTF_CAPTURE_RED, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou captured the ^1RED^BG flag"), "") \
125 MSG_CENTER_NOTIF(CENTER_CTF_CAPTURE_BLUE, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou captured the ^4BLUE^BG flag"), "") \
126 MSG_CENTER_NOTIF(CENTER_CTF_PICKUP_RED, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou got the ^1RED^BG flag!"), "") \
127 MSG_CENTER_NOTIF(CENTER_CTF_PICKUP_BLUE, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou got the ^4BLUE^BG flag!"), "") \
128 MSG_CENTER_NOTIF(CENTER_CTF_PICKUP_TEAM, 1, 0, s1, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYour %steam mate^BG got the flag! Protect them!"), "") \
129 MSG_CENTER_NOTIF(CENTER_CTF_PICKUP_TEAM_VERBOSE, 2, 0, XPND3(s1, s2, s1), CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "") \
130 MSG_CENTER_NOTIF(CENTER_CTF_PICKUP_ENEMY, 1, 0, s1, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") \
131 MSG_CENTER_NOTIF(CENTER_CTF_PICKUP_ENEMY_VERBOSE, 2, 0, XPND3(s1, s2, s1), CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"), "") \
132 MSG_CENTER_NOTIF(CENTER_CTF_STALEMATE_CARRIER, 0, 0, NO_STR_ARG, CPID_STALEMATE, XPND2(0, 0), _("^BGStalemate! Enemies can now see you on radar!"), "") \
133 MSG_CENTER_NOTIF(CENTER_CTF_STALEMATE_OTHER, 0, 0, NO_STR_ARG, CPID_STALEMATE, XPND2(0, 0), _("^BGStalemate! Flag carriers can now be seen by enemies on radar!"), "") \
134 MSG_CENTER_NOTIF(CENTER_CTF_FLAG_THROW_PUNISH, 0, 1, f1, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGToo many flag throws! Throwing disabled for %d seconds."), "") \
135 #undef MSG_CENTER_NOTIF
137 #define MSG_WEAPON_NOTIFICATIONS \
138 MSG_WEAPON_NOTIF(DEATH_MARBLES_LOST3, 2, 1, XPND3(s1, s2, f1), _("^F1%s^BG lost their marbles against ^F1%s^BG using the ^F2%s^BG\n"), "") \
139 #undef MSG_WEAPON_NOTIF
142 // ====================================
143 // Initialization/Create Declarations
144 // ====================================
146 #define NOTIF_FIRST 1
147 #define NOTIF_MAX 1024 // limit of recursive functions with ACCUMULATE_FUNCTION
148 float NOTIF_INFO_COUNT;
149 float NOTIF_CENTER_COUNT;
150 float NOTIF_WEAPON_COUNT;
151 float NOTIF_CPID_COUNT;
153 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
154 ADD_CSQC_AUTOCVAR(name) \
156 void RegisterNotification_##name() \
158 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \
159 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_INFO_COUNT, "notifications") \
161 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
163 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
164 ADD_CSQC_AUTOCVAR(name) \
167 void RegisterNotification_##name() \
169 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CENTER_COUNT) \
170 SET_FIELD_COUNT(cpid, NOTIF_FIRST, NOTIF_CPID_COUNT) \
171 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_CENTER_COUNT, "notifications") \
173 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
175 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
176 ADD_CSQC_AUTOCVAR(name) \
178 void RegisterNotification_##name() \
180 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_WEAPON_COUNT) \
181 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_WEAPON_COUNT, "notifications") \
183 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
185 // NOW we actually activate the declarations
186 MSG_INFO_NOTIFICATIONS
187 MSG_CENTER_NOTIFICATIONS
188 MSG_WEAPON_NOTIFICATIONS
191 // ======================
192 // Supporting Functions
193 // ======================
195 // select between the normal or the gentle message string based on client (or server) settings
196 string normal_or_gentle(string normal, string gentle)
199 if(autocvar_cl_gentle || autocvar_cl_gentle_messages)
201 if(autocvar_sv_gentle)
203 return ((gentle != "") ? gentle : normal);
208 float notif_stringcount(string s1, string s2)
211 if(s1 != NO_STR_ARG) ++stringcount;
212 if(s2 != NO_STR_ARG) ++stringcount;
216 float notif_floatcount(float f1, float f2, float f3)
219 if(f1 != NO_FL_ARG) ++floatcount;
220 if(f2 != NO_FL_ARG) ++floatcount;
221 if(f3 != NO_FL_ARG) ++floatcount;
225 // get the actual name of a notification and return it as a string
226 string Get_Field_Value(float field, float net_type, float net_name)
230 #define GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) \
231 if(field == F_NAME) { output = VAR_TO_TEXT(name); } \
232 else if(field == F_STRNUM) { output = ftos(strnum); } \
233 else if(field == F_FLNUM) { output = ftos(flnum); }
239 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
240 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
241 MSG_INFO_NOTIFICATIONS
246 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
247 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
248 MSG_CENTER_NOTIFICATIONS
253 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
254 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
255 MSG_WEAPON_NOTIFICATIONS
260 #undef GET_FIELD_VALUE_OUTPUT
264 // color code replace, place inside of sprintf and parse the string
265 string CCR(string input)
267 input = strreplace("^F1", "^2", input); // autocvar_notification_colors_F1
268 input = strreplace("^F2", "^3", input); // autocvar_notification_colors_F2
269 input = strreplace("^K1", "^1", input); // autocvar_notification_colors_K1
270 input = strreplace("^K2", "^3", input); // autocvar_notification_colors_K2
271 input = strreplace("^BG", "^7", input); // autocvar_notification_colors_BG
273 input = strreplace("^N", "^7", input); // "none"-- reset to white
279 // ===============================
280 // Frontend Notification Pushing
281 // ===============================
284 void Local_Notification(float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
290 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
291 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { print(sprintf(CCR(normal_or_gentle(normal, gentle)), args)); } }
292 MSG_INFO_NOTIFICATIONS
297 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
298 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { centerprint_generic(HANDLE_CPID(cpid), sprintf(CCR(normal_or_gentle(normal, gentle)), args), durcnt); } }
299 MSG_CENTER_NOTIFICATIONS
304 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
305 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { print("unhandled\n"); } }
306 MSG_WEAPON_NOTIFICATIONS
314 // =========================
315 // Notification Networking
316 // =========================
319 void Read_Notification(void)
321 float net_type = ReadByte();
322 float net_name = ReadShort();
324 float stringcount = stof(Get_Field_Value(F_STRNUM, net_type, net_name));
325 float floatcount = stof(Get_Field_Value(F_FLNUM, net_type, net_name));
327 Local_Notification(net_type, net_name,
328 ((stringcount >= 1) ? ReadString() : ""),
329 ((stringcount == 2) ? ReadString() : ""),
330 ((floatcount >= 1) ? ReadLong() : 0),
331 ((floatcount >= 2) ? ReadLong() : 0),
332 ((floatcount == 3) ? ReadLong() : 0));
337 void Send_Notification(entity client, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
339 if(net_type && net_name)
341 print("notification: ", Get_Field_Value(F_NAME, net_type, net_name), ": ", ftos(net_name), ".\n");
343 float stringcount = stof(Get_Field_Value(F_STRNUM, net_type, net_name));
344 float floatcount = stof(Get_Field_Value(F_FLNUM, net_type, net_name));
346 if(notif_stringcount(s1, s2) > stringcount) { backtrace("Too many string arguments for notification!\n"); return; }
347 if(notif_floatcount(f1, f2, f3) > floatcount) { backtrace("Too many float arguments for notification!\n"); return; }
349 if(client && (clienttype(client) == CLIENTTYPE_REAL) && (client.flags & FL_CLIENT))
351 // personal/direct notification sent to ONE person and their spectators
353 WRITESPECTATABLE_MSG_ONE({
354 WriteByte(MSG_ONE, SVC_TEMPENTITY);
355 WriteByte(MSG_ONE, TE_CSQC_NOTIFICATION);
356 WriteByte(MSG_ONE, net_type);
357 WriteShort(MSG_ONE, net_name);
358 if(stringcount >= 1) { WriteString(MSG_ONE, s1); }
359 if(stringcount == 2) { WriteString(MSG_ONE, s2); }
360 if(floatcount >= 1) { WriteLong(MSG_ONE, f1); }
361 if(floatcount >= 2) { WriteLong(MSG_ONE, f2); }
362 if(floatcount == 3) { WriteLong(MSG_ONE, f3); }
367 // global notification sent to EVERYONE
368 WriteByte(MSG_ALL, SVC_TEMPENTITY);
369 WriteByte(MSG_ALL, TE_CSQC_NOTIFICATION);
370 WriteByte(MSG_ALL, net_type);
371 WriteShort(MSG_ALL, net_name);
372 if(stringcount >= 1) { WriteString(MSG_ALL, s1); }
373 if(stringcount == 2) { WriteString(MSG_ALL, s2); }
374 if(floatcount >= 1) { WriteLong(MSG_ALL, f1); }
375 if(floatcount >= 2) { WriteLong(MSG_ALL, f2); }
376 if(floatcount == 3) { WriteLong(MSG_ALL, f3); }
379 if(!server_is_local && (net_type == MSG_INFO))
381 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
382 { NOTIF_MATCH(name, net_name) { print(sprintf(CCR(normal_or_gentle(normal, gentle)), args)); } }
383 MSG_INFO_NOTIFICATIONS
386 else { backtrace("Incorrect usage of Send_Notification!\n"); }
389 void Send_Notification_ToTeam(float targetteam, entity except, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
392 FOR_EACH_REALCLIENT(tmp_entity)
394 if(tmp_entity.classname == STR_PLAYER)
395 if(tmp_entity.team == targetteam)
396 if(tmp_entity != except)
398 Send_Notification(tmp_entity, net_type, net_name, s1, s2, f1, f2, f3);
403 // WARNING: use this ONLY if you need exceptions or want to exclude spectators, otherwise use Send_Notification(..., world, ...)
404 void Send_Notification_ToAll(entity except, float spectators, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
407 FOR_EACH_REALCLIENT(tmp_entity)
409 if((tmp_entity.classname == STR_PLAYER) || spectators)
410 if(tmp_entity != except)
412 Send_Notification(tmp_entity, net_type, net_name, s1, s2, f1, f2, f3);
418 // =============================
419 // LEGACY NOTIFICATION SYSTEMS
420 // =============================
422 void Send_KillNotification(string s1, string s2, string s3, float msg, float type)
424 WriteByte(MSG_ALL, SVC_TEMPENTITY);
425 WriteByte(MSG_ALL, TE_CSQC_KILLNOTIFY);
426 WriteString(MSG_ALL, s1);
427 WriteString(MSG_ALL, s2);
428 WriteString(MSG_ALL, s3);
429 WriteShort(MSG_ALL, msg);
430 WriteByte(MSG_ALL, type);
433 // Function is used to send a generic centerprint whose content CSQC gets to decide (gentle version or not in the below cases)
434 void Send_CSQC_KillCenterprint(entity e, string s1, string s2, float msg, float type)
436 if (clienttype(e) == CLIENTTYPE_REAL)
439 WRITESPECTATABLE_MSG_ONE({
440 WriteByte(MSG_ONE, SVC_TEMPENTITY);
441 WriteByte(MSG_ONE, TE_CSQC_KILLCENTERPRINT);
442 WriteString(MSG_ONE, s1);
443 WriteString(MSG_ONE, s2);
444 WriteShort(MSG_ONE, msg);
445 WriteByte(MSG_ONE, type);
450 void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num)
452 if ((clienttype(e) == CLIENTTYPE_REAL) && (e.flags & FL_CLIENT))
455 WRITESPECTATABLE_MSG_ONE({
456 WriteByte(MSG_ONE, SVC_TEMPENTITY);
457 WriteByte(MSG_ONE, TE_CSQC_CENTERPRINT_GENERIC);
458 WriteByte(MSG_ONE, id);
459 WriteString(MSG_ONE, s);
460 if (id != 0 && s != "")
462 WriteByte(MSG_ONE, duration);
463 WriteByte(MSG_ONE, countdown_num);
468 void Send_CSQC_Centerprint_Generic_Expire(entity e, float id)
470 Send_CSQC_Centerprint_Generic(e, id, "", 1, 0);