home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / godelqc3 / weapons.qc < prev    next >
Encoding:
Text File  |  1996-08-15  |  31.3 KB  |  1,406 lines

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