]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/gamec/cl_weapons.c
ops, i messed up kill-on-teamchange...
[divverent/nexuiz.git] / data / qcsrc / gamec / cl_weapons.c
1 // generic weapons table
2 // add new weapons here
3 void(float wpn, float wrequest) weapon_action =
4 {
5         if (cvar("g_minstagib"))
6         {
7                 if (wpn == WEP_NEX)
8                         w_nex(wrequest);
9                 return;
10         }
11         
12         if (wpn == WEP_LASER)
13                 w_laser(wrequest);
14         else if (wpn == WEP_SHOTGUN)
15                 w_shotgun(wrequest);
16         else if (wpn == WEP_UZI)
17                 w_uzi(wrequest);
18         else if (wpn == WEP_GRENADE_LAUNCHER)
19                 w_glauncher(wrequest);
20         else if (wpn == WEP_ELECTRO)
21                 w_electro(wrequest);
22         else if (wpn == WEP_CRYLINK)
23                 w_crylink(wrequest);
24         else if (wpn == WEP_NEX)
25                 w_nex(wrequest);
26         else if (wpn == WEP_HAGAR)
27                 w_hagar(wrequest);
28         else if (wpn == WEP_ROCKET_LAUNCHER)
29                 w_rlauncher(wrequest);
30 };
31
32 // think function for tossed weapons
33 void() thrown_wep_think =
34 {
35         self.solid = SOLID_TRIGGER;
36         SUB_SetFade(self, time + 20, 1);
37         setorigin(self, self.origin);
38 };
39
40 // toss current weapon
41 void() W_ThrowWeapon
42 {
43         local float w;
44         local entity wep, e;
45         
46         e = self;
47         wep = spawn();
48         self = wep;
49         w = e.weapon;
50         setorigin(wep, e.origin);
51         makevectors(e.angles);
52         wep.velocity = e.velocity * 0.5 + v_forward * 750;
53         SUB_SetFade(wep, time + 20, 1);
54
55         if(w == WEP_SHOTGUN)
56         {
57                 w = IT_SHOTGUN;
58                 if(!(e.items & w))
59                 {
60                         remove(wep);
61                         return;
62                 }
63                 weapon_shotgun();
64                 wep.ammo_shells = 1;
65                 e.ammo_shells -= 1;
66         }
67         else if(w == WEP_UZI)
68         {       
69                 w = IT_UZI;
70                 if(!(e.items & w))
71                 {
72                         remove(wep);
73                         return;
74                 }
75                 weapon_uzi();
76                 wep.ammo_nails = 1;
77                 e.ammo_nails -= 1;
78         }
79         else if(w == WEP_GRENADE_LAUNCHER)
80         {
81                 w = IT_GRENADE_LAUNCHER;
82                 if(!(e.items & w))
83                 {
84                         remove(wep);
85                         return;
86                 }
87                 weapon_grenadelauncher();
88                 wep.ammo_rockets = 1;
89                 e.ammo_rockets -= 1;
90         }
91         else if(w == WEP_ELECTRO)
92         {
93                 w = IT_ELECTRO;
94                 if(!(e.items & w))
95                 {
96                         remove(wep);
97                         return;
98                 }
99                 weapon_electro();
100                 wep.ammo_cells = 1;
101                 e.ammo_cells -= 1;
102         }
103         else if(w == WEP_CRYLINK)
104         {
105                 w = IT_CRYLINK;
106                 if(!(e.items & w))
107                 {
108                         remove(wep);
109                         return;
110                 }
111                 weapon_crylink();
112                 wep.ammo_cells = 1;
113                 e.ammo_cells -= 1;
114         }
115         else if(w == WEP_NEX)
116         {
117                 w = IT_NEX;
118                 if(!(e.items & w))
119                 {
120                         remove(wep);
121                         return;
122                 }
123                 weapon_nex();
124                 wep.ammo_cells = 1;
125                 e.ammo_cells -= 1;
126         }
127         else if(w == WEP_HAGAR)
128         {
129                 w = IT_HAGAR;
130                 if(!(e.items & w))
131                 {
132                         remove(wep);
133                         return;
134                 }
135                 weapon_hagar();
136                 wep.ammo_rockets = 1;
137                 e.ammo_rockets -= 1;
138         }
139         else if(w == WEP_ROCKET_LAUNCHER)
140         {
141                 w = IT_ROCKET_LAUNCHER;
142                 if(!(e.items & w))
143                 {
144                         remove(wep);
145                         return;
146                 }
147                 weapon_rocketlauncher();
148                 wep.ammo_rockets = 1;
149                 e.ammo_rockets -= 1;
150         }
151
152         if(e.items & w)
153                 sprint(e, strcat("You dropped the ^2", wep.netname, "\n"));
154         wep.solid = SOLID_NOT;
155         setorigin(wep, wep.origin);
156         wep.nextthink = time + 0.25;
157         wep.think = thrown_wep_think;           
158         wep.classname = "droppedweapon";
159         e.items = e.items - (e.items & w);
160         e.switchweapon = w_getbestweapon(e);
161         self = e;
162 };
163
164 // switch between weapons
165 void(float imp) W_SwitchWeapon
166 {
167         weapon_hasammo = TRUE;
168         if (!client_hasweapon(self, imp, TRUE))
169         {
170                 if (!weapon_hasammo)
171                         sprint(self, "You don't have any ammo for that weapon\n");
172                 else
173                         sprint(self, "You don't own that weapon\n");
174         }
175         else
176                 self.switchweapon = imp;
177 };
178
179 // next weapon
180 void() W_NextWeapon =
181 {
182         local float weaponwant;
183
184         weaponwant = self.switchweapon + 1;
185         if (weaponwant < WEP_FIRST)
186                 weaponwant = WEP_LAST;
187         if (weaponwant > WEP_LAST)
188                 weaponwant = WEP_FIRST;
189         weapon_hasammo = TRUE;
190         while(!client_hasweapon(self, weaponwant, TRUE))
191         {
192                 weaponwant = weaponwant + 1;
193                 if (weaponwant < WEP_FIRST)
194                         weaponwant = WEP_LAST;
195                 if (weaponwant > WEP_LAST)
196                         weaponwant = WEP_FIRST;
197         }
198         self.switchweapon = weaponwant;
199 };
200
201 // prev weapon
202 void() W_PreviousWeapon =
203 {
204         local float weaponwant;
205
206         weaponwant = self.switchweapon - 1;
207         if (weaponwant < WEP_FIRST)
208                 weaponwant = WEP_LAST;
209         if (weaponwant > WEP_LAST)
210                 weaponwant = WEP_FIRST;
211         weapon_hasammo = TRUE;
212         while(!client_hasweapon(self, weaponwant, TRUE))
213         {
214                 weaponwant = weaponwant - 1;
215                 if (weaponwant < WEP_FIRST)
216                         weaponwant = WEP_LAST;
217                 if (weaponwant > WEP_LAST)
218                         weaponwant = WEP_FIRST;
219         }
220         self.switchweapon = weaponwant;
221 };
222
223 // Bringed back weapon frame
224 void() W_WeaponFrame =
225 {
226         if (!self.weaponentity || self.health <= 0)
227                 return; // Dead player can't use weapons and injure impulse commands
228
229         if (cvar("g_antilag"))
230         {
231                 // if aiming at a player and the original trace won't hit that player
232                 // anymore, try aiming at the player's new position
233                 if (self.cursor_trace_ent)
234                 {
235                         if (self.cursor_trace_ent.takedamage)
236                         {
237                                 traceline(self.origin + self.view_ofs, self.cursor_trace_endpos, FALSE, self);
238                                 if (trace_ent != self.cursor_trace_ent)
239                                 {
240                                         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);
241                                         if (trace_ent == self.cursor_trace_ent)
242                                                 self.cursor_trace_endpos = trace_endpos;
243                                 }
244                         }
245                 }
246                 self.v_angle = vectoangles(self.cursor_trace_endpos - (self.origin + self.view_ofs));
247                 self.v_angle_x = 0 - self.v_angle_x;
248         }
249
250         makevectors(self.v_angle);
251
252         // Change weapon
253         if (self.weapon != self.switchweapon)
254         {
255                 if (self.weaponentity.state == WS_CLEAR)
256                 {
257                         self.weaponentity.state = WS_RAISE;
258                         weapon_action(self.switchweapon, WR_SETUP);
259                         // VorteX: add player model weapon select frame here
260                         // setcustomframe(PlayerWeaponRaise);
261                         weapon_action(self.weapon, WR_UPDATECOUNTS);
262                         weapon_action(self.weapon, WR_RAISE);
263                 }
264                 else if (self.weaponentity.state == WS_READY)
265                 {
266                         sound (self, CHAN_WEAPON, "weapons/weapon_switch.ogg", 1, ATTN_NORM);
267                         self.weaponentity.state = WS_DROP;
268                         // VorteX: add player model weapon deselect frame here
269                         // setcustomframe(PlayerWeaponDrop);
270                         weapon_action(self.weapon, WR_DROP);
271                 }
272         }
273
274         if (self.button0)
275                 weapon_action(self.weapon, WR_FIRE1);
276         if (self.button3)
277                 weapon_action(self.weapon, WR_FIRE2);
278
279         // do weapon think
280         if (time >= self.weapon_nextthink)
281                 if (self.weapon_nextthink > 0)
282                         self.weapon_think();
283
284         // weapon bobbing and script actions
285         local float bobintensity, q1pitching, framespeed, diff;
286         local vector vel, realorg, layer1, boblayer;
287
288         bobintensity = cvar("g_viewweapon_bobintensity"); // weapon bob intensity
289         q1pitching = fabs(cvar("g_viewweapon_q1pitching")); // q1 style of "bob" when looking up and down
290
291         realorg = self.weaponentity.origin + self.weaponentity.view_ofs;
292         realorg = realorg - self.weaponentity.finaldest; // finaldest is last bob position
293
294         // VorteX: actually this is needed for weapon screen offset
295         if (q1pitching)
296         {
297                 self.weaponentity.view_ofs_x = q1pitching*bound(-5.5, self.v_angle_x/45, 5.5);
298                 self.weaponentity.view_ofs_z = q1pitching*bound(-1.5, self.v_angle_x/60, 1.5);
299         }
300
301         // weapon origin interpolation, layer 1
302         if (realorg != self.weaponentity.pos1)
303         {
304                 framespeed = frametime*self.weaponentity.lip*10; // lip is speed of origin changing (of layer1)
305                 diff = vlen(realorg - self.weaponentity.pos1);
306                 // VorteX: add speed modifier (haste)?
307                 layer1 = frametime*10*self.weaponentity.lip*normalize(self.weaponentity.pos1 - realorg);
308                 if (diff <= vlen(layer1))
309                         layer1 = normalize(self.weaponentity.pos1 - realorg)*diff;
310         }
311
312         // weapon bobbing (q3-style)
313         if (self.flags & FL_ONGROUND && self.waterlevel < 2)
314         {
315                 // VorteX: only xy velocity matters
316                 vel_x = self.velocity_x;
317                 vel_y = self.velocity_y;
318                 framespeed = vlen(vel);
319                 // Y axis
320                 diff = bobintensity*framespeed/300;
321                 self.weaponentity.destvec_y = self.weaponentity.destvec_y + frametime*10;
322                 boblayer_y = diff*cos(self.weaponentity.destvec_y + 90);
323                 // Z axis
324                 diff = bobintensity*framespeed/540;
325                 self.weaponentity.destvec_z = self.weaponentity.destvec_z + frametime*20;
326                 boblayer_z = diff*cos(self.weaponentity.destvec_z);
327                 self.weaponentity.finaldest = boblayer;
328         }
329         else if (self.waterlevel > 0)
330         {// swim, all velocity matters
331                 // X axis
332                 framespeed = vlen(self.velocity);
333                 diff = bobintensity*framespeed/100;
334                 self.weaponentity.destvec_x = self.weaponentity.destvec_x + frametime*6;
335                 boblayer_x = diff*cos(self.weaponentity.destvec_x);
336                 self.weaponentity.finaldest = boblayer;
337         }
338         else
339                 self.weaponentity.finaldest = '0 0 0';
340         self.weaponentity.origin = realorg + boblayer + layer1 - self.weaponentity.view_ofs;
341 };