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 = _("^5");
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
88 #define TWO_TEAMS_INFO(prefix,strnum,flnum,args,icon,normal,gentle) \
89 MSG_INFO_NOTIF(prefix##RED, strnum, flnum, args, sprintf(icon, "red"), TEAM_CCR(normal, team_color_red, team_name_red), TEAM_CCR(gentle, team_color_red, team_name_red)) \
90 MSG_INFO_NOTIF(prefix##BLUE, strnum, flnum, args, sprintf(icon, "blue"), TEAM_CCR(normal, team_color_blue, team_name_blue), TEAM_CCR(gentle, team_color_blue, team_name_blue))
91 #define MSG_INFO_NOTIFICATIONS \
92 MSG_INFO_NOTIF(INFO_EMPTY, 0, 0, NO_STR_ARG, "", "", "") \
93 TWO_TEAMS_INFO(INFO_CTF_FLAGRETURN_DROPPED_, 0, 0, NO_STR_ARG, "", _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself\n"), "") \
94 TWO_TEAMS_INFO(INFO_CTF_FLAGRETURN_DAMAGED_, 0, 0, NO_STR_ARG, "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base\n"), "") \
95 TWO_TEAMS_INFO(INFO_CTF_FLAGRETURN_SPEEDRUN_, 0, 1, f1/100, "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself\n"), "") \
96 TWO_TEAMS_INFO(INFO_CTF_FLAGRETURN_NEEDKILL_, 0, 0, NO_STR_ARG, "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base\n"), "") \
97 TWO_TEAMS_INFO(INFO_CTF_FLAGRETURN_ABORTRUN_, 0, 0, NO_STR_ARG, "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner\n"), "") \
98 TWO_TEAMS_INFO(INFO_CTF_FLAGRETURN_TIMEOUT_, 0, 0, NO_STR_ARG, "", _("^BGThe ^TC^TT^BG flag has returned to the base\n"), "") \
99 TWO_TEAMS_INFO(INFO_CTF_PICKUP_, 1, 0, s1, "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag\n"), "") \
100 TWO_TEAMS_INFO(INFO_CTF_RETURN_, 1, 0, s1, "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag\n"), "") \
101 TWO_TEAMS_INFO(INFO_CTF_LOST_, 1, 0, s1, "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag\n"), "") \
102 TWO_TEAMS_INFO(INFO_CTF_CAPTURE_, 1, 0, s1, "notify_%s_capture", _("^BG%s^BG captured the ^TC^TT^BG flag\n"), "") \
103 TWO_TEAMS_INFO(INFO_CTF_CAPTURE_TIME_, 1, 1, XPND2(s1, f1/100), "notify_%s_capture", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%.2f^BG seconds\n"), "") \
104 TWO_TEAMS_INFO(INFO_CTF_CAPTURE_BROKEN_, 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"), "") \
105 TWO_TEAMS_INFO(INFO_CTF_CAPTURE_UNBROKEN_, 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"), "") \
106 #undef MSG_INFO_NOTIF
108 #define TWO_TEAMS_CENTER(prefix,strnum,flnum,args,cpid,durcnt,normal,gentle) \
109 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)) \
110 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))
111 #define MSG_CENTER_NOTIFICATIONS \
112 MSG_CENTER_NOTIF(CENTER_EMPTY, 0, 0, NO_STR_ARG, NO_CPID, XPND2(0, 0), "", "") \
113 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."), "") \
114 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."), "") \
115 TWO_TEAMS_CENTER(CENTER_CTF_PASS_OTHER_, 2, 0, XPND2(s1, s2), CPID_CTF_PASS, XPND2(0, 0), _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") \
116 TWO_TEAMS_CENTER(CENTER_CTF_PASS_SENT_, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGYou passed the ^TC^TT^BG flag to %s"), "") \
117 TWO_TEAMS_CENTER(CENTER_CTF_PASS_RECEIVED_, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGYou received the ^TC^TT^BG flag from %s"), "") \
118 MSG_CENTER_NOTIF(CENTER_CTF_PASS_REQUESTING, 1, 0, s1, CPID_CTF_PASS, XPND2(0, 0), _("^BGRequesting %s^BG to pass you the flag"), "") \
119 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"), "") \
120 TWO_TEAMS_CENTER(CENTER_CTF_RETURN_, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou returned the ^TC^TT^BG flag!"), "") \
121 TWO_TEAMS_CENTER(CENTER_CTF_CAPTURE_, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou captured the ^TC^TT^BG flag!"), "") \
122 TWO_TEAMS_CENTER(CENTER_CTF_PICKUP_, 0, 0, NO_STR_ARG, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGYou got the ^TC^TT^BG flag!"), "") \
123 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!"), "") \
124 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!"), "") \
125 MSG_CENTER_NOTIF(CENTER_CTF_PICKUP_ENEMY, 1, 0, s1, CPID_CTF_LOWPRIO, XPND2(0, 0), _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") \
126 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!"), "") \
127 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!"), "") \
128 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!"), "") \
129 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."), "") \
130 #undef MSG_CENTER_NOTIF
132 #define MSG_WEAPON_NOTIFICATIONS \
133 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"), "") \
134 #undef MSG_WEAPON_NOTIF
137 // ====================================
138 // Initialization/Create Declarations
139 // ====================================
141 #define NOTIF_FIRST 1
142 #define NOTIF_MAX 1024 // limit of recursive functions with ACCUMULATE_FUNCTION
143 float NOTIF_INFO_COUNT;
144 float NOTIF_CENTER_COUNT;
145 float NOTIF_WEAPON_COUNT;
146 float NOTIF_CPID_COUNT;
148 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
149 ADD_CSQC_AUTOCVAR(name) \
151 void RegisterNotification_##name() \
153 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \
154 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_INFO_COUNT, "notifications") \
156 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
158 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
159 ADD_CSQC_AUTOCVAR(name) \
162 void RegisterNotification_##name() \
164 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CENTER_COUNT) \
165 SET_FIELD_COUNT(cpid, NOTIF_FIRST, NOTIF_CPID_COUNT) \
166 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_CENTER_COUNT, "notifications") \
168 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
170 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
171 ADD_CSQC_AUTOCVAR(name) \
173 void RegisterNotification_##name() \
175 SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_WEAPON_COUNT) \
176 CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_WEAPON_COUNT, "notifications") \
178 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
180 // NOW we actually activate the declarations
181 MSG_INFO_NOTIFICATIONS
182 MSG_CENTER_NOTIFICATIONS
183 MSG_WEAPON_NOTIFICATIONS
186 // ======================
187 // Supporting Functions
188 // ======================
190 // select between the normal or the gentle message string based on client (or server) settings
191 string normal_or_gentle(string normal, string gentle)
194 if(autocvar_cl_gentle || autocvar_cl_gentle_messages)
196 if(autocvar_sv_gentle)
198 return ((gentle != "") ? gentle : normal);
203 float notif_stringcount(string s1, string s2)
206 if(s1 != NO_STR_ARG) ++stringcount;
207 if(s2 != NO_STR_ARG) ++stringcount;
211 float notif_floatcount(float f1, float f2, float f3)
214 if(f1 != NO_FL_ARG) ++floatcount;
215 if(f2 != NO_FL_ARG) ++floatcount;
216 if(f3 != NO_FL_ARG) ++floatcount;
220 // get the actual name of a notification and return it as a string
221 string Get_Field_Value(float field, float net_type, float net_name)
225 #define GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) \
226 if(field == F_NAME) { output = VAR_TO_TEXT(name); } \
227 else if(field == F_STRNUM) { output = ftos(strnum); } \
228 else if(field == F_FLNUM) { output = ftos(flnum); }
234 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
235 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
236 MSG_INFO_NOTIFICATIONS
241 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
242 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
243 MSG_CENTER_NOTIFICATIONS
248 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
249 { NOTIF_MATCH(name, net_name) { GET_FIELD_VALUE_OUTPUT(field,name,strnum,flnum) } }
250 MSG_WEAPON_NOTIFICATIONS
255 #undef GET_FIELD_VALUE_OUTPUT
259 string TEAM_CCR(string input, string teamcolor, string teamtext)
261 input = strreplace("^TC", teamcolor, input);
262 input = strreplace("^TT", teamtext, input);
267 // color code replace, place inside of sprintf and parse the string
268 string CCR(string input)
270 input = strreplace("^F1", "^2", input); // autocvar_notification_colors_F1
271 input = strreplace("^F2", "^3", input); // autocvar_notification_colors_F2
272 input = strreplace("^K1", "^1", input); // autocvar_notification_colors_K1
273 input = strreplace("^K2", "^3", input); // autocvar_notification_colors_K2
274 input = strreplace("^BG", "^7", input); // autocvar_notification_colors_BG
276 input = strreplace("^N", "^7", input); // "none"-- reset to white
282 // ===============================
283 // Frontend Notification Pushing
284 // ===============================
287 void Local_Notification(float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
293 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
294 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { print(sprintf(CCR(normal_or_gentle(normal, gentle)), args)); } }
295 MSG_INFO_NOTIFICATIONS
300 #define MSG_CENTER_NOTIF(name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
301 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { centerprint_generic(HANDLE_CPID(cpid), sprintf(CCR(normal_or_gentle(normal, gentle)), args), durcnt); } }
302 MSG_CENTER_NOTIFICATIONS
307 #define MSG_WEAPON_NOTIF(name,strnum,flnum,args,normal,gentle) \
308 { NOTIF_MATCH(name, net_name) CHECK_AUTOCVAR(name) { print("unhandled\n"); } }
309 MSG_WEAPON_NOTIFICATIONS
317 // =========================
318 // Notification Networking
319 // =========================
322 void Read_Notification(void)
324 float net_type = ReadByte();
325 float net_name = ReadShort();
327 float stringcount = stof(Get_Field_Value(F_STRNUM, net_type, net_name));
328 float floatcount = stof(Get_Field_Value(F_FLNUM, net_type, net_name));
330 Local_Notification(net_type, net_name,
331 ((stringcount >= 1) ? ReadString() : ""),
332 ((stringcount == 2) ? ReadString() : ""),
333 ((floatcount >= 1) ? ReadLong() : 0),
334 ((floatcount >= 2) ? ReadLong() : 0),
335 ((floatcount == 3) ? ReadLong() : 0));
340 void Send_Notification(entity client, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
342 if(net_type && net_name)
344 print("notification: ", Get_Field_Value(F_NAME, net_type, net_name), ": ", ftos(net_name), ".\n");
346 float stringcount = stof(Get_Field_Value(F_STRNUM, net_type, net_name));
347 float floatcount = stof(Get_Field_Value(F_FLNUM, net_type, net_name));
349 if(notif_stringcount(s1, s2) > stringcount) { backtrace("Too many string arguments for notification!\n"); return; }
350 if(notif_floatcount(f1, f2, f3) > floatcount) { backtrace("Too many float arguments for notification!\n"); return; }
352 if(client && (clienttype(client) == CLIENTTYPE_REAL) && (client.flags & FL_CLIENT))
354 // personal/direct notification sent to ONE person and their spectators
356 WRITESPECTATABLE_MSG_ONE({
357 WriteByte(MSG_ONE, SVC_TEMPENTITY);
358 WriteByte(MSG_ONE, TE_CSQC_NOTIFICATION);
359 WriteByte(MSG_ONE, net_type);
360 WriteShort(MSG_ONE, net_name);
361 if(stringcount >= 1) { WriteString(MSG_ONE, s1); }
362 if(stringcount == 2) { WriteString(MSG_ONE, s2); }
363 if(floatcount >= 1) { WriteLong(MSG_ONE, f1); }
364 if(floatcount >= 2) { WriteLong(MSG_ONE, f2); }
365 if(floatcount == 3) { WriteLong(MSG_ONE, f3); }
370 // global notification sent to EVERYONE
371 WriteByte(MSG_ALL, SVC_TEMPENTITY);
372 WriteByte(MSG_ALL, TE_CSQC_NOTIFICATION);
373 WriteByte(MSG_ALL, net_type);
374 WriteShort(MSG_ALL, net_name);
375 if(stringcount >= 1) { WriteString(MSG_ALL, s1); }
376 if(stringcount == 2) { WriteString(MSG_ALL, s2); }
377 if(floatcount >= 1) { WriteLong(MSG_ALL, f1); }
378 if(floatcount >= 2) { WriteLong(MSG_ALL, f2); }
379 if(floatcount == 3) { WriteLong(MSG_ALL, f3); }
382 if(!server_is_local && (net_type == MSG_INFO))
384 #define MSG_INFO_NOTIF(name,strnum,flnum,args,icon,normal,gentle) \
385 { NOTIF_MATCH(name, net_name) { print(sprintf(CCR(normal_or_gentle(normal, gentle)), args)); } }
386 MSG_INFO_NOTIFICATIONS
389 else { backtrace("Incorrect usage of Send_Notification!\n"); }
392 void Send_Notification_ToTeam(float targetteam, entity except, float net_type, float net_name, string s1, string s2, float f1, float f2, float f3)
395 FOR_EACH_REALCLIENT(tmp_entity)
397 if(tmp_entity.classname == STR_PLAYER)
398 if(tmp_entity.team == targetteam)
399 if(tmp_entity != except)
401 Send_Notification(tmp_entity, net_type, net_name, s1, s2, f1, f2, f3);
406 // WARNING: use this ONLY if you need exceptions or want to exclude spectators, otherwise use Send_Notification(..., world, ...)
407 void Send_Notification_ToAll(entity except, float spectators, 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) || spectators)
413 if(tmp_entity != except)
415 Send_Notification(tmp_entity, net_type, net_name, s1, s2, f1, f2, f3);
421 // =============================
422 // LEGACY NOTIFICATION SYSTEMS
423 // =============================
425 void Send_KillNotification(string s1, string s2, string s3, float msg, float type)
427 WriteByte(MSG_ALL, SVC_TEMPENTITY);
428 WriteByte(MSG_ALL, TE_CSQC_KILLNOTIFY);
429 WriteString(MSG_ALL, s1);
430 WriteString(MSG_ALL, s2);
431 WriteString(MSG_ALL, s3);
432 WriteShort(MSG_ALL, msg);
433 WriteByte(MSG_ALL, type);
436 // Function is used to send a generic centerprint whose content CSQC gets to decide (gentle version or not in the below cases)
437 void Send_CSQC_KillCenterprint(entity e, string s1, string s2, float msg, float type)
439 if (clienttype(e) == CLIENTTYPE_REAL)
442 WRITESPECTATABLE_MSG_ONE({
443 WriteByte(MSG_ONE, SVC_TEMPENTITY);
444 WriteByte(MSG_ONE, TE_CSQC_KILLCENTERPRINT);
445 WriteString(MSG_ONE, s1);
446 WriteString(MSG_ONE, s2);
447 WriteShort(MSG_ONE, msg);
448 WriteByte(MSG_ONE, type);
453 void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num)
455 if ((clienttype(e) == CLIENTTYPE_REAL) && (e.flags & FL_CLIENT))
458 WRITESPECTATABLE_MSG_ONE({
459 WriteByte(MSG_ONE, SVC_TEMPENTITY);
460 WriteByte(MSG_ONE, TE_CSQC_CENTERPRINT_GENERIC);
461 WriteByte(MSG_ONE, id);
462 WriteString(MSG_ONE, s);
463 if (id != 0 && s != "")
465 WriteByte(MSG_ONE, duration);
466 WriteByte(MSG_ONE, countdown_num);
471 void Send_CSQC_Centerprint_Generic_Expire(entity e, float id)
473 Send_CSQC_Centerprint_Generic(e, id, "", 1, 0);