]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/gamec/w_common.c
Moved Nex shot back
[divverent/nexuiz.git] / qcsrc / gamec / w_common.c
1
2 // increments sprite frame, loops when end is hit.. simple
3
4 float TE_SMOKE =77;
5 void (vector vec) WriteVec =
6 {
7                 WriteCoord (MSG_BROADCAST, vec_x);
8                 WriteCoord (MSG_BROADCAST, vec_y);
9                 WriteCoord (MSG_BROADCAST, vec_z);
10 }
11 void (vector org, vector dir, float counts) W_Smoke =
12 {
13                 WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
14                 WriteByte (MSG_BROADCAST, TE_SMOKE);
15                 WriteVec (org);
16                 WriteVec (dir);
17                 WriteByte (MSG_BROADCAST, counts);
18 }
19
20 // increments sprite frame, loops when end is hit.. simple
21 void animate_sprite (float startframe, float frame_count)
22 {
23         if ((self.frame - startframe) >= (frame_count - 1 ))
24                 self.frame = startframe;
25         else
26                 self.frame = self.frame + 1;
27 }
28
29 void W_UpdateAmmo (void)
30 {
31         /*
32         self.items = self.items - (self.items & (IT_NAILS | IT_SHELLS | IT_ROCKETS | IT_CELLS));
33
34         if (self.weapon == IT_LASER)
35                 self.currentammo = 1;
36         else if (self.weapon == IT_SHOTGUN)
37         {
38                 self.currentammo = self.ammo_shells;
39                 self.items = self.items | IT_SHELLS;
40         }
41         else if (self.weapon == IT_UZI)
42         {
43                 self.currentammo = self.ammo_nails;
44                 self.items = self.items | IT_NAILS;
45         }
46         else if (self.weapon == IT_GRENADE_LAUNCHER || self.weapon == IT_HAGAR || self.weapon == IT_ROCKET_LAUNCHER)
47         {
48                 self.currentammo = self.ammo_rockets;
49                 self.items = self.items | IT_ROCKETS;
50         }
51         else if (self.weapon == IT_ELECTRO || self.weapon == IT_NEX || self.weapon == IT_CRYLINK)
52         {
53                 self.currentammo = self.ammo_cells;
54                 self.items = self.items | IT_CELLS;
55         }
56         */
57 }
58
59 void W_UpdateWeapon (void)
60 {
61         /*
62         if (self.weapon == IT_LASER)
63                 self.weaponmodel = "models/weapons/w_laser.zym";
64         else if (self.weapon == IT_SHOTGUN)
65                 self.weaponmodel = "models/weapons/w_shotgun.zym";
66         else if (self.weapon == IT_UZI)
67                 self.weaponmodel = "models/weapons/w_uzi.zym";
68         else if (self.weapon == IT_GRENADE_LAUNCHER)
69                 self.weaponmodel = "models/weapons/w_gl.zym";
70         else if (self.weapon == IT_ELECTRO)
71                 self.weaponmodel = "models/weapons/w_electro.zym";
72         else if (self.weapon == IT_CRYLINK)
73                 self.weaponmodel = "models/weapons/w_crylink.zym";
74         else if (self.weapon == IT_NEX)
75                 self.weaponmodel = "models/weapons/w_nex.zym";
76         else if (self.weapon == IT_HAGAR)
77                 self.weaponmodel = "models/weapons/w_hagar.zym";
78         else if (self.weapon == IT_ROCKET_LAUNCHER)
79                 self.weaponmodel = "models/weapons/w_rl.zym";
80         else
81                 objerror ("Illegal weapon - please register your guns please!");
82         */
83 }
84
85 float W_GetBestWeapon (entity e)
86 {
87         /*
88         if ((e.items & IT_ROCKET_LAUNCHER) && e.ammo_rockets)
89                 return IT_ROCKET_LAUNCHER;
90         else if ((e.items & IT_NEX) && e.ammo_cells)
91                 return IT_NEX;
92         else if ((e.items & IT_HAGAR) && e.ammo_rockets)
93                 return IT_HAGAR;
94         else if ((e.items & IT_GRENADE_LAUNCHER) && e.ammo_rockets)
95                 return IT_GRENADE_LAUNCHER;
96         else if ((e.items & IT_ELECTRO) && e.ammo_cells)
97                 return IT_ELECTRO;
98         else if ((e.items & IT_CRYLINK) && e.ammo_cells)
99                 return IT_CRYLINK;
100         else if ((e.items & IT_UZI) && e.ammo_nails)
101                 return IT_UZI;
102         else if ((e.items & IT_SHOTGUN) && e.ammo_shells)
103                 return IT_SHOTGUN;
104         else
105
106                 */
107         return IT_LASER;
108 }
109
110 void W_GiveWeapon (entity e, float wep, string name)
111 {
112         entity oldself;
113
114         if (!wep)
115                 return;
116
117         e.items = e.items | wep;
118
119         oldself = self;
120         self = e;
121
122         weapon_action(self.weapon, WR_UPDATECOUNTS);
123
124         if (other.classname == "player")
125         {
126                 sprint (other, "You got the ^2");
127                 sprint (other, name);
128                 sprint (other, "\n");
129         }
130
131         
132 /*
133         W_UpdateWeapon ();
134         W_UpdateAmmo ();
135 */
136         self = oldself;
137 }
138 /*
139 void W_SwitchWeapon (float wep)
140 {
141         float           nextwep;
142         var float       noammo = FALSE;
143
144         if (wep == 1)
145                 nextwep = IT_LASER;
146         else if (wep == 2)
147         {
148                 nextwep = IT_SHOTGUN;
149                 if (!self.ammo_shells)
150                         noammo = TRUE;
151         }
152         else if (wep == 3)
153         {
154                 nextwep = IT_UZI;
155                 if (!self.ammo_nails)
156                         noammo = TRUE;
157         }
158         else if (wep == 4)
159         {
160                 nextwep = IT_CRYLINK;
161                 if (!self.ammo_cells)
162                         noammo = TRUE;
163         }
164         else if (wep == 5)
165         {
166                 nextwep = IT_ELECTRO;
167                 if (!self.ammo_cells)
168                         noammo = TRUE;
169         }
170         else if (wep == 6)
171         {
172                 nextwep = IT_GRENADE_LAUNCHER;
173                 if (!self.ammo_rockets)
174                         noammo = TRUE;
175         }
176         else if (wep == 7)
177         {
178                 nextwep = IT_HAGAR;
179                 if (!self.ammo_rockets)
180                         noammo = TRUE;
181         }
182         else if (wep == 8)
183         {
184                 nextwep = IT_NEX;
185                 if (!self.ammo_cells)
186                         noammo = TRUE;
187         }
188         else if (wep == 9)
189         {
190                 nextwep = IT_ROCKET_LAUNCHER;
191                 if (!self.ammo_rockets)
192                         noammo = TRUE;
193         }
194
195
196         if (!(self.items & nextwep))
197         {
198                 sprint (self, "You don't own that weapon\n");
199                 return;
200         }
201         else if (noammo)
202         {
203                 sprint (self, "You don't have any ammo for that weapon\n");
204                 return;
205         }
206
207         self.weapon = nextwep;
208         W_UpdateWeapon ();
209         W_UpdateAmmo ();
210         self.attack_finished = time + 0.2;
211         if (self.viewzoom != 1)
212                 self.viewzoom = 1;
213 }
214
215 void W_NextWeapon (void)
216 {
217         float   noammo;
218
219         while (TRUE)
220         {
221                 noammo = FALSE;
222
223                 if (self.weapon == IT_ROCKET_LAUNCHER)
224                         self.weapon = IT_LASER;
225                 else if (self.weapon == IT_LASER)
226                 {
227                         self.weapon = IT_SHOTGUN;
228                         if (!self.ammo_shells)
229                                 noammo = TRUE;
230                 }
231                 else if (self.weapon == IT_SHOTGUN)
232                 {
233                         self.weapon = IT_UZI;
234                         if (!self.ammo_nails)
235                                 noammo = TRUE;
236                 }
237                 else if (self.weapon == IT_UZI)
238                 {
239                         self.weapon = IT_CRYLINK;
240                         if (!self.ammo_cells)
241                         noammo = TRUE;
242                 }
243                 else if (self.weapon == IT_CRYLINK)
244                 {
245                         self.weapon = IT_ELECTRO;
246                         if (!self.ammo_cells)
247                                 noammo = TRUE;
248                 }
249                 else if (self.weapon == IT_ELECTRO)
250                 {
251                         self.weapon = IT_GRENADE_LAUNCHER;
252                         if (!self.ammo_cells)
253                                 noammo = TRUE;
254                 }
255                 else if (self.weapon == IT_GRENADE_LAUNCHER)
256                 {
257                         self.weapon = IT_HAGAR;
258                         if (!self.ammo_rockets)
259                                 noammo = TRUE;
260                 }
261                 else if (self.weapon == IT_HAGAR)
262                 {
263                         self.weapon = IT_NEX;
264                         if (!self.ammo_rockets)
265                         noammo = TRUE;
266                 }
267                 else if (self.weapon == IT_NEX)
268                 {
269                         self.weapon = IT_ROCKET_LAUNCHER;
270                         if (!self.ammo_cells)
271                         noammo = TRUE;
272                 }
273
274                 if ((self.items & self.weapon) && !noammo)
275                 {
276                         W_UpdateWeapon ();
277                         W_UpdateAmmo ();
278                         return;
279                 }
280         }
281 }
282
283 void W_PreviousWeapon (void)
284 {
285         float   noammo;
286
287         while (TRUE)
288         {
289                 noammo = FALSE;
290
291                 if (self.weapon == IT_SHOTGUN)
292                         self.weapon = IT_LASER;
293                 else if (self.weapon == IT_UZI)
294                 {
295                         self.weapon = IT_SHOTGUN;
296                         if (!self.ammo_shells)
297                                 noammo = TRUE;
298                 }
299                 else if (self.weapon == IT_CRYLINK)
300                 {
301                         self.weapon = IT_UZI;
302                         if (!self.ammo_nails)
303                                 noammo = TRUE;
304                 }
305                 else if (self.weapon == IT_ELECTRO)
306                 {
307                         self.weapon = IT_CRYLINK;
308                         if (!self.ammo_cells)
309                                 noammo = TRUE;
310                 }
311                 else if (self.weapon == IT_GRENADE_LAUNCHER)
312                 {
313                         self.weapon = IT_ELECTRO;
314                         if (!self.ammo_cells)
315                                 noammo = TRUE;
316                 }
317                 else if (self.weapon == IT_HAGAR)
318                 {
319                         self.weapon = IT_GRENADE_LAUNCHER;
320                         if (!self.ammo_rockets)
321                                 noammo = TRUE;
322                 }
323                 else if (self.weapon == IT_NEX)
324                 {
325                         self.weapon = IT_HAGAR;
326                         if (!self.ammo_rockets)
327                                 noammo = TRUE;
328                 }
329                 else if (self.weapon == IT_ROCKET_LAUNCHER)
330                 {
331                         self.weapon = IT_NEX;
332                         if (!self.ammo_cells)
333                                 noammo = TRUE;
334                 }
335                 else if (self.weapon == IT_LASER)
336                 {
337                         self.weapon = IT_ROCKET_LAUNCHER;
338                         if (!self.ammo_rockets)
339                                 noammo = TRUE;
340                 }
341
342                 if ((self.items & self.weapon) && !noammo)
343                 {
344                         W_UpdateWeapon ();
345                         W_UpdateAmmo ();
346                         return;
347                 }
348         }
349 }
350 */
351 float W_CheckAmmo (void)
352 {
353         if ((cvar("g_instagib") == 1) | (cvar("g_rocketarena") == 1))
354                 return TRUE;
355
356         W_UpdateAmmo ();
357         if (self.weapon == IT_LASER)
358                 return TRUE;
359         else if (self.currentammo)
360                 return TRUE;
361
362         self.weapon = W_GetBestWeapon (self);
363         W_UpdateWeapon ();
364
365         return FALSE;
366 }
367
368 /*
369 void FireRailgunBullet (vector src, float bdamage, vector dir, float spread, float deathtype)
370 {
371         vector  v, lastpos;
372         entity  saveself, last;
373         vector  org;
374         org = self.origin + self.view_ofs;
375         if (bdamage < 1)
376                 return;
377
378         last = self;
379         lastpos = src;
380
381         while (bdamage > 0)
382         {
383                 traceline_hitcorpse (self, org, org + v_forward * 4096 + v_right * crandom () * spread + v_up * crandom () * spread, FALSE, self);
384                 last = trace_ent;
385                 lastpos = trace_endpos;
386                 if (trace_fraction != 1.0)
387                 {
388                         if (pointcontents(trace_endpos - dir*4) == CONTENT_SKY)
389                                 return;
390
391                         if (trace_ent.takedamage || trace_ent.classname == "case")
392                         {
393                                 if (trace_ent.classname == "player" || trace_ent.classname == "corpse" || trace_ent.classname == "gib")
394                                         te_blood (trace_endpos, dir * bdamage * 16, bdamage);
395                                 Damage (trace_ent, self, self, bdamage, deathtype, trace_endpos, dir * bdamage);
396                         }
397                 }
398                 if (last.solid == SOLID_BSP)
399                         bdamage = 0;
400         }
401 }
402 */
403
404 void FireRailgunBullet (vector start, vector end, float bdamage, float deathtype)
405 {
406         local vector hitloc, dir, force;
407         local entity ent;
408         //local entity explosion;
409
410         force = normalize(end - start) * 800; //(bdamage * 10);
411
412         // find how far the beam can go until it hits a wall
413         traceline (start, end, TRUE, self);
414         // go a little bit into the wall because we need to hit this wall later
415         end = trace_endpos + normalize(end - start);
416
417         // flash and burn the wall
418         te_plasmaburn (trace_endpos);
419
420         /*
421         // flame effect at impact
422         dir = trace_plane_normal * 100;
423         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
424         WriteByte (MSG_BROADCAST, TE_FLAMEJET);
425         WriteCoord (MSG_BROADCAST, trace_endpos_x);
426         WriteCoord (MSG_BROADCAST, trace_endpos_y);
427         WriteCoord (MSG_BROADCAST, trace_endpos_z);
428         WriteCoord (MSG_BROADCAST, dir_x);
429         WriteCoord (MSG_BROADCAST, dir_y);
430         WriteCoord (MSG_BROADCAST, dir_z);
431         WriteByte (MSG_BROADCAST, 255);
432         */
433         // play a sound
434         PointSound (trace_endpos, "weapons/neximpact.wav", 1, ATTN_NORM);
435
436
437         // trace multiple times until we hit a wall, each obstacle will be made
438         // non-solid so we can hit the next, while doing this we spawn effects and
439         // note down which entities were hit so we can damage them later
440         while (1)
441         {
442                 traceline_hitcorpse (self, start, end, FALSE, self);
443
444                 // if it is world we can't hurt it so stop now
445                 if (trace_ent == world || trace_fraction == 1)
446                         break;
447
448                 // make the entity non-solid so we can hit the next one
449                 trace_ent.railgunhit = TRUE;
450                 trace_ent.railgunhitloc = trace_endpos;
451                 trace_ent.railgunhitsolidbackup = trace_ent.solid;
452
453                 // stop if this is a wall
454                 if (trace_ent.solid == SOLID_BSP)
455                         break;
456
457                 // make the entity non-solid
458                 trace_ent.solid = SOLID_NOT;
459         }
460
461         // find all the entities the railgun hit and restore their solid state
462         ent = findfloat(world, railgunhit, TRUE);
463         while (ent)
464         {
465                 // restore their solid type
466                 ent.solid = ent.railgunhitsolidbackup;
467                 ent = findfloat(ent, railgunhit, TRUE);
468         }
469
470         // spawn a temporary explosion entity for RadiusDamage calls
471         //explosion = spawn();
472
473         // find all the entities the railgun hit and hurt them
474         ent = findfloat(world, railgunhit, TRUE);
475         while (ent)
476         {
477                 // get the details we need to call the damage function
478                 hitloc = ent.railgunhitloc;
479                 ent.railgunhitloc = '0 0 0';
480                 ent.railgunhitsolidbackup = SOLID_NOT;
481                 ent.railgunhit = FALSE;
482
483                 // apply the damage
484                 if (ent.takedamage || ent.classname == "case")
485                         Damage (ent, self, self, bdamage, deathtype, hitloc, force);
486
487                 // create a small explosion to throw gibs around (if applicable)
488                 //setorigin (explosion, hitloc);
489                 //RadiusDamage (explosion, self, 10, 0, 50, world, 300, deathtype);
490
491                 // advance to the next entity
492                 ent = findfloat(ent, railgunhit, TRUE);
493         }
494
495         // we're done with the explosion entity, remove it
496         //remove(explosion);
497 }
498
499 void fireBullet (vector start, vector dir, float spread, float damage, float dtype, float tracer)
500 {
501         vector  end;
502         float r;
503         local entity e;
504
505         // use traceline_hitcorpse to make sure it can hit gibs and corpses too
506         dir = dir + randomvec() * spread;
507         end = start + dir * 4096;
508         traceline_hitcorpse (self, start, end, FALSE, self);
509
510         if (tracer)
511         {
512                 e = spawn();
513                 e.owner = self;
514                 e.movetype = MOVETYPE_FLY;
515                 e.solid = SOLID_NOT;
516                 e.think = SUB_Remove;
517                 e.nextthink = time + vlen(trace_endpos - start) / 6000;
518                 e.velocity = dir * 6000;
519                 e.angles = vectoangles(e.velocity);
520                 setmodel (e, "models/tracer.mdl");
521                 setsize (e, '0 0 0', '0 0 0');
522                 setorigin (e, start);
523                 e.effects = e.effects | EF_ADDITIVE;
524         }
525
526         // FIXME - causes excessive 'tinking'. Hopefully remove "tink1.wav" from the ricochets with csqc
527         if ((trace_fraction != 1.0) && (pointcontents (trace_endpos) != CONTENT_SKY))
528         {
529                 if (trace_ent.solid == SOLID_BSP)
530                 {
531                         pointcontents (self.origin);
532                         te_gunshot (trace_endpos);
533                         r = random ();
534                         if (r < 0.10)
535                                 sound (self, CHAN_IMPACT, "weapons/ric1.wav", 1, ATTN_NORM);
536                         else if (r < 0.20)
537                                 sound (self, CHAN_IMPACT, "weapons/ric2.wav", 1, ATTN_NORM);
538                         else if (r < 0.30)
539                                 sound (self, CHAN_IMPACT, "weapons/ric3.wav", 1, ATTN_NORM);
540                 }
541                 else if (trace_ent.classname == "player" || trace_ent.classname == "corpse" || trace_ent.classname == "gib")
542                         sound (self, CHAN_BODY, "misc/hit.wav", 1, ATTN_NORM);
543                 Damage (trace_ent, self, self, damage, dtype, trace_endpos, dir * damage * 5);
544         }
545 }
546
547 /*
548 void W_Attack (void)
549 {
550         if (self.deadflag != DEAD_NO)
551         {
552                 if (self.death_time < time)
553                         PutClientInServer();
554
555                 return;
556         }
557
558         if (!W_CheckAmmo ())
559                 return;
560
561         makevectors (self.v_angle);
562         //if (self.weapon == IT_LASER)
563         //      W_Laser_Attack ();
564         //if (self.weapon == IT_SHOTGUN)
565                 //W_Shotgun_Attack ();
566         //else if (self.weapon == IT_UZI)
567                 //W_Uzi_Attack ();
568         if (self.weapon == IT_CRYLINK)
569                 W_Crylink_Attack ();
570         else if (self.weapon == IT_ELECTRO)
571                 {
572                 W_Electro_Attack (self.electrocount);
573                 self.electrocount = self.electrocount + 1;
574                 if (self.electrocount == 3)
575                         self.electrocount = 0;
576                 }
577         else if (self.weapon == IT_GRENADE_LAUNCHER)
578                 W_Grenade_Attack ();
579         else if (self.weapon == IT_HAGAR)
580                 W_Hagar_Attack ();
581         else if (self.weapon == IT_NEX)
582                 W_Nex_Attack ();
583         //else if (self.weapon == IT_ROCKET_LAUNCHER)
584         //      W_Rocket_Attack ();
585
586         W_UpdateAmmo ();
587 }
588
589 void W_SecondaryAttack (void)
590 {
591         if (self.deadflag != DEAD_NO)
592         {
593                 if (self.death_time < time)
594                         PutClientInServer();
595
596                 return;
597         }
598
599         if (!W_CheckAmmo ())
600                 return;
601
602         makevectors (self.v_angle);
603         //if (self.weapon == IT_LASER)
604                 //W_Laser_Attack2 ();
605         //if (self.weapon == IT_SHOTGUN)
606                 //W_Shotgun_Attack2 ();
607         //else if (self.weapon == IT_UZI)
608                 //W_Uzi_Attack2 ();
609         else if (self.weapon == IT_CRYLINK)
610                 W_Crylink_Attack2 ();
611         else if (self.weapon == IT_ELECTRO) {
612                 W_Electro_Attack2 (self.electrocount);
613                 self.electrocount = self.electrocount + 1;
614                 if (self.electrocount == 3)
615                         self.electrocount = 0;
616                 }
617         else if (self.weapon == IT_GRENADE_LAUNCHER)
618                 W_Grenade_Attack2 ();
619         else if (self.weapon == IT_HAGAR)
620                 W_Hagar_Attack2 ();
621         else if (self.weapon == IT_NEX)
622                 W_Nex_Attack2 ();
623         //else if (self.weapon == IT_ROCKET_LAUNCHER)
624                 //W_Rocket_Attack2 ();
625
626         W_UpdateAmmo ();
627 }
628
629 void W_ThirdAttack (void)
630 {
631         if (self.deadflag != DEAD_NO)
632         {
633                 if (self.death_time < time)
634                         PutClientInServer();
635
636                 return;
637         }
638
639         if (!W_CheckAmmo ())
640                 return;
641
642         makevectors (self.v_angle);
643         //if (self.weapon == IT_LASER)
644                 //W_Laser_Attack2 ();
645         //if (self.weapon == IT_SHOTGUN)
646                 //W_Shotgun_Attack2 ();
647         //else if (self.weapon == IT_UZI)
648                 //W_Uzi_Attack3 ();
649         else if (self.weapon == IT_CRYLINK)
650                 W_Crylink_Attack2 ();
651         else if (self.weapon == IT_ELECTRO) {
652                 W_Electro_Attack3 (self.electrocount);
653                 self.electrocount = self.electrocount + 1;
654                 if (self.electrocount == 3)
655                         self.electrocount = 0;
656                 }
657         else if (self.weapon == IT_GRENADE_LAUNCHER)
658                 W_Grenade_Attack3 ();
659         else if (self.weapon == IT_HAGAR)
660                 W_Hagar_Attack3 ();
661         else if (self.weapon == IT_NEX)
662                 W_Nex_Attack2 ();
663         //else if (self.weapon == IT_ROCKET_LAUNCHER)
664                 //W_Rocket_Attack3 ();
665
666         W_UpdateAmmo ();
667 }
668 */