]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/weapons/weapons.qc
Fix compile
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / weapons / weapons.qc
1 #ifndef MENUQC
2 #include "calculations.qc"
3 #endif
4 #include "all.qh"
5
6 // WEAPON PLUGIN SYSTEM
7 entity weapon_info[WEP_MAXCOUNT];
8 entity dummy_weapon_info;
9
10 #if WEP_MAXCOUNT > 72
11 # error Kein Weltraum links auf dem Gerät
12 #endif
13
14 WepSet WepSet_FromWeapon(float a) {
15         a -= WEP_FIRST;
16 #if WEP_MAXCOUNT > 24
17         if(a >= 24) {
18                 a -= 24;
19 #if WEP_MAXCOUNT > 48
20                 if(a >= 24) {
21                         a -= 24;
22                         return '0 0 1' * power2of(a);
23                 }
24 #endif
25                 return '0 1 0' * power2of(a);
26         }
27 #endif
28         return '1 0 0' * power2of(a);
29 }
30 #ifdef SVQC
31 void WepSet_AddStat()
32 {
33         addstat(STAT_WEAPONS, AS_INT, weapons_x);
34 #if WEP_MAXCOUNT > 24
35         addstat(STAT_WEAPONS2, AS_INT, weapons_y);
36 #if WEP_MAXCOUNT > 48
37         addstat(STAT_WEAPONS3, AS_INT, weapons_z);
38 #endif
39 #endif
40 }
41 void WriteWepSet(float dst, WepSet w)
42 {
43 #if WEP_MAXCOUNT > 48
44         WriteInt72_t(dst, w);
45 #elif WEP_MAXCOUNT > 24
46         WriteInt48_t(dst, w);
47 #else
48         WriteInt24_t(dst, w_x);
49 #endif
50 }
51 #endif
52 #ifdef CSQC
53 WepSet WepSet_GetFromStat()
54 {
55         WepSet w = '0 0 0';
56         w_x = getstati(STAT_WEAPONS);
57 #if WEP_MAXCOUNT > 24
58         w_y = getstati(STAT_WEAPONS2);
59 #if WEP_MAXCOUNT > 48
60         w_z = getstati(STAT_WEAPONS3);
61 #endif
62 #endif
63         return w;
64 }
65 WepSet ReadWepSet()
66 {
67 #if WEP_MAXCOUNT > 48
68         return ReadInt72_t();
69 #elif WEP_MAXCOUNT > 24
70         return ReadInt48_t();
71 #else
72         return ReadInt24_t() * '1 0 0';
73 #endif
74 }
75 #endif
76
77 void register_weapon(
78         float id,
79         WepSet bit,
80         float(float) func,
81         .float ammotype,
82         float i,
83         float weapontype,
84         float pickupbasevalue,
85         vector clr,
86         string modelname,
87         string simplemdl,
88         string crosshair,
89         string refname,
90         string wepname)
91 {
92         entity e;
93         weapon_info[id - 1] = e = spawn();
94         e.classname = "weapon_info";
95         e.weapon = id;
96         e.weapons = bit;
97         e.weapon_func = func;
98         e.ammo_field = ammotype;
99         e.impulse = i;
100         e.spawnflags = weapontype;
101         e.bot_pickupbasevalue = pickupbasevalue;
102         e.wpcolor = clr;
103         e.wpmodel = strzone(strcat("wpn-", ftos(id)));
104         e.mdl = modelname;
105         e.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
106         e.w_simplemdl = strzone(simplemdl); // simpleitems weapon model/image
107         e.w_crosshair = strzone(car(crosshair));
108         string s = cdr(crosshair);
109         e.w_crosshair_size = ((s != "") ? stof(s) : 1); // so that we can scale the crosshair from code (for compat)
110         e.netname = refname;
111         e.message = wepname;
112
113         #ifndef MENUQC
114         func(WR_INIT);
115         #endif
116 }
117 float w_null(float dummy)
118 {
119         return 0;
120 }
121 void register_weapons_done()
122 {
123         dummy_weapon_info = spawn();
124         dummy_weapon_info.classname = "weapon_info";
125         dummy_weapon_info.weapon = 0; // you can recognize dummies by this
126         dummy_weapon_info.weapons = '0 0 0';
127         dummy_weapon_info.netname = "";
128         dummy_weapon_info.message = "AOL CD Thrower";
129         dummy_weapon_info.weapon_func = w_null;
130         dummy_weapon_info.wpmodel = "";
131         dummy_weapon_info.mdl = "";
132         dummy_weapon_info.model = "";
133         dummy_weapon_info.spawnflags = 0;
134         dummy_weapon_info.impulse = -1;
135         dummy_weapon_info.bot_pickupbasevalue = 0;
136         dummy_weapon_info.ammo_field = ammo_none;
137
138         dummy_weapon_info.w_crosshair = "gfx/crosshair1";
139         dummy_weapon_info.w_crosshair_size = 1;
140
141         float i;
142         weaponorder_byid = "";
143         for(i = WEP_MAXCOUNT; i >= 1; --i)
144                 if(weapon_info[i-1])
145                         weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i));
146         weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
147 }
148 entity get_weaponinfo(float id)
149 {
150         entity w;
151         if(id < WEP_FIRST || id > WEP_LAST)
152                 return dummy_weapon_info;
153         w = weapon_info[id - 1];
154         if(w)
155                 return w;
156         return dummy_weapon_info;
157 }
158 string W_FixWeaponOrder(string order, float complete)
159 {
160         return fixPriorityList(order, WEP_FIRST, WEP_LAST, 230 - WEP_FIRST, complete);
161 }
162 string W_NameWeaponOrder_MapFunc(string s)
163 {
164         entity wi;
165         if(s == "0" || stof(s))
166         {
167                 wi = get_weaponinfo(stof(s));
168                 if(wi != dummy_weapon_info)
169                         return wi.netname;
170         }
171         return s;
172 }
173 string W_NameWeaponOrder(string order)
174 {
175         return mapPriorityList(order, W_NameWeaponOrder_MapFunc);
176 }
177 string W_NumberWeaponOrder_MapFunc(string s)
178 {
179         float i;
180         if(s == "0" || stof(s))
181                 return s;
182         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
183                 if(s == get_weaponinfo(i).netname)
184                         return ftos(i);
185         return s;
186 }
187 string W_NumberWeaponOrder(string order)
188 {
189         return mapPriorityList(order, W_NumberWeaponOrder_MapFunc);
190 }
191
192 float W_FixWeaponOrder_BuildImpulseList_buf[WEP_MAXCOUNT];
193 string W_FixWeaponOrder_BuildImpulseList_order;
194 void W_FixWeaponOrder_BuildImpulseList_swap(float i, float j, entity pass)
195 {
196         float h;
197         h = W_FixWeaponOrder_BuildImpulseList_buf[i];
198         W_FixWeaponOrder_BuildImpulseList_buf[i] = W_FixWeaponOrder_BuildImpulseList_buf[j];
199         W_FixWeaponOrder_BuildImpulseList_buf[j] = h;
200 }
201 float W_FixWeaponOrder_BuildImpulseList_cmp(float i, float j, entity pass)
202 {
203         entity e1, e2;
204         float d;
205         e1 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[i]);
206         e2 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[j]);
207         d = mod(e1.impulse + 9, 10) - mod(e2.impulse + 9, 10);
208         if(d != 0)
209                 return -d; // high impulse first!
210         return
211                 strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[i]), 0)
212                 -
213                 strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[j]), 0)
214                 ; // low char index first!
215 }
216 string W_FixWeaponOrder_BuildImpulseList(string o)
217 {
218         float i;
219         W_FixWeaponOrder_BuildImpulseList_order = o;
220         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
221                 W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST] = i;
222         heapsort(WEP_LAST - WEP_FIRST + 1, W_FixWeaponOrder_BuildImpulseList_swap, W_FixWeaponOrder_BuildImpulseList_cmp, world);
223         o = "";
224         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
225                 o = strcat(o, " ", ftos(W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST]));
226         W_FixWeaponOrder_BuildImpulseList_order = string_null;
227         return substring(o, 1, -1);
228 }
229
230 string W_FixWeaponOrder_AllowIncomplete(string order)
231 {
232         return W_FixWeaponOrder(order, 0);
233 }
234
235 string W_FixWeaponOrder_ForceComplete(string order)
236 {
237         if(order == "")
238                 order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
239         return W_FixWeaponOrder(order, 1);
240 }
241
242 void W_RandomWeapons(entity e, float n)
243 {
244         float i, j;
245         WepSet remaining;
246         WepSet result;
247         remaining = e.weapons;
248         result = '0 0 0';
249         for(i = 0; i < n; ++i)
250         {
251                 RandomSelection_Init();
252                 for(j = WEP_FIRST; j <= WEP_LAST; ++j)
253                         if(remaining & WepSet_FromWeapon(j))
254                                 RandomSelection_Add(world, j, string_null, 1, 1);
255                 result |= WepSet_FromWeapon(RandomSelection_chosen_float);
256                 remaining &= ~WepSet_FromWeapon(RandomSelection_chosen_float);
257         }
258         e.weapons = result;
259 }
260
261 #ifdef CSQC
262 .float GetAmmoFieldFromNum(float i)
263 {
264         switch(i)
265         {
266                 case 0: return ammo_shells;
267                 case 1: return ammo_nails;
268                 case 2: return ammo_rockets;
269                 case 3: return ammo_cells;
270                 case 4: return ammo_fuel;
271                 default: return ammo_none;
272         }
273 }
274
275 string GetAmmoPicture(.float ammotype)
276 {
277         switch(ammotype)
278         {
279                 case ammo_shells:  return "ammo_shells";
280                 case ammo_nails:   return "ammo_nails";
281                 case ammo_rockets: return "ammo_rockets";
282                 case ammo_cells:   return "ammo_cells";
283                 case ammo_fuel:    return "ammo_fuel";
284                 default: return ""; // wtf, no ammo type?
285         }
286 }
287
288 float GetAmmoStat(.float ammotype)
289 {
290         switch(ammotype)
291         {
292                 case ammo_shells: return STAT_SHELLS;
293                 case ammo_nails: return STAT_NAILS;
294                 case ammo_rockets: return STAT_ROCKETS;
295                 case ammo_cells: return STAT_CELLS;
296                 case ammo_fuel: return STAT_FUEL;
297                 default: return -1;
298         }
299 }
300 #endif