]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/weapons/weapons.qc
Some more cleanup
[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 shortname,
88         string wname)
89 {
90         entity e;
91         weapon_info[id - 1] = e = spawn();
92         e.classname = "weapon_info";
93         e.weapon = id;
94         e.weapons = bit;
95         e.netname = shortname;
96         e.message = wname;
97         e.weapon_func = func;
98         e.wpcolor = clr;
99         e.mdl = modelname;
100         e.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
101         e.spawnflags = weapontype;
102         e.model2 = strzone(strcat("wpn-", ftos(id)));
103         e.impulse = i;
104         e.bot_pickupbasevalue = pickupbasevalue;
105         e.ammo_field = ammotype;
106
107         #ifndef MENUQC
108         func(WR_INIT);
109         #endif
110 }
111 float w_null(float dummy)
112 {
113         return 0;
114 }
115 void register_weapons_done()
116 {
117         dummy_weapon_info = spawn();
118         dummy_weapon_info.classname = "weapon_info";
119         dummy_weapon_info.weapon = 0; // you can recognize dummies by this
120         dummy_weapon_info.weapons = '0 0 0';
121         dummy_weapon_info.netname = "";
122         dummy_weapon_info.message = "AOL CD Thrower";
123         dummy_weapon_info.weapon_func = w_null;
124         dummy_weapon_info.mdl = "";
125         dummy_weapon_info.model = "";
126         dummy_weapon_info.spawnflags = 0;
127         dummy_weapon_info.model2 = "";
128         dummy_weapon_info.impulse = -1;
129         dummy_weapon_info.bot_pickupbasevalue = 0;
130         dummy_weapon_info.ammo_field = ammo_none;
131
132         float i;
133         weaponorder_byid = "";
134         for(i = WEP_MAXCOUNT; i >= 1; --i)
135                 if(weapon_info[i-1])
136                         weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i));
137         weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
138 }
139 entity get_weaponinfo(float id)
140 {
141         entity w;
142         if(id < WEP_FIRST || id > WEP_LAST)
143                 return dummy_weapon_info;
144         w = weapon_info[id - 1];
145         if(w)
146                 return w;
147         return dummy_weapon_info;
148 }
149 string W_FixWeaponOrder(string order, float complete)
150 {
151         return fixPriorityList(order, WEP_FIRST, WEP_LAST, 230 - WEP_FIRST, complete);
152 }
153 string W_NameWeaponOrder_MapFunc(string s)
154 {
155         entity wi;
156         if(s == "0" || stof(s))
157         {
158                 wi = get_weaponinfo(stof(s));
159                 if(wi != dummy_weapon_info)
160                         return wi.netname;
161         }
162         return s;
163 }
164 string W_NameWeaponOrder(string order)
165 {
166         return mapPriorityList(order, W_NameWeaponOrder_MapFunc);
167 }
168 string W_NumberWeaponOrder_MapFunc(string s)
169 {
170         float i;
171         if(s == "0" || stof(s))
172                 return s;
173         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
174                 if(s == get_weaponinfo(i).netname)
175                         return ftos(i);
176         return s;
177 }
178 string W_NumberWeaponOrder(string order)
179 {
180         return mapPriorityList(order, W_NumberWeaponOrder_MapFunc);
181 }
182
183 float W_FixWeaponOrder_BuildImpulseList_buf[WEP_MAXCOUNT];
184 string W_FixWeaponOrder_BuildImpulseList_order;
185 void W_FixWeaponOrder_BuildImpulseList_swap(float i, float j, entity pass)
186 {
187         float h;
188         h = W_FixWeaponOrder_BuildImpulseList_buf[i];
189         W_FixWeaponOrder_BuildImpulseList_buf[i] = W_FixWeaponOrder_BuildImpulseList_buf[j];
190         W_FixWeaponOrder_BuildImpulseList_buf[j] = h;
191 }
192 float W_FixWeaponOrder_BuildImpulseList_cmp(float i, float j, entity pass)
193 {
194         entity e1, e2;
195         float d;
196         e1 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[i]);
197         e2 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[j]);
198         d = mod(e1.impulse + 9, 10) - mod(e2.impulse + 9, 10);
199         if(d != 0)
200                 return -d; // high impulse first!
201         return
202                 strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[i]), 0)
203                 -
204                 strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[j]), 0)
205                 ; // low char index first!
206 }
207 string W_FixWeaponOrder_BuildImpulseList(string o)
208 {
209         float i;
210         W_FixWeaponOrder_BuildImpulseList_order = o;
211         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
212                 W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST] = i;
213         heapsort(WEP_LAST - WEP_FIRST + 1, W_FixWeaponOrder_BuildImpulseList_swap, W_FixWeaponOrder_BuildImpulseList_cmp, world);
214         o = "";
215         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
216                 o = strcat(o, " ", ftos(W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST]));
217         W_FixWeaponOrder_BuildImpulseList_order = string_null;
218         return substring(o, 1, -1);
219 }
220
221 string W_FixWeaponOrder_AllowIncomplete(string order)
222 {
223         return W_FixWeaponOrder(order, 0);
224 }
225
226 string W_FixWeaponOrder_ForceComplete(string order)
227 {
228         if(order == "")
229                 order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
230         return W_FixWeaponOrder(order, 1);
231 }
232
233 void W_RandomWeapons(entity e, float n)
234 {
235         float i, j;
236         WepSet remaining;
237         WepSet result;
238         remaining = e.weapons;
239         result = '0 0 0';
240         for(i = 0; i < n; ++i)
241         {
242                 RandomSelection_Init();
243                 for(j = WEP_FIRST; j <= WEP_LAST; ++j)
244                         if(remaining & WepSet_FromWeapon(j))
245                                 RandomSelection_Add(world, j, string_null, 1, 1);
246                 result |= WepSet_FromWeapon(RandomSelection_chosen_float);
247                 remaining &= ~WepSet_FromWeapon(RandomSelection_chosen_float);
248         }
249         e.weapons = result;
250 }
251
252 string W_Name(float weaponid) // WEAPONTODO: make into a macro
253 {
254         return (get_weaponinfo(weaponid)).message;
255 }
256
257 #ifdef CSQC
258 .float GetAmmoFieldFromNum(float i)
259 {
260         switch(i)
261         {
262                 case 0: return ammo_shells;
263                 case 1: return ammo_nails;
264                 case 2: return ammo_rockets;
265                 case 3: return ammo_cells;
266                 case 4: return ammo_fuel;
267                 default: return ammo_none;
268         }
269 }
270
271 string GetAmmoPicture(.float ammotype)
272 {
273         switch(ammotype)
274         {
275                 case ammo_shells:  return "ammo_shells";
276                 case ammo_nails:   return "ammo_nails";
277                 case ammo_rockets: return "ammo_rockets";
278                 case ammo_cells:   return "ammo_cells";
279                 case ammo_fuel:    return "ammo_fuel";
280                 default: return ""; // wtf, no ammo type?
281         }
282 }
283
284 float GetAmmoStat(.float ammotype)
285 {
286         switch(ammotype)
287         {
288                 case ammo_shells: return STAT_SHELLS;
289                 case ammo_nails: return STAT_NAILS;
290                 case ammo_rockets: return STAT_ROCKETS;
291                 case ammo_cells: return STAT_CELLS;
292                 case ammo_fuel: return STAT_FUEL;
293                 default: return -1;
294         }
295 }
296 #endif