2c72d380fcc8db9274203062ce8685de3882fad6
[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/common.qh"
13         #include "../../warpzonelib/client.qh"
14         #include "../util.qh"
15         #include "../buffs/all.qh"
16         #include "../../client/autocvars.qh"
17         #include "../deathtypes.qh"
18         #include "../../csqcmodellib/interpolate.qh"
19         #include "../movetypes/movetypes.qh"
20         #include "../../client/main.qh"
21         #include "../../csqcmodellib/cl_model.qh"
22 #elif defined(MENUQC)
23 #elif defined(SVQC)
24         #include "../../dpdefs/progsdefs.qh"
25     #include "../../dpdefs/dpextensions.qh"
26     #include "../../warpzonelib/anglestransform.qh"
27     #include "../../warpzonelib/common.qh"
28     #include "../../warpzonelib/util_server.qh"
29     #include "../../warpzonelib/server.qh"
30     #include "../constants.qh"
31     #include "../stats.qh"
32     #include "../teams.qh"
33     #include "../util.qh"
34     #include "../buffs/all.qh"
35     #include "../monsters/all.qh"
36     #include "config.qh"
37     #include "../../server/weapons/csqcprojectile.qh"
38     #include "../../server/weapons/tracing.qh"
39     #include "../../server/t_items.qh"
40     #include "../../server/autocvars.qh"
41     #include "../../server/constants.qh"
42     #include "../../server/defs.qh"
43     #include "../notifications.qh"
44     #include "../deathtypes.qh"
45     #include "../../server/mutators/mutators_include.qh"
46     #include "../mapinfo.qh"
47     #include "../../server/command/common.qh"
48     #include "../../csqcmodellib/sv_model.qh"
49     #include "../../server/portals.qh"
50     #include "../../server/g_hook.qh"
51 #endif
52 #ifndef MENUQC
53 #include "calculations.qc"
54 #endif
55 #define IMPLEMENTATION
56 #include "all.inc"
57 #undef IMPLEMENTATION
58
59 // WEAPON PLUGIN SYSTEM
60
61 WepSet WepSet_FromWeapon(int a) {
62         a -= WEP_FIRST;
63         if (Weapons_MAX > 24)
64         if (a >= 24) {
65                 a -= 24;
66                 if (Weapons_MAX > 48)
67                 if (a >= 24) {
68                         a -= 24;
69                         return '0 0 1' * power2of(a);
70                 }
71                 return '0 1 0' * power2of(a);
72         }
73         return '1 0 0' * power2of(a);
74 }
75 #ifdef SVQC
76 void WepSet_AddStat()
77 {
78         addstat(STAT_WEAPONS, AS_INT, weapons_x);
79         if (Weapons_MAX > 24)
80         addstat(STAT_WEAPONS2, AS_INT, weapons_y);
81         if (Weapons_MAX > 48)
82         addstat(STAT_WEAPONS3, AS_INT, weapons_z);
83 }
84 void WepSet_AddStat_InMap()
85 {
86         addstat(STAT_WEAPONSINMAP, AS_INT, weaponsinmap_x);
87         if (Weapons_MAX > 24)
88         addstat(STAT_WEAPONSINMAP2, AS_INT, weaponsinmap_y);
89         if (Weapons_MAX > 48)
90         addstat(STAT_WEAPONSINMAP3, AS_INT, weaponsinmap_z);
91 }
92 void WriteWepSet(float dst, WepSet w)
93 {
94         if (Weapons_MAX > 48)
95         WriteInt72_t(dst, w);
96         else if (Weapons_MAX > 24)
97         WriteInt48_t(dst, w);
98         else
99         WriteInt24_t(dst, w.x);
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 (Weapons_MAX > 24)
108         w.y = getstati(STAT_WEAPONS2);
109         if (Weapons_MAX > 48)
110         w.z = getstati(STAT_WEAPONS3);
111         return w;
112 }
113 WepSet WepSet_GetFromStat_InMap()
114 {
115         WepSet w = '0 0 0';
116         w_x = getstati(STAT_WEAPONSINMAP);
117         if (Weapons_MAX > 24)
118         w_y = getstati(STAT_WEAPONSINMAP2);
119         if (Weapons_MAX > 48)
120         w_z = getstati(STAT_WEAPONSINMAP3);
121         return w;
122 }
123 WepSet ReadWepSet()
124 {
125         if (Weapons_MAX > 48)
126         return ReadInt72_t();
127         if (Weapons_MAX > 24)
128         return ReadInt48_t();
129         return ReadInt24_t() * '1 0 0';
130 }
131 #endif
132
133 string W_FixWeaponOrder(string order, float complete)
134 {
135         return fixPriorityList(order, WEP_FIRST, WEP_LAST, WEP_IMPULSE_BEGIN - WEP_FIRST, complete);
136 }
137 string W_NameWeaponOrder_MapFunc(string s)
138 {
139         entity wi;
140         if(s == "0" || stof(s))
141         {
142                 wi = get_weaponinfo(stof(s));
143                 if(wi != WEP_Null)
144                         return wi.netname;
145         }
146         return s;
147 }
148
149 string W_UndeprecateName(string s)
150 {
151         switch ( s )
152         {
153                 case "nex"            : return "vortex";
154                 case "rocketlauncher" : return "devastator";
155                 case "laser"          : return "blaster";
156                 case "minstanex"      : return "vaporizer";
157                 case "grenadelauncher": return "mortar";
158                 case "uzi"            : return "machinegun";
159                 default               : return s;
160         }
161 }
162 string W_NameWeaponOrder(string order)
163 {
164         return mapPriorityList(order, W_NameWeaponOrder_MapFunc);
165 }
166 string W_NumberWeaponOrder_MapFunc(string s)
167 {
168         int i;
169         if(s == "0" || stof(s))
170                 return s;
171         s = W_UndeprecateName(s);
172         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
173                 if(s == get_weaponinfo(i).netname)
174                         return ftos(i);
175         return s;
176 }
177 string W_NumberWeaponOrder(string order)
178 {
179         return mapPriorityList(order, W_NumberWeaponOrder_MapFunc);
180 }
181
182 float W_FixWeaponOrder_BuildImpulseList_buf[Weapons_MAX];
183 string W_FixWeaponOrder_BuildImpulseList_order;
184 void W_FixWeaponOrder_BuildImpulseList_swap(int i, int j, entity pass)
185 {
186         float h;
187         h = W_FixWeaponOrder_BuildImpulseList_buf[i];
188         W_FixWeaponOrder_BuildImpulseList_buf[i] = W_FixWeaponOrder_BuildImpulseList_buf[j];
189         W_FixWeaponOrder_BuildImpulseList_buf[j] = h;
190 }
191 float W_FixWeaponOrder_BuildImpulseList_cmp(int i, int j, entity pass)
192 {
193         entity e1, e2;
194         float d;
195         e1 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[i]);
196         e2 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[j]);
197         d = (e1.impulse + 9) % 10 - (e2.impulse + 9) % 10;
198         if(d != 0)
199                 return -d; // high impulse first!
200         return
201                 strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[i]), 0)
202                 -
203                 strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[j]), 0)
204                 ; // low char index first!
205 }
206 string W_FixWeaponOrder_BuildImpulseList(string o)
207 {
208         int i;
209         W_FixWeaponOrder_BuildImpulseList_order = o;
210         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
211                 W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST] = i;
212         heapsort(WEP_LAST - WEP_FIRST + 1, W_FixWeaponOrder_BuildImpulseList_swap, W_FixWeaponOrder_BuildImpulseList_cmp, world);
213         o = "";
214         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
215                 o = strcat(o, " ", ftos(W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST]));
216         W_FixWeaponOrder_BuildImpulseList_order = string_null;
217         return substring(o, 1, -1);
218 }
219
220 string W_FixWeaponOrder_AllowIncomplete(string order)
221 {
222         return W_FixWeaponOrder(order, 0);
223 }
224
225 string W_FixWeaponOrder_ForceComplete(string order)
226 {
227         if(order == "")
228                 order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
229         return W_FixWeaponOrder(order, 1);
230 }
231
232 void W_RandomWeapons(entity e, float n)
233 {
234         int i, j;
235         WepSet remaining;
236         WepSet result;
237         remaining = e.weapons;
238         result = '0 0 0';
239         for(i = 0; i < n; ++i)
240         {
241                 RandomSelection_Init();
242                 for(j = WEP_FIRST; j <= WEP_LAST; ++j)
243                         if(remaining & WepSet_FromWeapon(j))
244                                 RandomSelection_Add(world, j, string_null, 1, 1);
245                 result |= WepSet_FromWeapon(RandomSelection_chosen_float);
246                 remaining &= ~WepSet_FromWeapon(RandomSelection_chosen_float);
247         }
248         e.weapons = result;
249 }
250
251 string GetAmmoPicture(.int ammotype)
252 {
253         switch (ammotype)
254         {
255                 case ammo_shells:  return ITEM_Shells.m_icon;
256                 case ammo_nails:   return ITEM_Bullets.m_icon;
257                 case ammo_rockets: return ITEM_Rockets.m_icon;
258                 case ammo_cells:   return ITEM_Cells.m_icon;
259                 case ammo_plasma:  return ITEM_Plasma.m_icon;
260                 case ammo_fuel:    return ITEM_JetpackFuel.m_icon;
261                 default: return ""; // wtf, no ammo type?
262         }
263 }
264
265 #ifdef CSQC
266 .int GetAmmoFieldFromNum(int i)
267 {
268         switch(i)
269         {
270                 case 0: return ammo_shells;
271                 case 1: return ammo_nails;
272                 case 2: return ammo_rockets;
273                 case 3: return ammo_cells;
274                 case 4: return ammo_plasma;
275                 case 5: return ammo_fuel;
276                 default: return ammo_none;
277         }
278 }
279
280 int GetAmmoStat(.int ammotype)
281 {
282         switch(ammotype)
283         {
284                 case ammo_shells: return STAT_SHELLS;
285                 case ammo_nails: return STAT_NAILS;
286                 case ammo_rockets: return STAT_ROCKETS;
287                 case ammo_cells: return STAT_CELLS;
288                 case ammo_plasma: return STAT_PLASMA;
289                 case ammo_fuel: return STAT_FUEL;
290                 default: return -1;
291         }
292 }
293 #endif
294
295 string W_Sound(string w_snd)
296 {
297         #define extensions(X) X(wav) X(ogg)
298         #define tryext(ext) { if (fexists(strcat("sound/", output = strcat("weapons/", w_snd, "."#ext)))) break; }
299         string output;
300         do {
301                 extensions(tryext);
302                 #undef tryext
303                 #undef extensions
304                 output = strcat("weapons/", w_snd);
305         } while (0);
306
307 #ifdef SVQC
308         MUTATOR_CALLHOOK(WeaponSound, w_snd, output);
309         return weapon_sound_output;
310 #else
311         return output;
312 #endif
313 }
314
315 string W_Model(string w_mdl)
316 {
317         string output = strcat("models/weapons/", w_mdl);
318 #ifdef SVQC
319         MUTATOR_CALLHOOK(WeaponModel, w_mdl, output);
320         return weapon_model_output;
321 #else
322         return output;
323 #endif
324 }
325
326 #endif