]> icculus.org git repositories - divverent/nexuiz.git/blob - TeamNexuiz/game/gamec/cl_weaponsystem.c
- Added new backpack/tfitem property -- item_backpack gives metal ammo when var...
[divverent/nexuiz.git] / TeamNexuiz / game / gamec / cl_weaponsystem.c
1 /*\r
2 ===========================================================================\r
3 \r
4   CLIENT WEAPONSYSTEM CODE\r
5   Bring back W_Weaponframe\r
6 \r
7 ===========================================================================\r
8 */\r
9 \r
10 void() CL_Weaponentity_Think =\r
11 {\r
12         self.nextthink = time;\r
13         if (self.owner.weaponentity != self)\r
14         {\r
15                 remove(self);\r
16                 return;\r
17         }\r
18         self.effects = self.owner.effects;\r
19         if(!(self.class == CLASS_SPY && self.special_active))\r
20                 self.alpha = self.owner.alpha;\r
21 };\r
22 \r
23 void() CL_ExteriorWeaponentity_Think =\r
24 {\r
25         self.nextthink = time;\r
26         if (self.owner.exteriorweaponentity != self)\r
27         {\r
28                 remove(self);\r
29                 return;\r
30         }\r
31         if (self.cnt != self.owner.weaponentity.modelindex || self.dmg != self.owner.modelindex || self.deadflag != self.owner.deadflag)\r
32         {\r
33                 self.cnt = self.owner.weaponentity.modelindex;\r
34                 self.dmg = self.owner.modelindex;\r
35                 self.deadflag = self.owner.deadflag;\r
36                 if (self.owner.deadflag) self.model = "";\r
37                 else if (self.owner.wpn == WEP_LASER) setmodel(self, "models/weapons/v_laser.md3");\r
38                 else if (self.owner.wpn == WEP_SHOTGUN) setmodel(self, "models/weapons/v_shotgun.md3");\r
39                 else if (self.owner.wpn == WEP_UZI) setmodel(self, "models/weapons/v_uzi.md3");\r
40                 else if (self.owner.wpn == WEP_GRENADE_LAUNCHER) setmodel(self, "models/weapons/v_gl.md3");\r
41                 else if (self.owner.wpn == WEP_ELECTRO) setmodel(self, "models/weapons/v_electro.md3");\r
42                 else if (self.owner.wpn == WEP_CRYLINK) setmodel(self, "models/weapons/v_crylink.md3");\r
43                 else if (self.owner.wpn == WEP_NEX) setmodel(self, "models/weapons/v_nex.md3");\r
44                 else if (self.owner.wpn == WEP_HAGAR) setmodel(self, "models/weapons/v_hagar.md3");\r
45                 else if (self.owner.wpn == WEP_ROCKET_LAUNCHER) setmodel(self, "models/weapons/v_rl.md3");\r
46                 else if (self.owner.wpn == WEP_BOMBLETTS) setmodel(self, "models/weapons/v_nadelauncher.md3");\r
47                 else if (self.owner.wpn == WEP_ROCKET_INCENDIARY) setmodel(self, "models/weapons/v_rli.md3");\r
48                 else if (self.owner.wpn == WEP_HOTBOMBS) setmodel(self, "models/weapons/v_hotbombs.md3");\r
49                 else if (self.owner.wpn == WEP_GRAPPLE) setmodel(self, "models/weapons/v_grapple.md3");\r
50                 else if (self.owner.wpn == WEP_NAMEK) setmodel(self, "models/weapons/v_namek.md3");\r
51                 else if (self.owner.wpn == WEP_RAILGUN) setmodel(self, "models/weapons/v_nex.md3");\r
52                 else if (self.owner.wpn == WEP_MAC) setmodel(self, "models/weapons/v_mac.md3");\r
53                 else if (self.owner.wpn == WEP_FLAMER) setmodel(self, "models/weapons/v_flamethrower.md3");\r
54                 else if (self.owner.wpn == WEP_PISTOL) setmodel(self, "models/weapons/v_soldpistol.md3");\r
55                 setattachment(self, self.owner, "bip01 r hand");\r
56                 // if that didn't find a tag, hide the exterior weapon model\r
57                 if (!self.tag_index)\r
58                         self.model = "";\r
59         }\r
60         self.effects = self.owner.weaponentity.effects;\r
61 };\r
62 \r
63 // spawning weaponentity for client\r
64 void() CL_SpawnWeaponentity =\r
65 {\r
66         if (self.weaponentity)\r
67         {\r
68                 w_clear();\r
69                 return;\r
70         }\r
71         self.weaponentity = spawn();\r
72         self.weaponentity.solid = SOLID_NOT;\r
73         self.weaponentity.owner = self;\r
74         self.weaponentity.weaponentity = self.weaponentity;\r
75         setmodel(self.weaponentity, "");\r
76         self.weaponentity.origin = '0 0 0';\r
77         self.weaponentity.angles = '0 0 0';\r
78         self.weaponentity.viewmodelforclient = self;\r
79         self.weaponentity.flags = 0;\r
80         self.weaponentity.think = CL_Weaponentity_Think;\r
81         self.weaponentity.nextthink = time;\r
82 \r
83         self.exteriorweaponentity = spawn();\r
84         self.exteriorweaponentity.solid = SOLID_NOT;\r
85         self.exteriorweaponentity.exteriorweaponentity = self.exteriorweaponentity;\r
86         self.exteriorweaponentity.owner = self;\r
87         self.exteriorweaponentity.origin = '0 0 0';\r
88         self.exteriorweaponentity.angles = '0 0 0';\r
89         self.exteriorweaponentity.think = CL_ExteriorWeaponentity_Think;\r
90         self.exteriorweaponentity.nextthink = time;\r
91 };\r
92 \r
93 // convertion from index (= impulse) to flag in .items\r
94 float(float index) weapon_translateindextoflag =\r
95 {\r
96         if (index == WEP1)\r
97                 return IT_WEP1;\r
98         else if (index == WEP2)\r
99                 return IT_WEP2;\r
100         else if (index == WEP3)\r
101                 return IT_WEP3;\r
102         else if (index == WEP4)\r
103                 return IT_WEP4;\r
104         else if (index == WEP5)\r
105                 return IT_WEP5;\r
106         return IT_WEP1;\r
107 };\r
108 \r
109 float(entity cl, float wpn, float andammo) client_hasweapon =\r
110 {\r
111         local float itemcode;\r
112         local entity oldself;\r
113 \r
114         weapon_hasammo = TRUE;\r
115         if (wpn < WEP_FIRST || wpn > WEP_LAST)\r
116                 return FALSE;\r
117         itemcode = weapon_translateindextoflag(wpn);\r
118         if (cl.items & itemcode)\r
119         {\r
120                 if (andammo)\r
121                 {\r
122                         oldself = self;\r
123                         self = cl;\r
124                         weapon_action(wpn, WR_CHECKAMMO);\r
125                         self = oldself;\r
126                         if (weapon_hasammo)\r
127                                 return TRUE;\r
128                         return FALSE;\r
129                 }\r
130                 return TRUE;\r
131         }\r
132         return FALSE;\r
133 };\r
134 \r
135 // Weapon subs\r
136 void() w_clear =\r
137 {\r
138         weapon_action(self.weapon, WR_CLEAR);\r
139         if (self.weapon != -1)\r
140                 self.weapon = 0;\r
141         if (self.weaponentity)\r
142         {\r
143                 self.weaponentity.state = WS_CLEAR;\r
144                 setmodel(self.weaponentity, "");\r
145                 self.weaponentity.effects = 0;\r
146         }\r
147 };\r
148 \r
149 void() w_ready =\r
150 {\r
151         self.weaponentity.state = WS_READY;\r
152         weapon_action(self.weapon, WR_IDLE);\r
153 };\r
154 \r
155 // FIXME: add qw-style client-custom weaponrating (cl_weaponrating)?\r
156 float(entity e) w_getbestweapon\r
157 {// add new weapons here\r
158         if(e.class == CLASS_SCOUT)\r
159         {\r
160                 if (client_hasweapon(e, WEP5, TRUE))\r
161                         return WEP5;\r
162                 else if (client_hasweapon(e, WEP3, TRUE))\r
163                         return WEP3;\r
164                 else if (client_hasweapon(e, WEP2, TRUE))\r
165                         return WEP2;\r
166                 weapon_hasammo = TRUE;\r
167                 return WEP1;\r
168         }\r
169         if(e.class == CLASS_SPY)\r
170         {\r
171                 if (client_hasweapon(e, WEP5, TRUE))\r
172                         return WEP5;\r
173                 else if (client_hasweapon(e, WEP2, TRUE))\r
174                         return WEP2;\r
175                 weapon_hasammo = TRUE;\r
176                 return WEP1;\r
177         }\r
178         if(e.class == CLASS_SOLDIER)\r
179         {\r
180                 if (client_hasweapon(e, WEP5, TRUE))\r
181                         return WEP5;\r
182                 else if (client_hasweapon(e, WEP4, TRUE))\r
183                         return WEP4;\r
184                 else if (client_hasweapon(e, WEP3, TRUE))\r
185                         return WEP3;\r
186                 else if (client_hasweapon(e, WEP2, TRUE))\r
187                         return WEP2;\r
188                 weapon_hasammo = TRUE;\r
189                 return WEP1;\r
190         }\r
191         if(e.class == CLASS_PYRO)\r
192         {\r
193                 if (client_hasweapon(e, WEP5, TRUE))\r
194                         return WEP5;\r
195                 else if (client_hasweapon(e, WEP3, TRUE))\r
196                         return WEP3;\r
197                 else if (client_hasweapon(e, WEP2, TRUE))\r
198                         return WEP2;\r
199                 else if (client_hasweapon(e, WEP4, TRUE))\r
200                         return WEP4;\r
201                 weapon_hasammo = TRUE;\r
202                 return WEP1;\r
203         }\r
204         if(e.class == CLASS_MEDIC)\r
205         {\r
206                 if (client_hasweapon(e, WEP5, TRUE))\r
207                         return WEP5;\r
208                 else if (client_hasweapon(e, WEP4, TRUE))\r
209                         return WEP4;\r
210                 else if (client_hasweapon(e, WEP3, TRUE))\r
211                         return WEP3;\r
212                 else if (client_hasweapon(e, WEP2, TRUE))\r
213                         return WEP2;\r
214                 weapon_hasammo = TRUE;\r
215                 return WEP1;\r
216         }\r
217         if(e.class == CLASS_ENGINEER)\r
218         {\r
219                 if (client_hasweapon(e, WEP5, TRUE))\r
220                         return WEP5;\r
221                 else if (client_hasweapon(e, WEP4, TRUE))\r
222                         return WEP4;\r
223                 else if (client_hasweapon(e, WEP3, TRUE))\r
224                         return WEP3;\r
225                 else if (client_hasweapon(e, WEP2, TRUE))\r
226                         return WEP2;\r
227                 weapon_hasammo = TRUE;\r
228                 return WEP1;\r
229         }\r
230         weapon_hasammo = TRUE;\r
231         return WEP1;\r
232 };\r
233 \r
234 // Setup weapon for client (after this raise frame will be launched)\r
235 void(float new_wep, string wmodel, float hudammo) weapon_setup =\r
236 {\r
237         local string weaponmdl;\r
238 \r
239         self.items = self.items - (self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS));\r
240         self.items = self.items | hudammo;\r
241 \r
242         self.weapon = self.switchweapon;\r
243         //self.weapon = weapon_translateindextoflag(new_wep);\r
244         self.wpn = new_wep;\r
245 \r
246         if (wmodel != "")\r
247         {\r
248                 weaponmdl = strzone(strcat("models/weapons/", wmodel));\r
249                 setmodel(self.weaponentity, weaponmdl);\r
250         }\r
251         // VorteX: update visible weapon\r
252         // CL_ViswepUpdate();\r
253 };\r
254 \r
255 /*void(float new_wep, string wmodel, float hudammo, void spfunciton()) weapon_setup_special =\r
256 {\r
257         weapon_setup(new_wep, wmodel, hudammo);\r
258         spfunction();\r
259 }*/\r
260 \r
261 // shot direction\r
262 float WEAPON_MAXRELX = 14; // if more, shot can be spawned after wall surface (in empty worldspace) or inside other entity if client stands close to it\r
263 void(float x, float y, float z) weapon_shotdir =\r
264 {\r
265         makevectors(self.v_angle);\r
266         self.shotorg  = self.origin + self.view_ofs + v_forward*bound(0, x, WEAPON_MAXRELX) + v_right*(y + self.weaponentity.view_ofs_y) + v_up*z;\r
267         self.shotdir = aim(self, 1000);\r
268 };\r
269 \r
270 // perform weapon to attack (weaponstate and attack_finished check is here)\r
271 void(float() checkfunc1, float() checkfunc2, void() firefunc, float atktime) weapon_prepareattack =\r
272 {\r
273         // fixme: does spy need to decloak here?\r
274         //if(self.class == CLASS_SPY)\r
275         //{\r
276         //      SpyDecloak();\r
277         //}\r
278         // Change to best weapon if failed\r
279         if ((cvar("g_instagib") == 0) && (cvar("g_rocketarena") == 0))\r
280         {\r
281                 if (!checkfunc1())\r
282                 {\r
283                         if (!checkfunc2())\r
284                                 self.switchweapon = w_getbestweapon(self);\r
285                         return;\r
286                 }\r
287         }\r
288         // Don't do shot if previos attack  not finished\r
289                 if (time < self.attack_finished)\r
290                         return;\r
291         // Can't do shot if changing weapon\r
292                 if (self.weaponentity.state != WS_READY)\r
293                         return;\r
294 \r
295         self.attack_finished = time + atktime;\r
296         firefunc();\r
297 };\r
298 \r
299 void SpyDecloak();\r
300 // perform weapon attack\r
301 void(float() checkfunc1, float() checkfunc2, void() firefunc) weapon_doattack\r
302 {\r
303         if(self.class == CLASS_SPY)\r
304         {\r
305                 SpyDecloak();\r
306         }\r
307 \r
308 \r
309         // Change to best weapon if failed\r
310         if ((cvar("g_instagib") == 0) && (cvar("g_rocketarena") == 0))\r
311         {\r
312                 if (!checkfunc1())\r
313                 {\r
314                         if (!checkfunc2())\r
315                                 self.switchweapon = w_getbestweapon(self);\r
316                         return;\r
317                 }\r
318         }\r
319         self.weaponentity.state = WS_INUSE;\r
320         firefunc();\r
321         weapon_action(self.weapon, WR_UPDATECOUNTS); // update ammo now\r
322 };\r
323 \r
324 void(entity ent, float recoil) weapon_recoil =\r
325 {\r
326         ent.punchangle = (randomvec() + '-1 0 0')*recoil;\r
327         ent.punchangle_z = 0; // don't want roll\r
328         if (recoil > 3) // push back if large recoil\r
329                 ent.velocity = ent.velocity - normalize(ent.shotdir)*recoil*25;\r
330 };\r
331 \r
332 void(float fr, float t, void() func) weapon_thinkf =\r
333 {\r
334         if (fr >= 0)\r
335                 if (self.weaponentity != world)\r
336                         self.weaponentity.frame = fr;\r
337         // VorteX: haste can be added here\r
338         self.weapon_nextthink = time + t;\r
339         self.weapon_think = func;\r
340 };\r
341 \r
342 void(float spd, vector org) weapon_boblayer1 =\r
343 {\r
344         // VorteX: haste can be added here\r
345         self.weaponentity.pos1 =org;\r
346         self.weaponentity.lip = spd;\r
347 };\r