]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/notifications.qc
b60f5d9f418b87fa7a3209aec152f44b5aadd1db
[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(arg1,arg2,arg3,arg4) arg1, arg2, arg3, arg4
14 #define CLPS3(arg1,arg2,arg3) arg1, arg2, arg3
15 #define CLPS2(arg1,arg2) arg1, arg2
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, special, 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     Special:
73       MSG_INFO: NULL/FLOAT: leave as FALSE
74       MSG_NOTIFY: STRING: icon string name for the hud notify panel, "" if no icon is used
75       MSG_CENTER: FLOAT: centerprint ID number (CPID_*), NO_CPID if no CPID is needed
76       MSG_WEAPON: NULL/FLOAT: leave as FALSE
77     Normal message (string for sprintf when gentle messages are NOT enabled)
78     Gentle message (string for sprintf when gentle messages ARE enabled)
79
80  Messages have ^F1, ^F2, and ^BG in them-- these are replaced
81  with colors according to the cvars the user has chosen.
82     ^F1 = highest priority, "primary"
83     ^F2 = next highest priority, "secondary"
84     ^BG = normal/less important priority, "tertiary"
85
86  Guidlines:
87     ALWAYS start the string with a color, preferably background
88     ALWAYS end messages with a new line
89     ARIRE unir frk jvgu lbhe bja zbgure (gvc sbe zvxrrhfn)
90 */
91 #define MSG_INFO_NOTIFICATIONS \
92         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         /* nothing */
94
95 #define MSG_NOTIFY_NOTIFICATIONS \
96         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"), "") \
97         /* nothing */
98
99 #define MSG_CENTER_NOTIFICATIONS \
100         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."), "") \
101         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."), "") \
102         MSG_CENTER_NOTIF(CENTER_CTF_EVENT_PASS, CLPS2(s1, s2, s3), CPID_CTF_PASS, _("^BG%s passed the ^F1%s^BG to %s"), "") \
103         MSG_CENTER_NOTIF(CENTER_CTF_EVENT_PASS_SENT, CLPS2(s1, s2), CPID_CTF_PASS, _("^BGYou passed the ^F1%s^BG to %s"), "") \
104         MSG_CENTER_NOTIF(CENTER_CTF_EVENT_PASS_RECEIVED, CLPS2(s1, s2), CPID_CTF_PASS, _("^BGYou received the ^F1%s^BG from %s"), "") \
105         MSG_CENTER_NOTIF(CENTER_CTF_EVENT_RETURN, s1, CPID_CTF_LOWPRIO, _("^BGYou returned the ^F1%s"), "") \
106         MSG_CENTER_NOTIF(CENTER_CTF_EVENT_CAPTURE, s1, NO_CPID, _("^BGYou captured the ^F1%s"), "") \
107         /* nothing */
108
109 #define MSG_WEAPON_NOTIFICATIONS \
110         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"), "") \
111         /* nothing */
112
113 // NOW we actually activate the declarations
114 MSG_INFO_NOTIFICATIONS
115 MSG_NOTIFY_NOTIFICATIONS
116 MSG_CENTER_NOTIFICATIONS
117 MSG_WEAPON_NOTIFICATIONS
118
119 // finally, since that's done... undeclare the handlers so that we can use the list in other ways.
120 #undef MSG_INFO_NOTIF
121 #undef MSG_NOTIFY_NOTIF
122 #undef MSG_CENTER_NOTIF
123 #undef MSG_WEAPON_NOTIF
124
125
126 // ======================
127 //  Supporting Functions
128 // ======================
129
130 #ifdef SVQC
131 #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
132 #define WRITESPECTATABLE_MSG_ONE(statement) WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement)
133 #define WRITESPECTATABLE(msg,statement) if(msg == MSG_ONE) { WRITESPECTATABLE_MSG_ONE(statement); } else statement float WRITESPECTATABLE_workaround = 0
134 #endif
135
136 string CCR(string input) // color code replace, place inside of sprintf and parse the string
137 {
138         input = strreplace("^F1", "^3", input);
139         input = strreplace("^F2", "^2", input);
140         input = strreplace("^BG", "^7", input);
141
142         input = strreplace("^N", "^7", input); // "none"-- reset to white
143
144         return input;
145 }
146
147
148 // ===============================
149 //  Frontend Notification Pushing
150 // ===============================
151
152
153 // =========================
154 //  Notification Networking
155 // =========================
156
157 #ifdef CSQC
158 void Read_Notification()
159 {
160         
161 }
162 #endif
163 #ifdef SVQC
164 void Send_Notification(float type, entity client, float id, string s, float duration, float countdown_num)
165 {
166         if((clienttype(client) == CLIENTTYPE_REAL) && (client.flags & FL_CLIENT))
167         {
168                 msg_entity = client;
169                 WRITESPECTATABLE_MSG_ONE({
170                         WriteByte(MSG_ONE, SVC_TEMPENTITY);
171                         WriteByte(MSG_ONE, TE_CSQC_NOTIFICATION);
172                         WriteByte(MSG_ONE, id);
173                         WriteString(MSG_ONE, s);
174                         if (id != 0 && s != "")
175                         {
176                                 WriteByte(MSG_ONE, duration);
177                                 WriteByte(MSG_ONE, countdown_num);
178                         }
179                 });
180         }
181 }
182
183 // LEGACY NOTIFICATION SYSTEMS
184 void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num)
185 {
186         if ((clienttype(e) == CLIENTTYPE_REAL) && (e.flags & FL_CLIENT))
187         {
188                 msg_entity = e;
189                 WRITESPECTATABLE_MSG_ONE({
190                         WriteByte(MSG_ONE, SVC_TEMPENTITY);
191                         WriteByte(MSG_ONE, TE_CSQC_CENTERPRINT_GENERIC);
192                         WriteByte(MSG_ONE, id);
193                         WriteString(MSG_ONE, s);
194                         if (id != 0 && s != "")
195                         {
196                                 WriteByte(MSG_ONE, duration);
197                                 WriteByte(MSG_ONE, countdown_num);
198                         }
199                 });
200         }
201 }
202 void Send_CSQC_Centerprint_Generic_Expire(entity e, float id)
203 {
204         Send_CSQC_Centerprint_Generic(e, id, "", 1, 0);
205 }
206 #endif