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