Fix compilation with gmqcc.
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / items.qc
1 // WEAPON PLUGIN SYSTEM
2 entity weapon_info[WEP_MAXCOUNT];
3 entity dummy_weapon_info;
4
5 #if WEP_MAXCOUNT > 72
6 # error Kein Weltraum links auf dem Gerät
7 #endif
8
9 WepSet WepSet_FromWeapon(float a) {
10         a -= WEP_FIRST;
11 #if WEP_MAXCOUNT > 24
12         if(a >= 24) {
13                 a -= 24;
14 #if WEP_MAXCOUNT > 48
15                 if(a >= 24) {
16                         a -= 24;
17                         return '0 0 1' * power2of(a);
18                 }
19 #endif
20                 return '0 1 0' * power2of(a);
21         }
22 #endif
23         return '1 0 0' * power2of(a);
24 }
25 #ifdef SVQC
26 void WepSet_AddStat()
27 {
28         addstat(STAT_WEAPONS, AS_INT, weapons_x);
29 #if WEP_MAXCOUNT > 24
30         addstat(STAT_WEAPONS2, AS_INT, weapons_y);
31 #if WEP_MAXCOUNT > 48
32         addstat(STAT_WEAPONS3, AS_INT, weapons_z);
33 #endif
34 #endif
35 }
36 void WriteWepSet(float dst, WepSet w)
37 {
38 #if WEP_MAXCOUNT > 48
39         WriteInt72_t(dst, w);
40 #elif WEP_MAXCOUNT > 24
41         WriteInt48_t(dst, w);
42 #else
43         WriteInt24_t(dst, w_x);
44 #endif
45 }
46 #endif
47 #ifdef CSQC
48 WepSet WepSet_GetFromStat()
49 {
50         WepSet w = '0 0 0';
51         w_x = getstati(STAT_WEAPONS);
52 #if WEP_MAXCOUNT > 24
53         w_y = getstati(STAT_WEAPONS2);
54 #if WEP_MAXCOUNT > 48
55         w_z = getstati(STAT_WEAPONS3);
56 #endif
57 #endif
58         return w;
59 }
60 WepSet ReadWepSet()
61 {
62 #if WEP_MAXCOUNT > 48
63         return ReadInt72_t();
64 #elif WEP_MAXCOUNT > 24
65         return ReadInt48_t();
66 #else
67         return ReadInt24_t() * '1 0 0';
68 #endif
69 }
70 #endif
71
72 void register_weapon(float id, WepSet bit, float(float) func, float ammotype, float i, float weapontype, float pickupbasevalue, string modelname, string shortname, string wname)
73 {
74         entity e;
75         weapon_info[id - 1] = e = spawn();
76         e.classname = "weapon_info";
77         e.weapon = id;
78         e.weapons = bit;
79         e.netname = shortname;
80         e.message = wname;
81         e.items = ammotype;
82         e.weapon_func = func;
83         e.mdl = modelname;
84         e.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
85         e.spawnflags = weapontype;
86         e.model2 = strzone(strcat("wpn-", e.mdl));
87         e.impulse = i;
88         e.bot_pickupbasevalue = pickupbasevalue;
89         if(ammotype & IT_SHELLS)
90                 e.ammo_field = ammo_shells;
91         else if(ammotype & IT_NAILS)
92                 e.ammo_field = ammo_nails;
93         else if(ammotype & IT_ROCKETS)
94                 e.ammo_field = ammo_rockets;
95         else if(ammotype & IT_CELLS)
96                 e.ammo_field = ammo_cells;
97         else if(ammotype & IT_FUEL)
98                 e.ammo_field = ammo_fuel;
99         else
100                 e.ammo_field = ammo_batteries;
101 }
102 float w_null(float dummy)
103 {
104         return 0;
105 }
106 void register_weapons_done()
107 {
108         dummy_weapon_info = spawn();
109         dummy_weapon_info.classname = "weapon_info";
110         dummy_weapon_info.weapon = 0; // you can recognize dummies by this
111         dummy_weapon_info.weapons = '0 0 0';
112         dummy_weapon_info.netname = "";
113         dummy_weapon_info.message = "AOL CD Thrower";
114         dummy_weapon_info.items = 0;
115         dummy_weapon_info.weapon_func = w_null;
116         dummy_weapon_info.mdl = "";
117         dummy_weapon_info.model = "";
118         dummy_weapon_info.spawnflags = 0;
119         dummy_weapon_info.model2 = "";
120         dummy_weapon_info.impulse = -1;
121         dummy_weapon_info.bot_pickupbasevalue = 0;
122
123         float i;
124         weaponorder_byid = "";
125         for(i = WEP_MAXCOUNT; i >= 1; --i)
126                 if(weapon_info[i-1])
127                         weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i));
128         weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
129 }
130 entity get_weaponinfo(float id)
131 {
132         entity w;
133         if(id < WEP_FIRST || id > WEP_LAST)
134                 return dummy_weapon_info;
135         w = weapon_info[id - 1];
136         if(w)
137                 return w;
138         return dummy_weapon_info;
139 }
140 string W_FixWeaponOrder(string order, float complete)
141 {
142         return fixPriorityList(order, WEP_FIRST, WEP_LAST, 230 - WEP_FIRST, complete);
143 }
144 string W_NameWeaponOrder_MapFunc(string s)
145 {
146         entity wi;
147         if(s == "0" || stof(s))
148         {
149                 wi = get_weaponinfo(stof(s));
150                 if(wi != dummy_weapon_info)
151                         return wi.netname;
152         }
153         return s;
154 }
155 string W_NameWeaponOrder(string order)
156 {
157         return mapPriorityList(order, W_NameWeaponOrder_MapFunc);
158 }
159 string W_NumberWeaponOrder_MapFunc(string s)
160 {
161         float i;
162         if(s == "0" || stof(s))
163                 return s;
164         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
165                 if(s == get_weaponinfo(i).netname)
166                         return ftos(i);
167         return s;
168 }
169 string W_NumberWeaponOrder(string order)
170 {
171         return mapPriorityList(order, W_NumberWeaponOrder_MapFunc);
172 }
173
174 float W_FixWeaponOrder_BuildImpulseList_buf[WEP_MAXCOUNT];
175 string W_FixWeaponOrder_BuildImpulseList_order;
176 void W_FixWeaponOrder_BuildImpulseList_swap(float i, float j, entity pass)
177 {
178         float h;
179         h = W_FixWeaponOrder_BuildImpulseList_buf[i];
180         W_FixWeaponOrder_BuildImpulseList_buf[i] = W_FixWeaponOrder_BuildImpulseList_buf[j];
181         W_FixWeaponOrder_BuildImpulseList_buf[j] = h;
182 }
183 float W_FixWeaponOrder_BuildImpulseList_cmp(float i, float j, entity pass)
184 {
185         entity e1, e2;
186         float d;
187         e1 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[i]);
188         e2 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[j]);
189         d = mod(e1.impulse + 9, 10) - mod(e2.impulse + 9, 10);
190         if(d != 0)
191                 return -d; // high impulse first!
192         return
193                 strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[i]), 0)
194                 -
195                 strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[j]), 0)
196                 ; // low char index first!
197 }
198 string W_FixWeaponOrder_BuildImpulseList(string o)
199 {
200         float i;
201         W_FixWeaponOrder_BuildImpulseList_order = o;
202         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
203                 W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST] = i;
204         heapsort(WEP_LAST - WEP_FIRST + 1, W_FixWeaponOrder_BuildImpulseList_swap, W_FixWeaponOrder_BuildImpulseList_cmp, world);
205         o = "";
206         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
207                 o = strcat(o, " ", ftos(W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST]));
208         W_FixWeaponOrder_BuildImpulseList_order = string_null;
209         return substring(o, 1, -1);
210 }
211
212 string W_FixWeaponOrder_AllowIncomplete(string order)
213 {
214         return W_FixWeaponOrder(order, 0);
215 }
216
217 string W_FixWeaponOrder_ForceComplete(string order)
218 {
219         if(order == "")
220                 order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
221         return W_FixWeaponOrder(order, 1);
222 }
223
224 void W_RandomWeapons(entity e, float n)
225 {
226         float i, j;
227         WepSet remaining;
228         WepSet result;
229         remaining = e.weapons;
230         result = '0 0 0';
231         for(i = 0; i < n; ++i)
232         {
233                 RandomSelection_Init();
234                 for(j = WEP_FIRST; j <= WEP_LAST; ++j)
235                         if(remaining & WepSet_FromWeapon(j))
236                                 RandomSelection_Add(world, j, string_null, 1, 1);
237                 result |= WepSet_FromWeapon(RandomSelection_chosen_float);
238                 remaining &= ~WepSet_FromWeapon(RandomSelection_chosen_float);
239         }
240         e.weapons = result;
241 }
242
243 string W_Name(float weaponid)
244 {
245         return (get_weaponinfo(weaponid)).message;
246 }
247
248 float W_AmmoItemCode(float wpn)
249 {
250         return (get_weaponinfo(wpn)).items & IT_AMMO;
251 }