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