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 // weaponorder[f1].netname
82 #define MULTITEAM_INFO(prefix,teams,strnum,flnum,args,hudargs,icon,normal,gentle) \
83 MSG_INFO_NOTIF(prefix##RED, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STR_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(STR_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(STR_TEAM_1))) \
84 MSG_INFO_NOTIF(prefix##BLUE, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STR_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(STR_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(STR_TEAM_2))) \
86 MSG_INFO_NOTIF(prefix##YELLOW, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STR_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(STR_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(STR_TEAM_3))) \
89 MSG_INFO_NOTIF(prefix##PINK, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STR_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(STR_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(STR_TEAM_4))) \
91 #define MSG_INFO_NOTIFICATIONS \
92 MSG_INFO_NOTIF(INFO_EMPTY, 0, 0, NO_STR_ARG, XPND2("", ""), "", "", "") \
93 MULTITEAM_INFO(INFO_SCORES_, 2, 0, 0, NO_STR_ARG, XPND2("", ""), "", _("^TC^TT ^BGteam scores!\n"), "") \
94 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_DROPPED_, 2, 0, 0, NO_STR_ARG, XPND2("", ""), "", _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself\n"), "") \
95 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_DAMAGED_, 2, 0, 0, NO_STR_ARG, XPND2("", ""), "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base\n"), "") \
96 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_SPEEDRUN_, 2, 0, 1, f1/100, XPND2("", ""), "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself\n"), "") \
97 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_NEEDKILL_, 2, 0, 0, NO_STR_ARG, XPND2("", ""), "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base\n"), "") \
98 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_ABORTRUN_, 2, 0, 0, NO_STR_ARG, XPND2("", ""), "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner\n"), "") \
99 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_TIMEOUT_, 2, 0, 0, NO_STR_ARG, XPND2("", ""), "", _("^BGThe ^TC^TT^BG flag has returned to the base\n"), "") \
100 MULTITEAM_INFO(INFO_CTF_PICKUP_, 2, 1, 0, s1, XPND2(s1, ""), "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag\n"), "") \
101 MULTITEAM_INFO(INFO_CTF_RETURN_, 2, 1, 0, s1, XPND2(s1, ""), "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag\n"), "") \
102 MULTITEAM_INFO(INFO_CTF_LOST_, 2, 1, 0, s1, XPND2(s1, ""), "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag\n"), "") \
103 MULTITEAM_INFO(INFO_CTF_CAPTURE_, 2, 1, 0, s1, XPND2(s1, ""), "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag\n"), "") \
104 MULTITEAM_INFO(INFO_CTF_CAPTURE_TIME_, 2, 1, 1, XPND2(s1, f1/100), XPND2(s1, ""), "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%.2f^BG seconds\n"), "") \
105 MULTITEAM_INFO(INFO_CTF_CAPTURE_BROKEN_, 2, 2, 2, XPND4(s1, f1/100, s2, f2/100), XPND2(s1, ""), "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%.2f^BG seconds, breaking ^BG%s^BG's previous record of ^F2%.2f^BG seconds\n"), "") \
106 MULTITEAM_INFO(INFO_CTF_CAPTURE_UNBROKEN_, 2, 2, 2, XPND4(s1, f1/100, s2, f2/100), XPND2(s1, ""), "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%.2f^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%.2f^BG seconds\n"), "") \
107 #undef MSG_INFO_NOTIF
109 #define MULTITEAM_CENTER(prefix,teams,strnum,flnum,args,cpid,durcnt,normal,gentle) \
110 MSG_CENTER_NOTIF(prefix##RED, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(STR_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(STR_TEAM_1))) \
111 MSG_CENTER_NOTIF(prefix##BLUE, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_2, strtoupper(STR_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(STR_TEAM_2))) \
113 MSG_CENTER_NOTIF(prefix##YELLOW, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_3, strtoupper(STR_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(STR_TEAM_3))) \
116 MSG_CENTER_NOTIF(prefix##PINK, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_4, strtoupper(STR_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(STR_TEAM_4))) \
118 #define MSG_CENTER_NOTIFICATIONS \
119 MSG_CENTER_NOTIF(CENTER_EMPTY, 0, 0, NO_STR_ARG, NO_CPID, XPND2(0, 0), "", "") \
120 MSG_CENTER_NOTIF(CENTER_CTF_CAPTURESHIELD_SHIELDED, 0, 0, NO_STR_ARG, CPID_CTF_CAPSHIELD, 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."), "") \
121 MSG_CENTER_NOTIF(CENTER_CTF_CAPTURESHIELD_FREE, 0, 0, NO_STR_ARG, CPID_CTF_CAPSHIELD, 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."), "") \
122 MULTITEAM_CENTER(CENTER_CTF_PASS_OTHER_, 2, 2, 0, XPND2(s1, s2), CPID_CTF_PASS, XPND2(0, 0), _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") \
123 MULTITEAM_CENTER(CENTER_CTF_PASS_SENT_, 2, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGYou passed the ^TC^TT^BG flag to %s"), "") \
124 MULTITEAM_CENTER(CENTER_CTF_PASS_RECEIVED_, 2, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGYou received the ^TC^TT^BG flag from %s"), "") \
125 MSG_CENTER_NOTIF(CENTER_CTF_PASS_REQUESTING, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGRequesting %s^BG to pass you the flag"), "") \
126 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"), "") \
127 MULTITEAM_CENTER(CENTER_CTF_RETURN_, 2, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou returned the ^TC^TT^BG flag!"), "") \
128 MULTITEAM_CENTER(CENTER_CTF_CAPTURE_, 2, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou captured the ^TC^TT^BG flag!"), "") \
129 MULTITEAM_CENTER(CENTER_CTF_PICKUP_, 2, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou got the ^TC^TT^BG flag!"), "") \
130 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!"), "") \
131 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!"), "") \
132 MSG_CENTER_NOTIF(CENTER_CTF_PICKUP_ENEMY, 1, 0, s1, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") \
133 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!"), "") \
134 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!"), "") \
135 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!"), "") \
136 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."), "") \
137 #undef MSG_CENTER_NOTIF
139 #define MSG_WEAPON_NOTIFICATIONS \
140 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"), "") \
141 #undef MSG_WEAPON_NOTIF
144 // ====================================
145 // Initialization/Create Declarations
146 // ====================================
148 #define NOTIF_FIRST 1
149 #define NOTIF_MAX 1024 // limit of recursive functions with ACCUMULATE_FUNCTION
150 float NOTIF_INFO_COUNT;
151 float NOTIF_CENTER_COUNT;
152 float NOTIF_WEAPON_COUNT;
153 float NOTIF_CPID_COUNT;
155 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
156 ADD_CSQC_AUTOCVAR(name) \
158 void RegisterNotification_##name() \
160 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \
161 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_INFO_COUNT, "notifications") \
163 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
165 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
166 ADD_CSQC_AUTOCVAR(name) \
169 void RegisterNotification_##name() \
171 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CENTER_COUNT) \
172 SET_FIELD_COUNT(cpid, NOTIF_FIRST, NOTIF_CPID_COUNT) \
173 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_CENTER_COUNT, "notifications") \
175 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
177 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
178 ADD_CSQC_AUTOCVAR(name) \
180 void RegisterNotification_##name() \
182 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_WEAPON_COUNT) \
183 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_WEAPON_COUNT, "notifications") \
185 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
187 // NOW we actually activate the declarations
188 MSG_INFO_NOTIFICATIONS
189 MSG_CENTER_NOTIFICATIONS
190 MSG_WEAPON_NOTIFICATIONS
193 // ======================
194 // Supporting Functions
195 // ======================
197 // select between the normal or the gentle message string based on client (or server) settings
198 string normal_or_gentle(string normal, string gentle)
201 if(autocvar_cl_gentle || autocvar_cl_gentle_messages)
203 if(autocvar_sv_gentle)
205 return ((gentle != "") ? gentle : normal);
210 float notif_stringcount(string s1, string s2)
213 if(s1 != NO_STR_ARG) ++stringcount;
214 if(s2 != NO_STR_ARG) ++stringcount;
218 float notif_floatcount(float f1, float f2, float f3)
221 if(f1 != NO_FL_ARG) ++floatcount;
222 if(f2 != NO_FL_ARG) ++floatcount;
223 if(f3 != NO_FL_ARG) ++floatcount;
227 // get the actual name of a notification and return it as a string
228 string Get_Field_Value(float field, float net_type, float net_name)
232 #define GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) \
233 if(field == F_NAME) { output = VAR_TO_TEXT(name); } \
234 else if(field == F_STRNUM) { output = ftos(strnum); } \
235 else if(field == F_FLNUM) { output = ftos(flnum); }
241 #define MSG_INFO_NOTIF(name,strnum,flnum,args,hudargs,icon,normal,gentle) \
242 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
243 MSG_INFO_NOTIFICATIONS
248 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
249 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
250 MSG_CENTER_NOTIFICATIONS
255 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
256 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
257 MSG_WEAPON_NOTIFICATIONS
262 #undef GET_FIELD_VALUE_OUTPUT
267 string TCR(string input, string teamcolor, string teamtext)
269 input = strreplace("^TC", teamcolor, input);
270 input = strreplace("^TT", teamtext, input);
274 // color code replace, place inside of sprintf and parse the string
275 string CCR(string input)
277 input = strreplace("^F1", "^2", input); // autocvar_notification_colors_F1
278 input = strreplace("^F2", "^3", input); // autocvar_notification_colors_F2
279 input = strreplace("^K1", "^1", input); // autocvar_notification_colors_K1
280 input = strreplace("^K2", "^3", input); // autocvar_notification_colors_K2
281 input = strreplace("^BG", "^7", input); // autocvar_notification_colors_BG
282 input = strreplace("^N", "^7", input); // "none"-- reset to white
287 // ===============================
288 // Frontend Notification Pushing
289 // ===============================
292 #define KN_MAX_ENTRIES 10
294 float killnotify_times[KN_MAX_ENTRIES];
295 string killnotify_icon[KN_MAX_ENTRIES];
296 string killnotify_attackers[KN_MAX_ENTRIES];
297 string killnotify_victims[KN_MAX_ENTRIES];
298 // 0 = "Y [used by] X", 1 = "X [did action to] Y"
299 void HUD_Notify_Push(string icon, string attacker, string victim)
304 if (kn_index == -1) { kn_index = KN_MAX_ENTRIES-1; }
305 killnotify_times[kn_index] = time;
308 if(killnotify_icon[kn_index]) { strunzone(killnotify_icon[kn_index]); }
309 killnotify_icon[kn_index] = strzone(icon);
312 if(killnotify_attackers[kn_index]) { strunzone(killnotify_attackers[kn_index]); }
313 killnotify_attackers[kn_index] = strzone(attacker);
316 if(killnotify_victims[kn_index]) { strunzone(killnotify_victims[kn_index]); }
317 killnotify_victims[kn_index] = strzone(victim);
321 void Local_Notification(float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
327 #define MSG_INFO_NOTIF(name,strnum,flnum,args,hudargs,icon,normal,gentle) \
328 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { print(sprintf(CCR(normal_or_gentle(normal, gentle)), args)); if(strtolower(icon) != "") { HUD_Notify_Push(icon, hudargs); } } }
329 MSG_INFO_NOTIFICATIONS
334 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
335 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { centerprint_generic(HANDLE_CPID(cpid), sprintf(CCR(normal_or_gentle(normal, gentle)), args), durcnt); } }
336 MSG_CENTER_NOTIFICATIONS
341 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
342 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { print("unhandled\n"); } }
343 MSG_WEAPON_NOTIFICATIONS
351 // =========================
352 // Notification Networking
353 // =========================
356 void Read_Notification(void)
358 float net_type = ReadByte();
359 float net_name = ReadShort();
361 float stringcount = stof(Get_Field_Value(F_STRNUM, net_type, net_name));
362 float floatcount = stof(Get_Field_Value(F_FLNUM, net_type, net_name));
364 Local_Notification(net_type, net_name,
365 ((stringcount >= 1) ? ReadString() : ""),
366 ((stringcount == 2) ? ReadString() : ""),
367 ((floatcount >= 1) ? ReadLong() : 0),
368 ((floatcount >= 2) ? ReadLong() : 0),
369 ((floatcount == 3) ? ReadLong() : 0));
374 void Send_Notification(entity client, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
376 if(net_type && net_name)
378 //print("notification: ", Get_Field_Value(F_NAME, net_type, net_name), ": ", ftos(net_name), ".\n");
380 float stringcount = stof(Get_Field_Value(F_STRNUM, net_type, net_name));
381 float floatcount = stof(Get_Field_Value(F_FLNUM, net_type, net_name));
383 if(notif_stringcount(s1, s2) > stringcount) { backtrace("Too many string arguments for notification!\n"); return; }
384 if(notif_floatcount(f1, f2, f3) > floatcount) { backtrace("Too many float arguments for notification!\n"); return; }
386 if(client && (clienttype(client) == CLIENTTYPE_REAL) && (client.flags & FL_CLIENT))
388 // personal/direct notification sent to ONE person and their spectators
390 WRITESPECTATABLE_MSG_ONE({
391 WriteByte(MSG_ONE, SVC_TEMPENTITY);
392 WriteByte(MSG_ONE, TE_CSQC_NOTIFICATION);
393 WriteByte(MSG_ONE, net_type);
394 WriteShort(MSG_ONE, net_name);
395 if(stringcount >= 1) { WriteString(MSG_ONE, s1); }
396 if(stringcount == 2) { WriteString(MSG_ONE, s2); }
397 if(floatcount >= 1) { WriteLong(MSG_ONE, f1); }
398 if(floatcount >= 2) { WriteLong(MSG_ONE, f2); }
399 if(floatcount == 3) { WriteLong(MSG_ONE, f3); }
404 // global notification sent to EVERYONE
405 WriteByte(MSG_ALL, SVC_TEMPENTITY);
406 WriteByte(MSG_ALL, TE_CSQC_NOTIFICATION);
407 WriteByte(MSG_ALL, net_type);
408 WriteShort(MSG_ALL, net_name);
409 if(stringcount >= 1) { WriteString(MSG_ALL, s1); }
410 if(stringcount == 2) { WriteString(MSG_ALL, s2); }
411 if(floatcount >= 1) { WriteLong(MSG_ALL, f1); }
412 if(floatcount >= 2) { WriteLong(MSG_ALL, f2); }
413 if(floatcount == 3) { WriteLong(MSG_ALL, f3); }
416 if(!server_is_local && (net_type == MSG_INFO))
418 #define MSG_INFO_NOTIF(name,strnum,flnum,args,hudargs,icon,normal,gentle) \
419 { NOTIF_MATCH(name, net_name) { print(sprintf(CCR(normal_or_gentle(normal, gentle)), args)); } }
420 MSG_INFO_NOTIFICATIONS
423 else { backtrace("Incorrect usage of Send_Notification!\n"); }
426 void Send_Notification_ToTeam(float targetteam, entity except, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
429 FOR_EACH_REALCLIENT(tmp_entity)
431 if(tmp_entity.classname == STR_PLAYER)
432 if(tmp_entity.team == targetteam)
433 if(tmp_entity != except)
435 Send_Notification(tmp_entity, net_type, net_name, s1, s2, f1, f2, f3);
440 // WARNING: use this ONLY if you need exceptions or want to exclude spectators, otherwise use Send_Notification(..., world, ...)
441 void Send_Notification_ToAll(entity except, float spectators, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
444 FOR_EACH_REALCLIENT(tmp_entity)
446 if((tmp_entity.classname == STR_PLAYER) || spectators)
447 if(tmp_entity != except)
449 Send_Notification(tmp_entity, net_type, net_name, s1, s2, f1, f2, f3);
455 // =============================
456 // LEGACY NOTIFICATION SYSTEMS
457 // =============================
459 void Send_KillNotification(string s1, string s2, string s3, float msg, float type)
461 WriteByte(MSG_ALL, SVC_TEMPENTITY);
462 WriteByte(MSG_ALL, TE_CSQC_KILLNOTIFY);
463 WriteString(MSG_ALL, s1);
464 WriteString(MSG_ALL, s2);
465 WriteString(MSG_ALL, s3);
466 WriteShort(MSG_ALL, msg);
467 WriteByte(MSG_ALL, type);
470 // Function is used to send a generic centerprint whose content CSQC gets to decide (gentle version or not in the below cases)
471 void Send_CSQC_KillCenterprint(entity e, string s1, string s2, float msg, float type)
473 if (clienttype(e) == CLIENTTYPE_REAL)
476 WRITESPECTATABLE_MSG_ONE({
477 WriteByte(MSG_ONE, SVC_TEMPENTITY);
478 WriteByte(MSG_ONE, TE_CSQC_KILLCENTERPRINT);
479 WriteString(MSG_ONE, s1);
480 WriteString(MSG_ONE, s2);
481 WriteShort(MSG_ONE, msg);
482 WriteByte(MSG_ONE, type);
487 void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num)
489 if ((clienttype(e) == CLIENTTYPE_REAL) && (e.flags & FL_CLIENT))
492 WRITESPECTATABLE_MSG_ONE({
493 WriteByte(MSG_ONE, SVC_TEMPENTITY);
494 WriteByte(MSG_ONE, TE_CSQC_CENTERPRINT_GENERIC);
495 WriteByte(MSG_ONE, id);
496 WriteString(MSG_ONE, s);
497 if (id != 0 && s != "")
499 WriteByte(MSG_ONE, duration);
500 WriteByte(MSG_ONE, countdown_num);
505 void Send_CSQC_Centerprint_Generic_Expire(entity e, float id)
507 Send_CSQC_Centerprint_Generic(e, id, "", 1, 0);