]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/notifications.qc
Move this stuff too
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / notifications.qc
1 // ================================================
2 //  Unified notification system, written by Samual
3 //  Last updated: September, 2012
4 // ================================================
5
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)
11
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
16
17 // accumulate functions for declarations
18 #define NOTIF_FIRST 1
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;
24
25 #define MSG_INFO_NOTIF(name,args,normal,gentle) \
26         float name; \
27         void DecNotif_##name() { \
28                 if(!name) { \
29                         name = (NOTIF_FIRST + NOTIF_INFO_COUNT); \
30                         ++NOTIF_INFO_COUNT; } } \
31         ACCUMULATE_FUNCTION(DecNotifs, DecNotif_##name)
32
33 #define MSG_NOTIFY_NOTIF(name,args,icon,normal,gentle) \
34         float name; \
35         void DecNotif_##name() { \
36                 if(!name) { \
37                         name = (NOTIF_FIRST + NOTIF_NOTIFY_COUNT); \
38                         ++NOTIF_NOTIFY_COUNT; } } \
39         ACCUMULATE_FUNCTION(DecNotifs, DecNotif_##name)
40
41 #define MSG_CENTER_NOTIF(name,args,cpid,normal,gentle) \
42         float name; \
43         float cpid; \
44         void DecNotif_##name() { \
45                 if(!name) { \
46                         name = (NOTIF_FIRST + NOTIF_CENTER_COUNT); \
47                         ++NOTIF_CENTER_COUNT; } \
48                 if(!cpid) { \
49                         cpid = (NOTIF_FIRST + NOTIF_CPID_COUNT); \
50                         ++NOTIF_CPID_COUNT; } } \
51         ACCUMULATE_FUNCTION(DecNotifs, DecNotif_##name)
52
53 #define MSG_WEAPON_NOTIF(name,args,normal,gentle) \
54         float name; \
55         void DecNotif_##name() { \
56                 if(!name) { \
57                         name = (NOTIF_FIRST + NOTIF_WEAPON_COUNT); \
58                         ++NOTIF_WEAPON_COUNT; } } \
59         ACCUMULATE_FUNCTION(DecNotifs, DecNotif_##name)
60
61
62 // ====================================
63 //  Notifications List and Information
64 // ====================================
65 /*
66  List of all notifications (including identifiers and display information)
67  Format: name, number, args, icon/CPID, normal, gentle
68  Specifications:
69     Name of notification
70     ID number of notification
71     Arguments for sprintf(string, args), if no args needed then use ""
72     Icon/CPID:
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)
77
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"
83
84  Guidlines:
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)
88 */
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"), "") \
91         #undef MSG_INFO_NOTIF
92
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
96
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
106
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
110
111 // NOW we actually activate the declarations
112 MSG_INFO_NOTIFICATIONS
113 MSG_NOTIFY_NOTIFICATIONS
114 MSG_CENTER_NOTIFICATIONS
115 MSG_WEAPON_NOTIFICATIONS
116
117
118 // ======================
119 //  Supporting Functions
120 // ======================
121
122 #ifdef SVQC
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
126 #endif
127
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)
130
131 string CCR(string input) // color code replace, place inside of sprintf and parse the string
132 {
133         input = strreplace("^F1", "^3", input);
134         input = strreplace("^F2", "^2", input);
135         input = strreplace("^BG", "^7", input);
136
137         input = strreplace("^N", "^7", input); // "none"-- reset to white
138
139         return input;
140 }
141
142
143 // ===============================
144 //  Frontend Notification Pushing
145 // ===============================
146
147
148 // =========================
149 //  Notification Networking
150 // =========================
151
152 #ifdef CSQC
153 void Read_Notification()
154 {
155         float net_type = ReadByte();
156         float net_name = ReadByte();
157         string s1 = ReadString();
158         string s2 = ReadString();
159         string s3 = ReadString();
160
161         switch(net_type)
162         {
163                 case MSG_INFO:
164                 {
165                         break;
166                 }
167
168                 case MSG_NOTIFY:
169                 {
170                         break;
171                 }
172
173                 case MSG_CENTER:
174                 {
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); } }
177
178                         MSG_CENTER_NOTIFICATIONS
179                         break;
180                 }
181
182                 case MSG_WEAPON:
183                 {
184                         break;
185                 }
186         }
187 }
188 #endif
189 #ifdef SVQC
190 void Send_Notification(float type, entity client, float id, string s, float duration, float countdown_num)
191 {
192         //WriteByte(
193         if((clienttype(client) == CLIENTTYPE_REAL) && (client.flags & FL_CLIENT))
194         {
195                 msg_entity = 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 != "")
202                         {
203                                 WriteByte(MSG_ONE, duration);
204                                 WriteByte(MSG_ONE, countdown_num);
205                         }
206                 });
207         }
208 }
209
210 // LEGACY NOTIFICATION SYSTEMS
211 void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num)
212 {
213         if ((clienttype(e) == CLIENTTYPE_REAL) && (e.flags & FL_CLIENT))
214         {
215                 msg_entity = e;
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 != "")
222                         {
223                                 WriteByte(MSG_ONE, duration);
224                                 WriteByte(MSG_ONE, countdown_num);
225                         }
226                 });
227         }
228 }
229 void Send_CSQC_Centerprint_Generic_Expire(entity e, float id)
230 {
231         Send_CSQC_Centerprint_Generic(e, id, "", 1, 0);
232 }
233 #endif