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)
39 string team_name_red = _("RED");
40 string team_name_blue = _("BLUE");
41 string team_color_red = _("^1");
42 string team_color_blue = _("^4");
45 // ====================================
46 // Notifications List and Information
47 // ====================================
49 List of all notifications (including identifiers and display information)
50 Format: name, strnum, flnum, args, *icon/CPID, *durcnt, normal, gentle
51 Asterisked fields are not present in all notification types.
54 Number of STRING arguments (so that networking knows how many to send/receive)
55 Number of FLOAT arguments (so that networking knows how many to send/receive)
56 Arguments for sprintf(string, args), if no args needed then use ""
58 MSG_INFO: STRING: icon string name for the hud notify panel, "" if no icon is used
59 MSG_CENTER: FLOAT: centerprint ID number (CPID_*), NO_CPID if no CPID is needed
61 MSG_CENTER: XPND2(FLOAT, FLOAT): extra arguments for centerprint messages
62 Normal message (string for sprintf when gentle messages are NOT enabled)
63 Gentle message (string for sprintf when gentle messages ARE enabled)
65 Messages have ^F1, ^F2, and ^BG in them-- these are replaced
66 with colors according to the cvars the user has chosen.
67 ^F1 = highest priority, "primary"
68 ^F2 = next highest priority, "secondary"
69 ^BG = normal/less important priority, "tertiary"
71 Guidlines (please try and follow these):
72 -ALWAYS start the string with a color, preferably background.
73 -ALWAYS reset a color after a name (this way they don't set it for the whole string).
74 -NEVER re-declare an event twice.
75 -NEVER add or remove fields from the format, it SHOULD already work.
76 -MSG_INFO messages must ALWAYS end with a new line: \n
77 -Be clean and simple with your notification naming,
78 nothing too long for the name field... Abbreviations are your friend. :D
79 -Keep the spacing as clean as possible... if the arguments are abnormally long,
80 it's okay to go out of line a bit... but try and keep it clean still.
81 -Keep the notifications in alphabetical order.
82 ARIRE unir frk jvgu lbhe bja zbgure. (gvc sbe zvxrrhfn) -- Don't pay attention to this ^_^
85 // flag.netname = ((teamnumber) ? "^1RED^7 flag" : "^4BLUE^7 flag");
86 // weaponorder[f1].netname
89 #define MULTITEAM_INFO(prefix,teams,strnum,flnum,args,icon,normal,gentle) \
90 MSG_INFO_NOTIF(prefix##RED, strnum, flnum, args, sprintf(icon, strtolower(team_name_red)), TEAM_CCR(normal, team_color_red, team_name_red), TEAM_CCR(gentle, team_color_red, team_name_red)) \
91 MSG_INFO_NOTIF(prefix##BLUE, strnum, flnum, args, sprintf(icon, strtolower(team_name_blue)), TEAM_CCR(normal, team_color_blue, team_name_blue), TEAM_CCR(gentle, team_color_blue, team_name_blue)) \
93 MSG_INFO_NOTIF(prefix##YELLOW, strnum, flnum, args, sprintf(icon, strtolower(team_name_yellow)), TEAM_CCR(normal, team_color_yellow, team_name_yellow), TEAM_CCR(gentle, team_color_yellow, team_name_yellow)) \
96 MSG_INFO_NOTIF(prefix##PINK, strnum, flnum, args, sprintf(icon, strtolower(team_name_pink)), TEAM_CCR(normal, team_color_pink, team_name_pink), TEAM_CCR(gentle, team_color_pink, team_name_pink)) \
98 #define MSG_INFO_NOTIFICATIONS \
99 MSG_INFO_NOTIF(INFO_EMPTY, 0, 0, NO_STR_ARG, "", "", "") \
100 MULTITEAM_INFO(INFO_SCORES_, 2, 0, 0, NO_STR_ARG, "", _("^TC^TT ^BGteam scores!\n"), "") \
101 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_DROPPED_, 2, 0, 0, NO_STR_ARG, "", _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself\n"), "") \
102 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_DAMAGED_, 2, 0, 0, NO_STR_ARG, "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base\n"), "") \
103 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_SPEEDRUN_, 2, 0, 1, f1/100, "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself\n"), "") \
104 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_NEEDKILL_, 2, 0, 0, NO_STR_ARG, "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base\n"), "") \
105 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_ABORTRUN_, 2, 0, 0, NO_STR_ARG, "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner\n"), "") \
106 MULTITEAM_INFO(INFO_CTF_FLAGRETURN_TIMEOUT_, 2, 0, 0, NO_STR_ARG, "", _("^BGThe ^TC^TT^BG flag has returned to the base\n"), "") \
107 MULTITEAM_INFO(INFO_CTF_PICKUP_, 2, 1, 0, s1, "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag\n"), "") \
108 MULTITEAM_INFO(INFO_CTF_RETURN_, 2, 1, 0, s1, "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag\n"), "") \
109 MULTITEAM_INFO(INFO_CTF_LOST_, 2, 1, 0, s1, "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag\n"), "") \
110 MULTITEAM_INFO(INFO_CTF_CAPTURE_, 2, 1, 0, s1, "notify_%s_capture", _("^BG%s^BG captured the ^TC^TT^BG flag\n"), "") \
111 MULTITEAM_INFO(INFO_CTF_CAPTURE_TIME_, 2, 1, 1, XPND2(s1, f1/100), "notify_%s_capture", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%.2f^BG seconds\n"), "") \
112 MULTITEAM_INFO(INFO_CTF_CAPTURE_BROKEN_, 2, 2, 2, XPND4(s1, f1/100, s2, f2/100), "notify_%s_capture", _("^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"), "") \
113 MULTITEAM_INFO(INFO_CTF_CAPTURE_UNBROKEN_, 2, 2, 2, XPND4(s1, f1/100, s2, f2/100), "notify_%s_capture", _("^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"), "") \
114 #undef MSG_INFO_NOTIF
117 #define MULTITEAM_CENTER(prefix,teams,strnum,flnum,args,cpid,durcnt,normal,gentle) \
118 MSG_CENTER_NOTIF(prefix##RED, strnum, flnum, args, cpid, durcnt, TEAM_CCR(normal, team_color_red, team_name_red), TEAM_CCR(gentle, team_color_red, team_name_red)) \
119 MSG_CENTER_NOTIF(prefix##BLUE, strnum, flnum, args, cpid, durcnt, TEAM_CCR(normal, team_color_blue, team_name_blue), TEAM_CCR(gentle, team_color_blue, team_name_blue)) \
121 MSG_CENTER_NOTIF(prefix##YELLOW, strnum, flnum, args, cpid, durcnt, TEAM_CCR(normal, team_color_yellow, team_name_yellow), TEAM_CCR(gentle, team_color_yellow, team_name_yellow)) \
124 MSG_CENTER_NOTIF(prefix##PINK, strnum, flnum, args, cpid, durcnt, TEAM_CCR(normal, team_color_pink, team_name_pink), TEAM_CCR(gentle, team_color_pink, team_name_pink)) \
126 #define MSG_CENTER_NOTIFICATIONS \
127 MSG_CENTER_NOTIF(CENTER_EMPTY, 0, 0, NO_STR_ARG, NO_CPID, XPND2(0, 0), "", "") \
128 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."), "") \
129 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."), "") \
130 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"), "") \
131 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"), "") \
132 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"), "") \
133 MSG_CENTER_NOTIF(CENTER_CTF_PASS_REQUESTING, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGRequesting %s^BG to pass you the flag"), "") \
134 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"), "") \
135 MULTITEAM_CENTER(CENTER_CTF_RETURN_, 2, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou returned the ^TC^TT^BG flag!"), "") \
136 MULTITEAM_CENTER(CENTER_CTF_CAPTURE_, 2, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou captured the ^TC^TT^BG flag!"), "") \
137 MULTITEAM_CENTER(CENTER_CTF_PICKUP_, 2, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou got the ^TC^TT^BG flag!"), "") \
138 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!"), "") \
139 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!"), "") \
140 MSG_CENTER_NOTIF(CENTER_CTF_PICKUP_ENEMY, 1, 0, s1, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") \
141 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!"), "") \
142 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!"), "") \
143 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!"), "") \
144 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."), "") \
145 #undef MSG_CENTER_NOTIF
147 #define MSG_WEAPON_NOTIFICATIONS \
148 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"), "") \
149 #undef MSG_WEAPON_NOTIF
152 // ====================================
153 // Initialization/Create Declarations
154 // ====================================
156 #define NOTIF_FIRST 1
157 #define NOTIF_MAX 1024 // limit of recursive functions with ACCUMULATE_FUNCTION
158 float NOTIF_INFO_COUNT;
159 float NOTIF_CENTER_COUNT;
160 float NOTIF_WEAPON_COUNT;
161 float NOTIF_CPID_COUNT;
163 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
164 ADD_CSQC_AUTOCVAR(name) \
166 void RegisterNotification_##name() \
168 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \
169 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_INFO_COUNT, "notifications") \
171 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
173 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
174 ADD_CSQC_AUTOCVAR(name) \
177 void RegisterNotification_##name() \
179 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CENTER_COUNT) \
180 SET_FIELD_COUNT(cpid, NOTIF_FIRST, NOTIF_CPID_COUNT) \
181 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_CENTER_COUNT, "notifications") \
183 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
185 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
186 ADD_CSQC_AUTOCVAR(name) \
188 void RegisterNotification_##name() \
190 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_WEAPON_COUNT) \
191 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_WEAPON_COUNT, "notifications") \
193 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
195 // NOW we actually activate the declarations
196 MSG_INFO_NOTIFICATIONS
197 MSG_CENTER_NOTIFICATIONS
198 MSG_WEAPON_NOTIFICATIONS
201 // ======================
202 // Supporting Functions
203 // ======================
205 // select between the normal or the gentle message string based on client (or server) settings
206 string normal_or_gentle(string normal, string gentle)
209 if(autocvar_cl_gentle || autocvar_cl_gentle_messages)
211 if(autocvar_sv_gentle)
213 return ((gentle != "") ? gentle : normal);
218 float notif_stringcount(string s1, string s2)
221 if(s1 != NO_STR_ARG) ++stringcount;
222 if(s2 != NO_STR_ARG) ++stringcount;
226 float notif_floatcount(float f1, float f2, float f3)
229 if(f1 != NO_FL_ARG) ++floatcount;
230 if(f2 != NO_FL_ARG) ++floatcount;
231 if(f3 != NO_FL_ARG) ++floatcount;
235 // get the actual name of a notification and return it as a string
236 string Get_Field_Value(float field, float net_type, float net_name)
240 #define GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) \
241 if(field == F_NAME) { output = VAR_TO_TEXT(name); } \
242 else if(field == F_STRNUM) { output = ftos(strnum); } \
243 else if(field == F_FLNUM) { output = ftos(flnum); }
249 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
250 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
251 MSG_INFO_NOTIFICATIONS
256 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
257 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
258 MSG_CENTER_NOTIFICATIONS
263 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
264 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
265 MSG_WEAPON_NOTIFICATIONS
270 #undef GET_FIELD_VALUE_OUTPUT
274 string TEAM_CCR(string input, string teamcolor, string teamtext)
276 input = strreplace("^TC", teamcolor, input);
277 input = strreplace("^TT", teamtext, input);
282 // color code replace, place inside of sprintf and parse the string
283 string CCR(string input)
285 input = strreplace("^F1", "^2", input); // autocvar_notification_colors_F1
286 input = strreplace("^F2", "^3", input); // autocvar_notification_colors_F2
287 input = strreplace("^K1", "^1", input); // autocvar_notification_colors_K1
288 input = strreplace("^K2", "^3", input); // autocvar_notification_colors_K2
289 input = strreplace("^BG", "^7", input); // autocvar_notification_colors_BG
291 input = strreplace("^N", "^7", input); // "none"-- reset to white
297 // ===============================
298 // Frontend Notification Pushing
299 // ===============================
302 void Local_Notification(float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
308 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
309 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { print(sprintf(CCR(normal_or_gentle(normal, gentle)), args)); } }
310 MSG_INFO_NOTIFICATIONS
315 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
316 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { centerprint_generic(HANDLE_CPID(cpid), sprintf(CCR(normal_or_gentle(normal, gentle)), args), durcnt); } }
317 MSG_CENTER_NOTIFICATIONS
322 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
323 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { print("unhandled\n"); } }
324 MSG_WEAPON_NOTIFICATIONS
332 // =========================
333 // Notification Networking
334 // =========================
337 void Read_Notification(void)
339 float net_type = ReadByte();
340 float net_name = ReadShort();
342 float stringcount = stof(Get_Field_Value(F_STRNUM, net_type, net_name));
343 float floatcount = stof(Get_Field_Value(F_FLNUM, net_type, net_name));
345 Local_Notification(net_type, net_name,
346 ((stringcount >= 1) ? ReadString() : ""),
347 ((stringcount == 2) ? ReadString() : ""),
348 ((floatcount >= 1) ? ReadLong() : 0),
349 ((floatcount >= 2) ? ReadLong() : 0),
350 ((floatcount == 3) ? ReadLong() : 0));
355 void Send_Notification(entity client, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
357 if(net_type && net_name)
359 print("notification: ", Get_Field_Value(F_NAME, net_type, net_name), ": ", ftos(net_name), ".\n");
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 if(notif_stringcount(s1, s2) > stringcount) { backtrace("Too many string arguments for notification!\n"); return; }
365 if(notif_floatcount(f1, f2, f3) > floatcount) { backtrace("Too many float arguments for notification!\n"); return; }
367 if(client && (clienttype(client) == CLIENTTYPE_REAL) && (client.flags & FL_CLIENT))
369 // personal/direct notification sent to ONE person and their spectators
371 WRITESPECTATABLE_MSG_ONE({
372 WriteByte(MSG_ONE, SVC_TEMPENTITY);
373 WriteByte(MSG_ONE, TE_CSQC_NOTIFICATION);
374 WriteByte(MSG_ONE, net_type);
375 WriteShort(MSG_ONE, net_name);
376 if(stringcount >= 1) { WriteString(MSG_ONE, s1); }
377 if(stringcount == 2) { WriteString(MSG_ONE, s2); }
378 if(floatcount >= 1) { WriteLong(MSG_ONE, f1); }
379 if(floatcount >= 2) { WriteLong(MSG_ONE, f2); }
380 if(floatcount == 3) { WriteLong(MSG_ONE, f3); }
385 // global notification sent to EVERYONE
386 WriteByte(MSG_ALL, SVC_TEMPENTITY);
387 WriteByte(MSG_ALL, TE_CSQC_NOTIFICATION);
388 WriteByte(MSG_ALL, net_type);
389 WriteShort(MSG_ALL, net_name);
390 if(stringcount >= 1) { WriteString(MSG_ALL, s1); }
391 if(stringcount == 2) { WriteString(MSG_ALL, s2); }
392 if(floatcount >= 1) { WriteLong(MSG_ALL, f1); }
393 if(floatcount >= 2) { WriteLong(MSG_ALL, f2); }
394 if(floatcount == 3) { WriteLong(MSG_ALL, f3); }
397 if(!server_is_local && (net_type == MSG_INFO))
399 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
400 { NOTIF_MATCH(name, net_name) { print(sprintf(CCR(normal_or_gentle(normal, gentle)), args)); } }
401 MSG_INFO_NOTIFICATIONS
404 else { backtrace("Incorrect usage of Send_Notification!\n"); }
407 void Send_Notification_ToTeam(float targetteam, entity except, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
410 FOR_EACH_REALCLIENT(tmp_entity)
412 if(tmp_entity.classname == STR_PLAYER)
413 if(tmp_entity.team == targetteam)
414 if(tmp_entity != except)
416 Send_Notification(tmp_entity, net_type, net_name, s1, s2, f1, f2, f3);
421 // WARNING: use this ONLY if you need exceptions or want to exclude spectators, otherwise use Send_Notification(..., world, ...)
422 void Send_Notification_ToAll(entity except, float spectators, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
425 FOR_EACH_REALCLIENT(tmp_entity)
427 if((tmp_entity.classname == STR_PLAYER) || spectators)
428 if(tmp_entity != except)
430 Send_Notification(tmp_entity, net_type, net_name, s1, s2, f1, f2, f3);
436 // =============================
437 // LEGACY NOTIFICATION SYSTEMS
438 // =============================
440 void Send_KillNotification(string s1, string s2, string s3, float msg, float type)
442 WriteByte(MSG_ALL, SVC_TEMPENTITY);
443 WriteByte(MSG_ALL, TE_CSQC_KILLNOTIFY);
444 WriteString(MSG_ALL, s1);
445 WriteString(MSG_ALL, s2);
446 WriteString(MSG_ALL, s3);
447 WriteShort(MSG_ALL, msg);
448 WriteByte(MSG_ALL, type);
451 // Function is used to send a generic centerprint whose content CSQC gets to decide (gentle version or not in the below cases)
452 void Send_CSQC_KillCenterprint(entity e, string s1, string s2, float msg, float type)
454 if (clienttype(e) == CLIENTTYPE_REAL)
457 WRITESPECTATABLE_MSG_ONE({
458 WriteByte(MSG_ONE, SVC_TEMPENTITY);
459 WriteByte(MSG_ONE, TE_CSQC_KILLCENTERPRINT);
460 WriteString(MSG_ONE, s1);
461 WriteString(MSG_ONE, s2);
462 WriteShort(MSG_ONE, msg);
463 WriteByte(MSG_ONE, type);
468 void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num)
470 if ((clienttype(e) == CLIENTTYPE_REAL) && (e.flags & FL_CLIENT))
473 WRITESPECTATABLE_MSG_ONE({
474 WriteByte(MSG_ONE, SVC_TEMPENTITY);
475 WriteByte(MSG_ONE, TE_CSQC_CENTERPRINT_GENERIC);
476 WriteByte(MSG_ONE, id);
477 WriteString(MSG_ONE, s);
478 if (id != 0 && s != "")
480 WriteByte(MSG_ONE, duration);
481 WriteByte(MSG_ONE, countdown_num);
486 void Send_CSQC_Centerprint_Generic_Expire(entity e, float id)
488 Send_CSQC_Centerprint_Generic(e, id, "", 1, 0);