- Put Client Commands in a seperate file
[divverent/nexuiz.git] / TeamNexuiz / game / gamec / cl_weapons.c
1 \r
2 // generic weapons table\r
3 // add new weapons here\r
4 void (float wreq) w_railgun;\r
5 void (float wreq) w_healgun;\r
6 void (float wreq) w_mac;\r
7 void (float wreq) w_pistol;\r
8 void(float wpn, float wrequest) weapon_action =\r
9 {\r
10         if ((self.reload_time + .25) > time || self.is_feigning == 1) { \r
11                 return; }\r
12         if (wpn == WEP5)\r
13         {\r
14                 wpn = self.wpn5.weapon;\r
15 \r
16                 // various extra weapons the player can equip\r
17                 if (wpn == WEP_LASER)\r
18                         w_laser(wrequest);\r
19                 else if (wpn == WEP_SHOTGUN)\r
20                         w_shotgun(wrequest);\r
21                 else if (wpn == WEP_UZI)\r
22                         w_uzi(wrequest);\r
23                 else if (wpn == WEP_GRENADE_LAUNCHER)\r
24                         w_glauncher(wrequest);\r
25                 else if (wpn == WEP_ELECTRO)\r
26                         w_electro(wrequest);\r
27                 else if (wpn == WEP_CRYLINK)\r
28                         w_crylink(wrequest);\r
29                 else if (wpn == WEP_NEX)\r
30                         w_nex(wrequest);\r
31                 else if (wpn == WEP_HAGAR)\r
32                         w_hagar(wrequest);\r
33                 else if (wpn == WEP_ROCKET_LAUNCHER)\r
34                         w_rlauncher(wrequest);\r
35                 return;\r
36         }\r
37         else if(self.class == CLASS_SCOUT)\r
38         {\r
39                 if (wpn == WEP1)\r
40                         w_shotgun(wrequest);\r
41                 else if (wpn == WEP2)\r
42                         w_grapple(wrequest);\r
43                 else if (wpn == WEP3)\r
44                         w_uzi(wrequest);\r
45                 else if (wpn == WEP4)\r
46                         w_crylink(wrequest);\r
47         }\r
48         else if(self.class == CLASS_SPY)\r
49         {\r
50                 if (wpn == WEP1)\r
51                         w_laser(wrequest);\r
52                 else if (wpn == WEP2)\r
53                         w_uzi(wrequest);                //later be replaced with tranq gun\r
54                 else if (wpn == WEP3)\r
55                         w_shotgun(wrequest);\r
56 //                      w_uzi(wrequest);\r
57                 else if (wpn == WEP4)\r
58                         w_mac(wrequest);\r
59 //                      w_uzi(wrequest);\r
60         }\r
61         else if(self.class == CLASS_SOLDIER)\r
62         {\r
63                 if (wpn == WEP1)\r
64                         w_pistol(wrequest);\r
65                         //w_shotgun(wrequest);\r
66                 else if (wpn == WEP2)\r
67                         w_shotgun(wrequest);\r
68                         //w_namek(wrequest);\r
69                 else if (wpn == WEP3)\r
70                         w_namek(wrequest);\r
71 //                      w_electro(wrequest);\r
72                 else if (wpn == WEP4)\r
73                         w_rlauncher(wrequest);\r
74         }\r
75         else if(self.class == CLASS_PYRO)\r
76         {\r
77                 if (wpn == WEP1)\r
78                         w_bombletts(wrequest);\r
79                 else if (wpn == WEP2)\r
80                         w_flamer(wrequest);\r
81                 else if (wpn == WEP3)\r
82                         w_rincendiary(wrequest);\r
83                 else if (wpn == WEP4)\r
84                         w_hotbombs(wrequest);\r
85         }\r
86         else if(self.class == CLASS_MEDIC)\r
87         {\r
88                 if (wpn == WEP1)\r
89                         w_healgun(wrequest);\r
90                 else if (wpn == WEP2)\r
91                         w_shotgun(wrequest);\r
92                 else if (wpn == WEP3)\r
93                         w_laser(wrequest);\r
94                 else if (wpn == WEP4)\r
95                         w_uzi(wrequest);\r
96         }\r
97         else if(self.class == CLASS_ENGINEER)\r
98         {\r
99                 if (wpn == WEP1)\r
100                         w_laser(wrequest);\r
101                 else if (wpn == WEP2)\r
102                         w_railgun(wrequest);\r
103                 else if (wpn == WEP3)\r
104                         w_shotgun(wrequest);\r
105                         //w_electro(wrequest);\r
106                 else if (wpn == WEP4)\r
107                         w_electro(wrequest);\r
108                         //w_rlauncher(wrequest);\r
109         }\r
110         else\r
111         {\r
112                 if (wpn == WEP_LASER)\r
113                         w_laser(wrequest);\r
114                 else if (wpn == WEP_SHOTGUN)\r
115                         w_shotgun(wrequest);\r
116                 else if (wpn == WEP_UZI)\r
117                         w_uzi(wrequest);\r
118                 else if (wpn == WEP_GRENADE_LAUNCHER)\r
119                         w_glauncher(wrequest);\r
120                 else if (wpn == WEP_ELECTRO)\r
121                         w_electro(wrequest);\r
122                 else if (wpn == WEP_CRYLINK)\r
123                         w_crylink(wrequest);\r
124                 else if (wpn == WEP_NEX)\r
125                         w_nex(wrequest);\r
126                 else if (wpn == WEP_HAGAR)\r
127                         w_hagar(wrequest);\r
128                 else if (wpn == WEP_ROCKET_LAUNCHER)\r
129                         w_rlauncher(wrequest);\r
130         }\r
131 \r
132 };\r
133 \r
134 void () CheckTeamClass =\r
135 {\r
136         if (self.impulse_wait > time)   // So the GUI menus doesnt flicker\r
137                 return;\r
138         if (self.playerclass < 1)               // Bring up menu if no team/class\r
139         {\r
140                 if (self.team_no < 1)\r
141                 {\r
142                         stuffcmd(self, "set scmenu_directmenu TeamSelect; togglemenu\n");\r
143                 }\r
144                 else \r
145                 {\r
146                         stuffcmd(self, "set scmenu_directmenu ClassSelect; togglemenu\n");\r
147                 }\r
148                 self.impulse_wait = time + .5;\r
149                 return;\r
150         }\r
151 };\r
152 \r
153 // switch between weapons\r
154 void(float imp) W_SwitchWeapon\r
155 {\r
156 /*      if (self.reload_time > time - .1)\r
157         {\r
158                 return;\r
159         }*/\r
160         weapon_hasammo = TRUE;\r
161         if (!client_hasweapon(self, imp, TRUE))\r
162         {\r
163                 if (!weapon_hasammo)\r
164 //                      sprint(self, "You don't have any ammo for that weapon\n");\r
165                         TeamNexuiz_HUD_ShowSign(self, NO_AMMO_WARNING);\r
166                 else\r
167                         sprint(self, "You don't own that weapon\n");\r
168         }\r
169         else\r
170                 self.switchweapon = imp;\r
171 };\r
172 \r
173 // next weapon\r
174 void() W_NextWeapon =\r
175 {\r
176         local float weaponwant, i;\r
177 \r
178         weaponwant = self.switchweapon + 1;\r
179         if (weaponwant < WEP_FIRST)\r
180                 weaponwant = WEP_LAST;\r
181         if (weaponwant > WEP_LAST)\r
182                 weaponwant = WEP_FIRST;\r
183         weapon_hasammo = TRUE;\r
184         i = 0;\r
185         while(!client_hasweapon(self, weaponwant, TRUE))\r
186         {\r
187                 i = i + 1;\r
188                 if(i >= 20)\r
189                         return; // failed; there's probably some weird problem causing an infinite loop\r
190                 weaponwant = weaponwant + 1;\r
191                 if (weaponwant < WEP_FIRST)\r
192                         weaponwant = WEP_LAST;\r
193                 if (weaponwant > WEP_LAST)\r
194                         weaponwant = WEP_FIRST;\r
195         }\r
196         self.switchweapon = weaponwant;\r
197 };\r
198 \r
199 // prev weapon\r
200 void() W_PreviousWeapon =\r
201 {\r
202         local float weaponwant, i;\r
203 \r
204         weaponwant = self.switchweapon - 1;\r
205         if (weaponwant < WEP_FIRST)\r
206                 weaponwant = WEP_LAST;\r
207         if (weaponwant > WEP_LAST)\r
208                 weaponwant = WEP_FIRST;\r
209         weapon_hasammo = TRUE;\r
210         i = 0;\r
211         while(!client_hasweapon(self, weaponwant, TRUE))\r
212         {\r
213                 i = i + 1;\r
214                 if(i >= 20)\r
215                         return; // failed; there's probably some weird problem causing an infinite loop\r
216                 weaponwant = weaponwant - 1;\r
217                 if (weaponwant < WEP_FIRST)\r
218                         weaponwant = WEP_LAST;\r
219                 if (weaponwant > WEP_LAST)\r
220                         weaponwant = WEP_FIRST;\r
221         }\r
222         self.switchweapon = weaponwant;\r
223 };\r
224 \r
225 void () Use_Function;\r
226 // Brought back weapon frame\r
227 void() W_WeaponFrame =\r
228 {\r
229         if (self.current_menu > 0)                              // calls the text menu display\r
230         {\r
231                 Player_Menu ();\r
232                 if ((self.impulse > 0) && (self.impulse < 11))\r
233                 {\r
234                         Menu_Input (self.impulse);\r
235                 }\r
236         }\r
237         if(self.buttonuse)\r
238                 Use_Function();         // for engineer and medic, though I'm putting this in engineer.c...\r
239 \r
240         if (self.button0 || self.button2 || self.button3  || self.button4)\r
241                 CheckTeamClass();\r
242         if (!self.weaponentity || self.health <= 0)\r
243                 return; // Dead player can't use weapons and injure impulse commands\r
244 \r
245         if (cvar("g_antilag"))\r
246         {\r
247                 // if aiming at a player and the original trace won't hit that player\r
248                 // anymore, try aiming at the player's new position\r
249                 if (self.cursor_trace_ent)\r
250                 {\r
251                         if (self.cursor_trace_ent.takedamage)\r
252                         {\r
253                                 traceline(self.origin + self.view_ofs, self.cursor_trace_endpos, FALSE, self);\r
254                                 if (trace_ent != self.cursor_trace_ent)\r
255                                 {\r
256                                         traceline(self.origin + self.view_ofs, self.cursor_trace_ent.origin + (self.cursor_trace_ent.mins + self.cursor_trace_ent.maxs) * 0.5, FALSE, self);\r
257                                         if (trace_ent == self.cursor_trace_ent)\r
258                                                 self.cursor_trace_endpos = trace_endpos;\r
259                                 }\r
260                         }\r
261                 }\r
262                 self.v_angle = vectoangles(self.cursor_trace_endpos - (self.origin + self.view_ofs));\r
263                 self.v_angle_x = 0 - self.v_angle_x;\r
264         }\r
265 \r
266         makevectors(self.v_angle);\r
267 \r
268         // Change weapon\r
269         if (self.weapon != self.switchweapon && self.is_feigning != 1)\r
270         {\r
271                 //bprint("switching weapon: ");\r
272                 //bprint(ftos(self.weapon));\r
273                 //bprint(" --> ");\r
274                 //bprint(ftos(self.switchweapon));\r
275                 //bprint("\n");\r
276 \r
277                 //self.weaponentity.state = WS_CLEAR;\r
278                 if (self.weaponentity.state == WS_CLEAR)\r
279                 {\r
280                         //bprint("switching in\n");\r
281                         self.weaponentity.state = WS_RAISE;\r
282                         weapon_action(self.switchweapon, WR_SETUP);\r
283                         // VorteX: add player model weapon select frame here\r
284                         // setcustomframe(PlayerWeaponRaise);\r
285                         weapon_action(self.weapon, WR_UPDATECOUNTS);\r
286                         weapon_action(self.weapon, WR_RAISE);\r
287                 }\r
288                 else if (self.weaponentity.state == WS_READY)\r
289                 {\r
290                         //bprint("switching out\n");\r
291                         sound (self, CHAN_WEAPON, "weapons/weapon_switch.wav", 1, ATTN_NORM);\r
292                         self.weaponentity.state = WS_DROP;\r
293                         // VorteX: add player model weapon deselect frame here\r
294                         // setcustomframe(PlayerWeaponDrop);\r
295                         weapon_action(self.weapon, WR_DROP);\r
296                 }\r
297         }\r
298 \r
299         if (self.button0)\r
300         {\r
301                 if (self.pistol_fired == 1)                             // code so that if fire is held down with pistol,\r
302                 {                                                                               //// it will not keep firing automatically.\r
303                         self.next_pistol_fire = time + .2;\r
304                 }\r
305                 weapon_action(self.weapon, WR_FIRE1);\r
306         }\r
307         if (self.button3)\r
308                 weapon_action(self.weapon, WR_FIRE2);\r
309 \r
310         if (!self.button0 && self.pistol_fired == 1)\r
311                 self.pistol_fired = 0;\r
312         // do weapon think\r
313         if (time >= self.weapon_nextthink)\r
314                 if (self.weapon_nextthink > 0)\r
315                         self.weapon_think();\r
316 \r
317         // weapon bobbing and script actions\r
318         local float bobintensity, q1pitching, framespeed, diff;\r
319         local vector vel, realorg, layer1, boblayer;\r
320 \r
321         bobintensity = cvar("g_viewweapon_bobintensity"); // weapon bob intensity\r
322         q1pitching = fabs(cvar("g_viewweapon_q1pitching")); // q1 style of "bob" when looking up and down\r
323 \r
324         realorg = self.weaponentity.origin + self.weaponentity.view_ofs;\r
325         realorg = realorg - self.weaponentity.finaldest; // finaldest is last bob position\r
326 \r
327         // VorteX: actually this is needed for weapon screen offset\r
328         if (q1pitching)\r
329         {\r
330                 self.weaponentity.view_ofs_x = q1pitching*bound(-5.5, self.v_angle_x/45, 5.5);\r
331                 self.weaponentity.view_ofs_z = q1pitching*bound(-1.5, self.v_angle_x/60, 1.5);\r
332         }\r
333 \r
334         // weapon origin interpolation, layer 1\r
335         if (realorg != self.weaponentity.pos1)\r
336         {\r
337                 framespeed = frametime*self.weaponentity.lip*10; // lip is speed of origin changing (of layer1)\r
338                 diff = vlen(realorg - self.weaponentity.pos1);\r
339                 // VorteX: add speed modifier (haste)?\r
340                 layer1 = frametime*10*self.weaponentity.lip*normalize(self.weaponentity.pos1 - realorg);\r
341                 if (diff <= vlen(layer1))\r
342                         layer1 = normalize(self.weaponentity.pos1 - realorg)*diff;\r
343         }\r
344 \r
345         // weapon bobbing (q3-style)\r
346         if (self.flags & FL_ONGROUND && self.waterlevel < 2)\r
347         {\r
348                 // VorteX: only xy velocity matters\r
349                 vel_x = self.velocity_x;\r
350                 vel_y = self.velocity_y;\r
351                 framespeed = vlen(vel);\r
352                 // Y axis\r
353                 diff = bobintensity*framespeed/300;\r
354                 self.weaponentity.destvec_y = self.weaponentity.destvec_y + frametime*10;\r
355                 boblayer_y = diff*cos(self.weaponentity.destvec_y + 90);\r
356                 // Z axis\r
357                 diff = bobintensity*framespeed/540;\r
358                 self.weaponentity.destvec_z = self.weaponentity.destvec_z + frametime*20;\r
359                 boblayer_z = diff*cos(self.weaponentity.destvec_z);\r
360                 self.weaponentity.finaldest = boblayer;\r
361         }\r
362         else if (self.waterlevel > 0)\r
363         {// swim, all velocity matters\r
364                 // X axis\r
365                 framespeed = vlen(self.velocity);\r
366                 diff = bobintensity*framespeed/100;\r
367                 self.weaponentity.destvec_x = self.weaponentity.destvec_x + frametime*6;\r
368                 boblayer_x = diff*cos(self.weaponentity.destvec_x);\r
369                 self.weaponentity.finaldest = boblayer;\r
370         }\r
371         else\r
372                 self.weaponentity.finaldest = '0 0 0';\r
373         self.weaponentity.origin = realorg + boblayer + layer1 - self.weaponentity.view_ofs;\r
374 };