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