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