]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/weapons.qc
Fixed two minor bugs.
[divverent/nexuiz.git] / qcsrc / weapons.qc
1 float TE_SMOKE =77;
2 void (vector vec) WriteVec =
3 {
4                 WriteCoord (MSG_BROADCAST, vec_x);
5                 WriteCoord (MSG_BROADCAST, vec_y);
6                 WriteCoord (MSG_BROADCAST, vec_z);
7 }
8 void (vector org, vector dir, float counts) W_Smoke =
9 {
10                 WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
11                 WriteByte (MSG_BROADCAST, TE_SMOKE);
12                 WriteVec (org);
13                 WriteVec (dir);
14                 WriteByte (MSG_BROADCAST, counts);
15 }
16
17 // increments sprite frame, loops when end is hit.. simple
18 void animate_sprite (float startframe, float frame_count)
19 {
20         if ((self.frame - startframe) >= (frame_count - 1 ))
21                 self.frame = startframe;
22         else
23                 self.frame = self.frame + 1;
24 }
25
26 void W_UpdateAmmo (void)
27 {
28         self.items = self.items - (self.items & (IT_NAILS | IT_SHELLS | IT_ROCKETS | IT_CELLS));
29
30         if (self.weapon == IT_LASER)
31                 self.currentammo = 1;
32         else if (self.weapon == IT_UZI)
33         {
34                 self.currentammo = self.ammo_nails;
35                 self.items = self.items | IT_NAILS;
36         }
37         else if (self.weapon == IT_SHOTGUN)
38         {
39                 self.currentammo = self.ammo_shells;
40                 self.items = self.items | IT_SHELLS;
41         }
42         else if (self.weapon == IT_GRENADE_LAUNCHER || self.weapon == IT_HAGAR || self.weapon == IT_ROCKET_LAUNCHER)
43         {
44                 self.currentammo = self.ammo_rockets;
45                 self.items = self.items | IT_ROCKETS;
46         }
47         else if (self.weapon == IT_ELECTRO || self.weapon == IT_NEX || self.weapon == IT_CRYLINK)
48         {
49                 self.currentammo = self.ammo_cells;
50                 self.items = self.items | IT_CELLS;
51         }
52 }
53
54 void W_UpdateWeapon (void)
55 {
56         if (self.weapon == IT_LASER)
57                 self.weaponmodel = "models/weapons/w_laser.zym";
58         else if (self.weapon == IT_UZI)
59                 self.weaponmodel = "models/weapons/w_uzi.zym";
60         else if (self.weapon == IT_SHOTGUN)
61                 self.weaponmodel = "models/weapons/w_shotgun.zym";
62         else if (self.weapon == IT_GRENADE_LAUNCHER)
63                 self.weaponmodel = "models/weapons/w_gl.zym";
64         else if (self.weapon == IT_ELECTRO)
65                 self.weaponmodel = "models/weapons/w_electro.zym";
66         else if (self.weapon == IT_CRYLINK)
67                 self.weaponmodel = "models/weapons/w_crylink.zym";
68         else if (self.weapon == IT_NEX)
69                 self.weaponmodel = "models/weapons/w_nex.zym";
70         else if (self.weapon == IT_HAGAR)
71                 self.weaponmodel = "models/weapons/w_hagar.zym";
72         else if (self.weapon == IT_ROCKET_LAUNCHER)
73                 self.weaponmodel = "models/weapons/w_rl.zym";
74         else
75                 objerror ("Illegal weapon - please register your guns please!");
76 }
77
78 float W_GetBestWeapon (void)
79 {
80         if ((self.items & IT_ROCKET_LAUNCHER) && self.ammo_rockets)
81                 return IT_ROCKET_LAUNCHER;
82         else if ((self.items & IT_HAGAR) && self.ammo_rockets)
83                 return IT_HAGAR;
84         else if ((self.items & IT_NEX) && self.ammo_cells)
85                 return IT_NEX;
86         else if ((self.items & IT_CRYLINK) && self.ammo_cells)
87                 return IT_CRYLINK;
88         else if ((self.items & IT_ELECTRO) && self.ammo_cells)
89                 return IT_ELECTRO;
90         else if ((self.items & IT_GRENADE_LAUNCHER) && self.ammo_rockets)
91                 return IT_GRENADE_LAUNCHER;
92         else if ((self.items & IT_SHOTGUN) && self.ammo_shells)
93                 return IT_SHOTGUN;
94         else if ((self.items & IT_UZI) && self.ammo_nails)
95                 return IT_UZI;
96         else
97                 return IT_LASER;
98 }
99
100 void W_GiveWeapon (entity e, float wep) // FIXME - make it 'smarter'
101 {
102         entity oldself;
103
104         if (!wep)
105                 return;
106
107         if (!(e.items & wep))
108         {
109                 e.items = e.items | wep;
110                 e.weapon = wep;
111         }
112
113         oldself = self;
114         self = e;
115
116         W_UpdateWeapon ();
117         W_UpdateAmmo ();
118
119         self = oldself;
120 }
121
122 void W_SwitchWeapon (float wep)
123 {
124         float           nextwep;
125         var float       noammo = FALSE;
126
127         if (wep == 1)
128                 nextwep = IT_LASER;
129         else if (wep == 2)
130         {
131                 nextwep = IT_UZI;
132                 if (!self.ammo_nails)
133                         noammo = TRUE;
134         }
135         else if (wep == 3)
136         {
137                 nextwep = IT_SHOTGUN;
138                 if (!self.ammo_shells)
139                         noammo = TRUE;
140         }
141         else if (wep == 4)
142         {
143                 nextwep = IT_GRENADE_LAUNCHER;
144                 if (!self.ammo_rockets)
145                         noammo = TRUE;
146         }
147         else if (wep == 5)
148         {
149                 nextwep = IT_ELECTRO;
150                 if (!self.ammo_cells)
151                         noammo = TRUE;
152         }
153         else if (wep == 6)
154         {
155                 nextwep = IT_CRYLINK;
156                 if (!self.ammo_cells)
157                         noammo = TRUE;
158         }
159         else if (wep == 7)
160         {
161                 nextwep = IT_NEX;
162                 if (!self.ammo_cells)
163                         noammo = TRUE;
164         }
165         else if (wep == 8)
166         {
167                 nextwep = IT_HAGAR;
168                 if (!self.ammo_rockets)
169                         noammo = TRUE;
170         }
171         else if (wep == 9)
172         {
173                 nextwep = IT_ROCKET_LAUNCHER;
174                 if (!self.ammo_rockets)
175                         noammo = TRUE;
176         }
177
178
179         if (!(self.items & nextwep))
180         {
181                 sprint (self, "You don't own that weapon\n");
182                 return;
183         }
184         else if (noammo)
185         {
186                 sprint (self, "You don't have any ammo for that weapon\n");
187                 return;
188         }
189
190         self.weapon = nextwep;
191         W_UpdateWeapon ();
192         W_UpdateAmmo ();
193         self.attack_finished = time + 0.2;
194         if (self.viewzoom != 1)
195                 self.viewzoom = 1;
196 }
197
198 void W_NextWeapon (void)
199 {
200         float   noammo;
201
202         while (TRUE)
203         {
204                 noammo = FALSE;
205
206                 if (self.weapon == IT_ROCKET_LAUNCHER)
207                         self.weapon = IT_LASER;
208                 else if (self.weapon == IT_LASER)
209                 {
210                         self.weapon = IT_UZI;
211                         if (!self.ammo_nails)
212                                 noammo = TRUE;
213                 }
214                 else if (self.weapon == IT_UZI)
215                 {
216                         self.weapon = IT_SHOTGUN;
217                         if (!self.ammo_shells)
218                                 noammo = TRUE;
219                 }
220                 else if (self.weapon == IT_SHOTGUN)
221                 {
222                         self.weapon = IT_GRENADE_LAUNCHER;
223                         if (!self.ammo_rockets)
224                                 noammo = TRUE;
225                 }
226                 else if (self.weapon == IT_GRENADE_LAUNCHER)
227                 {
228                         self.weapon = IT_ELECTRO;
229                         if (!self.ammo_cells)
230                                 noammo = TRUE;
231                 }
232                 else if (self.weapon == IT_ELECTRO)
233                 {
234                         self.weapon = IT_CRYLINK;
235                         if (!self.ammo_cells)
236                         noammo = TRUE;
237                 }
238                 else if (self.weapon == IT_CRYLINK)
239                 {
240                         self.weapon = IT_NEX;
241                         if (!self.ammo_cells)
242                         noammo = TRUE;
243                 }
244                 else if (self.weapon == IT_NEX)
245                 {
246                         self.weapon = IT_HAGAR;
247                         if (!self.ammo_rockets)
248                         noammo = TRUE;
249                 }
250                 else if (self.weapon == IT_HAGAR)
251                 {
252                         self.weapon = IT_ROCKET_LAUNCHER;
253                         if (!self.ammo_rockets)
254                                 noammo = TRUE;
255                 }
256
257                 if ((self.items & self.weapon) && !noammo)
258                 {
259                         W_UpdateWeapon ();
260                         W_UpdateAmmo ();
261                         return;
262                 }
263         }
264 }
265
266 void W_PreviousWeapon (void)
267 {
268         float   noammo;
269
270         while (TRUE)
271         {
272                 noammo = FALSE;
273
274                 if (self.weapon == IT_UZI)
275                         self.weapon = IT_LASER;
276                 else if (self.weapon == IT_SHOTGUN)
277                 {
278                         self.weapon = IT_UZI;
279                         if (!self.ammo_nails)
280                                 noammo = TRUE;
281                 }
282                 else if (self.weapon == IT_GRENADE_LAUNCHER)
283                 {
284                         self.weapon = IT_SHOTGUN;
285                         if (!self.ammo_shells)
286                                 noammo = TRUE;
287                 }
288                 else if (self.weapon == IT_ELECTRO)
289                 {
290                         self.weapon = IT_GRENADE_LAUNCHER;
291                         if (!self.ammo_rockets)
292                                 noammo = TRUE;
293                 }
294                 else if (self.weapon == IT_CRYLINK)
295                 {
296                         self.weapon = IT_ELECTRO;
297                         if (!self.ammo_cells)
298                                 noammo = TRUE;
299                 }
300                 else if (self.weapon == IT_NEX)
301                 {
302                         self.weapon = IT_CRYLINK;
303                         if (!self.ammo_cells)
304                                 noammo = TRUE;
305                 }
306                 else if (self.weapon == IT_HAGAR)
307                 {
308                         self.weapon = IT_NEX;
309                         if (!self.ammo_cells)
310                                 noammo = TRUE;
311                 }
312                 else if (self.weapon == IT_ROCKET_LAUNCHER)
313                 {
314                         self.weapon = IT_HAGAR;
315                         if (!self.ammo_rockets)
316                                 noammo = TRUE;
317                 }
318                 else if (self.weapon == IT_LASER)
319                 {
320                         self.weapon = IT_ROCKET_LAUNCHER;
321                         if (!self.ammo_rockets)
322                                 noammo = TRUE;
323                 }
324
325                 if ((self.items & self.weapon) && !noammo)
326                 {
327                         W_UpdateWeapon ();
328                         W_UpdateAmmo ();
329                         return;
330                 }
331         }
332 }
333
334 float W_CheckAmmo (void)
335 {
336         if (game & (GAME_INSTAGIB | GAME_ROCKET_ARENA))
337                 return TRUE;
338
339         W_UpdateAmmo ();
340         if (self.weapon == IT_LASER)
341                 return TRUE;
342         else if (self.currentammo)
343                 return TRUE;
344
345         self.weapon = W_GetBestWeapon ();
346         W_UpdateWeapon ();
347
348         return FALSE;
349 }
350
351 /*
352 void FireRailgunBullet (vector src, float bdamage, vector dir, float spread, float deathtype)
353 {
354         vector  v, lastpos;
355         entity  saveself, last;
356         vector  org;
357         org = self.origin + self.view_ofs;
358         if (bdamage < 1)
359                 return;
360
361         last = self;
362         lastpos = src;
363
364         while (bdamage > 0)
365         {
366                 traceline_hitcorpse (self, org, org + v_forward * 4096 + v_right * crandom () * spread + v_up * crandom () * spread, FALSE, self);
367                 last = trace_ent;
368                 lastpos = trace_endpos;
369                 if (trace_fraction != 1.0)
370                 {
371                         if (pointcontents(trace_endpos - dir*4) == CONTENT_SKY)
372                                 return;
373
374                         if (trace_ent.takedamage || trace_ent.classname == "case")
375                         {
376                                 if (trace_ent.classname == "player" || trace_ent.classname == "corpse" || trace_ent.classname == "gib")
377                                         te_blood (trace_endpos, dir * bdamage * 16, bdamage);
378                                 Damage (trace_ent, self, self, bdamage, deathtype, trace_endpos, dir * bdamage);
379                         }
380                 }
381                 if (last.solid == SOLID_BSP)
382                         bdamage = 0;
383         }
384 }
385 */
386
387 void FireRailgunBullet (vector start, vector end, float damage, float dtype)
388 {
389         vector  dir;
390
391         dir = normalize (end - start);
392         traceline_hitcorpse (self, start, end, FALSE, self);
393
394         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
395         WriteByte (MSG_BROADCAST, 76);
396         WriteCoord (MSG_BROADCAST, start_x);
397         WriteCoord (MSG_BROADCAST, start_y);
398         WriteCoord (MSG_BROADCAST, start_z);
399         WriteCoord (MSG_BROADCAST, trace_endpos_x);
400         WriteCoord (MSG_BROADCAST, trace_endpos_y);
401         WriteCoord (MSG_BROADCAST, trace_endpos_z);
402         WriteCoord (MSG_BROADCAST, 0);
403         WriteCoord (MSG_BROADCAST, 0);
404         WriteCoord (MSG_BROADCAST, 0);
405
406         if ((trace_fraction != 1.0) && (trace_ent != self) && (pointcontents (trace_endpos) != CONTENT_SKY))
407         {
408                 if (trace_ent.classname == "case")
409                 {
410                         Damage (trace_ent, self, self, damage, dtype, trace_endpos, dir * damage);
411                 }
412                 else if (trace_ent.classname == "player" || trace_ent.classname == "corpse" || trace_ent.classname == "gib")
413                 {
414                         te_blood (trace_endpos, dir * damage * 16, damage);
415                         Damage (trace_ent, self, self, damage, dtype, trace_endpos, dir * damage);
416                 }
417         }
418 }
419
420
421 void fireBullet (vector dir, float spread, float damage, float dtype)
422 {
423         vector  org;
424
425         makevectors (self.v_angle);
426         float r;
427
428         // use traceline_hitcorpse to make sure it can hit gibs and corpses too
429         org = self.origin + self.view_ofs;
430         traceline_hitcorpse (self, org, org + v_forward * 4096 + v_right * crandom () * spread + v_up * crandom () * spread, FALSE, self);
431
432         // FIXME - causes excessive 'tinking'. Hopefully remove "tink1.wav" from the ricochets with csqc
433         if ((trace_fraction != 1.0) && (trace_ent != self) && (pointcontents (trace_endpos) != CONTENT_SKY))
434         {
435                 if (trace_ent == world)
436                 {
437                         pointcontents (self.origin);
438                         te_gunshot (trace_endpos);
439                         r = random ();
440                         if (r < 0.10)
441                                 sound (self, CHAN_IMPACT, "weapons/ric1.wav", 1, ATTN_NORM);
442                         else if (r < 0.20)
443                                 sound (self, CHAN_IMPACT, "weapons/ric2.wav", 1, ATTN_NORM);
444                         else if (r < 0.30)
445                                 sound (self, CHAN_IMPACT, "weapons/ric3.wav", 1, ATTN_NORM);
446                 }
447                 else if (trace_ent.classname == "case")
448                 {
449                         Damage (trace_ent, self, self, damage, dtype, trace_endpos, dir * damage);
450                 }
451                 else if (trace_ent.classname == "player" || trace_ent.classname == "corpse" || trace_ent.classname == "gib")
452                 {
453                         te_blood (trace_endpos, dir * damage * 16, damage);
454                         Damage (trace_ent, self, self, damage, dtype, trace_endpos, dir * damage);
455                         sound (trace_ent, CHAN_IMPACT, "misc/enemyimpact.wav", 1, ATTN_NORM);
456                 }
457         }
458 }
459
460 void W_Laser_Touch (void)
461 {
462         vector  dir;
463
464         if (other == self.owner)
465                 return;
466         else if (pointcontents (self.origin) == CONTENT_SKY)
467         {
468                 remove (self);
469                 return;
470         }
471
472         dir = normalize (self.owner.origin - self.origin);
473
474         /*
475         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
476         WriteByte (MSG_BROADCAST, TE_FLAMEJET);
477         WriteCoord (MSG_BROADCAST, self.origin_x);
478         WriteCoord (MSG_BROADCAST, self.origin_y);
479         WriteCoord (MSG_BROADCAST, self.origin_z);
480         WriteCoord (MSG_BROADCAST, 0);          // SeienAbunae: groan... Useless clutter
481         WriteCoord (MSG_BROADCAST, 0);
482         WriteCoord (MSG_BROADCAST, 0);
483         WriteByte (MSG_BROADCAST, 155); */
484
485         
486
487         self.event_damage = SUB_Null;
488         RadiusDamage (self, self.owner, 15, 7, 50, world, 200, IT_LASER);
489         sound (self, CHAN_IMPACT, "weapons/laserimpact.wav", 1, ATTN_NORM);
490
491         remove (self);
492 }
493
494 void W_Laser_Attack (void)
495 {
496         entity  missile;
497
498         sound (self, CHAN_WEAPON, "weapons/lasergun_fire.wav", 1, ATTN_NORM);
499
500         missile = spawn ();
501         missile.owner = self;
502         missile.classname = "spike";
503
504         missile.movetype = MOVETYPE_FLY;
505         missile.solid = SOLID_BBOX;
506
507         setmodel (missile, "models/laser.mdl");
508         setsize (missile, '0 0 0', '0 0 0');
509         setorigin (missile, self.origin + self.view_ofs + v_forward * 18 + v_right * 5 + v_up * -12);
510
511         makevectors (self.v_angle);
512         missile.velocity = v_forward * 1000;
513         missile.velocity = missile.velocity + v_right * ( crandom() * 45 );
514         missile.velocity = missile.velocity + v_up * ( crandom() * 25 );
515         missile.angles = vectoangles (missile.velocity);
516         missile.glow_color = 250; // 244, 250
517         missile.glow_size = 30;
518         missile.touch = W_Laser_Touch;
519         missile.think = SUB_Remove;
520         missile.nextthink = time + 9;
521
522         missile.effects = missile.effects | EF_ADDITIVE;
523
524         self.punchangle_x = random () - 0.5;
525         self.punchangle_y = random () - 0.5;
526         self.punchangle_z = random () - 0.5;
527
528         self.attack_finished = time + 0.2;
529 }
530
531 void W_Laser_Attack2 (void)
532 {
533         entity  missile;
534
535         sound (self, CHAN_WEAPON, "weapons/lasergun_fire.wav", 1, ATTN_NORM);
536
537         missile = spawn ();
538         missile.owner = self;
539         missile.classname = "spike";
540
541         missile.movetype = MOVETYPE_FLY;
542         missile.solid = SOLID_BBOX;
543
544         setmodel (missile, "models/laser.mdl");
545         setsize (missile, '0 0 0', '0 0 0');
546         setorigin (missile, self.origin + self.view_ofs + v_forward * 18 + v_right * 5 + v_up * -12);
547
548         makevectors (self.v_angle);
549         missile.velocity = v_forward * 4000;
550         missile.angles = vectoangles (missile.velocity);
551         missile.glow_color = 250; // 244, 250
552         missile.glow_size = 30;
553         missile.touch = W_Laser_Touch;
554         missile.think = SUB_Remove;
555         missile.nextthink = time + 2;
556
557         missile.effects = missile.effects | EF_ADDITIVE;
558
559         self.punchangle_x = random () - 0.5;
560         self.punchangle_y = random () - 0.5;
561         self.punchangle_z = random () - 0.5;
562
563         self.attack_finished = time + 0.4;
564 }
565
566 void W_Uzi_Attack (void)
567 {
568         sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", 1, ATTN_NORM);
569
570         fireBullet (v_forward, 100, 8, IT_UZI);
571
572         self.punchangle_x = random () - 0.5;
573         self.punchangle_y = random () - 0.5;
574         self.punchangle_z = random () - 0.5;
575
576         self.attack_finished = time + 0.075;
577         self.ammo_nails = self.ammo_nails - 1;
578
579         vector  org; // casing code
580         org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 1) + (v_forward * 20);
581         SpawnCasing (org, ((random () * 50 + 50) * v_right) - ((random () * 25 + 25) * v_forward) - ((random () * 5 + 10) * v_up), 2, v_forward,'0 250 0', 100, 2);
582         //W_Smoke(org, v_forward, 12);
583 }
584
585 void W_Uzi_Attack2 (void)
586 {
587         float   sc;
588         float   bullets;
589
590         sound (self, CHAN_WEAPON, "weapons/shotgun_fire.wav", 1, ATTN_NORM);
591
592         bullets = 5;
593         if (bullets > self.ammo_nails)
594                 bullets = self.ammo_nails;
595
596         sound (self, CHAN_WEAPON, "weapons/uzi_fire_secondary.wav", 1, ATTN_NORM);
597
598         for (sc = bullets; sc > 0; sc = sc - 1)
599                 fireBullet (v_forward, 400, 10, IT_SHOTGUN);
600
601         self.punchangle_x = -1.5;
602
603         self.ammo_nails = self.ammo_nails - bullets;
604         self.attack_finished = time + 0.4;
605
606         vector  org; // casing code
607         org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 4) + (v_forward * 15);
608         SpawnCasing (org, ((random () * 50 + 50) * v_right) - ((random () * 25 + 25) * v_forward) - ((random () * 5 + 10) * v_up), 2, v_forward,'0 250 0', 100, 3);
609 }
610
611 void W_Uzi_Attack3 (void)
612 {
613         sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", 1, ATTN_NORM);
614
615         fireBullet (v_forward, 0, 10, IT_UZI);
616
617         self.attack_finished = time + 0.16;
618         self.ammo_nails = self.ammo_nails - 1;
619
620         vector  org; // casing code
621         org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 1) + (v_forward * 20);
622         SpawnCasing (org, ((random () * 50 + 50) * v_right) - ((random () * 25 + 25) * v_forward) - ((random () * 5 + 10) * v_up), 2, v_forward,'0 250 0', 100, 2);
623 }
624
625 void W_Shotgun_Attack (void)
626 {
627         float   sc;
628         float   bullets;
629
630         sound (self, CHAN_WEAPON, "weapons/shotgun_fire.wav", 1, ATTN_NORM);
631
632         bullets = 10;
633
634         for (sc = bullets; sc > 0; sc = sc - 1)
635                 fireBullet (v_forward, 150, 8, IT_SHOTGUN);
636
637         self.ammo_shells = self.ammo_shells - 1;
638         self.attack_finished = time + 0.7;
639
640         vector  org; // casing code
641         org = self.origin + self.view_ofs + (v_right * 6) - (v_up * 4) + (v_forward * 15);
642         SpawnCasing (org, ((random () * 50 + 50) * v_right) - ((random () * 25 + 25) * v_forward) - ((random () * 5 + 10) * v_up), 2, v_forward,'0 250 0', 100, 1);
643 }
644
645 void W_Shotgun_Attack2 (void)
646 {
647         
648 }
649
650 void W_Grenade_Explode (entity ignore)
651 {
652         ImpactEffect (self, IT_GRENADE_LAUNCHER);
653
654         self.event_damage = SUB_Null;
655         RadiusDamage (self, self.owner, 65, 35, 140, world, 400, IT_GRENADE_LAUNCHER);
656
657         remove (self);
658 }
659
660 void W_Grenade_FuseExplode (void)
661 {
662         W_Grenade_Explode (world);
663 }
664
665 void W_Grenade_Touch (void)
666 {
667         // I decided to take this out to add more skill to using the grenade launcher, so the user always has to trigger it.
668         // I increased the power of the grenade launcher because of this.
669         //if (other.classname == "player" || other.classname == "corpse")
670         //      W_Grenade_Explode (other);
671         //else
672         sound (self, CHAN_BODY, "weapons/grenade_bounce.wav", 1, ATTN_NORM);
673 }
674
675 void W_Grenade_Damage (vector hitloc, float damage, entity inflictor, entity attacker, float deathtype)
676 {
677         self.health = self.health - damage;
678         if (self.health <= 0)
679                 W_Grenade_FuseExplode();
680 }
681
682 void W_Grenade_Attack (void)
683 {
684         entity  gren;
685
686         sound (self, CHAN_WEAPON, "weapons/grenade_fire.wav", 1, ATTN_NORM);
687
688         self.punchangle_x = -4;
689
690         gren = spawn ();
691         gren.owner = self;
692         gren.classname = "grenade";
693
694         gren.movetype = MOVETYPE_BOUNCE;
695         gren.solid = SOLID_BBOX;
696
697         gren.takedamage = DAMAGE_YES;
698         gren.damageforcescale = 4;
699         gren.health = 10;
700         gren.event_damage = W_Grenade_Damage;
701
702         setmodel (gren, "models/grenademodel.md3");
703         setsize (gren, '-6 -6 -3', '6 6 3');
704
705         makevectors (self.v_angle);
706         setorigin (gren, self.origin + self.view_ofs + v_forward * 18 + v_right * 5 + v_up * -12);
707
708         gren.velocity = v_forward * 900 + v_up * 200;
709         gren.angles = vectoangles (gren.velocity);
710         gren.avelocity = '100 150 100';
711
712         gren.touch = W_Grenade_Touch;
713         gren.think = W_Grenade_FuseExplode;
714         gren.nextthink = time + 5;
715
716         self.attack_finished = time + 1;
717         self.ammo_rockets = self.ammo_rockets - 1;
718 }
719
720 void W_Grenade_Attack2 (void)
721 {
722         entity  proj;
723         proj = findradius (self.origin, 50000);
724         while (proj)
725         {
726                 if (proj.classname == "grenade" && proj.owner == self)
727                 {
728                         proj.nextthink = time;
729                 }
730                 proj = proj.chain;
731         }
732
733         self.attack_finished = time;
734 }
735
736 void W_Grenade_Attack3 (void)
737 {
738         sound (self, CHAN_WEAPON, "weapons/grenade_fire.wav", 1, ATTN_NORM);
739         self.punchangle_x = -4;
740
741         entity gren;
742
743         gren = spawn ();
744         gren.owner = self;
745         gren.classname = "grenade";
746         gren.movetype = MOVETYPE_BOUNCE;
747         gren.solid = SOLID_BBOX;
748         setmodel(gren, "models/grenademodel.md3");
749         setsize(gren, '-14 -5 -4', '16 4 5');           
750         setorigin(gren, (self.origin + self.view_ofs));
751         gren.health = 1;
752         gren.takedamage = DAMAGE_YES;
753         makevectors (self.v_angle);
754         if (self.v_angle_x)
755                 gren.velocity = v_forward * (1200 + 1 * 800) + (v_up * 200) + (crandom () * v_right * 10) + (crandom () * v_up * 10);
756         else
757         {
758                 gren.velocity = aim (self, 10000) * (1200 + 1 * 800);
759                 gren.velocity_z = 200;
760         }
761         gren.avelocity_x = random () * -500 - 500;
762         gren.mins = normalize (gren.angles) * gren.mins;
763         gren.maxs = normalize (gren.angles) * gren.maxs;
764         setsize (gren, gren.mins, gren.maxs);
765         gren.angles = vectoangles (gren.velocity);
766         gren.touch = W_Grenade_Explode;
767         gren.think = W_Grenade_Explode;
768         gren.nextthink = time + 3;
769         self.ammo_rockets = self.ammo_rockets - 1;
770
771
772         self.attack_finished = time + 0.8;
773 }
774
775
776 void W_Electro_Touch (void)
777 {
778         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
779         WriteByte (MSG_BROADCAST, 79);
780         WriteCoord (MSG_BROADCAST, self.origin_x);
781         WriteCoord (MSG_BROADCAST, self.origin_y);
782         WriteCoord (MSG_BROADCAST, self.origin_z);
783         WriteCoord (MSG_BROADCAST, 0);          // SeienAbunae: groan... Useless clutter
784         WriteCoord (MSG_BROADCAST, 0);          // Sajt: Yeah.. I agree with him
785         WriteCoord (MSG_BROADCAST, 0);
786         WriteByte (MSG_BROADCAST, 155);
787         self.event_damage = SUB_Null;
788         RadiusDamage (self, self.owner, 50, 10, 70, world, 50, IT_ELECTRO);
789         sound (self, CHAN_IMPACT, "weapons/plasmahit.wav", 1, ATTN_NORM);
790         remove (self);
791 }
792
793 void W_Electro_Attack (float postion)
794 {
795         entity  proj;
796
797         sound (self, CHAN_WEAPON, "weapons/electro_fire.wav", 1, ATTN_NORM);
798
799         proj = spawn ();
800         proj.owner = self;
801         proj.classname = "spike";
802
803         proj.movetype = MOVETYPE_FLY; 
804         proj.solid = SOLID_BBOX;
805         proj.effects = 1;
806         
807         makevectors (self.v_angle);
808
809         vector org;
810         org = self.origin + self.view_ofs + v_forward * 18 + v_right * 7 + v_up * -9;
811
812         te_smallflash(org);
813
814         //entity        flash;
815         //flash = spawn ();
816         //flash.drawonlytoclient;
817         //setorigin (flash, org);
818         //setmodel (flash, "models/flash.md3");
819         //flash.velocity = v_forward * 9;
820         //flash.angles = vectoangles (flash.velocity);
821         //SUB_SetFade (flash, time + 0 + random () * 4);
822
823         setmodel (proj, "models/elaser.mdl");
824         setsize (proj, '0 0 0', '0 0 0');
825         if (postion == 0)
826         setorigin (proj, self.origin + self.view_ofs + v_forward * 18 + v_right * 5 + v_up * -14);
827         if (postion == 1)
828         setorigin (proj, self.origin + self.view_ofs + v_forward * 18 + v_right * 10 + v_up * -12);
829         if (postion == 2)
830         setorigin (proj, self.origin + self.view_ofs + v_forward * 18 + v_right * 15 + v_up * -14);
831
832         proj.velocity = v_forward * 9999;
833         proj.touch = W_Electro_Touch;
834         proj.think = SUB_Remove;
835         proj.nextthink = time + 1.5;
836
837         proj.angles = vectoangles (proj.velocity);
838
839         proj.effects = proj.effects | EF_ADDITIVE;
840
841         self.attack_finished = time + 0.4;
842         self.ammo_cells = self.ammo_cells - 1;
843 }
844
845 void W_Plasma_Explode (entity ignore)
846 {
847         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
848         WriteByte (MSG_BROADCAST, 79);
849         WriteCoord (MSG_BROADCAST, self.origin_x);
850         WriteCoord (MSG_BROADCAST, self.origin_y);
851         WriteCoord (MSG_BROADCAST, self.origin_z);
852         WriteCoord (MSG_BROADCAST, 0);          // SeienAbunae: groan... Useless clutter
853         WriteCoord (MSG_BROADCAST, 0);
854         WriteCoord (MSG_BROADCAST, 0);
855         WriteByte (MSG_BROADCAST, 155);
856
857         te_customflash (self.origin, 5000, 10, '0 0 1');
858
859         self.event_damage = SUB_Null;
860         RadiusDamage (self, self.owner, 100, 50, 100, world, 50, IT_ELECTRO);
861         sound (self, CHAN_IMPACT, "weapons/plasmahit.wav", 1, ATTN_NORM);
862
863         remove (self);
864 }
865
866 void W_Plasma_FuseExplode (void)
867 {
868         W_Plasma_Explode (world);
869 }
870
871 void W_Plasma_Touch (void)
872 {
873         if (other.classname == "player" || other.classname == "corpse")
874                 W_Plasma_Explode (other);
875         else
876                 sound (self, CHAN_BODY, "weapons/grenade_bounce.wav", 1, ATTN_NORM);
877 }
878
879 void W_Plasma_Damage (vector hitloc, float damage, entity inflictor, entity attacker, float deathtype)
880 {
881         self.health = self.health - damage;
882         if (self.health <= 0)
883                 W_Plasma_FuseExplode ();
884 }
885
886 void W_Electro_Attack2 (float postion)
887 {
888         entity  Plasma;
889
890         sound (self, CHAN_WEAPON, "weapons/electro_fire.wav", 1, ATTN_NORM);
891
892         self.punchangle_x = -4;
893
894         Plasma = spawn ();
895         Plasma.owner = self;
896         Plasma.classname = "grenade";
897         Plasma.effects = 1;
898
899         Plasma.movetype = MOVETYPE_BOUNCE;
900         Plasma.solid = SOLID_BBOX;
901         
902         vector org;
903         org = self.origin + self.view_ofs + v_forward * 18 + v_right * 7 + v_up * -9;
904         te_smallflash(org);
905
906         Plasma.takedamage = DAMAGE_YES;
907         Plasma.damageforcescale = 4;
908         Plasma.health = 5;
909         Plasma.event_damage = W_Plasma_Damage;
910
911         setmodel (Plasma, "models/elaser.mdl");
912         setsize (Plasma, '-6 -6 -3', '6 6 3');
913
914         makevectors (self.v_angle);
915
916         if (postion == 0)
917         setorigin (Plasma, self.origin + self.view_ofs + v_forward * 18 + v_right * 0 + v_up * -14);
918         if (postion == 1)
919         setorigin (Plasma, self.origin + self.view_ofs + v_forward * 18 + v_right * 10 + v_up * -12);
920         if (postion == 2)
921         setorigin (Plasma, self.origin + self.view_ofs + v_forward * 18 + v_right * 20 + v_up * -14);
922
923         Plasma.velocity = v_forward * 900 + v_up * 200;
924         Plasma.angles = vectoangles (Plasma.velocity);
925         Plasma.avelocity = '0 0 0';
926
927         Plasma.touch = W_Plasma_Touch;
928         Plasma.think = W_Plasma_FuseExplode;
929         Plasma.nextthink = time + 2;
930
931         Plasma.effects = Plasma.effects | EF_ADDITIVE;
932
933         self.attack_finished = time + 1;
934         self.ammo_cells = self.ammo_cells - 2;
935
936 }
937
938 void W_Electro_Attack3 (float postion)
939 {
940         entity  proj;
941         vector org;
942
943         sound (self, CHAN_WEAPON, "weapons/electro_fire.wav", 1, ATTN_NORM);
944
945         proj = spawn ();
946         proj.owner = self;
947         proj.classname = "spike";
948
949         proj.movetype = MOVETYPE_BOUNCEMISSILE; 
950         proj.solid = SOLID_BBOX;
951         proj.effects = 1;
952         
953         makevectors (self.v_angle);
954
955         org = self.origin + self.view_ofs + v_forward * 18 + v_right * 7 + v_up * -9;
956         te_smallflash(org);
957
958         setmodel (proj, "models/bullet.mdl");
959         setsize (proj, '0 0 0', '0 0 0');
960         if (postion == 0)
961         setorigin (proj, self.origin + self.view_ofs + v_forward * 18 + v_right * 5 + v_up * -14);
962         if (postion == 1)
963         setorigin (proj, self.origin + self.view_ofs + v_forward * 18 + v_right * 10 + v_up * -12);
964         if (postion == 2)
965         setorigin (proj, self.origin + self.view_ofs + v_forward * 18 + v_right * 15 + v_up * -14);
966
967         proj.velocity = v_forward * 9999;
968         proj.think = W_Electro_Touch;
969         proj.nextthink = time + 8;
970
971         proj.effects = proj.effects | EF_ADDITIVE;
972
973         self.attack_finished = time + 0.4;
974         self.ammo_cells = self.ammo_cells - 1;
975
976 }
977
978 void W_Crylink_Touch (void)
979 {
980         self.event_damage = SUB_Null;
981         te_smallflash(self.origin);
982         RadiusDamage (self, self.owner, 45, 0, 3, world, 55, IT_CRYLINK);
983         remove (self);
984 }
985
986 void W_Crylink_Attack (void) //(float postion)
987 {
988         vector  org;
989
990         sound (self, CHAN_WEAPON, "weapons/crylink.wav", 1, ATTN_NORM);
991
992         //if (postion==1)
993         //      org = self.origin + self.view_ofs + v_forward * 18 + v_right * 9 + v_up * -27;
994         //if (postion==2)
995         //      org = self.origin + self.view_ofs + v_forward * 18 + v_right * 18 + v_up * -13;
996         //if (postion==3)
997         //      org = self.origin + self.view_ofs + v_forward * 18 + v_right * 9 + v_up * -6;
998         //if (postion==4)
999         //      org = self.origin + self.view_ofs + v_forward * 18 + v_right * 0 + v_up * -13;
1000
1001         makevectors (self.v_angle);
1002         org = self.origin + self.view_ofs + v_forward * 10 + v_right * 5 + v_up * -14;  
1003
1004         FireRailgunBullet (org, self.origin + self.view_ofs + v_forward * 4096, 25, IT_CRYLINK);
1005
1006         te_spark (trace_endpos, v_forward, 55);
1007
1008         self.ammo_cells = self.ammo_cells - 0.25;
1009         self.attack_finished = time + 0.165;
1010 }
1011
1012 void W_Crylink_Attack2 (void)
1013 {
1014
1015         entity  proj;
1016
1017         sound (self, CHAN_WEAPON, "weapons/crylink2.wav", 1, ATTN_NORM);
1018
1019         proj = spawn ();
1020         proj.owner = self;
1021         proj.classname = "spike";
1022
1023         proj.movetype = MOVETYPE_FLY; 
1024         proj.solid = SOLID_BBOX;
1025         
1026         makevectors (self.v_angle);
1027
1028         setmodel (proj, "models/sprites/bubbles.spr");
1029         setsize (proj, '0 0 0', '0 0 0');
1030         setorigin (proj, self.origin + self.view_ofs + v_forward * 10 + v_right * 5 + v_up * -14);
1031
1032         proj.velocity = v_forward * 5000;
1033         proj.velocity = proj.velocity + v_right * ( crandom() * 50 );
1034         proj.velocity = proj.velocity + v_up * ( crandom() * 50 );
1035         proj.touch = W_Crylink_Touch;
1036         proj.think = SUB_Remove;
1037         proj.nextthink = time + 9;
1038
1039         proj.glow_color = 10;
1040         proj.glow_size = 30;
1041
1042         self.attack_finished = time + 0.20;
1043         self.ammo_cells = self.ammo_cells - 0.2;
1044 }
1045
1046 void W_Nex_Attack (void)
1047 {
1048         vector  org;
1049         vector  dir;
1050         entity  explosion;
1051
1052         sound (self, CHAN_WEAPON, "weapons/nexfire.wav", 1, ATTN_NORM);
1053         self.punchangle_x = -4;
1054
1055         makevectors (self.v_angle);
1056
1057         org = self.origin + self.view_ofs + v_forward * 18 + v_right * 8 + v_up * -5;
1058         te_smallflash(org);
1059
1060         if (game & GAME_INSTAGIB)
1061                 FireRailgunBullet (org, self.origin + self.view_ofs + v_forward * 4096, 800, IT_NEX);
1062         else
1063                 FireRailgunBullet (org, self.origin + self.view_ofs + v_forward * 4096, 80, IT_NEX);
1064
1065         te_plasmaburn (trace_endpos);
1066
1067         if (trace_fraction < 1.0)
1068         {
1069                 dir = trace_plane_normal * 100;
1070                 WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
1071                 WriteByte (MSG_BROADCAST, TE_FLAMEJET);
1072                 WriteCoord (MSG_BROADCAST, trace_endpos_x);
1073                 WriteCoord (MSG_BROADCAST, trace_endpos_y);
1074                 WriteCoord (MSG_BROADCAST, trace_endpos_z);
1075                 WriteCoord (MSG_BROADCAST, dir_x);
1076                 WriteCoord (MSG_BROADCAST, dir_y);
1077                 WriteCoord (MSG_BROADCAST, dir_z);
1078                 WriteByte (MSG_BROADCAST, 255);
1079
1080                 explosion = spawn ();
1081                 setorigin (explosion, trace_endpos);
1082                 RadiusDamage (explosion, self, 10, 0, 50, world, 300, IT_ROCKET_LAUNCHER);
1083                 remove (explosion);
1084
1085                 PointSound (trace_endpos, "weapons/neximpact.wav", 1, ATTN_NORM);
1086         }
1087
1088         self.attack_finished = time + 1;
1089
1090         if (!(game & GAME_INSTAGIB))
1091                 self.ammo_cells = self.ammo_cells - 1;
1092 }
1093
1094 void W_Nex_Attack2 (void)
1095 {
1096
1097 }
1098
1099
1100 void W_Hagar_Explode (void)
1101 {
1102         ImpactEffect (self, IT_HAGAR);
1103
1104         self.event_damage = SUB_Null;
1105         RadiusDamage (self, self.owner, 40, 15, 70, world, 100, IT_HAGAR);
1106
1107         remove (self);
1108 }
1109
1110 void W_Hagar_Fireball (void)
1111 {
1112         self.effects = self.effects | EF_FLAME;
1113 }
1114
1115 void W_Hagar_Touch (void)
1116 {
1117         if (other == self.owner)
1118                 return;
1119         else if (pointcontents (self.origin) == CONTENT_SKY)
1120         {
1121                 remove (self);
1122                 return;
1123         }
1124
1125         W_Hagar_Explode ();
1126 }
1127
1128 void W_Hagar_Damage (vector hitloc, float damage, entity inflictor, entity attacker, float deathtype)
1129 {
1130         self.health = self.health - damage;
1131         if (self.health <= 0)
1132                 W_Hagar_Explode();
1133 }
1134
1135 void W_Hagar_Attack (void)
1136 {
1137         entity  missile;
1138
1139         sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);
1140
1141         missile = spawn ();
1142         missile.owner = self;
1143         missile.classname = "missile";
1144
1145         missile.takedamage = DAMAGE_YES;
1146         missile.damageforcescale = 4;
1147         missile.health = 10;
1148         missile.event_damage = W_Hagar_Damage;
1149
1150         missile.movetype = MOVETYPE_FLY;
1151         missile.solid = SOLID_BBOX;
1152         setmodel (missile, "models/hagarmissile.mdl");
1153         setsize (missile, '0 0 0', '0 0 0');
1154
1155         makevectors (self.v_angle);
1156
1157         setorigin (missile, self.origin + self.view_ofs + v_forward * 18 + v_right * 5 + v_up * -12);
1158
1159         missile.velocity = v_forward * 2000;
1160         missile.velocity = missile.velocity + v_right * ( crandom() * 70 );
1161         missile.velocity = missile.velocity + v_up * ( crandom() * 30 );
1162         missile.angles = vectoangles (missile.velocity);
1163         setorigin (missile, self.origin + self.view_ofs + v_forward * 18 + v_right * 5 + v_up * -12);
1164
1165         missile.touch = W_Hagar_Touch;
1166         missile.think = W_Hagar_Explode;
1167         missile.nextthink = time + 10;
1168
1169         self.attack_finished = time + 0.2;
1170         self.ammo_rockets = self.ammo_rockets - 0.25;
1171 }
1172
1173 void W_Hagar_Attack2 (void)
1174 {
1175         entity  missile;
1176
1177         sound (self, CHAN_WEAPON, "weapons/hagar_fire2.wav", 1, ATTN_NORM);
1178
1179         missile = spawn ();
1180         missile.owner = self;
1181         missile.classname = "missile";
1182
1183         missile.movetype = MOVETYPE_TOSS;
1184         missile.solid = SOLID_BBOX;
1185
1186         missile.takedamage = DAMAGE_YES;
1187         missile.damageforcescale = 4;
1188         missile.health = 5;
1189         missile.event_damage = W_Hagar_Damage;
1190
1191         setmodel (missile, "models/fire.mdl");
1192         setsize (missile, '-6 -6 -3', '6 6 3');
1193
1194         makevectors (self.v_angle);
1195         setorigin (missile, self.origin + self.view_ofs + v_forward * 18 + v_right * 5 + v_up * -12);
1196
1197         missile.velocity = v_forward * 1400 + v_up * 100;
1198         missile.angles = vectoangles (missile.velocity);
1199         missile.avelocity = '0 0 0';
1200
1201         missile.touch = W_Hagar_Touch;
1202         missile.think = W_Hagar_Fireball;
1203         missile.nextthink = time + 0.05;
1204
1205         self.attack_finished = time + 0.2;
1206         self.ammo_rockets = self.ammo_rockets - 0.25;
1207 }
1208
1209 void W_Hagar_Attack3 (void)
1210 {
1211         entity  proj;
1212         proj = findradius (self.origin, 50000);
1213         while (proj)
1214         {
1215                 if (proj.classname == "missile" && proj.owner == self)
1216                 {
1217                         proj.velocity = proj.velocity - v_up * 500;
1218                         proj.velocity = proj.velocity - v_forward * 1000;
1219                 }
1220                 proj = proj.chain;
1221         }
1222
1223         self.attack_finished = time;
1224 }
1225
1226 void W_Rocket_Explode (entity ignore)
1227 {
1228         ImpactEffect (self, IT_ROCKET_LAUNCHER);
1229
1230         self.event_damage = SUB_Null;
1231         RadiusDamage (self, self.owner, 130, 50, 170, ignore, 600, IT_ROCKET_LAUNCHER);
1232
1233         remove (self);
1234 }
1235
1236 void W_Rocket_Think (void)
1237 {
1238         W_Rocket_Explode (world);
1239 }
1240
1241 void W_Rocket_Touch (void)
1242 {
1243         if (other == self.owner)
1244                 return;
1245         else if (pointcontents (self.origin) == CONTENT_SKY)
1246         {
1247                 remove (self);
1248                 return;
1249         }
1250         else
1251                 W_Rocket_Explode (world);
1252 }
1253
1254 void W_Rocket_Damage (vector hitloc, float damage, entity inflictor, entity attacker, float deathtype)
1255 {
1256         self.health = self.health - damage;
1257         if (self.health <= 0)
1258                 W_Rocket_Explode(world);
1259 }
1260
1261 void W_Rocket_Attack (void)
1262 {
1263         entity  missile;
1264         vector  org;
1265
1266         sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", 1, ATTN_NORM);
1267
1268         missile = spawn ();
1269         missile.owner = self;
1270         missile.classname = "missile";
1271
1272         missile.takedamage = DAMAGE_YES;
1273         missile.damageforcescale = 4;
1274         missile.health = 10;
1275         missile.event_damage = W_Rocket_Damage;
1276
1277         missile.movetype = MOVETYPE_FLY;
1278         missile.solid = SOLID_BBOX;
1279         setmodel (missile, "models/rocketmissile.mdl");
1280         setsize (missile, '0 0 0', '0 0 0');
1281
1282         makevectors (self.v_angle);
1283
1284         org = self.origin + self.view_ofs + v_forward * 20 + v_right * 4 + v_up * -15;
1285
1286         setorigin (missile, org);
1287         missile.velocity = v_forward * 2000;
1288         missile.angles = vectoangles (missile.velocity);
1289
1290         missile.touch = W_Rocket_Touch ;
1291         missile.think = W_Rocket_Think;
1292         missile.nextthink = time + 9;
1293
1294         self.attack_finished = time + 1.5;
1295
1296         if (!(game & GAME_ROCKET_ARENA))
1297                 self.ammo_rockets = self.ammo_rockets - 1;
1298 }
1299
1300 void W_Rocket_Attack2 (void)
1301 {
1302         entity  proj;
1303         proj = findradius (self.origin, 50000);
1304         while (proj)
1305         {
1306                 if (proj.classname == "missile" && proj.owner == self)
1307                 {
1308                         proj.nextthink = time;
1309                 }
1310                 proj = proj.chain;
1311         }
1312
1313         self.attack_finished = time;
1314 }
1315
1316
1317 void W_Rocket_Attack3 (void)
1318 {
1319
1320 }
1321
1322
1323 void W_Attack (void)
1324 {
1325         if (self.deadflag != DEAD_NO)
1326         {
1327                 if (self.death_time < time)
1328                         PutClientInServer();
1329
1330                 return;
1331         }
1332
1333         if (!W_CheckAmmo ())
1334                 return;
1335
1336         if (self.weapon == IT_LASER)
1337                 W_Laser_Attack ();
1338         else if (self.weapon == IT_UZI)
1339                 W_Uzi_Attack ();
1340         else if (self.weapon == IT_SHOTGUN)
1341                 W_Shotgun_Attack ();
1342         else if (self.weapon == IT_GRENADE_LAUNCHER)
1343                 W_Grenade_Attack ();
1344         else if (self.weapon == IT_ELECTRO)
1345                 {
1346                 W_Electro_Attack (self.electrocount);
1347                 self.electrocount = self.electrocount + 1;
1348                 if (self.electrocount == 3)
1349                         self.electrocount = 0;
1350                 }
1351         else if (self.weapon == IT_CRYLINK)
1352                 W_Crylink_Attack ();
1353         else if (self.weapon == IT_NEX)
1354                 W_Nex_Attack ();
1355         else if (self.weapon == IT_HAGAR)
1356                 W_Hagar_Attack ();
1357         else if (self.weapon == IT_ROCKET_LAUNCHER)
1358                 W_Rocket_Attack ();
1359
1360         W_UpdateAmmo ();
1361 }
1362
1363 void W_SecondaryAttack (void)
1364 {
1365         if (self.deadflag != DEAD_NO)
1366         {
1367                 if (self.death_time < time)
1368                         PutClientInServer();
1369
1370                 return;
1371         }
1372
1373         if (!W_CheckAmmo ())
1374                 return;
1375
1376         if (self.weapon == IT_LASER)
1377                 W_Laser_Attack2 ();
1378         else if (self.weapon == IT_UZI)
1379                 W_Uzi_Attack2 ();
1380         else if (self.weapon == IT_SHOTGUN)
1381                 W_Shotgun_Attack2 ();
1382         else if (self.weapon == IT_GRENADE_LAUNCHER)
1383                 W_Grenade_Attack2 ();
1384         else if (self.weapon == IT_ELECTRO) {
1385                 W_Electro_Attack2 (self.electrocount);
1386                 self.electrocount = self.electrocount + 1;
1387                 if (self.electrocount == 3)
1388                         self.electrocount = 0;
1389                 }
1390         else if (self.weapon == IT_CRYLINK)
1391                 W_Crylink_Attack2 ();
1392         else if (self.weapon == IT_NEX)
1393                 W_Nex_Attack2 ();
1394         else if (self.weapon == IT_HAGAR)
1395                 W_Hagar_Attack2 ();
1396         else if (self.weapon == IT_ROCKET_LAUNCHER)
1397                 W_Rocket_Attack2 ();
1398
1399         W_UpdateAmmo ();
1400 }
1401
1402 void W_ThirdAttack (void)
1403 {
1404         if (self.deadflag != DEAD_NO)
1405         {
1406                 if (self.death_time < time)
1407                         PutClientInServer();
1408
1409                 return;
1410         }
1411
1412         if (!W_CheckAmmo ())
1413                 return;
1414         
1415         if (self.weapon == IT_LASER)
1416                 W_Laser_Attack2 ();
1417         else if (self.weapon == IT_UZI)
1418                 W_Uzi_Attack3 ();
1419         else if (self.weapon == IT_SHOTGUN)
1420                 W_Shotgun_Attack2 ();
1421         else if (self.weapon == IT_GRENADE_LAUNCHER)
1422                 W_Grenade_Attack3 ();
1423         else if (self.weapon == IT_ELECTRO) {
1424                 W_Electro_Attack3 (self.electrocount);
1425                 self.electrocount = self.electrocount + 1;
1426                 if (self.electrocount == 3)
1427                         self.electrocount = 0;
1428                 }
1429         else if (self.weapon == IT_CRYLINK)
1430                 W_Crylink_Attack2 ();
1431         else if (self.weapon == IT_NEX)
1432                 W_Nex_Attack2 ();
1433         else if (self.weapon == IT_HAGAR)
1434                 W_Hagar_Attack3 ();
1435         else if (self.weapon == IT_ROCKET_LAUNCHER)
1436                 W_Rocket_Attack3 ();
1437
1438         W_UpdateAmmo ();
1439 }