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