home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / advwepv7 / weapons.qc < prev    next >
Encoding:
Text File  |  1996-07-28  |  32.7 KB  |  1,535 lines

  1. /*
  2. */
  3. void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
  4. void () player_run;
  5. void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
  6. void(vector org, vector vel, float damage) SpawnBlood;
  7. void() SuperDamageSound;
  8.  
  9. // called by worldspawn
  10. void() W_Precache =
  11. {
  12.     precache_sound ("weapons/r_exp3.wav");    // new rocket explosion
  13.     precache_sound ("weapons/rocket1i.wav");    // spike gun
  14.     precache_sound ("weapons/sgun1.wav");
  15.     precache_sound ("weapons/guncock.wav");    // player shotgun
  16.     precache_sound ("weapons/ric1.wav");    // ricochet (used in c code)
  17.     precache_sound ("weapons/ric2.wav");    // ricochet (used in c code)
  18.     precache_sound ("weapons/ric3.wav");    // ricochet (used in c code)
  19.     precache_sound ("weapons/spike2.wav");    // super spikes
  20.     precache_sound ("weapons/tink1.wav");    // spikes tink (used in c code)
  21.     precache_sound ("weapons/grenade.wav");    // grenade launcher
  22.     precache_sound ("weapons/bounce.wav");        // grenade bounce
  23.     precache_sound ("weapons/shotgn2.wav");    // super shotgun
  24. };
  25.  
  26. float() crandom =
  27. {
  28.     return 2*(random() - 0.5);
  29. };
  30. /*
  31. ================
  32. W_FireAxe
  33. ================
  34. */
  35. void() W_FireAxe =
  36. {
  37.     local    vector    source;
  38.     local    vector    org;
  39.  
  40.     source = self.origin + '0 0 16';
  41.     traceline (source, source + v_forward*64, FALSE, self);
  42.     if (trace_fraction == 1.0)
  43.         return;
  44.     
  45.     org = trace_endpos - v_forward*4;
  46.  
  47.     if (trace_ent.takedamage)
  48.     {
  49.         trace_ent.axhitme = 1;
  50.         SpawnBlood (org, '0 0 0', 20);
  51.         T_Damage (trace_ent, self, self, 20);
  52.     }
  53.     else
  54.     {    // hit wall
  55.         sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  56.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  57.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  58.         WriteCoord (MSG_BROADCAST, org_x);
  59.         WriteCoord (MSG_BROADCAST, org_y);
  60.         WriteCoord (MSG_BROADCAST, org_z);
  61.     }
  62. };
  63.  
  64.  
  65. //============================================================================
  66.  
  67.  
  68. vector() wall_velocity =
  69. {
  70.     local vector    vel;
  71.     
  72.     vel = normalize (self.velocity);
  73.     vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
  74.     vel = vel + 2*trace_plane_normal;
  75.     vel = vel * 200;
  76.     
  77.     return vel;
  78. };
  79.  
  80.  
  81. /*
  82. ================
  83. SpawnMeatSpray
  84. ================
  85. */
  86. void(vector org, vector vel) SpawnMeatSpray =
  87. {
  88.     local    entity missile, mpuff;
  89.     local    vector    org;
  90.  
  91.     missile = spawn ();
  92.     missile.owner = self;
  93.     missile.movetype = MOVETYPE_BOUNCE;
  94.     missile.solid = SOLID_NOT;
  95.  
  96.     makevectors (self.angles);
  97.  
  98.     missile.velocity = vel;
  99.     missile.velocity_z = missile.velocity_z + 250 + 50*random();
  100.  
  101.     missile.avelocity = '3000 1000 2000';
  102.     
  103. // set missile duration
  104.     missile.nextthink = time + 1;
  105.     missile.think = SUB_Remove;
  106.  
  107.     setmodel (missile, "progs/zom_gib.mdl");
  108.     setsize (missile, '0 0 0', '0 0 0');        
  109.     setorigin (missile, org);
  110. };
  111.  
  112. /*
  113. ================
  114. SpawnBlood
  115. ================
  116. */
  117. void(vector org, vector vel, float damage) SpawnBlood =
  118. {
  119.     particle (org, vel*0.1, 73, damage*2);
  120. };
  121.  
  122. /*
  123. ================
  124. spawn_touchblood
  125. ================
  126. */
  127. void(float damage) spawn_touchblood =
  128. {
  129.     local vector    vel;
  130.  
  131.     vel = wall_velocity () * 0.2;
  132.     SpawnBlood (self.origin + vel*0.01, vel, damage);
  133. };
  134.  
  135.  
  136. /*
  137. ================
  138. SpawnChunk
  139. ================
  140. */
  141. void(vector org, vector vel) SpawnChunk =
  142. {
  143.     particle (org, vel*0.02, 0, 10);
  144. };
  145.  
  146. /*
  147. ==============================================================================
  148.  
  149. MULTI-DAMAGE
  150.  
  151. Collects multiple small damages into a single damage
  152.  
  153. ==============================================================================
  154. */
  155.  
  156. entity    multi_ent;
  157. float    multi_damage;
  158.  
  159. void() ClearMultiDamage =
  160. {
  161.     multi_ent = world;
  162.     multi_damage = 0;
  163. };
  164.  
  165. void() ApplyMultiDamage =
  166. {
  167.     if (!multi_ent)
  168.         return;
  169.     T_Damage (multi_ent, self, self, multi_damage);
  170. };
  171.  
  172. void(entity hit, float damage) AddMultiDamage =
  173. {
  174.     if (!hit)
  175.         return;
  176.     
  177.     if (hit != multi_ent)
  178.     {
  179.         ApplyMultiDamage ();
  180.         multi_damage = damage;
  181.         multi_ent = hit;
  182.     }
  183.     else
  184.         multi_damage = multi_damage + damage;
  185. };
  186.  
  187. /*
  188. ==============================================================================
  189.  
  190. BULLETS
  191.  
  192. ==============================================================================
  193. */
  194.  
  195. /*
  196. ================
  197. TraceAttack
  198. ================
  199. */
  200. void(float damage, vector dir) TraceAttack =
  201. {
  202.     local    vector    vel, org;
  203.     
  204.     vel = normalize(dir + v_up*crandom() + v_right*crandom());
  205.     vel = vel + 2*trace_plane_normal;
  206.     vel = vel * 200;
  207.  
  208.     org = trace_endpos - dir*4;
  209.  
  210.     if (trace_ent.takedamage)
  211.     {
  212.         SpawnBlood (org, vel*0.2, damage);
  213.         AddMultiDamage (trace_ent, damage);
  214.     }
  215.     else
  216.     {
  217.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  218.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  219.         WriteCoord (MSG_BROADCAST, org_x);
  220.         WriteCoord (MSG_BROADCAST, org_y);
  221.         WriteCoord (MSG_BROADCAST, org_z);
  222.     }
  223. };
  224.  
  225. /*
  226. ================
  227. FireBullets
  228.  
  229. Used by shotgun, super shotgun, and enemy soldier firing
  230. Go to the trouble of combining multiple pellets into a single damage call.
  231. ================
  232. */
  233. void(float shotcount, vector dir, vector spread) FireBullets =
  234. {
  235.     local    vector direction;
  236.     local    vector    src;
  237.     
  238.     makevectors(self.v_angle);
  239.  
  240.     src = self.origin + v_forward*10;
  241.     src_z = self.absmin_z + self.size_z * 0.7;
  242.  
  243.     ClearMultiDamage ();
  244.     while (shotcount > 0)
  245.     {
  246.         direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
  247.  
  248.         traceline (src, src + direction*2048, FALSE, self);
  249.         if (trace_fraction != 1.0)
  250.             TraceAttack (4, direction);
  251.  
  252.         shotcount = shotcount - 1;
  253.     }
  254.     ApplyMultiDamage ();
  255. };
  256.  
  257. /*
  258. ================
  259. W_FireShotgun
  260. ================
  261. */
  262. void() W_FireShotgun =
  263. {
  264.     local vector dir;
  265.  
  266.     sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);    
  267.  
  268.     self.punchangle_x = -2;
  269.     
  270.     self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  271.     dir = aim (self, 100000);
  272.     FireBullets (6, dir, '0.04 0.04 0');
  273. };
  274.  
  275.  
  276. /*
  277. ================
  278. W_FireSuperShotgun
  279. ================
  280. */
  281. void() W_FireSuperShotgun =
  282. {
  283.     local vector dir;
  284.  
  285.     if (self.currentammo == 1)
  286.     {
  287.         W_FireShotgun ();
  288.         return;
  289.     }
  290.         
  291.     sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);    
  292.  
  293.     self.punchangle_x = -4;
  294.     
  295.     self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  296.     dir = aim (self, 100000);
  297.     FireBullets (14, dir, '0.14 0.08 0');
  298. };
  299.  
  300.  
  301. /*
  302. ==============================================================================
  303.  
  304. ROCKETS
  305.  
  306. ==============================================================================
  307. */
  308.  
  309. void()    s_explode1    =    [0,        s_explode2] {};
  310. void()    s_explode2    =    [1,        s_explode3] {};
  311. void()    s_explode3    =    [2,        s_explode4] {};
  312. void()    s_explode4    =    [3,        s_explode5] {};
  313. void()    s_explode5    =    [4,        s_explode6] {};
  314. void()    s_explode6    =    [5,        SUB_Remove] {};
  315.  
  316. void() BecomeExplosion =
  317. {
  318.     self.movetype = MOVETYPE_NONE;
  319.     self.velocity = '0 0 0';
  320.     self.touch = SUB_Null;
  321.     setmodel (self, "progs/s_explod.spr");
  322.     self.solid = SOLID_NOT;
  323.     s_explode1 ();
  324. };
  325.  
  326. void() T_MissileTouch =
  327. {
  328.     local float    damg;
  329.  
  330.     if (other == self.owner)
  331.         return;        // don't explode on owner
  332.  
  333.     if (pointcontents(self.origin) == CONTENT_SKY)
  334.     {
  335.         remove(self);
  336.         return;
  337.     }
  338.  
  339.     damg = 100 + random()*20;
  340.     
  341.     if (other.health)
  342.     {
  343.         if (other.classname == "monster_shambler")
  344.             damg = damg * 0.5;    // mostly immune
  345.         T_Damage (other, self, self.owner, damg );
  346.     }
  347.  
  348.     // don't do radius damage to the other, because all the damage
  349.     // was done in the impact
  350.     T_RadiusDamage (self, self.owner, 120, other);
  351.  
  352. //    sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  353.     self.origin = self.origin - 8*normalize(self.velocity);
  354.  
  355.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  356.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  357.     WriteCoord (MSG_BROADCAST, self.origin_x);
  358.     WriteCoord (MSG_BROADCAST, self.origin_y);
  359.     WriteCoord (MSG_BROADCAST, self.origin_z);
  360.  
  361.     BecomeExplosion ();
  362. };
  363.  
  364. /*
  365. ================
  366. W_FireRocket
  367. ================
  368. */
  369. void() W_FireRocket =
  370. {
  371.     local    entity missile, mpuff;
  372.     
  373.     self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  374.     
  375.     sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  376.  
  377.     self.punchangle_x = -2;
  378.  
  379.     missile = spawn ();
  380.     missile.owner = self;
  381.     missile.movetype = MOVETYPE_FLYMISSILE;
  382.     missile.solid = SOLID_BBOX;
  383.         
  384. // set missile speed    
  385.  
  386.     makevectors (self.v_angle);
  387.     missile.velocity = aim(self, 1000);
  388.     missile.velocity = missile.velocity * 1000;
  389.     missile.angles = vectoangles(missile.velocity);
  390.     
  391.     missile.touch = T_MissileTouch;
  392.     
  393. // set missile duration
  394.     missile.nextthink = time + 5;
  395.     missile.think = SUB_Remove;
  396.  
  397.     setmodel (missile, "progs/missile.mdl");
  398.     setsize (missile, '0 0 0', '0 0 0');        
  399.     setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  400. };
  401.  
  402.  
  403.  
  404. /*
  405. ================
  406. W_FireARocket
  407. ================
  408. */
  409. void()   HomeThink;
  410. entity() HomeFindTarget;
  411. float(entity targ) visible;
  412. float(entity targ) infront;
  413.  
  414. void() W_FireARocket =
  415. {
  416.     local    entity missile, mpuff;
  417.         if (self.currentammo < 5)
  418.                self.currentammo = self.ammo_rockets = 0;
  419.         else                
  420.                self.currentammo = self.ammo_rockets = self.ammo_rockets - 5;
  421.     
  422.     sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  423.  
  424.     self.punchangle_x = -2;
  425.  
  426.     missile = spawn ();
  427.     missile.owner = self;
  428.     missile.movetype = MOVETYPE_FLYMISSILE;
  429.     missile.solid = SOLID_BBOX;
  430.         missile.classname = "arocket";
  431.         
  432. // set missile speed    
  433.  
  434.     makevectors (self.v_angle);
  435.     missile.velocity = aim(self, 1000);
  436.     missile.velocity = missile.velocity * 300;
  437.     missile.angles = vectoangles(missile.velocity);
  438.     
  439.     missile.touch = T_MissileTouch;
  440.     
  441. // set missile duration
  442. //    missile.nextthink = time + 30;
  443. //    missile.think = SUB_Remove;
  444.  
  445.     missile.nextthink = time + 0.2;
  446.     missile.think = HomeThink;
  447.     missile.enemy = world;
  448.  
  449.     setmodel (missile, "progs/missile.mdl");
  450.     setsize (missile, '0 0 0', '0 0 0');        
  451.     setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  452. };
  453.  
  454. entity() HomeFindTarget = 
  455. {
  456.     local entity head, selected;
  457.     local float dist;
  458.     dist = 100000;
  459.     selected = world;
  460.     head = findradius(self.origin, 100000);
  461.     while(head)
  462.     {
  463.                 if( (head.health > 1) && (head.classname != "misc_explobox") && (head != self) && (head != self.owner) && !(head.items & IT_INVISIBILITY) )
  464.         {
  465.             traceline(self.origin,head.origin,TRUE,self);
  466.             if ( (trace_fraction >= 1) && (vlen(head.origin - self.origin) < dist) )
  467.             {
  468.                 selected = head;
  469.                 dist = vlen(head.origin - self.origin);
  470.             }
  471.         }        
  472.         head = head.chain;
  473.     }
  474.     if (selected != world)
  475.     {
  476.         sprint (self.owner,"Homing->");
  477.         if (selected.classname == "player")
  478.         {
  479.             sprint (self.owner,selected.netname);
  480.             sprint (selected,self.owner.netname);
  481.             sprint (selected," has a bogey on you!\n");
  482.         }
  483.         else
  484.             sprint (self.owner,selected.classname);
  485.         sprint (self.owner,"\n");
  486.     }
  487.     return selected;
  488. };
  489.  
  490. void() HomeThink =
  491. {
  492.         local vector dir, olddir, vtemp;
  493.         local float turnrate;
  494.  
  495.         turnrate= 0.2;
  496.     if ( !(self.enemy) || (self.enemy == world) || (self.enemy.health < 1) )
  497.         self.enemy = HomeFindTarget();
  498.  
  499.     if (self.enemy != world) // Arr.. don't be taken on da World!
  500.     {
  501.         vtemp = self.enemy.origin + '0 0 10';
  502.                 olddir = normalize(self.velocity);
  503.         dir = normalize(vtemp - self.origin);
  504.                 //Limits the turnrate of the rockets
  505.                 if (olddir_x - dir_x > turnrate)
  506.                         dir_x = olddir_x - turnrate;
  507.                 if (olddir_x - dir_x < -1 * turnrate)
  508.                         dir_x = olddir_x + turnrate;
  509.                 if (olddir_y - dir_y > turnrate)
  510.                         dir_y = olddir_y - turnrate;
  511.                 if (olddir_y - dir_y < -1 * turnrate)
  512.                         dir_y = olddir_y + turnrate;
  513.                 if (olddir_z - dir_z > turnrate)
  514.                         dir_z = olddir_z - turnrate;
  515.                 if (olddir_z - dir_z < -1 * turnrate)
  516.                         dir_z = olddir_z + turnrate;
  517.                 self.velocity = dir * 230;
  518.         self.angles = vectoangles(self.velocity);
  519.     }
  520.  
  521.     self.nextthink = time + 0.2;
  522.     self.think=HomeThink;
  523. };
  524. /*
  525. ===============================================================================
  526.  
  527. LIGHTNING
  528.  
  529. ===============================================================================
  530. */
  531.  
  532. /*
  533. =================
  534. LightningDamage
  535. =================
  536. */
  537. void(vector p1, vector p2, entity from, float damage) LightningDamage =
  538. {
  539.     local entity        e1, e2;
  540.     local vector        f;
  541.     
  542.     f = p2 - p1;
  543.     normalize (f);
  544.     f_x = 0 - f_y;
  545.     f_y = f_x;
  546.     f_z = 0;
  547.     f = f*16;
  548.  
  549.     e1 = e2 = world;
  550.  
  551.     traceline (p1, p2, FALSE, self);
  552.     if (trace_ent.takedamage)
  553.     {
  554.         particle (trace_endpos, '0 0 100', 225, damage*4);
  555.         T_Damage (trace_ent, from, from, damage);
  556.         if (self.classname == "player")
  557.         {
  558.             if (other.classname == "player")
  559.                 trace_ent.velocity_z = trace_ent.velocity_z + 400;
  560.         }
  561.     }
  562.     e1 = trace_ent;
  563.  
  564.     traceline (p1 + f, p2 + f, FALSE, self);
  565.     if (trace_ent != e1 && trace_ent.takedamage)
  566.     {
  567.         particle (trace_endpos, '0 0 100', 225, damage*4);
  568.         T_Damage (trace_ent, from, from, damage);
  569.     }
  570.     e2 = trace_ent;
  571.  
  572.     traceline (p1 - f, p2 - f, FALSE, self);
  573.     if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
  574.     {
  575.         particle (trace_endpos, '0 0 100', 225, damage*4);
  576.         T_Damage (trace_ent, from, from, damage);
  577.     }
  578. };
  579.  
  580.  
  581. void() W_FireLightning =
  582. {
  583.     local    vector        org;
  584.  
  585.     if (self.ammo_cells < 1)
  586.     {
  587.         self.weapon = W_BestWeapon ();
  588.         W_SetCurrentAmmo ();
  589.         return;
  590.     }
  591.  
  592. // explode if under water
  593.     if (self.waterlevel > 1)
  594.     {
  595.         T_RadiusDamage (self, self, 35*self.ammo_cells, world);
  596.         self.ammo_cells = 0;
  597.         W_SetCurrentAmmo ();
  598.         return;
  599.     }
  600.  
  601.     if (self.t_width < time)
  602.     {
  603.         sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  604.         self.t_width = time + 0.6;
  605.     }
  606.     self.punchangle_x = -2;
  607.  
  608.     self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  609.  
  610.     org = self.origin + '0 0 16';
  611.     
  612.     traceline (org, org + v_forward*600, TRUE, self);
  613.  
  614.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  615.     WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  616.     WriteEntity (MSG_BROADCAST, self);
  617.     WriteCoord (MSG_BROADCAST, org_x);
  618.     WriteCoord (MSG_BROADCAST, org_y);
  619.     WriteCoord (MSG_BROADCAST, org_z);
  620.     WriteCoord (MSG_BROADCAST, trace_endpos_x);
  621.     WriteCoord (MSG_BROADCAST, trace_endpos_y);
  622.     WriteCoord (MSG_BROADCAST, trace_endpos_z);
  623.  
  624.     LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
  625. };
  626.  
  627.  
  628. //=============================================================================
  629.  
  630.  
  631. void() GrenadeExplode =
  632. {
  633.     T_RadiusDamage (self, self.owner, 120, world);
  634.  
  635.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  636.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  637.     WriteCoord (MSG_BROADCAST, self.origin_x);
  638.     WriteCoord (MSG_BROADCAST, self.origin_y);
  639.     WriteCoord (MSG_BROADCAST, self.origin_z);
  640.  
  641.     BecomeExplosion ();
  642. };
  643.  
  644. void() GrenadeTouch =
  645. {
  646.     if (other == self.owner)
  647.         return;        // don't explode on owner
  648.     if (other.takedamage == DAMAGE_AIM)
  649.     {
  650.         GrenadeExplode();
  651.         return;
  652.     }
  653.     sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);    // bounce sound
  654.     if (self.velocity == '0 0 0')
  655.         self.avelocity = '0 0 0';
  656. };
  657.  
  658. /*
  659. ================
  660. W_FireGrenade
  661. ================
  662. */
  663. void() W_FireGrenade =
  664. {
  665.     local    entity missile, mpuff;
  666.     
  667.     self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  668.     
  669.     sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  670.  
  671.     self.punchangle_x = -2;
  672.  
  673.     missile = spawn ();
  674.     missile.owner = self;
  675.     missile.movetype = MOVETYPE_BOUNCE;
  676.     missile.solid = SOLID_BBOX;
  677.     missile.classname = "grenade";
  678.         
  679. // set missile speed    
  680.  
  681.     makevectors (self.v_angle);
  682.  
  683.     if (self.v_angle_x)
  684.         missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  685.     else
  686.     {
  687.         missile.velocity = aim(self, 10000);
  688.         missile.velocity = missile.velocity * 600;
  689.         missile.velocity_z = 200;
  690.     }
  691.  
  692.     missile.avelocity = '300 300 300';
  693.  
  694.     missile.angles = vectoangles(missile.velocity);
  695.     
  696.     missile.touch = GrenadeTouch;
  697.     
  698. // set missile duration
  699.     missile.nextthink = time + 2.5;
  700.     missile.think = GrenadeExplode;
  701.  
  702.     setmodel (missile, "progs/grenade.mdl");
  703.     setsize (missile, '0 0 0', '0 0 0');        
  704.     setorigin (missile, self.origin);
  705. };
  706. void() Proximity;
  707. /*
  708. =================
  709. W_FireAGrenade ****
  710. =================
  711. */
  712. void() W_FireAGrenade =
  713. {
  714.     local    entity missile, mpuff;
  715.     
  716.         if (self.currentammo < 5)
  717.                self.currentammo = self.ammo_rockets = 0;
  718.         else                
  719.                self.currentammo = self.ammo_rockets = self.ammo_rockets - 5;
  720.         
  721.     sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  722.  
  723.     self.punchangle_x = -2;
  724.  
  725.     missile = spawn ();
  726.     missile.owner = self;
  727.     missile.movetype = MOVETYPE_BOUNCE;
  728.     missile.solid = SOLID_BBOX;
  729.         missile.classname = "agrenade";
  730.         
  731. // set missile speed    
  732.  
  733.     makevectors (self.v_angle);
  734.  
  735.     if (self.v_angle_x)
  736.                 missile.velocity = v_forward*200 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  737.     else
  738.     {
  739.         missile.velocity = aim(self, 10000);
  740.                 missile.velocity = missile.velocity * 200;
  741.                 missile.velocity_z = 200;
  742.     }
  743.  
  744.     missile.avelocity = '300 300 300';
  745.  
  746.     missile.angles = vectoangles(missile.velocity);
  747.     
  748.         //missile.touch = Proximity;
  749.     
  750. // set missile duration
  751.         missile.nextthink = time + 0.75;
  752.         missile.think = Proximity;
  753.  
  754.     setmodel (missile, "progs/grenade.mdl");
  755.     setsize (missile, '0 0 0', '0 0 0');        
  756.     setorigin (missile, self.origin);
  757. };
  758. /*
  759. ======================
  760. Proximity Trigger ****
  761. ======================
  762. */
  763.  
  764. void() Proximity =
  765. {
  766.         local entity head;
  767.  
  768.         head = findradius(self.origin,100);
  769.         while(head)
  770.         {
  771.                 if( (head.health > 1) && (head.classname != "misc_explobox") && (head != self) && (head != self.owner) && !(head.items & IT_INVISIBILITY) )
  772.                 {
  773.                         GrenadeExplode();
  774.                         return;
  775.                 }
  776.                 head = head.chain;
  777.         }
  778.         self.nextthink = time + 0.25;
  779. };
  780. //=============================================================================
  781.  
  782. void() spike_touch;
  783. void() superspike_touch;
  784.  
  785.  
  786. /*
  787. ===============
  788. launch_spike
  789.  
  790. Used for both the player and the ogre
  791. ===============
  792. */
  793. void(vector org, vector dir) launch_spike =
  794. {
  795.     newmis = spawn ();
  796.     newmis.owner = self;
  797.     newmis.movetype = MOVETYPE_FLYMISSILE;
  798.     newmis.solid = SOLID_BBOX;
  799.  
  800.     newmis.angles = vectoangles(dir);
  801.     
  802.     newmis.touch = spike_touch;
  803.     newmis.classname = "spike";
  804.     newmis.think = SUB_Remove;
  805.     newmis.nextthink = time + 6;
  806.     setmodel (newmis, "progs/spike.mdl");
  807.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  808.     setorigin (newmis, org);
  809.  
  810.     newmis.velocity = dir * 1000;
  811. };
  812.  
  813. void() W_FireSuperSpikes =
  814. {
  815.     local vector    dir;
  816.     local entity    old;
  817.     
  818.     sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
  819.     self.attack_finished = time + 0.2;
  820.     self.currentammo = self.ammo_nails = self.ammo_nails - 2;
  821.     dir = aim (self, 1000);
  822.     launch_spike (self.origin + '0 0 16', dir);
  823.     newmis.touch = superspike_touch;
  824.     setmodel (newmis, "progs/s_spike.mdl");
  825.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  826.     self.punchangle_x = -2;
  827. };
  828.  
  829. void(float ox) W_FireSpikes =
  830. {
  831.     local vector    dir;
  832.     local entity    old;
  833.     
  834.     makevectors (self.v_angle);
  835.     
  836.     if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
  837.     {
  838.         W_FireSuperSpikes ();
  839.         return;
  840.     }
  841.  
  842.     if (self.ammo_nails < 1)
  843.     {
  844.         self.weapon = W_BestWeapon ();
  845.         W_SetCurrentAmmo ();
  846.         return;
  847.     }
  848.  
  849.     sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  850.     self.attack_finished = time + 0.2;
  851.     self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  852.     dir = aim (self, 1000);
  853.     launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
  854.  
  855.     self.punchangle_x = -2;
  856. };
  857.  
  858.  
  859.  
  860. .float hit_z;
  861. void() spike_touch =
  862. {
  863. local float rand;
  864.     if (other == self.owner)
  865.         return;
  866.  
  867.     if (other.solid == SOLID_TRIGGER)
  868.         return;    // trigger field, do nothing
  869.  
  870.     if (pointcontents(self.origin) == CONTENT_SKY)
  871.     {
  872.         remove(self);
  873.         return;
  874.     }
  875.     
  876. // hit something that bleeds
  877.     if (other.takedamage)
  878.     {
  879.         spawn_touchblood (9);
  880.         T_Damage (other, self, self.owner, 9);
  881.     }
  882.     else
  883.     {
  884.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  885.         
  886.         if (self.classname == "wizspike")
  887.             WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
  888.         else if (self.classname == "knightspike")
  889.             WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
  890.         else
  891.             WriteByte (MSG_BROADCAST, TE_SPIKE);
  892.         WriteCoord (MSG_BROADCAST, self.origin_x);
  893.         WriteCoord (MSG_BROADCAST, self.origin_y);
  894.         WriteCoord (MSG_BROADCAST, self.origin_z);
  895.     }
  896.  
  897.     remove(self);
  898.  
  899. };
  900.  
  901. void() superspike_touch =
  902. {
  903. local float rand;
  904.     if (other == self.owner)
  905.         return;
  906.  
  907.     if (other.solid == SOLID_TRIGGER)
  908.         return;    // trigger field, do nothing
  909.  
  910.     if (pointcontents(self.origin) == CONTENT_SKY)
  911.     {
  912.         remove(self);
  913.         return;
  914.     }
  915.     
  916. // hit something that bleeds
  917.     if (other.takedamage)
  918.     {
  919.         spawn_touchblood (18);
  920.         T_Damage (other, self, self.owner, 18);
  921.     }
  922.     else
  923.     {
  924.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  925.         WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
  926.         WriteCoord (MSG_BROADCAST, self.origin_x);
  927.         WriteCoord (MSG_BROADCAST, self.origin_y);
  928.         WriteCoord (MSG_BROADCAST, self.origin_z);
  929.     }
  930.  
  931.     remove(self);
  932.  
  933. };
  934.  
  935. /*
  936. ================
  937. W_FireAdv
  938. ================
  939. */
  940. void () W_FireAdv =
  941. {
  942.         if (self.weapon == IT_GRENADE_LAUNCHER)
  943.                 W_FireAGrenade();
  944.         else if (self.weapon == IT_ROCKET_LAUNCHER)
  945.                 W_FireARocket();
  946.  
  947. };
  948.  
  949. /*
  950. ===============================================================================
  951.  
  952. PLAYER WEAPON USE
  953.  
  954. ===============================================================================
  955. */
  956.  
  957. void() W_SetCurrentAmmo =
  958. {
  959.     player_run ();        // get out of any weapon firing states
  960.  
  961.     self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
  962.     
  963.     if (self.weapon == IT_AXE)
  964.     {
  965.         self.currentammo = 0;
  966.         self.weaponmodel = "progs/v_axe.mdl";
  967.         self.weaponframe = 0;
  968.     }
  969.     else if (self.weapon == IT_SHOTGUN)
  970.     {
  971.         self.currentammo = self.ammo_shells;
  972.         self.weaponmodel = "progs/v_shot.mdl";
  973.         self.weaponframe = 0;
  974.         self.items = self.items | IT_SHELLS;
  975.     }
  976.     else if (self.weapon == IT_SUPER_SHOTGUN)
  977.     {
  978.         self.currentammo = self.ammo_shells;
  979.         self.weaponmodel = "progs/v_shot2.mdl";
  980.         self.weaponframe = 0;
  981.         self.items = self.items | IT_SHELLS;
  982.     }
  983.     else if (self.weapon == IT_NAILGUN)
  984.     {
  985.         self.currentammo = self.ammo_nails;
  986.         self.weaponmodel = "progs/v_nail.mdl";
  987.         self.weaponframe = 0;
  988.         self.items = self.items | IT_NAILS;
  989.     }
  990.     else if (self.weapon == IT_SUPER_NAILGUN)
  991.     {
  992.         self.currentammo = self.ammo_nails;
  993.         self.weaponmodel = "progs/v_nail2.mdl";
  994.         self.weaponframe = 0;
  995.         self.items = self.items | IT_NAILS;
  996.     }
  997.     else if (self.weapon == IT_GRENADE_LAUNCHER)
  998.     {
  999.         self.currentammo = self.ammo_rockets;
  1000.         self.weaponmodel = "progs/v_rock.mdl";
  1001.         self.weaponframe = 0;
  1002.         self.items = self.items | IT_ROCKETS;
  1003.     }
  1004.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1005.     {
  1006.         self.currentammo = self.ammo_rockets;
  1007.         self.weaponmodel = "progs/v_rock2.mdl";
  1008.         self.weaponframe = 0;
  1009.         self.items = self.items | IT_ROCKETS;
  1010.     }
  1011.     else if (self.weapon == IT_LIGHTNING)
  1012.     {
  1013.         self.currentammo = self.ammo_cells;
  1014.         self.weaponmodel = "progs/v_light.mdl";
  1015.         self.weaponframe = 0;
  1016.         self.items = self.items | IT_CELLS;
  1017.     }
  1018.     else
  1019.     {
  1020.         self.currentammo = 0;
  1021.         self.weaponmodel = "";
  1022.         self.weaponframe = 0;
  1023.     }
  1024. };
  1025.  
  1026. float() W_BestWeapon =
  1027. {
  1028.     local    float    it;
  1029.     
  1030.     it = self.items;
  1031.  
  1032.     if(self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
  1033.         return IT_LIGHTNING;
  1034.     else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
  1035.         return IT_SUPER_NAILGUN;
  1036.     else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
  1037.         return IT_SUPER_SHOTGUN;
  1038.     else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
  1039.         return IT_NAILGUN;
  1040.     else if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
  1041.         return IT_SHOTGUN;
  1042.         
  1043. /*
  1044.     if(self.ammo_rockets >= 1 && (it & IT_ROCKET_LAUNCHER) )
  1045.         return IT_ROCKET_LAUNCHER;
  1046.     else if(self.ammo_rockets >= 1 && (it & IT_GRENADE_LAUNCHER) )
  1047.         return IT_GRENADE_LAUNCHER;
  1048.  
  1049. */
  1050.  
  1051.     return IT_AXE;
  1052. };
  1053.  
  1054. float() W_CheckNoAmmo =
  1055. {
  1056.     if (self.currentammo > 0)
  1057.         return TRUE;
  1058.  
  1059.     if (self.weapon == IT_AXE)
  1060.         return TRUE;
  1061.     
  1062.     self.weapon = W_BestWeapon ();
  1063.  
  1064.     W_SetCurrentAmmo ();
  1065.     
  1066. // drop the weapon down
  1067.     return FALSE;
  1068. };
  1069.  
  1070. /*
  1071. ============
  1072. W_Attack
  1073.  
  1074. An attack impulse can be triggered now
  1075. ============
  1076. */
  1077. void()    player_axe1;
  1078. void()    player_axeb1;
  1079. void()    player_axec1;
  1080. void()    player_axed1;
  1081. void()    player_shot1;
  1082. void()    player_nail1;
  1083. void()    player_light1;
  1084. void()    player_rocket1;
  1085.  
  1086. void() W_Attack =
  1087. {
  1088.     local    float    r;
  1089.  
  1090.     if (!W_CheckNoAmmo ())
  1091.         return;
  1092.  
  1093.     makevectors    (self.v_angle);            // calculate forward angle for velocity
  1094.     self.show_hostile = time + 1;    // wake monsters up
  1095.  
  1096.     if (self.weapon == IT_AXE)
  1097.     {
  1098.         sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
  1099.         r = random();
  1100.         if (r < 0.25)
  1101.             player_axe1 ();
  1102.         else if (r<0.5)
  1103.             player_axeb1 ();
  1104.         else if (r<0.75)
  1105.             player_axec1 ();
  1106.         else
  1107.             player_axed1 ();
  1108.         self.attack_finished = time + 0.5;
  1109.     }
  1110.     else if (self.weapon == IT_SHOTGUN)
  1111.     {
  1112.         player_shot1 ();
  1113.         W_FireShotgun ();
  1114.         self.attack_finished = time + 0.5;
  1115.     }
  1116.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1117.     {
  1118.         player_shot1 ();
  1119.         W_FireSuperShotgun ();
  1120.         self.attack_finished = time + 0.7;
  1121.     }
  1122.     else if (self.weapon == IT_NAILGUN)
  1123.     {
  1124.         player_nail1 ();
  1125.     }
  1126.     else if (self.weapon == IT_SUPER_NAILGUN)
  1127.     {
  1128.         player_nail1 ();
  1129.     }
  1130.     else if (self.weapon == IT_GRENADE_LAUNCHER)
  1131.     {
  1132.         player_rocket1();
  1133.         W_FireGrenade();
  1134.         self.attack_finished = time + 0.6;
  1135.     }
  1136.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1137.     {
  1138.         player_rocket1();
  1139.         W_FireRocket();
  1140.         self.attack_finished = time + 0.8;
  1141.     }
  1142.     else if (self.weapon == IT_LIGHTNING)
  1143.     {
  1144.         player_light1();
  1145.         self.attack_finished = time + 0.1;
  1146.         sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
  1147.     }
  1148. };
  1149.  
  1150. /*
  1151. ============
  1152. W_ChangeWeapon
  1153.  
  1154. ============
  1155. */
  1156. void() W_ChangeWeapon =
  1157. {
  1158.     local    float    it, am, fl;
  1159.     
  1160.     it = self.items;
  1161.     am = 0;
  1162.     
  1163.     if (self.impulse == 1)
  1164.     {
  1165.         fl = IT_AXE;
  1166.     }
  1167.     else if (self.impulse == 2)
  1168.     {
  1169.         fl = IT_SHOTGUN;
  1170.         if (self.ammo_shells < 1)
  1171.             am = 1;
  1172.     }
  1173.     else if (self.impulse == 3)
  1174.     {
  1175.         fl = IT_SUPER_SHOTGUN;
  1176.         if (self.ammo_shells < 2)
  1177.             am = 1;
  1178.     }        
  1179.     else if (self.impulse == 4)
  1180.     {
  1181.         fl = IT_NAILGUN;
  1182.         if (self.ammo_nails < 1)
  1183.             am = 1;
  1184.     }
  1185.     else if (self.impulse == 5)
  1186.     {
  1187.         fl = IT_SUPER_NAILGUN;
  1188.         if (self.ammo_nails < 2)
  1189.             am = 1;
  1190.     }
  1191.     else if (self.impulse == 6)
  1192.     {
  1193.         fl = IT_GRENADE_LAUNCHER;
  1194.         if (self.ammo_rockets < 1)
  1195.             am = 1;
  1196.     }
  1197.     else if (self.impulse == 7)
  1198.     {
  1199.         fl = IT_ROCKET_LAUNCHER;
  1200.         if (self.ammo_rockets < 1)
  1201.             am = 1;
  1202.     }
  1203.     else if (self.impulse == 8)
  1204.     {
  1205.         fl = IT_LIGHTNING;
  1206.         if (self.ammo_cells < 1)
  1207.             am = 1;
  1208.     }
  1209.  
  1210.     self.impulse = 0;
  1211.     
  1212.     if (!(self.items & fl))
  1213.     {    // don't have the weapon or the ammo
  1214.         sprint (self, "no weapon.\n");
  1215.         return;
  1216.     }
  1217.     
  1218.     if (am)
  1219.     {    // don't have the ammo
  1220.         sprint (self, "not enough ammo.\n");
  1221.         return;
  1222.     }
  1223.  
  1224. //
  1225. // set weapon, set ammo
  1226. //
  1227.     self.weapon = fl;        
  1228.     W_SetCurrentAmmo ();
  1229. };
  1230.  
  1231. /*
  1232. ============
  1233. CheatCommand
  1234. ============
  1235. */
  1236. void() CheatCommand =
  1237. {
  1238.     if (deathmatch || coop)
  1239.         return;
  1240.  
  1241.     self.ammo_rockets = 100;
  1242.     self.ammo_nails = 200;
  1243.     self.ammo_shells = 100;
  1244.     self.items = self.items | 
  1245.         IT_AXE |
  1246.         IT_SHOTGUN |
  1247.         IT_SUPER_SHOTGUN |
  1248.         IT_NAILGUN |
  1249.         IT_SUPER_NAILGUN |
  1250.         IT_GRENADE_LAUNCHER |
  1251.         IT_ROCKET_LAUNCHER |
  1252.         IT_KEY1 | IT_KEY2;
  1253.  
  1254.     self.ammo_cells = 200;
  1255.     self.items = self.items | IT_LIGHTNING;
  1256.  
  1257.     self.weapon = IT_ROCKET_LAUNCHER;
  1258.     self.impulse = 0;
  1259.     W_SetCurrentAmmo ();
  1260. };
  1261.  
  1262. /*
  1263. ============
  1264. CycleWeaponCommand
  1265.  
  1266. Go to the next weapon with ammo
  1267. ============
  1268. */
  1269. void() CycleWeaponCommand =
  1270. {
  1271.     local    float    it, am;
  1272.     
  1273.     it = self.items;
  1274.     self.impulse = 0;
  1275.     
  1276.     while (1)
  1277.     {
  1278.         am = 0;
  1279.  
  1280.         if (self.weapon == IT_LIGHTNING)
  1281.         {
  1282.             self.weapon = IT_AXE;
  1283.         }
  1284.         else if (self.weapon == IT_AXE)
  1285.         {
  1286.             self.weapon = IT_SHOTGUN;
  1287.             if (self.ammo_shells < 1)
  1288.                 am = 1;
  1289.         }
  1290.         else if (self.weapon == IT_SHOTGUN)
  1291.         {
  1292.             self.weapon = IT_SUPER_SHOTGUN;
  1293.             if (self.ammo_shells < 2)
  1294.                 am = 1;
  1295.         }        
  1296.         else if (self.weapon == IT_SUPER_SHOTGUN)
  1297.         {
  1298.             self.weapon = IT_NAILGUN;
  1299.             if (self.ammo_nails < 1)
  1300.                 am = 1;
  1301.         }
  1302.         else if (self.weapon == IT_NAILGUN)
  1303.         {
  1304.             self.weapon = IT_SUPER_NAILGUN;
  1305.             if (self.ammo_nails < 2)
  1306.                 am = 1;
  1307.         }
  1308.         else if (self.weapon == IT_SUPER_NAILGUN)
  1309.         {
  1310.             self.weapon = IT_GRENADE_LAUNCHER;
  1311.             if (self.ammo_rockets < 1)
  1312.                 am = 1;
  1313.         }
  1314.         else if (self.weapon == IT_GRENADE_LAUNCHER)
  1315.         {
  1316.             self.weapon = IT_ROCKET_LAUNCHER;
  1317.             if (self.ammo_rockets < 1)
  1318.                 am = 1;
  1319.         }
  1320.         else if (self.weapon == IT_ROCKET_LAUNCHER)
  1321.         {
  1322.             self.weapon = IT_LIGHTNING;
  1323.             if (self.ammo_cells < 1)
  1324.                 am = 1;
  1325.         }
  1326.     
  1327.         if ( (self.items & self.weapon) && am == 0)
  1328.         {
  1329.             W_SetCurrentAmmo ();
  1330.             return;
  1331.         }
  1332.     }
  1333.  
  1334. };
  1335.  
  1336. /*
  1337. ============
  1338. ServerflagsCommand
  1339.  
  1340. Just for development
  1341. ============
  1342. */
  1343. void() ServerflagsCommand =
  1344. {
  1345.     serverflags = serverflags * 2 + 1;
  1346. };
  1347.  
  1348. void() QuadCheat =
  1349. {
  1350.     if (deathmatch || coop)
  1351.         return;
  1352.     self.super_time = 1;
  1353.     self.super_damage_finished = time + 30;
  1354.     self.items = self.items | IT_QUAD;
  1355.     dprint ("quad cheat\n");
  1356. };
  1357.  
  1358. /*
  1359. =======================
  1360. ThrowBackpack by Vhold
  1361. =======================
  1362. */
  1363. void() ThrowBackpack =
  1364. {
  1365.     local entity     item;
  1366.  
  1367.     if ( (self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells) == 0)
  1368.         return;
  1369.  
  1370.     item = spawn();
  1371.  
  1372.         if ( self.ammo_shells >= 20)
  1373.     {
  1374.         item.ammo_shells = 20;
  1375.         self.ammo_shells = self.ammo_shells - 20;
  1376.     }
  1377.     else
  1378.     {
  1379.         item.ammo_shells = self.ammo_shells;
  1380.         self.ammo_shells = 0;
  1381.     }
  1382.     
  1383.         if ( self.ammo_nails >= 20)
  1384.     {
  1385.         item.ammo_nails = 20;
  1386.                 self.ammo_nails = self.ammo_nails - 20;
  1387.     }
  1388.     else
  1389.     {
  1390.         item.ammo_nails = self.ammo_nails;
  1391.         self.ammo_nails = 0;
  1392.     }
  1393.  
  1394.     if ( self.ammo_rockets >= 10)
  1395.     {
  1396.         item.ammo_rockets = 10;
  1397.         self.ammo_rockets = self.ammo_rockets - 10;
  1398.     }
  1399.     else
  1400.     {
  1401.         item.ammo_rockets = self.ammo_rockets;
  1402.                 self.ammo_rockets = 0;
  1403.     }
  1404.  
  1405.     if (self.ammo_cells >= 20)
  1406.     {    
  1407.         item.ammo_cells = 20;
  1408.         self.ammo_cells = self.ammo_cells - 20;
  1409.     }
  1410.     else
  1411.     {
  1412.         item.ammo_cells = self.ammo_cells;
  1413.         self.ammo_cells = 0;
  1414.     }
  1415.  
  1416.     item.owner = self;
  1417.     makevectors(self.v_angle);
  1418.     setorigin(item, self.origin + '0 0 16');
  1419.     item.velocity = aim(self, 1000);
  1420.     item.velocity = item.velocity * 500;
  1421.     item.flags = FL_ITEM;
  1422.     item.solid = SOLID_TRIGGER;
  1423.     item.movetype = MOVETYPE_BOUNCE;
  1424.  
  1425.     setmodel (item, "progs/backpack.mdl");
  1426.     setsize(item, '-16 -16 0', '16 16 56');
  1427.     item.touch = BackpackTouch;
  1428.     item.nextthink = time + 120;    // remove after 2 minutes
  1429.     item.think = SUB_Remove;
  1430.  
  1431.     W_SetCurrentAmmo();
  1432. };
  1433. /*
  1434. ============
  1435. Det some pineapples ****
  1436. ============
  1437. */
  1438. void() DetGrenades =
  1439. {
  1440.         local entity    head;
  1441.  
  1442.         head = findradius (self.origin, 100000);
  1443.         while(head)
  1444.         {
  1445.                 if ( (head.classname == "grenade") && (head.owner == self) )
  1446.                         head.nextthink = time;
  1447.                 else if ( (head.classname == "rocket") && (head.owner == self) )
  1448.                 {
  1449.                         head.nextthink = time;
  1450.                         head.think = T_MissileTouch;
  1451.                 }
  1452.                 else if ( (head.classname == "arocket") && (head.owner == self) )
  1453.                 {
  1454.                         head.nextthink = time;
  1455.                         head.think = T_MissileTouch;
  1456.                 }
  1457.                 head = head.chain;
  1458.         }
  1459. };
  1460. /*
  1461. ============
  1462. ImpulseCommands
  1463.  
  1464. ============
  1465. */
  1466. void() ImpulseCommands =
  1467. {
  1468.     if (self.impulse >= 1 && self.impulse <= 8)
  1469.         W_ChangeWeapon ();
  1470.  
  1471.     if (self.impulse == 9)
  1472.         CheatCommand ();
  1473.     if (self.impulse == 10)
  1474.         CycleWeaponCommand ();
  1475.     if (self.impulse == 11)
  1476.         ServerflagsCommand ();
  1477.         // D&L's Fire proximity grenade
  1478.         if (self.impulse == 16)
  1479.                 W_FireAdv ();
  1480.     // Vhold's Backpack thing
  1481.     if (self.impulse == 20)
  1482.         ThrowBackpack();
  1483.         // D&L's Detonate grenades
  1484.         if (self.impulse == 26)
  1485.                 DetGrenades();
  1486.     if (self.impulse == 255)
  1487.         QuadCheat ();
  1488.         
  1489.     self.impulse = 0;
  1490. };
  1491.  
  1492. /*
  1493. ============
  1494. W_WeaponFrame
  1495.  
  1496. Called every frame so impulse events can be handled as well as possible
  1497. ============
  1498. */
  1499. void() W_WeaponFrame =
  1500. {
  1501.     if (time < self.attack_finished)
  1502.         return;
  1503.  
  1504.     ImpulseCommands ();
  1505.     
  1506. // check for attack
  1507.     if (self.button0)
  1508.     {
  1509.         SuperDamageSound ();
  1510.         W_Attack ();
  1511.     }
  1512. };
  1513.  
  1514. /*
  1515. ========
  1516. SuperDamageSound
  1517.  
  1518. Plays sound if needed
  1519. ========
  1520. */
  1521. void() SuperDamageSound =
  1522. {
  1523.     if (self.super_damage_finished > time)
  1524.     {
  1525.         if (self.super_sound < time)
  1526.         {
  1527.             self.super_sound = time + 1;
  1528.             sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
  1529.         }
  1530.     }
  1531.     return;
  1532. };
  1533.  
  1534.  
  1535.