]> git.xonotic.org Git - xonotic/xonotic.wiki.git/blob - Functions-and-other-programming-QuakeC-things-in-Xonotic.md
Fixed some incorrect example, added more MUTATOR functions
[xonotic/xonotic.wiki.git] / Functions-and-other-programming-QuakeC-things-in-Xonotic.md
1 **Note:** The article is written as developer notes to ease developer tasks and save QuakeC function terms here. Some references are taken from `events.qh`.
2
3
4 # MUTATOR functions (from: `qcsrc/server/mutators/events.qh`)
5
6 ### Introduction
7
8 How to use MUTATOR functions:
9
10 **Attention:** to use a hook, first register your mutator using `REGISTER_MUTATOR`, then create your function using `MUTATOR_HOOKFUNCTION`.
11
12
13 - **`REGISTER_MUTATOR`**
14
15 Registers a new `MUTATOR_HOOKFUNCTION`.
16 ```c
17 REGISTER_MUTATOR(new_mutator_name, some_variable);
18 ```
19
20
21 - **`MUTATOR_HOOKFUNCTION`**
22
23 Creates a function and calls `new_mutator_name` (from `REGISTER_MUTATOR`) and one of `#define MUTATOR()` (from `qcsrc/server/mutators/events.qh` main hooks).
24
25 Example:
26 ```c
27 MUTATOR_HOOKFUNCTION(new_mutator_name_or_events.qh_main_hook, PlayerSpawn)
28 {
29     // whatever does
30 }
31 ```
32
33 - **`MUTATOR_CALLHOOK`**
34
35 Calls some `MUTATOR_HOOKFUNCTION`.
36 ```c
37 MUTATOR_CALLHOOK(name_of_MUTATOR_HOOKFUNCTION_or_events.qh_main_hook);
38 ```
39
40 There are different versions and depends how many variables need to be called in a `MUTATOR_HOOKFUNCTION`:
41
42 1 `MUTATOR_HOOKFUNCTION` and 1 variable:
43
44 ```c
45 MUTATOR_CALLHOOK(name_of_MUTATOR_HOOKFUNCTION_or_events.qh_main_hook, some_variable);
46 ```
47
48 1 `MUTATOR_HOOKFUNCTION` and 2 variables:
49
50 ```c
51 MUTATOR_CALLHOOK(name_of_MUTATOR_HOOKFUNCTION_or_events.qh_main_hook, some_variable, some_variable);
52 ```
53
54 1 `MUTATOR_HOOKFUNCTION` and 3 variables:
55
56 ```c
57 MUTATOR_CALLHOOK(name_of_MUTATOR_HOOKFUNCTION_or_events.qh_main_hook, some_variable, some_variable, some_variable);
58 ```
59
60 1 `MUTATOR_HOOKFUNCTION` and multiple variables:
61
62 ```c
63 MUTATOR_CALLHOOK(name_of_MUTATOR_HOOKFUNCTION_or_events.qh_main_hook, some_variable, some_variable, some_variable, some_variable, ...);
64 ```
65
66 <br />
67 <br />
68
69
70 ## List of MUTATOR functions
71
72 - **`MakePlayerObserver`**
73
74 Called when a player becomes observer, after shared setup.
75 ```c
76 #define EV_MakePlayerObserver(i, o) \
77     /** player */ i(entity, MUTATOR_ARGV_0_entity) \
78     /**/
79 MUTATOR_HOOKABLE(MakePlayerObserver, EV_MakePlayerObserver)
80 ```
81
82 - **`PutClientInServer`**
83
84 Called when client spawns in server. (Not sure described)
85 ```c
86 #define EV_PutClientInServer(i, o) \
87         /** client wanting to spawn */ i(entity, MUTATOR_ARGV_0_entity) \
88     /**/
89 MUTATOR_HOOKABLE(PutClientInServer, EV_PutClientInServer);
90 ```
91
92 - **`ForbidSpawn`**
93
94 Returns true to prevent a spectator/observer to spawn as player.
95 ```c
96  #define EV_ForbidSpawn(i, o) \
97     /** player */ i(entity, MUTATOR_ARGV_0_entity) \
98     /**/
99 MUTATOR_HOOKABLE(ForbidSpawn, EV_ForbidSpawn);
100 ```
101
102 - **`AutoJoinOnConnection`**
103
104 Returns true if client should be put as player on connection.
105 ```c
106 #define EV_AutoJoinOnConnection(i, o) \
107     /** player */ i(entity, MUTATOR_ARGV_0_entity) \
108     /**/
109 MUTATOR_HOOKABLE(AutoJoinOnConnection, EV_AutoJoinOnConnection);
110 ```
111
112 - **`ForbidRandomStartWeapons`**
113
114 Called when player spawns to determine whether to give them random start weapons. Return true to forbid giving them.
115 ```c
116 #define EV_ForbidRandomStartWeapons(i, o) \
117         /** player */ i(entity, MUTATOR_ARGV_0_entity) \
118     /**/
119 MUTATOR_HOOKABLE(ForbidRandomStartWeapons, EV_ForbidRandomStartWeapons);
120 ```
121
122 - **`PlayerSpawn`**
123
124 Called when a player spawns as player, after shared setup, before his weapon is chosen (so items may be changed in here)
125
126 ```c
127 #define EV_PlayerSpawn(i, o) \
128     /** player spawning */ i(entity, MUTATOR_ARGV_0_entity) \
129     /** spot that was used, or NULL */ i(entity, MUTATOR_ARGV_1_entity) \
130     /**/
131 MUTATOR_HOOKABLE(PlayerSpawn, EV_PlayerSpawn);
132 ```
133
134 - **`PlayerWeaponSelect`**
135
136 Called after a player's weapon is chosen so it can be overriden here.
137 ```c
138 #define EV_PlayerWeaponSelect(i, o) \
139         /** player spawning */ i(entity, MUTATOR_ARGV_0_entity) \
140     /**/
141 MUTATOR_HOOKABLE(PlayerWeaponSelect, EV_PlayerWeaponSelect);
142 ```
143
144 - **`reset_map_global`**
145
146 Called in reset_map.
147 ```c
148 #define EV_reset_map_global(i, o) \
149     /**/
150 MUTATOR_HOOKABLE(reset_map_global, EV_reset_map_global);
151 ```
152
153 - **`reset_map_players`**
154
155 Called in reset_map.
156 ```c
157 #define EV_reset_map_players(i, o) \
158     /**/
159 MUTATOR_HOOKABLE(reset_map_players, EV_reset_map_players);
160 ```
161
162 - **`ForbidPlayerScore_Clear`**
163
164 Returns 1 if clearing player score shall not be allowed.
165 ```c
166 #define EV_ForbidPlayerScore_Clear(i, o) \
167     /**/
168 MUTATOR_HOOKABLE(ForbidPlayerScore_Clear, EV_ForbidPlayerScore_Clear);
169 ```
170
171 - **`ClientDisconnect`**
172
173 Called when a player disconnects.
174 ```c
175 #define EV_ClientDisconnect(i, o) \
176     /** player */ i(entity, MUTATOR_ARGV_0_entity) \
177     /**/
178 MUTATOR_HOOKABLE(ClientDisconnect, EV_ClientDisconnect);
179 ```
180
181 - **`PlayerDies`**
182
183 Called when a player dies to e.g. remove stuff he was carrying.
184 ```c
185 #define EV_PlayerDies(i, o) \
186         /** inflictor           */ i(entity, MUTATOR_ARGV_0_entity) \
187     /** attacker        */ i(entity, MUTATOR_ARGV_1_entity) \
188     /** target                  */ i(entity, MUTATOR_ARGV_2_entity) \
189     /** deathtype       */ i(float,  MUTATOR_ARGV_3_float) \
190     /** damage         */ i(float,  MUTATOR_ARGV_4_float) \
191     /** damage                  */ o(float,  MUTATOR_ARGV_4_float) \
192     /**/
193 MUTATOR_HOOKABLE(PlayerDies, EV_PlayerDies);
194 ```
195
196 - **`PlayerDied`**
197
198 Called after a player died.
199 ```c
200 #define EV_PlayerDied(i, o) \
201     /** player                  */ i(entity, MUTATOR_ARGV_0_entity) \
202     /**/
203 MUTATOR_HOOKABLE(PlayerDied, EV_PlayerDied);
204 ```
205
206 - **`ClientObituary`**
207
208 Called when showing an obituary for the player. Returns true to show nothing (workarounds may be needed).
209 ```c
210 #define EV_ClientObituary(i, o) \
211     /** inflictor       */ i(entity, MUTATOR_ARGV_0_entity) \
212     /** attacker        */ i(entity, MUTATOR_ARGV_1_entity) \
213     /** target          */ i(entity, MUTATOR_ARGV_2_entity) \
214     /** deathtype       */ i(float,  MUTATOR_ARGV_3_float) \
215     /** wep entity      */ i(entity, MUTATOR_ARGV_4_entity) \
216     /** anonymous killer*/ o(bool,   MUTATOR_ARGV_5_bool) \
217     /**/
218 MUTATOR_HOOKABLE(ClientObituary, EV_ClientObituary);
219 ```
220
221 - **`FragCenterMessage`**
222
223 Allows overriding the frag centerprint messages.
224 ```c
225 #define EV_FragCenterMessage(i, o) \
226     /** attacker       */ i(entity, MUTATOR_ARGV_0_entity) \
227     /** target         */ i(entity, MUTATOR_ARGV_1_entity) \
228     /** deathtype      */ i(float, MUTATOR_ARGV_2_float) \
229     /** attacker kcount*/ i(int,  MUTATOR_ARGV_3_int) \
230     /** targ killcount */ i(int,  MUTATOR_ARGV_4_int) \
231     /**/
232 MUTATOR_HOOKABLE(FragCenterMessage, EV_FragCenterMessage);
233 ```
234
235 - **`PlayHitsound`**
236
237 Called when a player dies to e.g. remove stuff he was carrying.
238 ```c
239 #define EV_PlayHitsound(i, o) \
240     /** victim */ i(entity, MUTATOR_ARGV_0_entity) \
241     /** attacker */ i(entity, MUTATOR_ARGV_1_entity) \
242     /**/
243 MUTATOR_HOOKABLE(PlayHitsound, EV_PlayHitsound);
244 ```
245
246 - **`ItemModel`**
247
248 Called when an item model is about to be set, allows custom paths etc.
249 ```c
250 #define EV_ItemModel(i, o) \
251     /** model       */ i(string, MUTATOR_ARGV_0_string) \
252     /** output      */ i(string, MUTATOR_ARGV_1_string) \
253     /**/               o(string, MUTATOR_ARGV_1_string) \
254     /**/
255 MUTATOR_HOOKABLE(ItemModel, EV_ItemModel);
256 ```
257
258 - **`ItemSound`**
259
260 Called when an item sound is about to be played, allows custom paths etc.
261 ```c
262 #define EV_ItemSound(i, o) \
263     /** sound       */ i(string, MUTATOR_ARGV_0_string) \
264     /** output      */ i(string, MUTATOR_ARGV_1_string) \
265     /**/               o(string, MUTATOR_ARGV_1_string) \
266     /**/
267 MUTATOR_HOOKABLE(ItemSound, EV_ItemSound);
268 ```
269
270 - **`GiveFragsForKill`**
271
272 Called when someone was fragged by "self", and is expected to change frag_score to adjust scoring for the kill.
273 ```c
274 #define EV_GiveFragsForKill(i, o) \
275     /** attacker   */ i(entity, MUTATOR_ARGV_0_entity) \
276     /** target     */ i(entity, MUTATOR_ARGV_1_entity) \
277     /** frag score */ i(float, MUTATOR_ARGV_2_float) \
278     /**            */ o(float, MUTATOR_ARGV_2_float) \
279     /** deathtype  */ i(float, MUTATOR_ARGV_3_float) \
280     /** wep entity */ i(entity, MUTATOR_ARGV_4_entity) \
281     /**/
282 MUTATOR_HOOKABLE(GiveFragsForKill, EV_GiveFragsForKill);
283 ```
284
285 - **`MatchEnd`**
286
287 Called when the match ends.
288 ```c
289 MUTATOR_HOOKABLE(MatchEnd, EV_NO_ARGS);
290 ```
291
292 - **`TeamBalance_CheckAllowedTeams`**
293
294 Allows adjusting allowed teams. Return true to use the bitmask value and set non-empty string to use team entity name. Both behaviors can be active at the same time and will stack allowed teams.
295 ```c
296 #define EV_TeamBalance_CheckAllowedTeams(i, o) \
297     /** mask of teams      */ i(float, MUTATOR_ARGV_0_float) \
298     /**/                      o(float, MUTATOR_ARGV_0_float) \
299     /** team entity name   */ i(string, MUTATOR_ARGV_1_string) \
300     /**/                      o(string, MUTATOR_ARGV_1_string) \
301     /** player checked     */ i(entity, MUTATOR_ARGV_2_entity) \
302     /**/
303 MUTATOR_HOOKABLE(TeamBalance_CheckAllowedTeams, EV_TeamBalance_CheckAllowedTeams);
304 ```
305
306
307 <br />
308 <br />
309
310
311 - **`Damage_Calculate`**
312
313 Called to adjust damage and force values which are applied to the player, used for e.g. strength damage/force multiplier, I'm not sure if I should change this around slightly (Naming of the entities, and also how they're done in g_damage).
314
315 ```c
316 #define EV_Damage_Calculate(i, o) \
317     /** inflictor               */ i(entity, MUTATOR_ARGV_0_entity) \
318     /** attacker        */ i(entity, MUTATOR_ARGV_1_entity) \
319     /** target                  */ i(entity, MUTATOR_ARGV_2_entity) \
320     /** deathtype       */ i(float,  MUTATOR_ARGV_3_float) \
321     /** damage          */ i(float,  MUTATOR_ARGV_4_float) \
322     /** damage                  */ o(float,  MUTATOR_ARGV_4_float) \
323     /** mirrordamage    */ i(float,  MUTATOR_ARGV_5_float) \
324     /** mirrordamage    */ o(float,  MUTATOR_ARGV_5_float) \
325     /** force           */ i(vector, MUTATOR_ARGV_6_vector) \
326     /** force           */ o(vector, MUTATOR_ARGV_6_vector) \
327     /** weapon entity   */ i(entity, MUTATOR_ARGV_7_entity) \
328     /**/
329 MUTATOR_HOOKABLE(Damage_Calculate, EV_Damage_Calculate);
330 ```
331 <br />
332 <br />
333
334 AND.... STILL in process