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