home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / patch / mbq089 / weapons.qc < prev    next >
Encoding:
Text File  |  1996-09-01  |  38.2 KB  |  1,812 lines

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