]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/gamec/w_common.c
Make the weapon pickup message green, just to seperate it from normal chat
[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         // beam effect
418         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
419         WriteByte (MSG_BROADCAST, 76);
420         WriteCoord (MSG_BROADCAST, start_x);
421         WriteCoord (MSG_BROADCAST, start_y);
422         WriteCoord (MSG_BROADCAST, start_z);
423         WriteCoord (MSG_BROADCAST, end_x);
424         WriteCoord (MSG_BROADCAST, end_y);
425         WriteCoord (MSG_BROADCAST, end_z);
426         WriteCoord (MSG_BROADCAST, 0);
427         WriteCoord (MSG_BROADCAST, 0);
428         WriteCoord (MSG_BROADCAST, 0);
429
430         // flash and burn the wall
431         te_plasmaburn (trace_endpos);
432
433         /*
434         // flame effect at impact
435         dir = trace_plane_normal * 100;
436         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
437         WriteByte (MSG_BROADCAST, TE_FLAMEJET);
438         WriteCoord (MSG_BROADCAST, trace_endpos_x);
439         WriteCoord (MSG_BROADCAST, trace_endpos_y);
440         WriteCoord (MSG_BROADCAST, trace_endpos_z);
441         WriteCoord (MSG_BROADCAST, dir_x);
442         WriteCoord (MSG_BROADCAST, dir_y);
443         WriteCoord (MSG_BROADCAST, dir_z);
444         WriteByte (MSG_BROADCAST, 255);
445         */
446         // play a sound
447         PointSound (trace_endpos, "weapons/neximpact.wav", 1, ATTN_NORM);
448
449
450         // trace multiple times until we hit a wall, each obstacle will be made
451         // non-solid so we can hit the next, while doing this we spawn effects and
452         // note down which entities were hit so we can damage them later
453         while (1)
454         {
455                 traceline_hitcorpse (self, start, end, FALSE, self);
456
457                 // if it is world we can't hurt it so stop now
458                 if (trace_ent == world || trace_fraction == 1)
459                         break;
460
461                 // make the entity non-solid so we can hit the next one
462                 trace_ent.railgunhit = TRUE;
463                 trace_ent.railgunhitloc = trace_endpos;
464                 trace_ent.railgunhitsolidbackup = trace_ent.solid;
465
466                 // stop if this is a wall
467                 if (trace_ent.solid == SOLID_BSP)
468                         break;
469
470                 // make the entity non-solid
471                 trace_ent.solid = SOLID_NOT;
472         }
473
474         // find all the entities the railgun hit and restore their solid state
475         ent = findfloat(world, railgunhit, TRUE);
476         while (ent)
477         {
478                 // restore their solid type
479                 ent.solid = ent.railgunhitsolidbackup;
480                 ent = findfloat(ent, railgunhit, TRUE);
481         }
482
483         // spawn a temporary explosion entity for RadiusDamage calls
484         //explosion = spawn();
485
486         // find all the entities the railgun hit and hurt them
487         ent = findfloat(world, railgunhit, TRUE);
488         while (ent)
489         {
490                 // get the details we need to call the damage function
491                 hitloc = ent.railgunhitloc;
492                 ent.railgunhitloc = '0 0 0';
493                 ent.railgunhitsolidbackup = SOLID_NOT;
494                 ent.railgunhit = FALSE;
495
496                 // apply the damage
497                 if (ent.takedamage || ent.classname == "case")
498                         Damage (ent, self, self, bdamage, deathtype, hitloc, force);
499
500                 // create a small explosion to throw gibs around (if applicable)
501                 //setorigin (explosion, hitloc);
502                 //RadiusDamage (explosion, self, 10, 0, 50, world, 300, deathtype);
503
504                 // advance to the next entity
505                 ent = findfloat(ent, railgunhit, TRUE);
506         }
507
508         // we're done with the explosion entity, remove it
509         //remove(explosion);
510 }
511
512 void fireBullet (vector start, vector dir, float spread, float damage, float dtype, float tracer)
513 {
514         vector  end;
515         float r;
516         local entity e;
517
518         // use traceline_hitcorpse to make sure it can hit gibs and corpses too
519         dir = dir + randomvec() * spread;
520         end = start + dir * 4096;
521         traceline_hitcorpse (self, start, end, FALSE, self);
522
523         if (tracer)
524         {
525                 e = spawn();
526                 e.owner = self;
527                 e.movetype = MOVETYPE_FLY;
528                 e.solid = SOLID_NOT;
529                 e.think = SUB_Remove;
530                 e.nextthink = time + vlen(trace_endpos - start) / 6000;
531                 e.velocity = dir * 6000;
532                 e.angles = vectoangles(e.velocity);
533                 setmodel (e, "models/tracer.mdl");
534                 setsize (e, '0 0 0', '0 0 0');
535                 setorigin (e, start);
536                 e.effects = e.effects | EF_ADDITIVE;
537         }
538
539         // FIXME - causes excessive 'tinking'. Hopefully remove "tink1.wav" from the ricochets with csqc
540         if ((trace_fraction != 1.0) && (pointcontents (trace_endpos) != CONTENT_SKY))
541         {
542                 if (trace_ent.solid == SOLID_BSP)
543                 {
544                         pointcontents (self.origin);
545                         te_gunshot (trace_endpos);
546                         r = random ();
547                         if (r < 0.10)
548                                 sound (self, CHAN_IMPACT, "weapons/ric1.wav", 1, ATTN_NORM);
549                         else if (r < 0.20)
550                                 sound (self, CHAN_IMPACT, "weapons/ric2.wav", 1, ATTN_NORM);
551                         else if (r < 0.30)
552                                 sound (self, CHAN_IMPACT, "weapons/ric3.wav", 1, ATTN_NORM);
553                 }
554                 else if (trace_ent.classname == "player" || trace_ent.classname == "corpse" || trace_ent.classname == "gib")
555                         sound (self, CHAN_BODY, "misc/hit.wav", 1, ATTN_NORM);
556                 Damage (trace_ent, self, self, damage, dtype, trace_endpos, dir * damage * 5);
557         }
558 }
559
560 /*
561 void W_Attack (void)
562 {
563         if (self.deadflag != DEAD_NO)
564         {
565                 if (self.death_time < time)
566                         PutClientInServer();
567
568                 return;
569         }
570
571         if (!W_CheckAmmo ())
572                 return;
573
574         makevectors (self.v_angle);
575         //if (self.weapon == IT_LASER)
576         //      W_Laser_Attack ();
577         //if (self.weapon == IT_SHOTGUN)
578                 //W_Shotgun_Attack ();
579         //else if (self.weapon == IT_UZI)
580                 //W_Uzi_Attack ();
581         if (self.weapon == IT_CRYLINK)
582                 W_Crylink_Attack ();
583         else if (self.weapon == IT_ELECTRO)
584                 {
585                 W_Electro_Attack (self.electrocount);
586                 self.electrocount = self.electrocount + 1;
587                 if (self.electrocount == 3)
588                         self.electrocount = 0;
589                 }
590         else if (self.weapon == IT_GRENADE_LAUNCHER)
591                 W_Grenade_Attack ();
592         else if (self.weapon == IT_HAGAR)
593                 W_Hagar_Attack ();
594         else if (self.weapon == IT_NEX)
595                 W_Nex_Attack ();
596         //else if (self.weapon == IT_ROCKET_LAUNCHER)
597         //      W_Rocket_Attack ();
598
599         W_UpdateAmmo ();
600 }
601
602 void W_SecondaryAttack (void)
603 {
604         if (self.deadflag != DEAD_NO)
605         {
606                 if (self.death_time < time)
607                         PutClientInServer();
608
609                 return;
610         }
611
612         if (!W_CheckAmmo ())
613                 return;
614
615         makevectors (self.v_angle);
616         //if (self.weapon == IT_LASER)
617                 //W_Laser_Attack2 ();
618         //if (self.weapon == IT_SHOTGUN)
619                 //W_Shotgun_Attack2 ();
620         //else if (self.weapon == IT_UZI)
621                 //W_Uzi_Attack2 ();
622         else if (self.weapon == IT_CRYLINK)
623                 W_Crylink_Attack2 ();
624         else if (self.weapon == IT_ELECTRO) {
625                 W_Electro_Attack2 (self.electrocount);
626                 self.electrocount = self.electrocount + 1;
627                 if (self.electrocount == 3)
628                         self.electrocount = 0;
629                 }
630         else if (self.weapon == IT_GRENADE_LAUNCHER)
631                 W_Grenade_Attack2 ();
632         else if (self.weapon == IT_HAGAR)
633                 W_Hagar_Attack2 ();
634         else if (self.weapon == IT_NEX)
635                 W_Nex_Attack2 ();
636         //else if (self.weapon == IT_ROCKET_LAUNCHER)
637                 //W_Rocket_Attack2 ();
638
639         W_UpdateAmmo ();
640 }
641
642 void W_ThirdAttack (void)
643 {
644         if (self.deadflag != DEAD_NO)
645         {
646                 if (self.death_time < time)
647                         PutClientInServer();
648
649                 return;
650         }
651
652         if (!W_CheckAmmo ())
653                 return;
654
655         makevectors (self.v_angle);
656         //if (self.weapon == IT_LASER)
657                 //W_Laser_Attack2 ();
658         //if (self.weapon == IT_SHOTGUN)
659                 //W_Shotgun_Attack2 ();
660         //else if (self.weapon == IT_UZI)
661                 //W_Uzi_Attack3 ();
662         else if (self.weapon == IT_CRYLINK)
663                 W_Crylink_Attack2 ();
664         else if (self.weapon == IT_ELECTRO) {
665                 W_Electro_Attack3 (self.electrocount);
666                 self.electrocount = self.electrocount + 1;
667                 if (self.electrocount == 3)
668                         self.electrocount = 0;
669                 }
670         else if (self.weapon == IT_GRENADE_LAUNCHER)
671                 W_Grenade_Attack3 ();
672         else if (self.weapon == IT_HAGAR)
673                 W_Hagar_Attack3 ();
674         else if (self.weapon == IT_NEX)
675                 W_Nex_Attack2 ();
676         //else if (self.weapon == IT_ROCKET_LAUNCHER)
677                 //W_Rocket_Attack3 ();
678
679         W_UpdateAmmo ();
680 }
681 */