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