home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / patch / mbq704 / weapons.qc < prev   
Encoding:
Text File  |  1996-08-19  |  43.4 KB  |  1,876 lines

  1. /*
  2. ==========================================================
  3. Punish Weapons v1.21
  4. ==========================================================
  5. SplitMissile v1.03
  6. Tracer v1.01
  7. Nail Shotgun v1.01
  8. Auto Shotgun v1.01
  9. by Punisher  email: punisher@trojan.neta.com
  10. and Biafra
  11.  
  12. Bouncing Fragmentation Grenade!    7/28/96 by Steve Bond
  13. Email: wedge@nuc.net    WWW: http://www.nuc.net/quake
  14. improved by Punisher
  15. ==========================================================
  16. */
  17. void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
  18. void () player_run;
  19. void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
  20. void(vector org, vector vel, float damage) SpawnBlood;
  21. void() SuperDamageSound;
  22.  
  23.  
  24. // called by worldspawn
  25. void() W_Precache =
  26. {
  27.         precache_model ("progs/laser.mdl");     //for tracer
  28.         precache_sound ("weapons/r_exp3.wav");  // new rocket explosion
  29.     precache_sound ("weapons/rocket1i.wav");        // spike gun
  30.     precache_sound ("weapons/sgun1.wav");
  31.     precache_sound ("weapons/guncock.wav"); // player shotgun
  32.     precache_sound ("weapons/ric1.wav");    // ricochet (used in c code)
  33.     precache_sound ("weapons/ric2.wav");    // ricochet (used in c code)
  34.     precache_sound ("weapons/ric3.wav");    // ricochet (used in c code)
  35.     precache_sound ("weapons/spike2.wav");  // super spikes
  36.     precache_sound ("weapons/tink1.wav");   // spikes tink (used in c code)
  37.     precache_sound ("weapons/grenade.wav"); // grenade launcher
  38.     precache_sound ("weapons/bounce.wav");          // grenade bounce
  39.     precache_sound ("weapons/shotgn2.wav"); // super shotgun
  40. };
  41.  
  42. float() crandom =
  43. {
  44.     return 2*(random() - 0.5);
  45. };
  46.  
  47. /*
  48. ================
  49. W_FireAxe
  50. ================
  51. */
  52. void() W_FireAxe =
  53. {
  54.     local   vector  source;
  55.     local   vector  org;
  56.  
  57.     source = self.origin + '0 0 16';
  58.     traceline (source, source + v_forward*64, FALSE, self);
  59.     if (trace_fraction == 1.0)
  60.         return;
  61.     
  62.     org = trace_endpos - v_forward*4;
  63.  
  64.     if (trace_ent.takedamage)
  65.     {
  66.         trace_ent.axhitme = 1;
  67.         SpawnBlood (org, '0 0 0', 20);
  68.         T_Damage (trace_ent, self, self, 20);
  69.     }
  70.     else
  71.     {       // hit wall
  72.         sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  73.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  74.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  75.         WriteCoord (MSG_BROADCAST, org_x);
  76.         WriteCoord (MSG_BROADCAST, org_y);
  77.         WriteCoord (MSG_BROADCAST, org_z);
  78.     }
  79. };
  80.  
  81.  
  82. //============================================================================
  83.  
  84.  
  85. vector() wall_velocity =
  86. {
  87.     local vector    vel;
  88.     
  89.     vel = normalize (self.velocity);
  90.     vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
  91.     vel = vel + 2*trace_plane_normal;
  92.     vel = vel * 200;
  93.     
  94.     return vel;
  95. };
  96.  
  97.  
  98. /*
  99. ================
  100. SpawnMeatSpray
  101. ================
  102. */
  103. void(vector org, vector vel) SpawnMeatSpray =
  104. {
  105.     local   entity missile, mpuff;
  106.     local   vector  org;
  107.  
  108.     missile = spawn ();
  109.     missile.owner = self;
  110.     missile.movetype = MOVETYPE_BOUNCE;
  111.     missile.solid = SOLID_NOT;
  112.  
  113.     makevectors (self.angles);
  114.  
  115.     missile.velocity = vel;
  116.     missile.velocity_z = missile.velocity_z + 250 + 50*random();
  117.  
  118.     missile.avelocity = '3000 1000 2000';
  119.     
  120. // set missile duration
  121.     missile.nextthink = time + 1;
  122.     missile.think = SUB_Remove;
  123.  
  124.     setmodel (missile, "progs/zom_gib.mdl");
  125.     setsize (missile, '0 0 0', '0 0 0');            
  126.     setorigin (missile, org);
  127. };
  128.  
  129. /*
  130. ================
  131. SpawnBlood
  132. ================
  133. */
  134. void(vector org, vector vel, float damage) SpawnBlood =
  135. {
  136.     particle (org, vel*0.1, 73, damage*2);
  137. };
  138.  
  139. /*
  140. ================
  141. spawn_touchblood
  142. ================
  143. */
  144. void(float damage) spawn_touchblood =
  145. {
  146.     local vector    vel;
  147.  
  148.     vel = wall_velocity () * 0.2;
  149.     SpawnBlood (self.origin + vel*0.01, vel, damage);
  150. };
  151.  
  152.  
  153. /*
  154. ================
  155. SpawnChunk
  156. ================
  157. */
  158. void(vector org, vector vel) SpawnChunk =
  159. {
  160.     particle (org, vel*0.02, 0, 10);
  161. };
  162.  
  163. /*
  164. ==============================================================================
  165.  
  166. MULTI-DAMAGE
  167.  
  168. Collects multiple small damages into a single damage
  169.  
  170. ==============================================================================
  171. */
  172.  
  173. entity  multi_ent;
  174. float   multi_damage;
  175.  
  176. void() ClearMultiDamage =
  177. {
  178.     multi_ent = world;
  179.     multi_damage = 0;
  180. };
  181.  
  182. void() ApplyMultiDamage =
  183. {
  184.     if (!multi_ent)
  185.         return;
  186.     T_Damage (multi_ent, self, self, multi_damage);
  187. };
  188.  
  189. void(entity hit, float damage) AddMultiDamage =
  190. {
  191.     if (!hit)
  192.         return;
  193.     
  194.     if (hit != multi_ent)
  195.     {
  196.         ApplyMultiDamage ();
  197.         multi_damage = damage;
  198.         multi_ent = hit;
  199.     }
  200.     else
  201.         multi_damage = multi_damage + damage;
  202. };
  203.  
  204. /*
  205. ==============================================================================
  206.  
  207. BULLETS
  208.  
  209. ==============================================================================
  210. */
  211.  
  212. /*
  213. ================
  214. TraceAttack
  215. ================
  216. */
  217. void(float damage, vector dir) TraceAttack =
  218. {
  219.     local   vector  vel, org;
  220.     
  221.     vel = normalize(dir + v_up*crandom() + v_right*crandom());
  222.     vel = vel + 2*trace_plane_normal;
  223.     vel = vel * 200;
  224.  
  225.     org = trace_endpos - dir*4;
  226.  
  227.     if (trace_ent.takedamage)
  228.     {
  229.         SpawnBlood (org, vel*0.2, damage);
  230.         AddMultiDamage (trace_ent, damage);
  231.     }
  232.     else
  233.     {
  234.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  235.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  236.         WriteCoord (MSG_BROADCAST, org_x);
  237.         WriteCoord (MSG_BROADCAST, org_y);
  238.         WriteCoord (MSG_BROADCAST, org_z);
  239.     }
  240. };
  241.  
  242. /*
  243. ================
  244. FireBullets
  245.  
  246. Used by shotgun, super shotgun, and enemy soldier firing
  247. Go to the trouble of combining multiple pellets into a single damage call.
  248. ================
  249. */
  250. void(float shotcount, vector dir, vector spread) FireBullets =
  251. {
  252.     local   vector direction;
  253.     local   vector  src;
  254.     
  255.     makevectors(self.v_angle);
  256.  
  257.     src = self.origin + v_forward*10;
  258.     src_z = self.absmin_z + self.size_z * 0.7;
  259.  
  260.     ClearMultiDamage ();
  261.     while (shotcount > 0)
  262.     {
  263.         direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
  264.  
  265.         traceline (src, src + direction*2048, FALSE, self);
  266.         if (trace_fraction != 1.0)
  267.             TraceAttack (4, direction);
  268.  
  269.         shotcount = shotcount - 1;
  270.     }
  271.     ApplyMultiDamage ();
  272. };
  273. /*
  274. ================
  275. W_FireShotgun
  276. ================
  277. */
  278. void() W_FireShotgun =
  279. {
  280.     local vector dir;
  281.  
  282.     sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM); 
  283.  
  284.     self.punchangle_x = -2;
  285.     
  286.     self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  287.     dir = aim (self, 100000);
  288.     FireBullets (6, dir, '0.04 0.04 0');
  289. };
  290.  
  291.  
  292.  
  293. /*
  294. ================
  295. W_FireSuperShotgun
  296. ================
  297. */
  298. void() W_FireSuperShotgun =
  299. {
  300.     local vector dir;
  301.  
  302.     if (self.currentammo == 1)
  303.     {
  304.         W_FireShotgun ();
  305.         return;
  306.     }
  307.         
  308.     sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM); 
  309.  
  310.     self.punchangle_x = -4;
  311.     
  312.     self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  313.     dir = aim (self, 100000);
  314.     FireBullets (14, dir, '0.14 0.08 0');
  315. };
  316.  
  317.  
  318. /*
  319. ==============================================================================
  320.  
  321. ROCKETS
  322.  
  323. ==============================================================================
  324. */
  325.  
  326. void()  s_explode1      =       [0,             s_explode2] {};
  327. void()  s_explode2      =       [1,             s_explode3] {};
  328. void()  s_explode3      =       [2,             s_explode4] {};
  329. void()  s_explode4      =       [3,             s_explode5] {};
  330. void()  s_explode5      =       [4,             s_explode6] {};
  331. void()  s_explode6      =       [5,             SUB_Remove] {};
  332.  
  333. void() BecomeExplosion =
  334. {
  335.     self.movetype = MOVETYPE_NONE;
  336.     self.velocity = '0 0 0';
  337.     self.touch = SUB_Null;
  338.     setmodel (self, "progs/s_explod.spr");
  339.     self.solid = SOLID_NOT;
  340.     s_explode1 ();
  341. };
  342.  
  343. void() T_MissileTouch =
  344. {
  345.     local float     damg;
  346.  
  347.     if (other == self.owner)
  348.         return;         // don't explode on owner
  349.  
  350.     if (pointcontents(self.origin) == CONTENT_SKY)
  351.     {
  352.         remove(self);
  353.         return;
  354.     }
  355.  
  356.     damg = 100 + random()*20;
  357.     
  358.     if (other.health)
  359.     {
  360.         if (other.classname == "monster_shambler")
  361.             damg = damg * 0.5;      // mostly immune
  362.         T_Damage (other, self, self.owner, damg );
  363.     }
  364.  
  365.     // don't do radius damage to the other, because all the damage
  366.     // was done in the impact
  367.     T_RadiusDamage (self, self.owner, 120, other);
  368.  
  369. //      sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  370.     self.origin = self.origin - 8*normalize(self.velocity);
  371.  
  372.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  373.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  374.     WriteCoord (MSG_BROADCAST, self.origin_x);
  375.     WriteCoord (MSG_BROADCAST, self.origin_y);
  376.     WriteCoord (MSG_BROADCAST, self.origin_z);
  377.  
  378.     BecomeExplosion ();
  379. };
  380.  
  381.  
  382.  
  383. /*
  384. ================
  385. W_FireRocket
  386. ================
  387. */
  388. void() W_FireRocket =
  389. {
  390.     local   entity missile, mpuff;
  391.     
  392.     self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  393.     
  394.     sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  395.  
  396.     self.punchangle_x = -2;
  397.  
  398.     missile = spawn ();
  399.     missile.owner = self;
  400.     missile.movetype = MOVETYPE_FLYMISSILE;
  401.     missile.solid = SOLID_BBOX;
  402.         
  403. // set missile speed    
  404.  
  405.     makevectors (self.v_angle);
  406.     missile.velocity = aim(self, 1000);
  407.     missile.velocity = missile.velocity * 1000;
  408.     missile.angles = vectoangles(missile.velocity);
  409.     
  410.     missile.touch = T_MissileTouch;
  411.     
  412. // set missile duration
  413.     missile.nextthink = time + 5;
  414.     missile.think = SUB_Remove;
  415.  
  416.     setmodel (missile, "progs/missile.mdl");
  417.     setsize (missile, '0 0 0', '0 0 0');            
  418.     setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  419. };
  420.  
  421. /*
  422. ===============================================================================
  423.  
  424. LIGHTNING
  425.  
  426. ===============================================================================
  427. */
  428.  
  429. /*
  430. =================
  431. LightningDamage
  432. =================
  433. */
  434. void(vector p1, vector p2, entity from, float damage) LightningDamage =
  435. {
  436.     local entity            e1, e2;
  437.     local vector            f;
  438.     
  439.     f = p2 - p1;
  440.     normalize (f);
  441.     f_x = 0 - f_y;
  442.     f_y = f_x;
  443.     f_z = 0;
  444.     f = f*16;
  445.  
  446.     e1 = e2 = world;
  447.  
  448.     traceline (p1, p2, FALSE, self);
  449.     if (trace_ent.takedamage)
  450.     {
  451.         particle (trace_endpos, '0 0 100', 225, damage*4);
  452.         T_Damage (trace_ent, from, from, damage);
  453.         if (self.classname == "player")
  454.         {
  455.             if (other.classname == "player")
  456.                 trace_ent.velocity_z = trace_ent.velocity_z + 400;
  457.         }
  458.     }
  459.     e1 = trace_ent;
  460.  
  461.     traceline (p1 + f, p2 + f, FALSE, self);
  462.     if (trace_ent != e1 && trace_ent.takedamage)
  463.     {
  464.         particle (trace_endpos, '0 0 100', 225, damage*4);
  465.         T_Damage (trace_ent, from, from, damage);
  466.     }
  467.     e2 = trace_ent;
  468.  
  469.     traceline (p1 - f, p2 - f, FALSE, self);
  470.     if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
  471.     {
  472.         particle (trace_endpos, '0 0 100', 225, damage*4);
  473.         T_Damage (trace_ent, from, from, damage);
  474.     }
  475. };
  476.  
  477. void() W_FireLightning =
  478. {
  479.     local   vector          org;
  480.  
  481.     if (self.ammo_cells < 1)
  482.     {
  483.         self.weapon = W_BestWeapon ();
  484.         W_SetCurrentAmmo ();
  485.         return;
  486.     }
  487.  
  488. // explode if under water
  489.     if (self.waterlevel > 1)
  490.     {
  491.         T_RadiusDamage (self, self, 35*self.ammo_cells, world);
  492.         self.ammo_cells = 0;
  493.         W_SetCurrentAmmo ();
  494.         return;
  495.     }
  496.  
  497.     if (self.t_width < time)
  498.     {
  499.         sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  500.         self.t_width = time + 0.6;
  501.     }
  502.     self.punchangle_x = -2;
  503.  
  504.     self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  505.  
  506.     org = self.origin + '0 0 16';
  507.     
  508.     traceline (org, org + v_forward*600, TRUE, self);
  509.  
  510.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  511.     WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  512.     WriteEntity (MSG_BROADCAST, self);
  513.     WriteCoord (MSG_BROADCAST, org_x);
  514.     WriteCoord (MSG_BROADCAST, org_y);
  515.     WriteCoord (MSG_BROADCAST, org_z);
  516.     WriteCoord (MSG_BROADCAST, trace_endpos_x);
  517.     WriteCoord (MSG_BROADCAST, trace_endpos_y);
  518.     WriteCoord (MSG_BROADCAST, trace_endpos_z);
  519.  
  520.     LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
  521. };
  522.  
  523.  
  524. //=============================================================================
  525. void() GrenadeExplode =
  526. {
  527.     T_RadiusDamage (self, self.owner, 120, world);
  528.  
  529.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  530.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  531.     WriteCoord (MSG_BROADCAST, self.origin_x);
  532.     WriteCoord (MSG_BROADCAST, self.origin_y);
  533.     WriteCoord (MSG_BROADCAST, self.origin_z);
  534.  
  535.     BecomeExplosion ();
  536. };
  537.  
  538. void() GrenadeTouch =
  539. {
  540.     if (other == self.owner)
  541.         return;         // don't explode on owner
  542.     if (other.takedamage == DAMAGE_AIM)
  543.     {
  544.         GrenadeExplode();
  545.         return;
  546.     }
  547.     sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);  // bounce sound
  548.     if (self.velocity == '0 0 0')
  549.         self.avelocity = '0 0 0';
  550. };
  551.  
  552. /*
  553. ================
  554. W_FireGrenade
  555. ================
  556. */
  557. void() W_FireGrenade =
  558. {
  559.     local   entity missile, mpuff;
  560.     
  561.     self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  562.     
  563.     sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  564.  
  565.     self.punchangle_x = -2;
  566.  
  567.     missile = spawn ();
  568.     missile.owner = self;
  569.     missile.movetype = MOVETYPE_BOUNCE;
  570.     missile.solid = SOLID_BBOX;
  571.     missile.classname = "grenade";
  572.         
  573. // set missile speed    
  574.  
  575.     makevectors (self.v_angle);
  576.  
  577.     if (self.v_angle_x)
  578.         missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  579.     else
  580.     {
  581.         missile.velocity = aim(self, 10000);
  582.         missile.velocity = missile.velocity * 600;
  583.         missile.velocity_z = 200;
  584.     }
  585.  
  586.     missile.avelocity = '300 300 300';
  587.  
  588.     missile.angles = vectoangles(missile.velocity);
  589.     
  590.     missile.touch = GrenadeTouch;
  591.     
  592. // set missile duration
  593.     missile.nextthink = time + 2.5;
  594.         missile.think = GrenadeExplode;
  595.     setmodel (missile, "progs/grenade.mdl");
  596.     setsize (missile, '0 0 0', '0 0 0');            
  597.     setorigin (missile, self.origin);
  598. };
  599. /*
  600. ================
  601. Tracer Rounds
  602. ================
  603. */
  604. void() Tracer_Touch =
  605. {
  606.     local vector org;
  607.     
  608.     if (other.solid == SOLID_TRIGGER)
  609.         {
  610.                 return;
  611.         }        
  612.         if (pointcontents(self.origin) == CONTENT_SKY)
  613.     {
  614.         remove(self);
  615.         return;
  616.     }
  617.     if (other.takedamage)
  618.     {
  619.                 spawn_touchblood (5);
  620.                 T_Damage (other, self, self.owner, 5);
  621.                 remove(self);
  622.                 return;
  623.     }
  624.         else
  625.         {
  626.                 WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  627.                 WriteByte (MSG_BROADCAST, TE_SPIKE);
  628.                 WriteCoord (MSG_BROADCAST, org_x);
  629.                 WriteCoord (MSG_BROADCAST, org_y);
  630.                 WriteCoord (MSG_BROADCAST, org_z);
  631.         }
  632.         self.velocity = '0 0 0';
  633.  
  634. };
  635.  
  636. void(vector org, vector vec) LaunchTracer =
  637. {
  638.     local    vector    vec;
  639.         
  640.     vec = normalize(vec);
  641.     
  642.     newmis = spawn();
  643.     newmis.owner = self;
  644.     newmis.movetype = MOVETYPE_FLY;
  645.     newmis.solid = SOLID_BBOX;
  646.     newmis.effects = EF_DIMLIGHT;
  647.  
  648.     setmodel (newmis, "progs/laser.mdl");
  649.     setsize (newmis, '0 0 0', '0 0 0');        
  650.  
  651.     setorigin (newmis, org);
  652.  
  653.     newmis.velocity = vec * 600;
  654.     newmis.angles = vectoangles(newmis.velocity);
  655.  
  656.         newmis.nextthink = time + 5;
  657.     newmis.think = SUB_Remove;
  658.         newmis.touch = Tracer_Touch;
  659. };
  660.  
  661. void(vector org, vector vec) tracer_fire =
  662. {
  663.     self.effects = self.effects | EF_MUZZLEFLASH;
  664.     makevectors (self.angles);
  665.     
  666.         LaunchTracer(org, vec);
  667. };
  668.  
  669. //=============================================================================
  670.  
  671. void() spike_touch;
  672. void() superspike_touch;
  673.  
  674.  
  675. /*
  676. ===============
  677. launch_spike
  678.  
  679. Used for both the player and the ogre
  680. ===============
  681. */
  682. void(vector org, vector dir) launch_spike =
  683. {
  684.     newmis = spawn ();
  685.     newmis.owner = self;
  686.     newmis.movetype = MOVETYPE_FLYMISSILE;
  687.     newmis.solid = SOLID_BBOX;
  688.  
  689.     newmis.angles = vectoangles(dir);
  690.     
  691.     newmis.touch = spike_touch;
  692.     newmis.classname = "spike";
  693.         newmis.think = SUB_Remove;
  694.         newmis.nextthink = time + 6;
  695.     setmodel (newmis, "progs/spike.mdl");
  696.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);               
  697.     setorigin (newmis, org);
  698.  
  699.     newmis.velocity = dir * 1000;
  700. };
  701. /*
  702. ==================
  703. Nail Shotgun v1.0
  704. ==================
  705. */
  706. void(vector dir, vector spread, vector org) FireNailBull =
  707. {
  708.     makevectors(self.v_angle);
  709.     newmis = spawn();
  710.     newmis.owner = self;
  711.     newmis.movetype = MOVETYPE_FLY;
  712.     newmis.solid = SOLID_BBOX;
  713.         newmis.touch = spike_touch;
  714.     newmis.classname = "spike";
  715.         newmis.think = SUB_Remove;
  716.         newmis.nextthink = time + 6;
  717.     setmodel (newmis, "progs/spike.mdl");
  718.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);               
  719.     setorigin (newmis, org);
  720.         dir = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
  721.         newmis.velocity = dir * 1000;
  722.         newmis.angles = vectoangles(newmis.velocity);
  723. };
  724. void(float ox) W_FireNailShot =
  725. {
  726.     local vector dir;
  727.  
  728.     sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
  729.  
  730.     self.punchangle_x = -2;
  731.     
  732.         self.currentammo = self.ammo_nails = self.ammo_nails - 4;
  733.         dir = aim (self, 1000);
  734.         FireNailBull (dir, '0.04 0.04 0', self.origin + '0 0 16');
  735.         FireNailBull (dir, '0.04 0.04 0', self.origin + '0 0 16');
  736.         FireNailBull (dir, '0.04 0.04 0', self.origin + '0 0 16');
  737.         FireNailBull (dir, '0.04 0.04 0', self.origin + '0 0 16');
  738.         FireNailBull (dir, '0.04 0.04 0', self.origin + '0 0 16');
  739.         FireNailBull (dir, '0.04 0.04 0', self.origin + '0 0 16');
  740. };
  741. /*
  742. =============
  743. Auto Shotgun
  744. =============
  745. */
  746. void() W_FireAutoShot =
  747. {
  748.     local vector    dir;
  749.     local entity    old;
  750.     
  751.     self.attack_finished = time + 0.2;
  752.         sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
  753.         dir = aim (self, 100000);
  754.         self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  755.         self.punchangle_x = -2;
  756.     FireBullets (6, dir, '0.04 0.04 0');
  757. };
  758.  
  759. void() W_FireSuperSpikes =
  760. {
  761.     local vector    dir;
  762.     local entity    old;
  763.     
  764.     self.attack_finished = time + 0.2;
  765.         sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
  766.     dir = aim (self, 1000);
  767.         if (tracer == 0)
  768.         {
  769.                 tracer = 3;
  770.                 self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  771.                 tracer_fire (self.origin + '0 0 16', dir);
  772.                 self.punchangle_x = -2;
  773.                 return;
  774.         }
  775.         else
  776.         {
  777.                 tracer = tracer - 1;
  778.                 self.currentammo = self.ammo_nails = self.ammo_nails - 2;
  779.                 launch_spike (self.origin + '0 0 16', dir);
  780.                 newmis.touch = superspike_touch;
  781.                 setmodel (newmis, "progs/s_spike.mdl");
  782.                 setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);               
  783.                 self.punchangle_x = -2;
  784.                 return;
  785.         }
  786. };
  787.  
  788. void(float ox) W_FireSpikes =
  789. {
  790.     local vector    dir;
  791.     local entity    old;
  792.     
  793.     makevectors (self.v_angle);
  794.     
  795.         if (self.ammo_shells >= 2 && self.weapon == IT_SUPER_NAILGUN && ashot == 1)
  796.         {
  797.                 W_FireAutoShot ();
  798.                 return;
  799.         }
  800.  
  801.     if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
  802.     {
  803.         W_FireSuperSpikes ();
  804.         return;
  805.     }
  806.  
  807.     if (self.ammo_nails < 1)
  808.     {
  809.         self.weapon = W_BestWeapon ();
  810.         W_SetCurrentAmmo ();
  811.         return;
  812.     }
  813.  
  814.     sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  815.     self.attack_finished = time + 0.2;
  816.     self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  817.     dir = aim (self, 1000);
  818.     launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
  819.  
  820.     self.punchangle_x = -2;
  821. };
  822.  
  823.  
  824.  
  825. .float hit_z;
  826. void() spike_touch =
  827. {
  828. local float rand;
  829.     if (other == self.owner)
  830.         return;
  831.  
  832.     if (other.solid == SOLID_TRIGGER)
  833.         return; // trigger field, do nothing
  834.  
  835.     if (pointcontents(self.origin) == CONTENT_SKY)
  836.     {
  837.         remove(self);
  838.         return;
  839.     }
  840.     
  841. // hit something that bleeds
  842.     if (other.takedamage)
  843.     {
  844.         spawn_touchblood (9);
  845.         T_Damage (other, self, self.owner, 9);
  846.                 remove(self);
  847.     }
  848.     else
  849.     {
  850.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  851.         
  852.         if (self.classname == "wizspike")
  853.             WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
  854.         else if (self.classname == "knightspike")
  855.             WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
  856.         else
  857.             WriteByte (MSG_BROADCAST, TE_SPIKE);
  858.         WriteCoord (MSG_BROADCAST, self.origin_x);
  859.         WriteCoord (MSG_BROADCAST, self.origin_y);
  860.         WriteCoord (MSG_BROADCAST, self.origin_z);
  861.     }
  862.         remove(self);
  863.  
  864. };
  865.  
  866. void() superspike_touch =
  867. {
  868. local float rand;
  869.     if (other == self.owner)
  870.         return;
  871.  
  872.     if (other.solid == SOLID_TRIGGER)
  873.         return; // trigger field, do nothing
  874.  
  875.     if (pointcontents(self.origin) == CONTENT_SKY)
  876.     {
  877.         remove(self);
  878.         return;
  879.     }
  880.     
  881. // hit something that bleeds
  882.     if (other.takedamage)
  883.     {
  884.         spawn_touchblood (18);
  885.         T_Damage (other, self, self.owner, 18);
  886.     }
  887.     else
  888.     {
  889.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  890.         WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
  891.         WriteCoord (MSG_BROADCAST, self.origin_x);
  892.         WriteCoord (MSG_BROADCAST, self.origin_y);
  893.         WriteCoord (MSG_BROADCAST, self.origin_z);
  894.     }
  895.  
  896.     remove(self);
  897.  
  898. };
  899.  
  900. /*========================================================================
  901. BOUNCING FRAGMENTATION GRENADE - Version .9
  902. 7/28/96 - Steve Bond  email:wedge@nuc.net
  903. http://www.nuc.net/quake
  904. moded by Punisher
  905. =======================================================================*/
  906.  
  907. void() shrapnel_touch =
  908. {
  909. local float rand;
  910.     if (other.solid == SOLID_TRIGGER)
  911.         return; // trigger field, do nothing
  912.  
  913.     if (pointcontents(self.origin) == CONTENT_SKY)
  914.     {
  915.         remove(self);
  916.         return;
  917.     }
  918.     
  919.     if (other.takedamage)
  920.     {
  921.         spawn_touchblood (33);
  922.         T_Damage (other, self, self.owner, 33);
  923.     }
  924.     else
  925.     {
  926.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  927.         WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
  928.         WriteCoord (MSG_BROADCAST, self.origin_x);
  929.         WriteCoord (MSG_BROADCAST, self.origin_y);
  930.         WriteCoord (MSG_BROADCAST, self.origin_z);
  931.     }
  932.     remove(self);
  933. };
  934.  
  935. void (vector org, float spin) launch_shrapnel=
  936. {
  937.     local float xdir,ydir,zdir;
  938.     
  939.     xdir = 110 * random() - 55;
  940.     ydir = 110 * random() - 55;
  941.     zdir = 50 * random() - 25;
  942.  
  943.     newmis = spawn ();
  944.     newmis.owner = self;
  945.     newmis.movetype = MOVETYPE_BOUNCE;
  946.     self.touch = SUB_Null;
  947.     newmis.solid = SOLID_BBOX;
  948.  
  949.     newmis.touch = shrapnel_touch;
  950.     newmis.classname = "spike";
  951.     newmis.think = SUB_Remove;
  952.     
  953.     newmis.nextthink = time + 6;
  954.     
  955.     newmis.velocity_x = xdir * 5;
  956.     newmis.velocity_y = ydir * 5;
  957.     newmis.velocity_z = zdir * 4;
  958.  
  959.     if (spin == 0)
  960.     newmis.avelocity='250 300 400';
  961.     if (spin == 1)
  962.     newmis.avelocity='400 250 300';
  963.     if (spin == 2)
  964.     newmis.avelocity='300 400 250';
  965.     if (spin == 3)
  966.     newmis.avelocity='300 300 300';
  967.     if (spin == 4) 
  968.     newmis.avelocity='400 250 400';
  969.  
  970.     setmodel (newmis, "progs/s_spike.mdl");
  971.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
  972.     setorigin (newmis, org);
  973. };
  974.  
  975. void()  BouncerExplode =
  976. {
  977.     T_RadiusDamage (self, self.owner, 120, world);
  978.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  979.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  980.     WriteCoord (MSG_BROADCAST, self.origin_x);
  981.     WriteCoord (MSG_BROADCAST, self.origin_y);
  982.     WriteCoord (MSG_BROADCAST, self.origin_z);
  983.  
  984.     self.solid=SOLID_NOT;
  985.     BecomeExplosion ();
  986.  
  987.     launch_shrapnel (self.origin + '0 0 -1',0);
  988.     launch_shrapnel (self.origin + '0 0 -1',1);
  989.     launch_shrapnel (self.origin + '0 0 -1',2);
  990.     launch_shrapnel (self.origin + '0 0 -1',3);
  991.     launch_shrapnel (self.origin + '0 0 -1',4);
  992.     launch_shrapnel (self.origin + '0 0 -1',0);
  993.     launch_shrapnel (self.origin + '0 0 -1',1);
  994.     launch_shrapnel (self.origin + '0 0 -1',2);
  995.     launch_shrapnel (self.origin + '0 0 -1',3);
  996.     launch_shrapnel (self.origin + '0 0 -1',4);
  997.     launch_shrapnel (self.origin + '0 0 -1',0);
  998.     launch_shrapnel (self.origin + '0 0 -1',1);
  999.     launch_shrapnel (self.origin + '0 0 -1',2);
  1000.     launch_shrapnel (self.origin + '0 0 -1',3);
  1001.     launch_shrapnel (self.origin + '0 0 -1',4);
  1002.     launch_shrapnel (self.origin + '0 0 -1',0);
  1003.     launch_shrapnel (self.origin + '0 0 -1',1);
  1004.     launch_shrapnel (self.origin + '0 0 -1',2);
  1005.     launch_shrapnel (self.origin + '0 0 -1',3);
  1006.     launch_shrapnel (self.origin + '0 0 -1',4);
  1007. };
  1008.  
  1009. void() BouncerPopUp=
  1010. {
  1011.     local entity missile, mpuff;
  1012.  
  1013.     self.movetype=MOVETYPE_NONE;
  1014.     self.velocity='0 0 0';
  1015.     setmodel (self, "progs/s_explod.spr");
  1016.     s_explode1 ();
  1017.     sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  1018.     missile = spawn ();
  1019.     missile.owner = self;
  1020.     missile.movetype = MOVETYPE_BOUNCE;
  1021.     missile.solid = SOLID_BBOX;
  1022.     missile.classname = "grenade";
  1023.     missile.velocity = '0 0 650';
  1024.     missile.angles = vectoangles(missile.velocity);
  1025.     missile.touch = BouncerExplode;
  1026.     missile.nextthink = time + 1;
  1027.     missile.think = BouncerExplode;
  1028.  
  1029.     setmodel (missile, "progs/missile.mdl");
  1030.     setsize (missile, '0 0 0', '0 0 0');
  1031.     setorigin (missile, self.origin);
  1032. };
  1033.  
  1034.  
  1035. void() BouncerTouch =
  1036. {
  1037.     if (other.takedamage)
  1038.     {
  1039.     sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
  1040.     return;
  1041.     }
  1042.  
  1043.     sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
  1044.     if (self.velocity == '0 0 0')
  1045.         self.avelocity = '0 0 0';
  1046. };
  1047.  
  1048. void() W_LaunchBouncer =
  1049. {
  1050.     if (self.ammo_rockets < 3)
  1051.     {
  1052.     return;
  1053.     }
  1054.  
  1055.     local   entity missile, mpuff;
  1056.     
  1057.     self.currentammo = self.ammo_rockets = self.ammo_rockets - 3;
  1058.     
  1059.     self.punchangle_x = -2;
  1060.  
  1061.     missile = spawn ();
  1062.     missile.owner = self;
  1063.     missile.movetype = MOVETYPE_BOUNCE;
  1064.     missile.solid = SOLID_BBOX;
  1065.     missile.classname = "grenade";
  1066.         
  1067.  
  1068.     makevectors (self.v_angle);
  1069.  
  1070.     if (self.v_angle_x)
  1071.         missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  1072.     else
  1073.     {
  1074.         missile.velocity = aim(self, 10000);
  1075.         missile.velocity = missile.velocity * 600;
  1076.         missile.velocity_z = 200;
  1077.     }
  1078.  
  1079.     missile.avelocity = '300 300 300';
  1080.  
  1081.     missile.angles = vectoangles(missile.velocity);
  1082.     
  1083.     missile.touch = BouncerTouch;
  1084.     
  1085.     missile.nextthink = time + 1.5;
  1086.     
  1087.     missile.think = BouncerPopUp;
  1088.  
  1089.     setmodel (missile, "progs/grenade.mdl");
  1090.     setsize (missile, '0 0 0', '0 0 0');            
  1091.     setorigin (missile, self.origin);
  1092. };
  1093. /*
  1094. ===============================================================================
  1095. End of Bouncing Fragmentation Grenade code.
  1096. ===============================================================================
  1097. */
  1098.  
  1099.  
  1100.  
  1101.  
  1102.  
  1103.  
  1104. /*
  1105. ========================================================================
  1106. SplitMissile v1.02
  1107. by Punisher
  1108. =======================================================================
  1109. */
  1110.  
  1111. void() T_MissTouch =
  1112. {
  1113.     local float     damg;
  1114.  
  1115.     if (pointcontents(self.origin) == CONTENT_SKY)
  1116.     {
  1117.         remove(self);
  1118.         return;
  1119.     }
  1120.  
  1121.         damg = 20 + random() * 20;
  1122.     
  1123.     if (other.health)
  1124.     {
  1125.         if (other.classname == "monster_shambler")
  1126.             damg = damg * 0.5;      // mostly immune
  1127.         T_Damage (other, self, self.owner, damg );
  1128.     }
  1129.  
  1130.         T_RadiusDamage (self, self.owner, 60, other);
  1131.  
  1132.     self.origin = self.origin - 8*normalize(self.velocity);
  1133.  
  1134.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1135.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  1136.     WriteCoord (MSG_BROADCAST, self.origin_x);
  1137.     WriteCoord (MSG_BROADCAST, self.origin_y);
  1138.     WriteCoord (MSG_BROADCAST, self.origin_z);
  1139.  
  1140.         BecomeExplosion ();
  1141. };
  1142.  
  1143. void (vector org) LaunchMis2=
  1144. {
  1145.         local float xdir,ydir,zdir;
  1146.  
  1147.         sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  1148.  
  1149.  
  1150.         xdir = 110 * random() - 55;
  1151.         ydir = 110 * random() - 55;
  1152.         zdir = 110 * random() - 55;
  1153.         newmis = spawn ();
  1154.         newmis.owner = self;
  1155.         newmis.movetype = MOVETYPE_FLYMISSILE;
  1156.         newmis.solid = SOLID_BBOX;
  1157.         newmis.touch = T_MissTouch;
  1158.         newmis.think = SUB_Remove;
  1159.         newmis.nextthink = time + 6;
  1160.         newmis.velocity_x = xdir * 6;
  1161.         newmis.velocity_y = ydir * 6;
  1162.         newmis.velocity_z = zdir * 6;
  1163.         newmis.angles = vectoangles(newmis.velocity);
  1164.  
  1165.         setmodel (newmis, "progs/missile.mdl");
  1166.         setsize (newmis, '0 0 0', '0 0 0');
  1167.     setorigin (newmis, org);
  1168. };
  1169.  
  1170. void()  SplitMissile =
  1171. {    
  1172.         T_RadiusDamage (self, self.owner, 20, world);
  1173.  
  1174.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1175.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  1176.     WriteCoord (MSG_BROADCAST, self.origin_x);
  1177.     WriteCoord (MSG_BROADCAST, self.origin_y);
  1178.     WriteCoord (MSG_BROADCAST, self.origin_z);
  1179.  
  1180.     self.solid=SOLID_NOT;
  1181.         BecomeExplosion ();
  1182.  
  1183.         LaunchMis2 (self.origin);
  1184.         LaunchMis2 (self.origin);
  1185.         LaunchMis2 (self.origin);
  1186.         LaunchMis2 (self.origin);
  1187.         LaunchMis2 (self.origin);
  1188. };
  1189.  
  1190. void() W_LaunchSplitter =
  1191. {
  1192.         local   entity missile, mpuff;
  1193.  
  1194.         self.currentammo = self.ammo_rockets = self.ammo_rockets - 5;
  1195.     self.punchangle_x = -2;
  1196.     sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  1197.  
  1198.     missile = spawn ();
  1199.     missile.owner = self;
  1200.         missile.movetype = MOVETYPE_FLYMISSILE;
  1201.     missile.solid = SOLID_BBOX;
  1202.         missile.classname = "missile";
  1203.         makevectors (self.v_angle);
  1204.         missile.velocity = aim(self, 10000);
  1205.         missile.velocity = missile.velocity * 1000;
  1206.     missile.angles = vectoangles(missile.velocity);
  1207.         missile.touch = T_MissileTouch;
  1208.         missile.nextthink = time + 0.5;
  1209.         missile.think = SplitMissile;
  1210.         setmodel (missile, "progs/missile.mdl");
  1211.     setsize (missile, '0 0 0', '0 0 0');            
  1212.         setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  1213. };
  1214. /*
  1215. ===============================================================================
  1216. End of SplitMissile code.
  1217. ===============================================================================
  1218. */
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225. /*
  1226.  
  1227. PLAYER WEAPON USE
  1228.  
  1229. ===============================================================================
  1230. */
  1231.  
  1232. void() W_SetCurrentAmmo =
  1233. {
  1234.     player_run ();          // get out of any weapon firing states
  1235.  
  1236.     self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
  1237.     
  1238.     if (self.weapon == IT_AXE)
  1239.     {
  1240.         self.currentammo = 0;
  1241.         self.weaponmodel = "progs/v_axe.mdl";
  1242.         self.weaponframe = 0;
  1243.     }
  1244.         else if (self.weapon == IT_SHOTGUN && nshot == 0)
  1245.     {
  1246.         self.currentammo = self.ammo_shells;
  1247.         self.weaponmodel = "progs/v_shot.mdl";
  1248.         self.weaponframe = 0;
  1249.         self.items = self.items | IT_SHELLS;
  1250.     }
  1251.         else if (self.weapon == IT_SHOTGUN && nshot == 1)
  1252.     {
  1253.                 self.currentammo = self.ammo_nails;
  1254.                 self.weaponmodel = "progs/v_shot.mdl";
  1255.         self.weaponframe = 0;
  1256.                 self.items = self.items | IT_NAILS;
  1257.     }
  1258.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1259.     {
  1260.         self.currentammo = self.ammo_shells;
  1261.         self.weaponmodel = "progs/v_shot2.mdl";
  1262.         self.weaponframe = 0;
  1263.         self.items = self.items | IT_SHELLS;
  1264.     }
  1265.     else if (self.weapon == IT_NAILGUN)
  1266.     {
  1267.         self.currentammo = self.ammo_nails;
  1268.         self.weaponmodel = "progs/v_nail.mdl";
  1269.         self.weaponframe = 0;
  1270.         self.items = self.items | IT_NAILS;
  1271.     }
  1272.         else if (self.weapon == IT_SUPER_NAILGUN && ashot == 0)
  1273.     {
  1274.         self.currentammo = self.ammo_nails;
  1275.         self.weaponmodel = "progs/v_nail2.mdl";
  1276.         self.weaponframe = 0;
  1277.         self.items = self.items | IT_NAILS;
  1278.     }
  1279.         else if (self.weapon == IT_SUPER_NAILGUN && ashot == 1)
  1280.         {
  1281.                 self.currentammo = self.ammo_shells;
  1282.                 self.weaponmodel = "progs/v_nail2.mdl";
  1283.                 self.weaponframe = 0;
  1284.                 self.items = self.items | IT_SHELLS;
  1285.         }
  1286.         else if (self.weapon == IT_GRENADE_LAUNCHER)
  1287.     {
  1288.         self.currentammo = self.ammo_rockets;
  1289.         self.weaponmodel = "progs/v_rock.mdl";
  1290.         self.weaponframe = 0;
  1291.         self.items = self.items | IT_ROCKETS;
  1292.     }
  1293.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1294.     {
  1295.         self.currentammo = self.ammo_rockets;
  1296.         self.weaponmodel = "progs/v_rock2.mdl";
  1297.         self.weaponframe = 0;
  1298.         self.items = self.items | IT_ROCKETS;
  1299.     }
  1300.     else if (self.weapon == IT_LIGHTNING)
  1301.     {
  1302.         self.currentammo = self.ammo_cells;
  1303.         self.weaponmodel = "progs/v_light.mdl";
  1304.         self.weaponframe = 0;
  1305.         self.items = self.items | IT_CELLS;
  1306.     }
  1307.     else
  1308.     {
  1309.         self.currentammo = 0;
  1310.         self.weaponmodel = "";
  1311.         self.weaponframe = 0;
  1312.     }
  1313. };
  1314.  
  1315. float() W_BestWeapon =
  1316. {
  1317.     local   float   it;
  1318.     
  1319.     it = self.items;
  1320.  
  1321.     if(self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
  1322.         return IT_LIGHTNING;
  1323.     else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
  1324.         return IT_SUPER_NAILGUN;
  1325.     else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
  1326.         return IT_SUPER_SHOTGUN;
  1327.     else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
  1328.         return IT_NAILGUN;
  1329.     else if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
  1330.         return IT_SHOTGUN;      
  1331.         else if(self.ammo_rockets >= 1 && (it & IT_ROCKET_LAUNCHER) )
  1332.         return IT_ROCKET_LAUNCHER;
  1333.     else if(self.ammo_rockets >= 1 && (it & IT_GRENADE_LAUNCHER) )
  1334.         return IT_GRENADE_LAUNCHER;
  1335.  
  1336.  
  1337.     return IT_AXE;
  1338. };
  1339.  
  1340. float() W_CheckNoAmmo =
  1341. {
  1342.     if (self.currentammo > 0)
  1343.         return TRUE;
  1344.  
  1345.     if (self.weapon == IT_AXE)
  1346.         return TRUE;
  1347.     
  1348.     self.weapon = W_BestWeapon ();
  1349.  
  1350.     W_SetCurrentAmmo ();
  1351.     
  1352. // drop the weapon down
  1353.     return FALSE;
  1354. };
  1355. /*
  1356. ===========
  1357. Do Changes
  1358. ===========
  1359. */
  1360. void() ChangeSplit =
  1361. {
  1362.         if (smis == 0)
  1363.         {
  1364.                 smis = 1;
  1365.                 sprint (self, "Split Missile Activated\n");
  1366.                 break;
  1367.         }
  1368.         else
  1369.         {
  1370.                 smis = 0;
  1371.                 sprint (self, "Split Missile Deactivated\n");
  1372.                 break;
  1373.         }
  1374. };
  1375. void() ChangeAuto =
  1376. {
  1377.         if (ashot == 0 && self.weapon == IT_SUPER_NAILGUN && self.ammo_shells >=2)
  1378.         {
  1379.                 ashot = 1;
  1380.                 self.currentammo = self.ammo_shells;
  1381.                 sprint (self, "Auto Shotgun Activated\n");
  1382.                 break;
  1383.         }
  1384.         else if (ashot == 0 && self.weapon == IT_SUPER_NAILGUN && self.ammo_shells <=1)
  1385.         {
  1386.                 sprint (self, "not enough ammo\n");
  1387.                 break;
  1388.         }
  1389.         else if (ashot == 1 && self.weapon == IT_SUPER_NAILGUN)
  1390.         {
  1391.                 ashot = 0;
  1392.                 self.currentammo = self.ammo_nails;
  1393.                 sprint (self, "Auto Shotgun Deactivated\n");
  1394.                 break;
  1395.         }
  1396.         else if (ashot == 0 && self.weapon != IT_SUPER_NAILGUN)
  1397.         {
  1398.                 ashot = 1;
  1399.                 sprint (self, "Auto Shotgun Activated\n");
  1400.                 break;
  1401.         }
  1402.         else if (ashot == 1 && self.weapon != IT_SUPER_NAILGUN)
  1403.         {
  1404.                 ashot = 0;
  1405.                 sprint (self, "Auto Shotgun Deactivated\n");
  1406.                 break;
  1407.         }
  1408. };
  1409. void() ChangeNailS =
  1410. {
  1411.         if (nshot == 0 && self.weapon == IT_SHOTGUN && self.ammo_nails >=4)
  1412.         {
  1413.                 nshot = 1;
  1414.                 self.currentammo = self.ammo_nails;
  1415.                 sprint (self, "Nail Shotgun Activated\n");
  1416.                 break;
  1417.         }
  1418.         else if (nshot == 0 && self.weapon == IT_SHOTGUN && self.ammo_nails <=3)
  1419.         {
  1420.                 sprint (self, "not enough ammo\n");
  1421.                 break;
  1422.         }
  1423.         else if (nshot == 1 && self.weapon == IT_SHOTGUN)
  1424.         {
  1425.                 nshot = 0;
  1426.                 self.currentammo = self.ammo_shells;
  1427.                 sprint (self, "Nail Shotgun Deactivated\n");
  1428.                 break;
  1429.         }
  1430.         else if (nshot == 0 && self.weapon != IT_SHOTGUN)
  1431.         {
  1432.                 nshot = 1;
  1433.                 sprint (self, "Nail Shotgun Activated\n");
  1434.                 break;
  1435.         }
  1436.         else if (nshot == 1 && self.weapon != IT_SHOTGUN)
  1437.         {
  1438.                 nshot = 0;
  1439.                 sprint (self, "Nail Shotgun Deactivated\n");
  1440.                 break;
  1441.         }
  1442. };
  1443. void() ChangeGren =
  1444. {
  1445.         if (ngren == 0)
  1446.         {
  1447.                 ngren = 1;
  1448.                 sprint (self, "Nail Grenade Activated\n");
  1449.                 break;
  1450.         }
  1451.         else
  1452.         {
  1453.                 ngren = 0;
  1454.                 sprint (self, "Nail Grenade Deactivated\n");
  1455.                 break;
  1456.         }
  1457. };
  1458.  
  1459. /*
  1460. ============
  1461. W_Attack
  1462.  
  1463. An attack impulse can be triggered now
  1464. ============
  1465. */
  1466. void()  player_axe1;
  1467. void()  player_axeb1;
  1468. void()  player_axec1;
  1469. void()  player_axed1;
  1470. void()  player_shot1;
  1471. void()  player_nail1;
  1472. void()  player_light1;
  1473. void()  player_rocket1;
  1474. void()  player_rocket2;
  1475.  
  1476. void() W_Attack =
  1477. {
  1478.     local   float   r;
  1479.  
  1480.     if (!W_CheckNoAmmo ())
  1481.         return;
  1482.  
  1483.     makevectors     (self.v_angle);                 // calculate forward angle for velocity
  1484.     self.show_hostile = time + 1;   // wake monsters up
  1485.  
  1486.     if (self.weapon == IT_AXE)
  1487.     {
  1488.         sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
  1489.         r = random();
  1490.         if (r < 0.25)
  1491.             player_axe1 ();
  1492.         else if (r<0.5)
  1493.             player_axeb1 ();
  1494.         else if (r<0.75)
  1495.             player_axec1 ();
  1496.         else
  1497.             player_axed1 ();
  1498.         self.attack_finished = time + 0.5;
  1499.     }
  1500.         else if (self.weapon == IT_SHOTGUN && nshot == 0)
  1501.     {
  1502.         player_shot1 ();
  1503.         W_FireShotgun ();
  1504.         self.attack_finished = time + 0.5;
  1505.     }
  1506.         else if (self.weapon == IT_SHOTGUN && nshot == 1)
  1507.     {
  1508.                 if (self.ammo_nails <= 3)
  1509.                 {
  1510.                         ChangeNailS();
  1511.                         W_Attack();
  1512.                         return;
  1513.                 }
  1514.                 else
  1515.                 {
  1516.                         player_shot1 ();
  1517.                         W_FireNailShot ();
  1518.                         self.attack_finished = time + 0.5;
  1519.                 }
  1520.     }
  1521.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1522.     {
  1523.         player_shot1 ();
  1524.         W_FireSuperShotgun ();
  1525.         self.attack_finished = time + 0.7;
  1526.     }
  1527.     else if (self.weapon == IT_NAILGUN)
  1528.     {
  1529.         player_nail1 ();
  1530.     }
  1531.     else if (self.weapon == IT_SUPER_NAILGUN)
  1532.     {
  1533.         player_nail1 ();
  1534.     }
  1535.         else if (self.weapon == IT_GRENADE_LAUNCHER && ngren == 0)
  1536.     {
  1537.         player_rocket1();
  1538.         W_FireGrenade();
  1539.         self.attack_finished = time + 0.6;
  1540.     }
  1541.         else if (self.weapon == IT_GRENADE_LAUNCHER && ngren == 1)
  1542.     {
  1543.                 if (self.ammo_rockets <=2)
  1544.                 {
  1545.                         ChangeGren();
  1546.                         W_Attack();
  1547.                         return;
  1548.                 }
  1549.                 else
  1550.                 {
  1551.                         player_rocket1();
  1552.                         W_LaunchBouncer();
  1553.                         self.attack_finished = time + 0.9;
  1554.                 }
  1555.     }
  1556.  
  1557.         else if (self.weapon == IT_ROCKET_LAUNCHER && smis == 0)
  1558.     {
  1559.         player_rocket1();
  1560.         W_FireRocket();
  1561.         self.attack_finished = time + 0.8;
  1562.     }
  1563.         else if (self.weapon == IT_ROCKET_LAUNCHER && smis == 1)
  1564.     {
  1565.                 if (self.ammo_rockets <= 4)
  1566.                 {
  1567.                         ChangeSplit();
  1568.                         W_Attack();
  1569.                         return;
  1570.                 }
  1571.                 else
  1572.                 {
  1573.                         player_rocket1();
  1574.                         W_LaunchSplitter();
  1575.                         self.attack_finished = time + 1.2;
  1576.                 }
  1577.         }
  1578.     else if (self.weapon == IT_LIGHTNING)
  1579.     {
  1580.         player_light1();
  1581.         self.attack_finished = time + 0.1;
  1582.         sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
  1583.     }
  1584. };
  1585.  
  1586. /*
  1587. ============
  1588. W_ChangeWeapon
  1589.  
  1590. ============
  1591. */
  1592. void() W_ChangeWeapon =
  1593. {
  1594.     local   float   it, am, fl;
  1595.     
  1596.     it = self.items;
  1597.     am = 0;
  1598.     
  1599.     if (self.impulse == 1)
  1600.     {
  1601.         fl = IT_AXE;
  1602.     }
  1603.         else if (self.impulse == 2 && nshot == 0)
  1604.     {
  1605.         fl = IT_SHOTGUN;
  1606.         if (self.ammo_shells < 1)
  1607.             am = 1;
  1608.     }
  1609.         else if (self.impulse == 2 && nshot == 1)
  1610.     {
  1611.         fl = IT_SHOTGUN;
  1612.                 if (self.ammo_nails < 4)
  1613.             am = 1;
  1614.     }
  1615.     else if (self.impulse == 3)
  1616.     {
  1617.         fl = IT_SUPER_SHOTGUN;
  1618.         if (self.ammo_shells < 2)
  1619.             am = 1;
  1620.     }               
  1621.     else if (self.impulse == 4)
  1622.     {
  1623.         fl = IT_NAILGUN;
  1624.         if (self.ammo_nails < 1)
  1625.             am = 1;
  1626.     }
  1627.         else if (self.impulse == 5 && ashot == 0)
  1628.     {
  1629.         fl = IT_SUPER_NAILGUN;
  1630.         if (self.ammo_nails < 2)
  1631.             am = 1;
  1632.     }
  1633.         else if (self.impulse == 5 && ashot == 1)
  1634.     {
  1635.         fl = IT_SUPER_NAILGUN;
  1636.                 if (self.ammo_shells < 2)
  1637.             am = 1;
  1638.     }
  1639.     else if (self.impulse == 6)
  1640.     {
  1641.         fl = IT_GRENADE_LAUNCHER;
  1642.         if (self.ammo_rockets < 1)
  1643.             am = 1;
  1644.     }
  1645.     else if (self.impulse == 7)
  1646.     {
  1647.         fl = IT_ROCKET_LAUNCHER;
  1648.         if (self.ammo_rockets < 1)
  1649.             am = 1;
  1650.     }
  1651.     else if (self.impulse == 8)
  1652.     {
  1653.         fl = IT_LIGHTNING;
  1654.         if (self.ammo_cells < 1)
  1655.             am = 1;
  1656.     }
  1657.     self.impulse = 0;
  1658.     
  1659.     if (!(self.items & fl))
  1660.     {       // don't have the weapon or the ammo
  1661.         sprint (self, "no weapon.\n");
  1662.         return;
  1663.     }
  1664.     
  1665.     if (am)
  1666.     {       // don't have the ammo
  1667.         sprint (self, "not enough ammo.\n");
  1668.         return;
  1669.     }
  1670.  
  1671. //
  1672. // set weapon, set ammo
  1673. //
  1674.     self.weapon = fl;               
  1675.     W_SetCurrentAmmo ();
  1676. };
  1677.  
  1678. /*
  1679. ============
  1680. CheatCommand
  1681. ============
  1682. */
  1683. void() CheatCommand =
  1684. {
  1685.     if (deathmatch || coop)
  1686.         return;
  1687.  
  1688.     self.ammo_rockets = 100;
  1689.     self.ammo_nails = 200;
  1690.     self.ammo_shells = 100;
  1691.     self.items = self.items | 
  1692.         IT_AXE |
  1693.         IT_SHOTGUN |
  1694.         IT_SUPER_SHOTGUN |
  1695.         IT_NAILGUN |
  1696.         IT_SUPER_NAILGUN |
  1697.         IT_GRENADE_LAUNCHER |
  1698.         IT_ROCKET_LAUNCHER |
  1699.                 IT_KEY1 | IT_KEY2;
  1700.                 
  1701.     self.ammo_cells = 200;
  1702.     self.items = self.items | IT_LIGHTNING;
  1703.  
  1704.         self.weapon = IT_ROCKET_LAUNCHER;
  1705.     self.impulse = 0;
  1706.     W_SetCurrentAmmo ();
  1707. };
  1708.  
  1709. /*
  1710. ============
  1711. CycleWeaponCommand
  1712.  
  1713. Go to the next weapon with ammo
  1714. ============
  1715. */
  1716. void() CycleWeaponCommand =
  1717. {
  1718.     local   float   it, am;
  1719.     
  1720.     it = self.items;
  1721.     self.impulse = 0;
  1722.     
  1723.     while (1)
  1724.     {
  1725.         am = 0;
  1726.  
  1727.         if (self.weapon == IT_LIGHTNING)
  1728.         {
  1729.             self.weapon = IT_AXE;
  1730.         }
  1731.         else if (self.weapon == IT_AXE)
  1732.         {
  1733.             self.weapon = IT_SHOTGUN;
  1734.             if (self.ammo_shells < 1)
  1735.                 am = 1;
  1736.         }
  1737.         else if (self.weapon == IT_SHOTGUN)
  1738.         {
  1739.             self.weapon = IT_SUPER_SHOTGUN;
  1740.             if (self.ammo_shells < 2)
  1741.                 am = 1;
  1742.         }               
  1743.         else if (self.weapon == IT_SUPER_SHOTGUN)
  1744.         {
  1745.             self.weapon = IT_NAILGUN;
  1746.             if (self.ammo_nails < 1)
  1747.                 am = 1;
  1748.         }
  1749.         else if (self.weapon == IT_NAILGUN)
  1750.         {
  1751.             self.weapon = IT_SUPER_NAILGUN;
  1752.             if (self.ammo_nails < 2)
  1753.                 am = 1;
  1754.         }
  1755.         else if (self.weapon == IT_SUPER_NAILGUN)
  1756.         {
  1757.             self.weapon = IT_GRENADE_LAUNCHER;
  1758.             if (self.ammo_rockets < 1)
  1759.                 am = 1;
  1760.         }
  1761.         else if (self.weapon == IT_GRENADE_LAUNCHER)
  1762.         {
  1763.             self.weapon = IT_ROCKET_LAUNCHER;
  1764.             if (self.ammo_rockets < 1)
  1765.                 am = 1;
  1766.         }
  1767.         else if (self.weapon == IT_ROCKET_LAUNCHER)
  1768.         {
  1769.                         self.weapon = IT_LIGHTNING;
  1770.                         if (self.ammo_cells < 1)
  1771.                 am = 1;
  1772.         }
  1773.                 if ( (self.items & self.weapon) && am == 0)
  1774.         {
  1775.             W_SetCurrentAmmo ();
  1776.             return;
  1777.         }
  1778.     }
  1779.  
  1780. };
  1781.  
  1782. /*
  1783. ============
  1784. ServerflagsCommand
  1785.  
  1786. Just for development
  1787. ============
  1788. */
  1789. void() ServerflagsCommand =
  1790. {
  1791.     serverflags = serverflags * 2 + 1;
  1792. };
  1793.  
  1794. void() QuadCheat =
  1795. {
  1796.     if (deathmatch || coop)
  1797.         return;
  1798.     self.super_time = 1;
  1799.     self.super_damage_finished = time + 30;
  1800.     self.items = self.items | IT_QUAD;
  1801.     dprint ("quad cheat\n");
  1802. };
  1803.  
  1804. /*
  1805. ============
  1806. ImpulseCommands
  1807.  
  1808. ============
  1809. */
  1810. void() ImpulseCommands =
  1811. {
  1812.     if (self.impulse >= 1 && self.impulse <= 8)
  1813.         W_ChangeWeapon ();
  1814.     if (self.impulse == 9)
  1815.         CheatCommand ();
  1816.     if (self.impulse == 10)
  1817.         CycleWeaponCommand ();
  1818.     if (self.impulse == 11)
  1819.         ServerflagsCommand ();
  1820.         if (self.impulse == 12)
  1821.                 ChangeSplit ();
  1822.         if (self.impulse == 13)
  1823.                 ChangeAuto ();
  1824.         if (self.impulse == 14)
  1825.                 ChangeGren ();
  1826.         if (self.impulse == 15)
  1827.                 ChangeNailS ();
  1828.     if (self.impulse == 255)
  1829.         QuadCheat ();
  1830.         
  1831.     self.impulse = 0;
  1832. };
  1833.  
  1834. /*
  1835. ============
  1836. W_WeaponFrame
  1837.  
  1838. Called every frame so impulse events can be handled as well as possible
  1839. ============
  1840. */
  1841. void() W_WeaponFrame =
  1842. {
  1843.     if (time < self.attack_finished)
  1844.         return;
  1845.  
  1846.     ImpulseCommands ();
  1847.     
  1848. // check for attack
  1849.     if (self.button0)
  1850.     {
  1851.         SuperDamageSound ();
  1852.         W_Attack ();
  1853.     }
  1854. };
  1855.  
  1856. /*
  1857. ========
  1858. SuperDamageSound
  1859.  
  1860. Plays sound if needed
  1861. ========
  1862. */
  1863. void() SuperDamageSound =
  1864. {
  1865.     if (self.super_damage_finished > time)
  1866.     {
  1867.         if (self.super_sound < time)
  1868.         {
  1869.             self.super_sound = time + 1;
  1870.             sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
  1871.         }
  1872.     }
  1873.     return;
  1874. };
  1875.  
  1876.