]> icculus.org git repositories - divverent/nexuiz.git/blob - TeamNexuiz/game/gamec/cl_weaponsystem.c
- Changed railgun model to Morphed's v/w_nex models (railgun models are still precach...
[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                 setattachment(self, self.owner, "bip01 r hand");\r
54                 // if that didn't find a tag, hide the exterior weapon model\r
55                 if (!self.tag_index)\r
56                         self.model = "";\r
57         }\r
58         self.effects = self.owner.weaponentity.effects;\r
59 };\r
60 \r
61 // spawning weaponentity for client\r
62 void() CL_SpawnWeaponentity =\r
63 {\r
64         if (self.weaponentity)\r
65         {\r
66                 w_clear();\r
67                 return;\r
68         }\r
69         self.weaponentity = spawn();\r
70         self.weaponentity.solid = SOLID_NOT;\r
71         self.weaponentity.owner = self;\r
72         self.weaponentity.weaponentity = self.weaponentity;\r
73         setmodel(self.weaponentity, "");\r
74         self.weaponentity.origin = '0 0 0';\r
75         self.weaponentity.angles = '0 0 0';\r
76         self.weaponentity.viewmodelforclient = self;\r
77         self.weaponentity.flags = 0;\r
78         self.weaponentity.think = CL_Weaponentity_Think;\r
79         self.weaponentity.nextthink = time;\r
80 \r
81         self.exteriorweaponentity = spawn();\r
82         self.exteriorweaponentity.solid = SOLID_NOT;\r
83         self.exteriorweaponentity.exteriorweaponentity = self.exteriorweaponentity;\r
84         self.exteriorweaponentity.owner = self;\r
85         self.exteriorweaponentity.origin = '0 0 0';\r
86         self.exteriorweaponentity.angles = '0 0 0';\r
87         self.exteriorweaponentity.think = CL_ExteriorWeaponentity_Think;\r
88         self.exteriorweaponentity.nextthink = time;\r
89 };\r
90 \r
91 // convertion from index (= impulse) to flag in .items\r
92 float(float index) weapon_translateindextoflag =\r
93 {\r
94         if (index == WEP1)\r
95                 return IT_WEP1;\r
96         else if (index == WEP2)\r
97                 return IT_WEP2;\r
98         else if (index == WEP3)\r
99                 return IT_WEP3;\r
100         else if (index == WEP4)\r
101                 return IT_WEP4;\r
102         else if (index == WEP5)\r
103                 return IT_WEP5;\r
104         return IT_WEP1;\r
105 };\r
106 \r
107 float(entity cl, float wpn, float andammo) client_hasweapon =\r
108 {\r
109         local float itemcode;\r
110         local entity oldself;\r
111 \r
112         weapon_hasammo = TRUE;\r
113         if (wpn < WEP_FIRST || wpn > WEP_LAST)\r
114                 return FALSE;\r
115         itemcode = weapon_translateindextoflag(wpn);\r
116         if (cl.items & itemcode)\r
117         {\r
118                 if (andammo)\r
119                 {\r
120                         oldself = self;\r
121                         self = cl;\r
122                         weapon_action(wpn, WR_CHECKAMMO);\r
123                         self = oldself;\r
124                         if (weapon_hasammo)\r
125                                 return TRUE;\r
126                         return FALSE;\r
127                 }\r
128                 return TRUE;\r
129         }\r
130         return FALSE;\r
131 };\r
132 \r
133 // Weapon subs\r
134 void() w_clear =\r
135 {\r
136         weapon_action(self.weapon, WR_CLEAR);\r
137         if (self.weapon != -1)\r
138                 self.weapon = 0;\r
139         if (self.weaponentity)\r
140         {\r
141                 self.weaponentity.state = WS_CLEAR;\r
142                 setmodel(self.weaponentity, "");\r
143                 self.weaponentity.effects = 0;\r
144         }\r
145 };\r
146 \r
147 void() w_ready =\r
148 {\r
149         self.weaponentity.state = WS_READY;\r
150         weapon_action(self.weapon, WR_IDLE);\r
151 };\r
152 \r
153 // FIXME: add qw-style client-custom weaponrating (cl_weaponrating)?\r
154 float(entity e) w_getbestweapon\r
155 {// add new weapons here\r
156         if(e.class == CLASS_SCOUT)\r
157         {\r
158                 if (client_hasweapon(e, WEP5, TRUE))\r
159                         return WEP5;\r
160                 else if (client_hasweapon(e, WEP3, TRUE))\r
161                         return WEP3;\r
162                 else if (client_hasweapon(e, WEP2, TRUE))\r
163                         return WEP2;\r
164                 weapon_hasammo = TRUE;\r
165                 return WEP1;\r
166         }\r
167         if(e.class == CLASS_SPY)\r
168         {\r
169                 if (client_hasweapon(e, WEP5, TRUE))\r
170                         return WEP5;\r
171                 else if (client_hasweapon(e, WEP2, TRUE))\r
172                         return WEP2;\r
173                 weapon_hasammo = TRUE;\r
174                 return WEP1;\r
175         }\r
176         if(e.class == CLASS_SOLDIER)\r
177         {\r
178                 if (client_hasweapon(e, WEP5, TRUE))\r
179                         return WEP5;\r
180                 else if (client_hasweapon(e, WEP4, TRUE))\r
181                         return WEP4;\r
182                 else if (client_hasweapon(e, WEP3, TRUE))\r
183                         return WEP3;\r
184                 else if (client_hasweapon(e, WEP2, TRUE))\r
185                         return WEP2;\r
186                 weapon_hasammo = TRUE;\r
187                 return WEP1;\r
188         }\r
189         if(e.class == CLASS_PYRO)\r
190         {\r
191                 if (client_hasweapon(e, WEP5, TRUE))\r
192                         return WEP5;\r
193                 else if (client_hasweapon(e, WEP3, TRUE))\r
194                         return WEP3;\r
195                 else if (client_hasweapon(e, WEP2, TRUE))\r
196                         return WEP2;\r
197                 else if (client_hasweapon(e, WEP4, TRUE))\r
198                         return WEP4;\r
199                 weapon_hasammo = TRUE;\r
200                 return WEP1;\r
201         }\r
202         if(e.class == CLASS_MEDIC)\r
203         {\r
204                 if (client_hasweapon(e, WEP5, TRUE))\r
205                         return WEP5;\r
206                 else if (client_hasweapon(e, WEP4, TRUE))\r
207                         return WEP4;\r
208                 else if (client_hasweapon(e, WEP3, TRUE))\r
209                         return WEP3;\r
210                 else if (client_hasweapon(e, WEP2, TRUE))\r
211                         return WEP2;\r
212                 weapon_hasammo = TRUE;\r
213                 return WEP1;\r
214         }\r
215         if(e.class == CLASS_ENGINEER)\r
216         {\r
217                 if (client_hasweapon(e, WEP5, TRUE))\r
218                         return WEP5;\r
219                 else if (client_hasweapon(e, WEP4, TRUE))\r
220                         return WEP4;\r
221                 else if (client_hasweapon(e, WEP3, TRUE))\r
222                         return WEP3;\r
223                 else if (client_hasweapon(e, WEP2, TRUE))\r
224                         return WEP2;\r
225                 weapon_hasammo = TRUE;\r
226                 return WEP1;\r
227         }\r
228         weapon_hasammo = TRUE;\r
229         return WEP1;\r
230 };\r
231 \r
232 // Setup weapon for client (after this raise frame will be launched)\r
233 void(float new_wep, string wmodel, float hudammo) weapon_setup =\r
234 {\r
235         local string weaponmdl;\r
236 \r
237         self.items = self.items - (self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS));\r
238         self.items = self.items | hudammo;\r
239 \r
240         self.weapon = self.switchweapon;\r
241         //self.weapon = weapon_translateindextoflag(new_wep);\r
242         self.wpn = new_wep;\r
243 \r
244         if (wmodel != "")\r
245         {\r
246                 weaponmdl = strzone(strcat("models/weapons/", wmodel));\r
247                 setmodel(self.weaponentity, weaponmdl);\r
248         }\r
249         // VorteX: update visible weapon\r
250         // CL_ViswepUpdate();\r
251 };\r
252 \r
253 /*void(float new_wep, string wmodel, float hudammo, void spfunciton()) weapon_setup_special =\r
254 {\r
255         weapon_setup(new_wep, wmodel, hudammo);\r
256         spfunction();\r
257 }*/\r
258 \r
259 // shot direction\r
260 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
261 void(float x, float y, float z) weapon_shotdir =\r
262 {\r
263         makevectors(self.v_angle);\r
264         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
265         self.shotdir = aim(self, 1000);\r
266 };\r
267 \r
268 // perform weapon to attack (weaponstate and attack_finished check is here)\r
269 void(float() checkfunc1, float() checkfunc2, void() firefunc, float atktime) weapon_prepareattack =\r
270 {\r
271         // fixme: does spy need to decloak here?\r
272         //if(self.class == CLASS_SPY)\r
273         //{\r
274         //      SpyDecloak();\r
275         //}\r
276         // Change to best weapon if failed\r
277         if ((cvar("g_instagib") == 0) && (cvar("g_rocketarena") == 0))\r
278         {\r
279                 if (!checkfunc1())\r
280                 {\r
281                         if (!checkfunc2())\r
282                                 self.switchweapon = w_getbestweapon(self);\r
283                         return;\r
284                 }\r
285         }\r
286         // Don't do shot if previos attack  not finished\r
287                 if (time < self.attack_finished)\r
288                         return;\r
289         // Can't do shot if changing weapon\r
290                 if (self.weaponentity.state != WS_READY)\r
291                         return;\r
292 \r
293         self.attack_finished = time + atktime;\r
294         firefunc();\r
295 };\r
296 \r
297 void SpyDecloak();\r
298 // perform weapon attack\r
299 void(float() checkfunc1, float() checkfunc2, void() firefunc) weapon_doattack\r
300 {\r
301         if(self.class == CLASS_SPY)\r
302         {\r
303                 SpyDecloak();\r
304         }\r
305 \r
306 \r
307         // Change to best weapon if failed\r
308         if ((cvar("g_instagib") == 0) && (cvar("g_rocketarena") == 0))\r
309         {\r
310                 if (!checkfunc1())\r
311                 {\r
312                         if (!checkfunc2())\r
313                                 self.switchweapon = w_getbestweapon(self);\r
314                         return;\r
315                 }\r
316         }\r
317         self.weaponentity.state = WS_INUSE;\r
318         firefunc();\r
319         weapon_action(self.weapon, WR_UPDATECOUNTS); // update ammo now\r
320 };\r
321 \r
322 void(entity ent, float recoil) weapon_recoil =\r
323 {\r
324         ent.punchangle = (randomvec() + '-1 0 0')*recoil;\r
325         ent.punchangle_z = 0; // don't want roll\r
326         if (recoil > 3) // push back if large recoil\r
327                 ent.velocity = ent.velocity - normalize(ent.shotdir)*recoil*25;\r
328 };\r
329 \r
330 void(float fr, float t, void() func) weapon_thinkf =\r
331 {\r
332         if (fr >= 0)\r
333                 if (self.weaponentity != world)\r
334                         self.weaponentity.frame = fr;\r
335         // VorteX: haste can be added here\r
336         self.weapon_nextthink = time + t;\r
337         self.weapon_think = func;\r
338 };\r
339 \r
340 void(float spd, vector org) weapon_boblayer1 =\r
341 {\r
342         // VorteX: haste can be added here\r
343         self.weaponentity.pos1 =org;\r
344         self.weaponentity.lip = spd;\r
345 };\r