]> git.xonotic.org Git - xonotic/xonotic.wiki.git/blob - Programming-QuakeC-stuff-in-Xonotic.md
Update title
[xonotic/xonotic.wiki.git] / Programming-QuakeC-stuff-in-Xonotic.md
1 **Note:** The article is written as developer notes to ease developer tasks and save QuakeC terms here.
2
3 > ## Table of Contents
4 > 1. [CSQC, MENUQC, SVQC and GAMEQC blocks](#csqc-menuqc-svqc-and-gameqc-blocks)
5 > 2. [MUTATOR functions](#mutator-functions)
6 >
7 > 2.1. [How to use MUTATOR functions](#how-to-use-mutator-functions)
8 >
9 > 2.2. [List of MUTATOR functions](#list-of-mutator-functions)
10 >
11 > 3. [Weapon functions](#weapon-functions)
12 >
13 > 3.1. [A bit of introduction](#a-bit-of-introduction)
14 >
15 > 3.2. [List of weapon functions](#list-of-weapon-functions)
16 >
17 > 4. [HUD, Menu and Draw functions](#hud-menu-and-draw-functions)
18 >
19 > 5. [Gamemodes](#gamemodes)
20 >
21 > 5.1. [Samples](#samples)
22 >
23 > 6. [Effects](#effects)
24
25 # CSQC, MENUQC, SVQC and GAMEQC blocks
26
27 Xonotic uses the ***csprogs.dat*** from the server you're playing on, as it must match the server's ***progs.dat*** code (whereas your ***menu.dat*** is always your local copy).
28
29 Menu and HUD code are actually separated as they run in 2 distinct programs: ***csprogs.dat*** and ***menu.dat***
30
31 Server program is ***progs.dat***
32
33 - Code inside a **`#ifdef CSQC`** block is part of the client code and will be compiled to **csprogs.dat**
34
35 - Code inside a **`#ifdef MENUQC`** block is part of the menu code and will be compiled to **menu.dat**
36
37 - Code inside a **`#ifdef SVQC`** block is part of the menu code and will be compiled to **progs.dat**
38
39 - Also, code inside a **`#ifdef GAMEQC`** block is part of both client (not menu) and server code.
40
41 ### A bit of explanation about the use of each type of cvars
42
43 - **g_*** cvars:
44
45 Example: `g_balance_grapplehook_speed_fly` is clearly a server or game cvar (**g_*** cvars are server and game cvars), so you CAN'T declare it within a `#ifdef CSQC` block. This type of cvar only can be declared inside a **`#ifdef SVQC`** or **`#ifdef GAMEQC`** block (if possible).
46
47 - **sv_*** cvars:
48
49 Example: `sv_campcheck` is clearly a server cvar (**sv_*** cvars are server cvars), only can be declared inside a **`#ifdef SVQC`** block.
50
51 - **cl_*** cvars:
52
53 Example: `cl_chatsound` is clearly a client cvar (**cl_*** cvars are client cvars), only can be declared inside a **`#ifdef CSQC`** block.
54
55 - **hud_*** cvars:
56
57 Example: `hud_progressbar_alpha` is a client cvar (**hud_*** cvars belong to client cvars), only can be declared inside a **`#ifdef CSQC`** block.
58
59
60 <br />
61
62 # MUTATOR functions
63
64 ### How to use MUTATOR functions
65
66 You can look the following link if you're trying/testing your own mutator: [Writing your first mutator](writing-your-first-mutator)
67
68 **Attention:** to use a hook, first register your mutator using `REGISTER_MUTATOR`, then create your function using `MUTATOR_HOOKFUNCTION`.
69
70
71 - **`REGISTER_MUTATOR`**
72
73 Registers a new `MUTATOR_HOOKFUNCTION`.
74 ```c
75 REGISTER_MUTATOR(new_mutator_name, some_variable);
76 ```
77
78
79 - **`MUTATOR_HOOKFUNCTION`**
80
81 Creates a function and calls `new_mutator_name` (from `REGISTER_MUTATOR`) and one of `#define MUTATOR()` (from `qcsrc/server/mutators/events.qh` main hooks).
82
83 Example:
84 ```c
85 MUTATOR_HOOKFUNCTION(new_mutator_name, events.qh_main_hook)
86 {
87     // whatever does
88 }
89 ```
90
91 - **`MUTATOR_CALLHOOK`**
92
93 Calls some `MUTATOR_HOOKFUNCTION`.
94 ```c
95 MUTATOR_CALLHOOK(name_of_MUTATOR_HOOKFUNCTION_or_events.qh_main_hook);
96 ```
97
98 There are different versions and depends how many variables need to be called in a `MUTATOR_HOOKFUNCTION`:
99
100 1 `MUTATOR_HOOKFUNCTION` and 1 variable:
101
102 ```c
103 MUTATOR_CALLHOOK(name_of_MUTATOR_HOOKFUNCTION_or_events.qh_main_hook, some_variable);
104 ```
105
106 1 `MUTATOR_HOOKFUNCTION` and 2 variables:
107
108 ```c
109 MUTATOR_CALLHOOK(name_of_MUTATOR_HOOKFUNCTION_or_events.qh_main_hook, some_variable, some_variable);
110 ```
111
112 1 `MUTATOR_HOOKFUNCTION` and 3 variables:
113
114 ```c
115 MUTATOR_CALLHOOK(name_of_MUTATOR_HOOKFUNCTION_or_events.qh_main_hook, some_variable, some_variable, some_variable);
116 ```
117
118 1 `MUTATOR_HOOKFUNCTION` and multiple variables:
119
120 ```c
121 MUTATOR_CALLHOOK(name_of_MUTATOR_HOOKFUNCTION_or_events.qh_main_hook, some_variable, some_variable, some_variable, some_variable, ...);
122 ```
123
124 <br />
125
126 ## List of MUTATOR functions
127
128 You can look the MUTATOR functions in:
129
130 - **COMMON:** [`qcsrc/common/mutators/events.qh`](https://timepath.github.io/scratchspace/d4/d95/common_2mutators_2events_8qh.html)
131
132 - **CLIENT:** [`qcsrc/client/mutators/events.qh`](https://timepath.github.io/scratchspace/d8/d0e/client_2mutators_2events_8qh.html)
133
134 - **SERVER:** [`qcsrc/server/mutators/events.qh`](https://timepath.github.io/scratchspace/d6/ddd/server_2mutators_2events_8qh.html)
135
136 <br />
137 <br />
138
139 # Weapon functions
140
141 ## A bit of introduction
142
143 You'll need understand that weapons can be interacted with **autocvars** variables (example: `float autocvar_g_balance_someweapon_speed;`) and each weapon with .qh file where cvars are declared without the need to declare using `autocvar_blabla...`. *Think*, *touch*, *explode* and those types of functions can be declared within an *attack* function and *whatever* it is called. Note that there are also METHODs that are necessary for the weapon to work.
144
145 - **Think** function makes the weapon shot react on what to do.
146 - **Touch** function makes the weapon shot react against some element where touch (like player, monster, vehicle, ...).
147 - **Explode** function makes the weapon explosion react.
148 - **Attack/Whatever** function is where the weapon attack executes, keep in mind that it has the other functions attached to be executed.
149
150 You can look the example of this weapon code:
151 - [**devastator.qh**](https://timepath.github.io/scratchspace/d9/dfa/devastator_8qh_source.html)
152 - [**devastator.qc**](https://timepath.github.io/scratchspace/d9/d5d/devastator_8qc_source.html)
153
154 <br />
155
156 ## List of weapon functions
157
158 This is a created list of functions to modify/create weapons. There may be incomplete explanations for each function.
159
160 There are contents taken from [`qcsrc/common/weapons/all.qh`](https://timepath.github.io/scratchspace/d0/ddd/weapons_2all_8qh_source.html)
161
162 **WARNING:** The contents may content wonky code, and the interactions can change and not do the same what happens here.
163
164 <br />
165
166 - [**W_SetupShot_Dir**](https://timepath.github.io/scratchspace/d4/d3f/tracing_8qh.html#aff0ea351757ee6caf83b25d12d18656c)
167
168 ```c
169 W_SetupShot_Dir(
170         ent,
171         wepent,
172         s_forward,
173         antilag,
174         recoil,
175         snd,
176         chan,
177         maxdamage,
178         deathtype 
179 )
180 ```
181
182 - [**W_SetupProjVelocity_Explicit**](https://timepath.github.io/scratchspace/d7/d31/tracing_8qc.html#a55f8f2b1828413bfb123a5fcb61b9f8e)
183
184 ```c
185 void W_SetupProjVelocity_Explicit(
186     entity      proj,
187     vector      dir,
188     vector      upDir,
189     float       pSpeed,
190     float       pUpSpeed,
191     float       pZSpeed,
192     float       spread,
193     float       forceAbsolute 
194 )
195 ```
196
197 - [**W_MuzzleFlash**](https://timepath.github.io/scratchspace/d0/ddd/weapons_2all_8qh_source.html)(located in **`qcsrc/common/weapons/all.qh`** line 406)
198
199 In the moment when player shots the weapon, weapon flashes. 
200
201 **Note:** write **`#ifdef SVQC`** at the start of using this function, and write with **`#endif`** after declared the function (only can do this if the code needs to be executed, although maybe you need more functions/things in the code inside this).
202
203 ```c
204 void W_MuzzleFlash(Weapon thiswep, entity actor, .entity weaponentity, vector shotorg, vector shotdir);
205 ```
206
207 - [**Weapon selection functions**](https://timepath.github.io/scratchspace/d8/d6b/selection_8qh.html)
208 (located in **`qcsrc/server/weapons/selection.qh`**)
209
210 - [**Weapon decrease ammo, speed factor, rate factor, reload functions**](https://timepath.github.io/scratchspace/d5/de0/weaponsystem_8qc.html)
211 (located in **`qcsrc/server/weapons/weaponsystem.qh`**)
212
213 <br />
214
215 # HUD, Menu and Draw functions
216
217 You can look the draw functions where HUD is being drawn: 
218 - [**Draw functions and macros (`qcsrc/client/draw.qh`)**](https://timepath.github.io/scratchspace/d5/d8d/client_2draw_8qh_source.html)
219
220 More info inside the code where you can draw/print HUD and menu: 
221 - [**Globals, constants, fonts, prints, error cmds, vector stuff, conversion functions and all drawing/printing HUDs/menus/characters related (`qcsrc/dpdefs/upstream/menudefs.qc`)**](https://timepath.github.io/scratchspace/d8/de2/menudefs_8qc_source.html)
222
223 Important changes about menus we could learn of:
224 - [**Terms of Service in window display and multiplayer dialog**](https://gitlab.com/xonotic/xonotic-data.pk3dir/-/commit/19bd3a4f)
225 - [**Welcome dialog**](https://gitlab.com/xonotic/xonotic-data.pk3dir/-/commit/19d753312f0deff7bd297822907874d532e9303e)
226 - [**A button to properly quit the campaign, a "Game menu" (on ESC) and remove the Disconnect dialogue**](https://gitlab.com/xonotic/xonotic-data.pk3dir/-/commit/2b2f743fc929bbbe0fc765edf8c433c946764607)
227 <br />
228
229 # Gamemodes
230
231 Keep in mind that to develop a gamemode, you need a map having enabled inside its *name_of_map.mapinfo* file this: `gametype shortcut_of_gamemode`. (example: `gametype tdm` (tdm is Team Deathmatch). After modifying the map file, compress the map contents, save as `.zip` and rename the extension to `.pk3`
232
233 Making gamemodes doesn't seem easy. There's a little explanation of what does each element. 
234
235 ### Generated files for gamemodes:
236
237 [`qcsrc/common/gamemodes/gamemode/_mod.inc`](https://timepath.github.io/scratchspace/d9/d67/common_2gamemodes_2__mod_8inc_source.html) generated file where the includes of each gamemode are stored.
238
239 [`qcsrc/common/gamemodes/gamemode/_mod.qh`](https://timepath.github.io/scratchspace/d7/d0b/common_2gamemodes_2__mod_8qh_source.html) generated file where the includes of each gamemode are stored.
240
241 <br />
242
243 ### Gamemode files:
244
245 - Server type:
246
247 `qcsrc/common/gamemodes/gamemode/name_of_gamemode/sv_name_of_gamemode.qc`
248
249 `qcsrc/common/gamemodes/gamemode/name_of_gamemode/sv_name_of_gamemode.qh`
250
251 <br />
252
253 - Client type:
254
255 `qcsrc/common/gamemodes/gamemode/name_of_gamemode/cl_name_of_gamemode.qc`
256
257 `qcsrc/common/gamemodes/gamemode/name_of_gamemode/cl_name_of_gamemode.qh`
258
259 <br />
260
261 - Base:
262
263 `qcsrc/common/gamemodes/gamemode/name_of_gamemode/name_of_gamemode.qc`
264
265 `qcsrc/common/gamemodes/gamemode/name_of_gamemode/name_of_gamemode.qh`
266
267 `qcsrc/common/gamemodes/gamemode/name_of_gamemode/_mod.inc` generated file where the includes of a gamemode is generated.
268
269 `qcsrc/common/gamemodes/gamemode/name_of_gamemode/_mod.qh` generated file where the includes of a gamemode is generated.
270
271 <br />
272
273 ### Optional things (if necessary):
274
275 [`qcsrc/common/ent_cs.qc`](https://timepath.github.io/scratchspace/d5/dff/ent__cs_8qc_source.html) (if an `ENTCS_PROP()` is needed for a gamemode)
276
277 [`qcsrc/common/mutators/mutator/waypoints/all.inc`](https://timepath.github.io/scratchspace/d2/d2b/mutators_2mutator_2waypoints_2all_8inc_source.html) where `REGISTER_WAYPOINT` can interact the situation of waypoints.
278
279 <br />
280
281 ### Notifications, applying BADCVAR and displaying gamemode in the menu: 
282
283 [`qcsrc/common/notifications/all.inc`](https://timepath.github.io/scratchspace/d9/d09/notifications_2all_8inc_source.html) where notifications output appears in the scenario.
284
285 [`qcsrc/common/notifications/all.qh`](https://timepath.github.io/scratchspace/dc/d8f/notifications_2all_8qh_source.html) where `CASE(CPID, NAME_OF_ELEMENT)` is needed for a gamemode.
286
287 [`qcsrc/menu/xonotic/util.qc`](https://timepath.github.io/scratchspace/df/d9b/menu_2xonotic_2util_8qc_source.html) where gamemodes can appear in the main menu (Multiplayer > Create). `GAMETYPE(MAPINFO_TYPE_NAME_OF_GAMEMODE) \`
288  
289 [`qcsrc/server/world.qc`](https://timepath.github.io/scratchspace/dd/dbe/world_8qc_source.html)  where `BADCVAR(g_*)` for each gamemode are stored.
290
291 <br />
292
293 ### Configuration files where gamemodes interact:
294
295 `xonotic-data.pk3dir/gamemodes-server.cfg` where server gamestart hooks, gametype vote hooks, respawn delay/waves/weapon_stay cvars and gamemode game/server cvars connect.
296
297 `xonotic-data.pk3dir/gamemodes-client.cfg` where client gamestart hooks cvars connect.
298
299 `xonotic-data.pk3dir/notifications.cfg` where notifications need to be activated in the scenario.
300
301 <br />
302
303 ### Menu and HUD icons:
304
305 `gfx/menu/luma/gametype_nameshortcut.tga`
306
307 `gfx/menu/luminos/gametype_nameshortcut.tga`
308
309 `gfx/menu/wickedx/gametype_nameshortcut.tga`
310
311 `gfx/menu/xaw/gametype_nameshortcut.tga`
312
313 (Example: `gametype_tdm.tga` is an icon of Team Deathmatch)
314
315 <br />
316
317 ## Samples
318
319 There are good examples of the commits and repositories of people who developed gamemodes:
320
321 - [**Lyberta's GunGame gametype commits**](https://gitlab.com/xonotic/xonotic-data.pk3dir/-/merge_requests/482/diffs)
322
323 Taken from: https://forums.xonotic.org/showthread.php?tid=7314
324
325 You can look and test the [**Lyberta's GunGame gametype repository**](https://gitlab.com/xonotic/xonotic-data.pk3dir/-/tree/Lyberta/GunGame)
326
327 - [**How Survival gamemode was developed (first commit)**](https://gitlab.com/xonotic/xonotic-data.pk3dir/-/commit/8f61a40877542ac94baa74c5ed653c77b77bd855)
328
329 It's recommended use the final product in this [**repository**](https://gitlab.com/xonotic/xonotic-data.pk3dir/-/tree/Mario/survival). Many changes have been influenced.
330
331 [**SMB modpack repository**](https://github.com/MarioSMB/modpack/tree/master/mod/common/gamemodes/survival) has added Survival gamemode and others.
332
333 # Effects
334
335 Spawns effect particle in-game.
336
337 The effects can be used with `Send_Effect(effect, org, vel, howmany)` function to test the effects from [**qcsrc/common/effects/all.inc**](https://timepath.github.io/scratchspace/d9/d95/effects_2all_8inc_source.html)
338
339 **Send_Effect** function definition is inside: [**qcsrc/common/effects/effect.qh**](https://timepath.github.io/scratchspace/d5/de6/effect_8qh_source.html)
340
341 For example, you can test the smokes, using `EFFECT_SMOKE_LARGE`:
342 ```c
343 Send_Effect(EFFECT_SMOKE_LARGE, this.origin, '0 0 0', 1);
344 ```
345
346 EFFECT list: [**qcsrc/common/effects/all.inc**](https://timepath.github.io/scratchspace/d9/d95/effects_2all_8inc_source.html)
347
348 <br />