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