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