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 // information messages (sent to console)
8 #define MSG_NOTIFY 2 // events to be sent to the notification panel
9 #define MSG_CENTER 3 // centerprint messages
10 #define MSG_WEAPON 4 // weapon messages (like "You got the Nex", sent to weapon notify panel)
12 // collapse multiple arguments into one argument
13 #define CLPS4(s1,s2,s3,s4) s1, s2, s3, s4
14 #define CLPS3(s1,s2,s3) s1, s2, s3
15 #define CLPS2(s1,s2) s1, s2
17 // accumulate functions for declarations
19 float NOTIF_INFO_COUNT;
20 float NOTIF_NOTIFY_COUNT;
21 float NOTIF_CENTER_COUNT;
22 float NOTIF_WEAPON_COUNT;
23 float NOTIF_CPID_COUNT;
25 #define MSG_INFO_NOTIF(name,args,normal,gentle) \
27 void DecNotif_##name() { \
29 name = (NOTIF_FIRST + NOTIF_INFO_COUNT); \
30 ++NOTIF_INFO_COUNT; } } \
31 ACCUMULATE_FUNCTION(DecNotifs, DecNotif_##name)
33 #define MSG_NOTIFY_NOTIF(name,args,icon,normal,gentle) \
35 void DecNotif_##name() { \
37 name = (NOTIF_FIRST + NOTIF_NOTIFY_COUNT); \
38 ++NOTIF_NOTIFY_COUNT; } } \
39 ACCUMULATE_FUNCTION(DecNotifs, DecNotif_##name)
41 #define MSG_CENTER_NOTIF(name,args,cpid,normal,gentle) \
44 void DecNotif_##name() { \
46 name = (NOTIF_FIRST + NOTIF_CENTER_COUNT); \
47 ++NOTIF_CENTER_COUNT; } \
49 cpid = (NOTIF_FIRST + NOTIF_CPID_COUNT); \
50 ++NOTIF_CPID_COUNT; } } \
51 ACCUMULATE_FUNCTION(DecNotifs, DecNotif_##name)
53 #define MSG_WEAPON_NOTIF(name,args,normal,gentle) \
55 void DecNotif_##name() { \
57 name = (NOTIF_FIRST + NOTIF_WEAPON_COUNT); \
58 ++NOTIF_WEAPON_COUNT; } } \
59 ACCUMULATE_FUNCTION(DecNotifs, DecNotif_##name)
62 // ====================================
63 // Notifications List and Information
64 // ====================================
66 List of all notifications (including identifiers and display information)
67 Format: name, number, args, icon/CPID, normal, gentle
70 ID number of notification
71 Arguments for sprintf(string, args), if no args needed then use ""
73 MSG_NOTIFY: STRING: icon string name for the hud notify panel, "" if no icon is used
74 MSG_CENTER: FLOAT: centerprint ID number (CPID_*), NO_CPID if no CPID is needed
75 Normal message (string for sprintf when gentle messages are NOT enabled)
76 Gentle message (string for sprintf when gentle messages ARE enabled)
78 Messages have ^F1, ^F2, and ^BG in them-- these are replaced
79 with colors according to the cvars the user has chosen.
80 ^F1 = highest priority, "primary"
81 ^F2 = next highest priority, "secondary"
82 ^BG = normal/less important priority, "tertiary"
85 ALWAYS start the string with a color, preferably background
86 ALWAYS end messages with a new line
87 ARIRE unir frk jvgu lbhe bja zbgure (gvc sbe zvxrrhfn)
89 #define MSG_INFO_NOTIFICATIONS \
90 MSG_INFO_NOTIF(DEATH_MARBLES_LOST, CLPS3(s1, s2, s3), _("^F1%s^BG lost their marbles against ^F1%s^BG using the ^F2%s^BG\n"), "") \
93 #define MSG_NOTIFY_NOTIFICATIONS \
94 MSG_NOTIFY_NOTIF(DEATH_MARBLES_LOST2, CLPS3(s1, s2, s3), "notify_death", _("^F1%s^BG lost their marbles against ^F1%s^BG using the ^F2%s^BG\n"), "") \
95 #undef MSG_NOTIFY_NOTIF
97 #define MSG_CENTER_NOTIFICATIONS \
98 MSG_CENTER_NOTIF(CENTER_CTF_CAPTURESHIELD_SHIELDED, "", CPID_CTF_CAPTURESHIELD, _("^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."), "") \
99 MSG_CENTER_NOTIF(CENTER_CTF_CAPTURESHIELD_FREE, "", CPID_CTF_CAPTURESHIELD, _("^BGYou are now free.\n^BGFeel free to ^F2try to capture^BG the flag again\n^BGif you think you will succeed."), "") \
100 MSG_CENTER_NOTIF(CENTER_CTF_EVENT_PASS, CLPS2(s1, s2, s3), CPID_CTF_PASS, _("^BG%s passed the ^F1%s^BG to %s"), "") \
101 MSG_CENTER_NOTIF(CENTER_CTF_EVENT_PASS_SENT, CLPS2(s1, s2), CPID_CTF_PASS, _("^BGYou passed the ^F1%s^BG to %s"), "") \
102 MSG_CENTER_NOTIF(CENTER_CTF_EVENT_PASS_RECEIVED, CLPS2(s1, s2), CPID_CTF_PASS, _("^BGYou received the ^F1%s^BG from %s"), "") \
103 MSG_CENTER_NOTIF(CENTER_CTF_EVENT_RETURN, s1, CPID_CTF_LOWPRIO, _("^BGYou returned the ^F1%s"), "") \
104 MSG_CENTER_NOTIF(CENTER_CTF_EVENT_CAPTURE, s1, NO_CPID, _("^BGYou captured the ^F1%s"), "") \
105 #undef MSG_CENTER_NOTIF
107 #define MSG_WEAPON_NOTIFICATIONS \
108 MSG_WEAPON_NOTIF(DEATH_MARBLES_LOST3, CLPS3(s1, s2, s3), _("^F1%s^BG lost their marbles against ^F1%s^BG using the ^F2%s^BG\n"), "") \
109 #undef MSG_WEAPON_NOTIF
111 // NOW we actually activate the declarations
112 MSG_INFO_NOTIFICATIONS
113 MSG_NOTIFY_NOTIFICATIONS
114 MSG_CENTER_NOTIFICATIONS
115 MSG_WEAPON_NOTIFICATIONS
118 // ======================
119 // Supporting Functions
120 // ======================
123 #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
124 #define WRITESPECTATABLE_MSG_ONE(statement) WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement)
125 #define WRITESPECTATABLE(msg,statement) if(msg == MSG_ONE) { WRITESPECTATABLE_MSG_ONE(statement); } else statement float WRITESPECTATABLE_workaround = 0
128 #define NORMAL_OR_GENTLE(normal,gentle) ((autocvar_cl_gentle || autocvar_cl_gentle_messages) ? gentle : normal)
129 #define HANDLE_CPID(cpid) ((min(256, cpid) == NO_CPID) ? FALSE : cpid)
131 string CCR(string input) // color code replace, place inside of sprintf and parse the string
133 input = strreplace("^F1", "^3", input);
134 input = strreplace("^F2", "^2", input);
135 input = strreplace("^BG", "^7", input);
137 input = strreplace("^N", "^7", input); // "none"-- reset to white
143 // ===============================
144 // Frontend Notification Pushing
145 // ===============================
148 // =========================
149 // Notification Networking
150 // =========================
153 void Read_Notification()
155 float net_type = ReadByte();
156 float net_name = ReadByte();
157 string s1 = ReadString();
158 string s2 = ReadString();
159 string s3 = ReadString();
175 #define MSG_CENTER_NOTIF(name,args,cpid,normal,gentle) \
176 { if(min(256, name) == net_name) { centerprint_generic(HANDLE_CPID(cpid), sprintf(CCR(NORMAL_OR_GENTLE(normal, gentle)), args), 0, 0); } }
178 MSG_CENTER_NOTIFICATIONS
190 void Send_Notification(float type, entity client, float id, string s, float duration, float countdown_num)
193 if((clienttype(client) == CLIENTTYPE_REAL) && (client.flags & FL_CLIENT))
196 WRITESPECTATABLE_MSG_ONE({
197 WriteByte(MSG_ONE, SVC_TEMPENTITY);
198 WriteByte(MSG_ONE, TE_CSQC_NOTIFICATION);
199 WriteByte(MSG_ONE, id);
200 WriteString(MSG_ONE, s);
201 if (id != 0 && s != "")
203 WriteByte(MSG_ONE, duration);
204 WriteByte(MSG_ONE, countdown_num);
210 // LEGACY NOTIFICATION SYSTEMS
211 void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num)
213 if ((clienttype(e) == CLIENTTYPE_REAL) && (e.flags & FL_CLIENT))
216 WRITESPECTATABLE_MSG_ONE({
217 WriteByte(MSG_ONE, SVC_TEMPENTITY);
218 WriteByte(MSG_ONE, TE_CSQC_CENTERPRINT_GENERIC);
219 WriteByte(MSG_ONE, id);
220 WriteString(MSG_ONE, s);
221 if (id != 0 && s != "")
223 WriteByte(MSG_ONE, duration);
224 WriteByte(MSG_ONE, countdown_num);
229 void Send_CSQC_Centerprint_Generic_Expire(entity e, float id)
231 Send_CSQC_Centerprint_Generic(e, id, "", 1, 0);