]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/weapons/all.qc
Use explicit IMPLEMENTATION guard
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / weapons / all.qc
1 #ifndef WEAPONS_ALL_C
2 #define WEAPONS_ALL_C
3
4 #include "all.qh"
5
6 #if defined(CSQC)
7         #include "../../dpdefs/csprogsdefs.qh"
8         #include "../../client/defs.qh"
9         #include "../constants.qh"
10         #include "../stats.qh"
11         #include "../../warpzonelib/anglestransform.qh"
12         #include "../../warpzonelib/mathlib.qh"
13         #include "../../warpzonelib/common.qh"
14         #include "../../warpzonelib/client.qh"
15         #include "../util.qh"
16         #include "../buffs.qh"
17         #include "../../client/autocvars.qh"
18         #include "../deathtypes.qh"
19         #include "../../csqcmodellib/interpolate.qh"
20         #include "../movetypes/movetypes.qh"
21         #include "../../client/main.qh"
22         #include "../../csqcmodellib/cl_model.qh"
23 #elif defined(MENUQC)
24 #elif defined(SVQC)
25         #include "../../dpdefs/progsdefs.qh"
26     #include "../../dpdefs/dpextensions.qh"
27     #include "../../warpzonelib/anglestransform.qh"
28     #include "../../warpzonelib/mathlib.qh"
29     #include "../../warpzonelib/common.qh"
30     #include "../../warpzonelib/util_server.qh"
31     #include "../../warpzonelib/server.qh"
32     #include "../constants.qh"
33     #include "../stats.qh"
34     #include "../teams.qh"
35     #include "../util.qh"
36     #include "../buffs.qh"
37     #include "../monsters/all.qh"
38     #include "config.qh"
39     #include "../../server/weapons/csqcprojectile.qh"
40     #include "../../server/weapons/tracing.qh"
41     #include "../../server/t_items.qh"
42     #include "../../server/autocvars.qh"
43     #include "../../server/constants.qh"
44     #include "../../server/defs.qh"
45     #include "../notifications.qh"
46     #include "../deathtypes.qh"
47     #include "../../server/mutators/mutators_include.qh"
48     #include "../mapinfo.qh"
49     #include "../../server/command/common.qh"
50     #include "../../csqcmodellib/sv_model.qh"
51     #include "../../server/portals.qh"
52     #include "../../server/g_hook.qh"
53 #endif
54 #ifndef MENUQC
55 #include "calculations.qc"
56 #endif
57 #define IMPLEMENTATION
58 #include "all.inc"
59 #undef IMPLEMENTATION
60
61 // WEAPON PLUGIN SYSTEM
62 entity weapon_info[WEP_MAXCOUNT];
63 entity dummy_weapon_info;
64
65 #if WEP_MAXCOUNT > 72
66 # error Kein Weltraum links auf dem Gerät
67 #endif
68
69 WepSet WepSet_FromWeapon(int a) {
70         a -= WEP_FIRST;
71 #if WEP_MAXCOUNT > 24
72         if(a >= 24) {
73                 a -= 24;
74 #if WEP_MAXCOUNT > 48
75                 if(a >= 24) {
76                         a -= 24;
77                         return '0 0 1' * power2of(a);
78                 }
79 #endif
80                 return '0 1 0' * power2of(a);
81         }
82 #endif
83         return '1 0 0' * power2of(a);
84 }
85 #ifdef SVQC
86 void WepSet_AddStat()
87 {
88         addstat(STAT_WEAPONS, AS_INT, weapons_x);
89 #if WEP_MAXCOUNT > 24
90         addstat(STAT_WEAPONS2, AS_INT, weapons_y);
91 #if WEP_MAXCOUNT > 48
92         addstat(STAT_WEAPONS3, AS_INT, weapons_z);
93 #endif
94 #endif
95 }
96 void WepSet_AddStat_InMap()
97 {
98         addstat(STAT_WEAPONSINMAP, AS_INT, weaponsinmap_x);
99 #if WEP_MAXCOUNT > 24
100         addstat(STAT_WEAPONSINMAP2, AS_INT, weaponsinmap_y);
101 #if WEP_MAXCOUNT > 48
102         addstat(STAT_WEAPONSINMAP3, AS_INT, weaponsinmap_z);
103 #endif
104 #endif
105 }
106 void WriteWepSet(float dst, WepSet w)
107 {
108 #if WEP_MAXCOUNT > 48
109         WriteInt72_t(dst, w);
110 #elif WEP_MAXCOUNT > 24
111         WriteInt48_t(dst, w);
112 #else
113         WriteInt24_t(dst, w.x);
114 #endif
115 }
116 #endif
117 #ifdef CSQC
118 WepSet WepSet_GetFromStat()
119 {
120         WepSet w = '0 0 0';
121         w.x = getstati(STAT_WEAPONS);
122 #if WEP_MAXCOUNT > 24
123         w.y = getstati(STAT_WEAPONS2);
124 #if WEP_MAXCOUNT > 48
125         w.z = getstati(STAT_WEAPONS3);
126 #endif
127 #endif
128         return w;
129 }
130 WepSet WepSet_GetFromStat_InMap()
131 {
132         WepSet w = '0 0 0';
133         w_x = getstati(STAT_WEAPONSINMAP);
134 #if WEP_MAXCOUNT > 24
135         w_y = getstati(STAT_WEAPONSINMAP2);
136 #if WEP_MAXCOUNT > 48
137         w_z = getstati(STAT_WEAPONSINMAP3);
138 #endif
139 #endif
140         return w;
141 }
142 WepSet ReadWepSet()
143 {
144 #if WEP_MAXCOUNT > 48
145         return ReadInt72_t();
146 #elif WEP_MAXCOUNT > 24
147         return ReadInt48_t();
148 #else
149         return ReadInt24_t() * '1 0 0';
150 #endif
151 }
152 #endif
153
154 void register_weapon(
155         int id,
156         WepSet bit,
157         bool(int) func,
158         .int ammotype,
159         int i,
160         int weapontype,
161         float pickupbasevalue,
162         vector clr,
163         string modelname,
164         string simplemdl,
165         string crosshair,
166         string wepimg,
167         string refname,
168         string wepname)
169 {
170         entity e;
171         weapon_info[id - 1] = e = spawn();
172         e.classname = "weapon_info";
173         e.weapon = id;
174         e.weapons = bit;
175         e.weapon_func = func;
176         e.ammo_field = ammotype;
177         e.impulse = i;
178         e.spawnflags = weapontype;
179         e.bot_pickupbasevalue = pickupbasevalue;
180         e.wpcolor = clr;
181         e.wpmodel = strzone(strcat("wpn-", ftos(id)));
182         e.mdl = modelname;
183         e.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
184         e.w_simplemdl = strzone(simplemdl); // simpleitems weapon model/image
185         e.w_crosshair = strzone(car(crosshair));
186         string s = cdr(crosshair);
187         e.w_crosshair_size = ((s != "") ? stof(s) : 1); // so that we can scale the crosshair from code (for compat)
188         e.model2 = strzone(wepimg);
189         e.netname = refname;
190         e.message = wepname;
191
192         #ifdef CSQC
193         func(WR_INIT);
194         #endif
195 }
196 bool w_null(int dummy)
197 {
198         return 0;
199 }
200 void register_weapons_done()
201 {
202         dummy_weapon_info = spawn();
203         dummy_weapon_info.classname = "weapon_info";
204         dummy_weapon_info.weapon = 0; // you can recognize dummies by this
205         dummy_weapon_info.weapons = '0 0 0';
206         dummy_weapon_info.netname = "";
207         dummy_weapon_info.message = "AOL CD Thrower";
208         dummy_weapon_info.weapon_func = w_null;
209         dummy_weapon_info.wpmodel = "";
210         dummy_weapon_info.mdl = "";
211         dummy_weapon_info.model = "";
212         dummy_weapon_info.spawnflags = 0;
213         dummy_weapon_info.impulse = -1;
214         dummy_weapon_info.bot_pickupbasevalue = 0;
215         dummy_weapon_info.ammo_field = ammo_none;
216
217         dummy_weapon_info.w_crosshair = "gfx/crosshair1";
218         dummy_weapon_info.w_crosshair_size = 1;
219         dummy_weapon_info.model2 = "";
220
221         int i;
222         weaponorder_byid = "";
223         for(i = WEP_MAXCOUNT; i >= 1; --i)
224                 if(weapon_info[i-1])
225                         weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i));
226         weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
227 }
228 entity get_weaponinfo(int id)
229 {
230         entity w;
231         if(id < WEP_FIRST || id > WEP_LAST)
232                 return dummy_weapon_info;
233         w = weapon_info[id - 1];
234         if(w)
235                 return w;
236         return dummy_weapon_info;
237 }
238 string W_FixWeaponOrder(string order, float complete)
239 {
240         return fixPriorityList(order, WEP_FIRST, WEP_LAST, 230 - WEP_FIRST, complete);
241 }
242 string W_NameWeaponOrder_MapFunc(string s)
243 {
244         entity wi;
245         if(s == "0" || stof(s))
246         {
247                 wi = get_weaponinfo(stof(s));
248                 if(wi != dummy_weapon_info)
249                         return wi.netname;
250         }
251         return s;
252 }
253
254 string W_UndeprecateName(string s)
255 {
256         switch ( s )
257         {
258                 case "nex"            : return "vortex";
259                 case "rocketlauncher" : return "devastator";
260                 case "laser"          : return "blaster";
261                 case "minstanex"      : return "vaporizer";
262                 case "grenadelauncher": return "mortar";
263                 case "uzi"            : return "machinegun";
264                 default               : return s;
265         }
266 }
267 string W_NameWeaponOrder(string order)
268 {
269         return mapPriorityList(order, W_NameWeaponOrder_MapFunc);
270 }
271 string W_NumberWeaponOrder_MapFunc(string s)
272 {
273         int i;
274         if(s == "0" || stof(s))
275                 return s;
276         s = W_UndeprecateName(s);
277         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
278                 if(s == get_weaponinfo(i).netname)
279                         return ftos(i);
280         return s;
281 }
282 string W_NumberWeaponOrder(string order)
283 {
284         return mapPriorityList(order, W_NumberWeaponOrder_MapFunc);
285 }
286
287 float W_FixWeaponOrder_BuildImpulseList_buf[WEP_MAXCOUNT];
288 string W_FixWeaponOrder_BuildImpulseList_order;
289 void W_FixWeaponOrder_BuildImpulseList_swap(int i, int j, entity pass)
290 {
291         float h;
292         h = W_FixWeaponOrder_BuildImpulseList_buf[i];
293         W_FixWeaponOrder_BuildImpulseList_buf[i] = W_FixWeaponOrder_BuildImpulseList_buf[j];
294         W_FixWeaponOrder_BuildImpulseList_buf[j] = h;
295 }
296 float W_FixWeaponOrder_BuildImpulseList_cmp(int i, int j, entity pass)
297 {
298         entity e1, e2;
299         float d;
300         e1 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[i]);
301         e2 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[j]);
302         d = (e1.impulse + 9) % 10 - (e2.impulse + 9) % 10;
303         if(d != 0)
304                 return -d; // high impulse first!
305         return
306                 strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[i]), 0)
307                 -
308                 strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[j]), 0)
309                 ; // low char index first!
310 }
311 string W_FixWeaponOrder_BuildImpulseList(string o)
312 {
313         int i;
314         W_FixWeaponOrder_BuildImpulseList_order = o;
315         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
316                 W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST] = i;
317         heapsort(WEP_LAST - WEP_FIRST + 1, W_FixWeaponOrder_BuildImpulseList_swap, W_FixWeaponOrder_BuildImpulseList_cmp, world);
318         o = "";
319         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
320                 o = strcat(o, " ", ftos(W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST]));
321         W_FixWeaponOrder_BuildImpulseList_order = string_null;
322         return substring(o, 1, -1);
323 }
324
325 string W_FixWeaponOrder_AllowIncomplete(string order)
326 {
327         return W_FixWeaponOrder(order, 0);
328 }
329
330 string W_FixWeaponOrder_ForceComplete(string order)
331 {
332         if(order == "")
333                 order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
334         return W_FixWeaponOrder(order, 1);
335 }
336
337 void W_RandomWeapons(entity e, float n)
338 {
339         int i, j;
340         WepSet remaining;
341         WepSet result;
342         remaining = e.weapons;
343         result = '0 0 0';
344         for(i = 0; i < n; ++i)
345         {
346                 RandomSelection_Init();
347                 for(j = WEP_FIRST; j <= WEP_LAST; ++j)
348                         if(remaining & WepSet_FromWeapon(j))
349                                 RandomSelection_Add(world, j, string_null, 1, 1);
350                 result |= WepSet_FromWeapon(RandomSelection_chosen_float);
351                 remaining &= ~WepSet_FromWeapon(RandomSelection_chosen_float);
352         }
353         e.weapons = result;
354 }
355
356 string GetAmmoPicture(.int ammotype)
357 {
358         switch(ammotype)
359         {
360                 case ammo_shells:  return "ammo_shells";
361                 case ammo_nails:   return "ammo_bullets";
362                 case ammo_rockets: return "ammo_rockets";
363                 case ammo_cells:   return "ammo_cells";
364                 case ammo_plasma:  return "ammo_cells";
365                 case ammo_fuel:    return "ammo_fuel";
366                 default: return ""; // wtf, no ammo type?
367         }
368 }
369
370 #ifdef CSQC
371 .int GetAmmoFieldFromNum(int i)
372 {
373         switch(i)
374         {
375                 case 0: return ammo_shells;
376                 case 1: return ammo_nails;
377                 case 2: return ammo_rockets;
378                 case 3: return ammo_cells;
379                 case 4: return ammo_plasma;
380                 case 5: return ammo_fuel;
381                 default: return ammo_none;
382         }
383 }
384
385 int GetAmmoStat(.int ammotype)
386 {
387         switch(ammotype)
388         {
389                 case ammo_shells: return STAT_SHELLS;
390                 case ammo_nails: return STAT_NAILS;
391                 case ammo_rockets: return STAT_ROCKETS;
392                 case ammo_cells: return STAT_CELLS;
393                 case ammo_plasma: return STAT_PLASMA;
394                 case ammo_fuel: return STAT_FUEL;
395                 default: return -1;
396         }
397 }
398 #endif
399 #endif