]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/gamec/w_common.c
Added back some of LordHavocs changes
[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)
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         W_UpdateWeapon ();
125         W_UpdateAmmo ();
126 */
127         self = oldself;
128 }
129 /*
130 void W_SwitchWeapon (float wep)
131 {
132         float           nextwep;
133         var float       noammo = FALSE;
134
135         if (wep == 1)
136                 nextwep = IT_LASER;
137         else if (wep == 2)
138         {
139                 nextwep = IT_SHOTGUN;
140                 if (!self.ammo_shells)
141                         noammo = TRUE;
142         }
143         else if (wep == 3)
144         {
145                 nextwep = IT_UZI;
146                 if (!self.ammo_nails)
147                         noammo = TRUE;
148         }
149         else if (wep == 4)
150         {
151                 nextwep = IT_CRYLINK;
152                 if (!self.ammo_cells)
153                         noammo = TRUE;
154         }
155         else if (wep == 5)
156         {
157                 nextwep = IT_ELECTRO;
158                 if (!self.ammo_cells)
159                         noammo = TRUE;
160         }
161         else if (wep == 6)
162         {
163                 nextwep = IT_GRENADE_LAUNCHER;
164                 if (!self.ammo_rockets)
165                         noammo = TRUE;
166         }
167         else if (wep == 7)
168         {
169                 nextwep = IT_HAGAR;
170                 if (!self.ammo_rockets)
171                         noammo = TRUE;
172         }
173         else if (wep == 8)
174         {
175                 nextwep = IT_NEX;
176                 if (!self.ammo_cells)
177                         noammo = TRUE;
178         }
179         else if (wep == 9)
180         {
181                 nextwep = IT_ROCKET_LAUNCHER;
182                 if (!self.ammo_rockets)
183                         noammo = TRUE;
184         }
185
186
187         if (!(self.items & nextwep))
188         {
189                 sprint (self, "You don't own that weapon\n");
190                 return;
191         }
192         else if (noammo)
193         {
194                 sprint (self, "You don't have any ammo for that weapon\n");
195                 return;
196         }
197
198         self.weapon = nextwep;
199         W_UpdateWeapon ();
200         W_UpdateAmmo ();
201         self.attack_finished = time + 0.2;
202         if (self.viewzoom != 1)
203                 self.viewzoom = 1;
204 }
205
206 void W_NextWeapon (void)
207 {
208         float   noammo;
209
210         while (TRUE)
211         {
212                 noammo = FALSE;
213
214                 if (self.weapon == IT_ROCKET_LAUNCHER)
215                         self.weapon = IT_LASER;
216                 else if (self.weapon == IT_LASER)
217                 {
218                         self.weapon = IT_SHOTGUN;
219                         if (!self.ammo_shells)
220                                 noammo = TRUE;
221                 }
222                 else if (self.weapon == IT_SHOTGUN)
223                 {
224                         self.weapon = IT_UZI;
225                         if (!self.ammo_nails)
226                                 noammo = TRUE;
227                 }
228                 else if (self.weapon == IT_UZI)
229                 {
230                         self.weapon = IT_CRYLINK;
231                         if (!self.ammo_cells)
232                         noammo = TRUE;
233                 }
234                 else if (self.weapon == IT_CRYLINK)
235                 {
236                         self.weapon = IT_ELECTRO;
237                         if (!self.ammo_cells)
238                                 noammo = TRUE;
239                 }
240                 else if (self.weapon == IT_ELECTRO)
241                 {
242                         self.weapon = IT_GRENADE_LAUNCHER;
243                         if (!self.ammo_cells)
244                                 noammo = TRUE;
245                 }
246                 else if (self.weapon == IT_GRENADE_LAUNCHER)
247                 {
248                         self.weapon = IT_HAGAR;
249                         if (!self.ammo_rockets)
250                                 noammo = TRUE;
251                 }
252                 else if (self.weapon == IT_HAGAR)
253                 {
254                         self.weapon = IT_NEX;
255                         if (!self.ammo_rockets)
256                         noammo = TRUE;
257                 }
258                 else if (self.weapon == IT_NEX)
259                 {
260                         self.weapon = IT_ROCKET_LAUNCHER;
261                         if (!self.ammo_cells)
262                         noammo = TRUE;
263                 }
264
265                 if ((self.items & self.weapon) && !noammo)
266                 {
267                         W_UpdateWeapon ();
268                         W_UpdateAmmo ();
269                         return;
270                 }
271         }
272 }
273
274 void W_PreviousWeapon (void)
275 {
276         float   noammo;
277
278         while (TRUE)
279         {
280                 noammo = FALSE;
281
282                 if (self.weapon == IT_SHOTGUN)
283                         self.weapon = IT_LASER;
284                 else if (self.weapon == IT_UZI)
285                 {
286                         self.weapon = IT_SHOTGUN;
287                         if (!self.ammo_shells)
288                                 noammo = TRUE;
289                 }
290                 else if (self.weapon == IT_CRYLINK)
291                 {
292                         self.weapon = IT_UZI;
293                         if (!self.ammo_nails)
294                                 noammo = TRUE;
295                 }
296                 else if (self.weapon == IT_ELECTRO)
297                 {
298                         self.weapon = IT_CRYLINK;
299                         if (!self.ammo_cells)
300                                 noammo = TRUE;
301                 }
302                 else if (self.weapon == IT_GRENADE_LAUNCHER)
303                 {
304                         self.weapon = IT_ELECTRO;
305                         if (!self.ammo_cells)
306                                 noammo = TRUE;
307                 }
308                 else if (self.weapon == IT_HAGAR)
309                 {
310                         self.weapon = IT_GRENADE_LAUNCHER;
311                         if (!self.ammo_rockets)
312                                 noammo = TRUE;
313                 }
314                 else if (self.weapon == IT_NEX)
315                 {
316                         self.weapon = IT_HAGAR;
317                         if (!self.ammo_rockets)
318                                 noammo = TRUE;
319                 }
320                 else if (self.weapon == IT_ROCKET_LAUNCHER)
321                 {
322                         self.weapon = IT_NEX;
323                         if (!self.ammo_cells)
324                                 noammo = TRUE;
325                 }
326                 else if (self.weapon == IT_LASER)
327                 {
328                         self.weapon = IT_ROCKET_LAUNCHER;
329                         if (!self.ammo_rockets)
330                                 noammo = TRUE;
331                 }
332
333                 if ((self.items & self.weapon) && !noammo)
334                 {
335                         W_UpdateWeapon ();
336                         W_UpdateAmmo ();
337                         return;
338                 }
339         }
340 }
341 */
342 float W_CheckAmmo (void)
343 {
344         if (game & (GAME_INSTAGIB | GAME_ROCKET_ARENA))
345                 return TRUE;
346
347         W_UpdateAmmo ();
348         if (self.weapon == IT_LASER)
349                 return TRUE;
350         else if (self.currentammo)
351                 return TRUE;
352
353         self.weapon = W_GetBestWeapon (self);
354         W_UpdateWeapon ();
355
356         return FALSE;
357 }
358
359 /*
360 void FireRailgunBullet (vector src, float bdamage, vector dir, float spread, float deathtype)
361 {
362         vector  v, lastpos;
363         entity  saveself, last;
364         vector  org;
365         org = self.origin + self.view_ofs;
366         if (bdamage < 1)
367                 return;
368
369         last = self;
370         lastpos = src;
371
372         while (bdamage > 0)
373         {
374                 traceline_hitcorpse (self, org, org + v_forward * 4096 + v_right * crandom () * spread + v_up * crandom () * spread, FALSE, self);
375                 last = trace_ent;
376                 lastpos = trace_endpos;
377                 if (trace_fraction != 1.0)
378                 {
379                         if (pointcontents(trace_endpos - dir*4) == CONTENT_SKY)
380                                 return;
381
382                         if (trace_ent.takedamage || trace_ent.classname == "case")
383                         {
384                                 if (trace_ent.classname == "player" || trace_ent.classname == "corpse" || trace_ent.classname == "gib")
385                                         te_blood (trace_endpos, dir * bdamage * 16, bdamage);
386                                 Damage (trace_ent, self, self, bdamage, deathtype, trace_endpos, dir * bdamage);
387                         }
388                 }
389                 if (last.solid == SOLID_BSP)
390                         bdamage = 0;
391         }
392 }
393 */
394
395 void FireRailgunBullet (vector start, vector end, float bdamage, float deathtype)
396 {
397         local vector hitloc, dir, force;
398         local entity ent;
399         //local entity explosion;
400
401         force = normalize(end - start) * (bdamage * 0.1);
402
403         // find how far the beam can go until it hits a wall
404         traceline (start, end, TRUE, self);
405         // go a little bit into the wall because we need to hit this wall later
406         end = trace_endpos + normalize(end - start);
407
408         // beam effect
409         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
410         WriteByte (MSG_BROADCAST, 76);
411         WriteCoord (MSG_BROADCAST, start_x);
412         WriteCoord (MSG_BROADCAST, start_y);
413         WriteCoord (MSG_BROADCAST, start_z);
414         WriteCoord (MSG_BROADCAST, end_x);
415         WriteCoord (MSG_BROADCAST, end_y);
416         WriteCoord (MSG_BROADCAST, end_z);
417         WriteCoord (MSG_BROADCAST, 0);
418         WriteCoord (MSG_BROADCAST, 0);
419         WriteCoord (MSG_BROADCAST, 0);
420
421         // flash and burn the wall
422         te_plasmaburn (trace_endpos);
423
424         // flame effect at impact
425         dir = trace_plane_normal * 100;
426         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
427         WriteByte (MSG_BROADCAST, TE_FLAMEJET);
428         WriteCoord (MSG_BROADCAST, trace_endpos_x);
429         WriteCoord (MSG_BROADCAST, trace_endpos_y);
430         WriteCoord (MSG_BROADCAST, trace_endpos_z);
431         WriteCoord (MSG_BROADCAST, dir_x);
432         WriteCoord (MSG_BROADCAST, dir_y);
433         WriteCoord (MSG_BROADCAST, dir_z);
434         WriteByte (MSG_BROADCAST, 255);
435
436         // play a sound
437         PointSound (trace_endpos, "weapons/neximpact.wav", 1, ATTN_NORM);
438
439
440         // trace multiple times until we hit a wall, each obstacle will be made
441         // non-solid so we can hit the next, while doing this we spawn effects and
442         // note down which entities were hit so we can damage them later
443         while (1)
444         {
445                 traceline_hitcorpse (self, start, end, FALSE, self);
446
447                 // if it is world we can't hurt it so stop now
448                 if (trace_ent == world || trace_fraction == 1)
449                         break;
450
451                 // make the entity non-solid so we can hit the next one
452                 trace_ent.railgunhit = TRUE;
453                 trace_ent.railgunhitloc = trace_endpos;
454                 trace_ent.railgunhitsolidbackup = trace_ent.solid;
455
456                 // stop if this is a wall
457                 if (trace_ent.solid == SOLID_BSP)
458                         break;
459
460                 // make the entity non-solid
461                 trace_ent.solid = SOLID_NOT;
462         }
463
464         // find all the entities the railgun hit and restore their solid state
465         ent = findfloat(world, railgunhit, TRUE);
466         while (ent)
467         {
468                 // restore their solid type
469                 ent.solid = ent.railgunhitsolidbackup;
470                 ent = findfloat(ent, railgunhit, TRUE);
471         }
472
473         // spawn a temporary explosion entity for RadiusDamage calls
474         //explosion = spawn();
475
476         // find all the entities the railgun hit and hurt them
477         ent = findfloat(world, railgunhit, TRUE);
478         while (ent)
479         {
480                 // get the details we need to call the damage function
481                 hitloc = ent.railgunhitloc;
482                 ent.railgunhitloc = '0 0 0';
483                 ent.railgunhitsolidbackup = SOLID_NOT;
484                 ent.railgunhit = FALSE;
485
486                 // apply the damage
487                 if (ent.takedamage || ent.classname == "case")
488                         Damage (ent, self, self, bdamage, deathtype, hitloc, force);
489
490                 // create a small explosion to throw gibs around (if applicable)
491                 //setorigin (explosion, hitloc);
492                 //RadiusDamage (explosion, self, 10, 0, 50, world, 300, deathtype);
493
494                 // advance to the next entity
495                 ent = findfloat(ent, railgunhit, TRUE);
496         }
497
498         // we're done with the explosion entity, remove it
499         //remove(explosion);
500 }
501
502
503 void fireBullet (vector start, vector dir, float spread, float damage, float dtype)
504 {
505         vector  end;
506         float r;
507
508         // use traceline_hitcorpse to make sure it can hit gibs and corpses too
509         end = start + (dir + randomvec() * spread) * 1048576;
510         traceline_hitcorpse (self, start, end, FALSE, self);
511
512         // FIXME - causes excessive 'tinking'. Hopefully remove "tink1.wav" from the ricochets with csqc
513         if ((trace_fraction != 1.0) && (pointcontents (trace_endpos) != CONTENT_SKY))
514         {
515                 if (trace_ent.solid == SOLID_BSP)
516                 {
517                         pointcontents (self.origin);
518                         te_gunshot (trace_endpos);
519                         r = random ();
520                         if (r < 0.10)
521                                 sound (self, CHAN_IMPACT, "weapons/ric1.wav", 1, ATTN_NORM);
522                         else if (r < 0.20)
523                                 sound (self, CHAN_IMPACT, "weapons/ric2.wav", 1, ATTN_NORM);
524                         else if (r < 0.30)
525                                 sound (self, CHAN_IMPACT, "weapons/ric3.wav", 1, ATTN_NORM);
526                 }
527                 else if (trace_ent.classname == "player" || trace_ent.classname == "corpse" || trace_ent.classname == "gib")
528                         sound (trace_ent, CHAN_IMPACT, "misc/enemyimpact.wav", 1, ATTN_NORM);
529                 Damage (trace_ent, self, self, damage, dtype, trace_endpos, dir * damage);
530         }
531 }
532
533 /*
534 void W_Attack (void)
535 {
536         if (self.deadflag != DEAD_NO)
537         {
538                 if (self.death_time < time)
539                         PutClientInServer();
540
541                 return;
542         }
543
544         if (!W_CheckAmmo ())
545                 return;
546
547         makevectors (self.v_angle);
548         //if (self.weapon == IT_LASER)
549         //      W_Laser_Attack ();
550         //if (self.weapon == IT_SHOTGUN)
551                 //W_Shotgun_Attack ();
552         //else if (self.weapon == IT_UZI)
553                 //W_Uzi_Attack ();
554         if (self.weapon == IT_CRYLINK)
555                 W_Crylink_Attack ();
556         else if (self.weapon == IT_ELECTRO)
557                 {
558                 W_Electro_Attack (self.electrocount);
559                 self.electrocount = self.electrocount + 1;
560                 if (self.electrocount == 3)
561                         self.electrocount = 0;
562                 }
563         else if (self.weapon == IT_GRENADE_LAUNCHER)
564                 W_Grenade_Attack ();
565         else if (self.weapon == IT_HAGAR)
566                 W_Hagar_Attack ();
567         else if (self.weapon == IT_NEX)
568                 W_Nex_Attack ();
569         //else if (self.weapon == IT_ROCKET_LAUNCHER)
570         //      W_Rocket_Attack ();
571
572         W_UpdateAmmo ();
573 }
574
575 void W_SecondaryAttack (void)
576 {
577         if (self.deadflag != DEAD_NO)
578         {
579                 if (self.death_time < time)
580                         PutClientInServer();
581
582                 return;
583         }
584
585         if (!W_CheckAmmo ())
586                 return;
587
588         makevectors (self.v_angle);
589         //if (self.weapon == IT_LASER)
590                 //W_Laser_Attack2 ();
591         //if (self.weapon == IT_SHOTGUN)
592                 //W_Shotgun_Attack2 ();
593         //else if (self.weapon == IT_UZI)
594                 //W_Uzi_Attack2 ();
595         else if (self.weapon == IT_CRYLINK)
596                 W_Crylink_Attack2 ();
597         else if (self.weapon == IT_ELECTRO) {
598                 W_Electro_Attack2 (self.electrocount);
599                 self.electrocount = self.electrocount + 1;
600                 if (self.electrocount == 3)
601                         self.electrocount = 0;
602                 }
603         else if (self.weapon == IT_GRENADE_LAUNCHER)
604                 W_Grenade_Attack2 ();
605         else if (self.weapon == IT_HAGAR)
606                 W_Hagar_Attack2 ();
607         else if (self.weapon == IT_NEX)
608                 W_Nex_Attack2 ();
609         //else if (self.weapon == IT_ROCKET_LAUNCHER)
610                 //W_Rocket_Attack2 ();
611
612         W_UpdateAmmo ();
613 }
614
615 void W_ThirdAttack (void)
616 {
617         if (self.deadflag != DEAD_NO)
618         {
619                 if (self.death_time < time)
620                         PutClientInServer();
621
622                 return;
623         }
624
625         if (!W_CheckAmmo ())
626                 return;
627         
628         makevectors (self.v_angle);
629         //if (self.weapon == IT_LASER)
630                 //W_Laser_Attack2 ();
631         //if (self.weapon == IT_SHOTGUN)
632                 //W_Shotgun_Attack2 ();
633         //else if (self.weapon == IT_UZI)
634                 //W_Uzi_Attack3 ();
635         else if (self.weapon == IT_CRYLINK)
636                 W_Crylink_Attack2 ();
637         else if (self.weapon == IT_ELECTRO) {
638                 W_Electro_Attack3 (self.electrocount);
639                 self.electrocount = self.electrocount + 1;
640                 if (self.electrocount == 3)
641                         self.electrocount = 0;
642                 }
643         else if (self.weapon == IT_GRENADE_LAUNCHER)
644                 W_Grenade_Attack3 ();
645         else if (self.weapon == IT_HAGAR)
646                 W_Hagar_Attack3 ();
647         else if (self.weapon == IT_NEX)
648                 W_Nex_Attack2 ();
649         //else if (self.weapon == IT_ROCKET_LAUNCHER)
650                 //W_Rocket_Attack3 ();
651
652         W_UpdateAmmo ();
653 }
654 */