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