Guest
Public paste!

Untitled

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