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