home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / mon_dm09 / weapons.qc < prev   
Encoding:
Text File  |  1996-08-20  |  21.8 KB  |  1,020 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_model ("progs/v_spike.mdl");
  12.         precache_sound ("shalrath/attack2.wav");
  13.         precache_sound ("shalrath/attack.wav");
  14.  
  15.         precache_sound ("shalrath/pain.wav");
  16.         precache_sound ("shalrath/death.wav");
  17.         precache_model ("progs/shalrath.mdl");
  18.         precache_sound ("hknight/attack1.wav");
  19.         precache_model ("progs/k_spike.mdl");
  20.         precache_model ("progs/hknight.mdl");
  21.         precache_sound ("hknight/death1.wav");
  22.         precache_sound ("hknight/pain1.wav");
  23.         precache_sound ("knight/sword2.wav");
  24.  
  25.         precache_sound ("enforcer/enfire.wav");
  26.         precache_sound ("enforcer/death1.wav");
  27.         precache_sound ("enforcer/pain1.wav");
  28.         precache_sound ("enforcer/enfstop.wav");
  29.         precache_model ("progs/laser.mdl");
  30.         precache_model ("progs/enforcer.mdl");
  31.         precache_sound ("demon/ddeath.wav");
  32.         precache_sound ("soldier/death1.wav");
  33.         precache_sound ("knight/kdeath.wav");
  34.         precache_sound ("wizard/wdeath.wav");
  35.         precache_sound ("ogre/ogdth.wav");
  36.  
  37.         precache_sound ("wizard/wpain.wav");
  38.         precache_sound ("wizard/wdeath.wav");
  39.         precache_sound ("wizard/wattack.wav");
  40.         precache_model ("progs/w_spike.mdl");
  41.         precache_sound ("ogre/ogsawatk.wav");
  42.         precache_sound ("ogre/ogpain1.wav");
  43.         precache_sound ("demon/dpain1.wav");
  44.         precache_sound ("demon/ddeath.wav");
  45.         precache_sound ("soldier/pain1.wav");
  46.         precache_sound ("soldier/death1.wav");
  47.         precache_sound ("knight/khurt.wav");
  48.         precache_sound ("knight/kdeath.wav");
  49.  
  50.         precache_model ("progs/ogre.mdl");
  51.         precache_model ("progs/wizard.mdl");
  52.         precache_model ("progs/soldier.mdl");
  53.         precache_sound ("demon/dhit2.wav");
  54.         precache_sound ("demon/djump.wav");
  55.         precache_model ("progs/demon.mdl");
  56.         precache_model ("progs/knight.mdl");
  57.         precache_sound ("knight/sword1.wav");
  58.     precache_sound ("weapons/r_exp3.wav");    // new rocket explosion
  59.     precache_sound ("weapons/rocket1i.wav");    // spike gun
  60.     precache_sound ("weapons/sgun1.wav");
  61.     precache_sound ("weapons/guncock.wav");    // player shotgun
  62.     precache_sound ("weapons/ric1.wav");    // ricochet (used in c code)
  63.     precache_sound ("weapons/ric2.wav");    // ricochet (used in c code)
  64.     precache_sound ("weapons/ric3.wav");    // ricochet (used in c code)
  65.     precache_sound ("weapons/tink1.wav");    // spikes tink (used in c code)
  66.     precache_sound ("weapons/grenade.wav");    // grenade launcher
  67.     precache_sound ("weapons/bounce.wav");        // grenade bounce
  68. };
  69.  
  70. float() crandom =
  71. {
  72.     return 2*(random() - 0.5);
  73. };
  74.  
  75. //============================================================================
  76.  
  77.  
  78. vector() wall_velocity =
  79. {
  80.     local vector    vel;
  81.     
  82.     vel = normalize (self.velocity);
  83.     vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
  84.     vel = vel + 2*trace_plane_normal;
  85.     vel = vel * 200;
  86.     
  87.     return vel;
  88. };
  89.  
  90.  
  91. /*
  92. ================
  93. SpawnMeatSpray
  94. ================
  95. */
  96. void(vector org, vector vel) SpawnMeatSpray =
  97. {
  98.     local    entity missile, mpuff;
  99.     local    vector    org;
  100.  
  101.     missile = spawn ();
  102.     missile.owner = self;
  103.     missile.movetype = MOVETYPE_BOUNCE;
  104.     missile.solid = SOLID_NOT;
  105.  
  106.     makevectors (self.angles);
  107.  
  108.     missile.velocity = vel;
  109.     missile.velocity_z = missile.velocity_z + 250 + 50*random();
  110.  
  111.     missile.avelocity = '3000 1000 2000';
  112.     
  113. // set missile duration
  114.     missile.nextthink = time + 1;
  115.     missile.think = SUB_Remove;
  116.  
  117.     setmodel (missile, "progs/zom_gib.mdl");
  118.     setsize (missile, '0 0 0', '0 0 0');        
  119.     setorigin (missile, org);
  120. };
  121.  
  122. /*
  123. ================
  124. SpawnBlood
  125. ================
  126. */
  127. void(vector org, vector vel, float damage) SpawnBlood =
  128. {
  129.     particle (org, vel*0.1, 73, damage*2);
  130. };
  131.  
  132. /*
  133. ================
  134. spawn_touchblood
  135. ================
  136. */
  137. void(float damage) spawn_touchblood =
  138. {
  139.     local vector    vel;
  140.  
  141.     vel = wall_velocity () * 0.2;
  142.     SpawnBlood (self.origin + vel*0.01, vel, damage);
  143. };
  144.  
  145.  
  146. /*
  147. ================
  148. SpawnChunk
  149. ================
  150. */
  151. void(vector org, vector vel) SpawnChunk =
  152. {
  153.     particle (org, vel*0.02, 0, 10);
  154. };
  155.  
  156. /*
  157. ==============================================================================
  158.  
  159. MULTI-DAMAGE
  160.  
  161. Collects multiple small damages into a single damage
  162.  
  163. ==============================================================================
  164. */
  165.  
  166. entity    multi_ent;
  167. float    multi_damage;
  168.  
  169. void() ClearMultiDamage =
  170. {
  171.     multi_ent = world;
  172.     multi_damage = 0;
  173. };
  174.  
  175. void() ApplyMultiDamage =
  176. {
  177.     if (!multi_ent)
  178.         return;
  179.     T_Damage (multi_ent, self, self, multi_damage);
  180. };
  181.  
  182. void(entity hit, float damage) AddMultiDamage =
  183. {
  184.     if (!hit)
  185.         return;
  186.     
  187.     if (hit != multi_ent)
  188.     {
  189.         ApplyMultiDamage ();
  190.         multi_damage = damage;
  191.         multi_ent = hit;
  192.     }
  193.     else
  194.         multi_damage = multi_damage + damage;
  195. };
  196.  
  197. /*
  198. ==============================================================================
  199.  
  200. BULLETS
  201.  
  202. ==============================================================================
  203. */
  204.  
  205. /*
  206. ================
  207. TraceAttack
  208. ================
  209. */
  210. void(float damage, vector dir) TraceAttack =
  211. {
  212.     local    vector    vel, org;
  213.     
  214.     vel = normalize(dir + v_up*crandom() + v_right*crandom());
  215.     vel = vel + 2*trace_plane_normal;
  216.     vel = vel * 200;
  217.  
  218.     org = trace_endpos - dir*4;
  219.  
  220.     if (trace_ent.takedamage)
  221.     {
  222.         SpawnBlood (org, vel*0.2, damage);
  223.         AddMultiDamage (trace_ent, damage);
  224.     }
  225.     else
  226.     {
  227.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  228.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  229.         WriteCoord (MSG_BROADCAST, org_x);
  230.         WriteCoord (MSG_BROADCAST, org_y);
  231.         WriteCoord (MSG_BROADCAST, org_z);
  232.     }
  233. };
  234.  
  235. /*
  236. ================
  237. FireBullets
  238.  
  239. Used by shotgun, super shotgun, and enemy soldier firing
  240. Go to the trouble of combining multiple pellets into a single damage call.
  241. ================
  242. */
  243. void(float shotcount, vector dir, vector spread) FireBullets =
  244. {
  245.     local    vector direction;
  246.     local    vector    src;
  247.     
  248.     makevectors(self.v_angle);
  249.  
  250.     src = self.origin + v_forward*10;
  251.     src_z = self.absmin_z + self.size_z * 0.7;
  252.  
  253.     ClearMultiDamage ();
  254.     while (shotcount > 0)
  255.     {
  256.         direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
  257.  
  258.         traceline (src, src + direction*2048, FALSE, self);
  259.         if (trace_fraction != 1.0)
  260.             TraceAttack (4, direction);
  261.  
  262.         shotcount = shotcount - 1;
  263.     }
  264.     ApplyMultiDamage ();
  265. };
  266.  
  267.  
  268. //=============================================================================
  269.  
  270. void()    s_explode1    =    [0,        s_explode2] {};
  271. void()    s_explode2    =    [1,        s_explode3] {};
  272. void()    s_explode3    =    [2,        s_explode4] {};
  273. void()    s_explode4    =    [3,        s_explode5] {};
  274. void()    s_explode5    =    [4,        s_explode6] {};
  275. void()    s_explode6    =    [5,        SUB_Remove] {};
  276.  
  277. void() BecomeExplosion =
  278. {
  279.     self.movetype = MOVETYPE_NONE;
  280.     self.velocity = '0 0 0';
  281.     self.touch = SUB_Null;
  282.     setmodel (self, "progs/s_explod.spr");
  283.     self.solid = SOLID_NOT;
  284.     s_explode1 ();
  285. };
  286.  
  287. void() T_MissileTouch =
  288. {
  289.     local float    damg;
  290.  
  291.     if (other == self.owner)
  292.         return;        // don't explode on owner
  293.  
  294.     if (pointcontents(self.origin) == CONTENT_SKY)
  295.     {
  296.         remove(self);
  297.         return;
  298.     }
  299.  
  300.     damg = 100 + random()*20;
  301.     
  302.     if (other.health)
  303.     {
  304.         if (other.classname == "monster_shambler")
  305.             damg = damg * 0.5;    // mostly immune
  306.         T_Damage (other, self, self.owner, damg );
  307.     }
  308.  
  309.     // don't do radius damage to the other, because all the damage
  310.     // was done in the impact
  311.     T_RadiusDamage (self, self.owner, 120, other);
  312.  
  313. //    sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  314.     self.origin = self.origin - 8*normalize(self.velocity);
  315.  
  316.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  317.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  318.     WriteCoord (MSG_BROADCAST, self.origin_x);
  319.     WriteCoord (MSG_BROADCAST, self.origin_y);
  320.     WriteCoord (MSG_BROADCAST, self.origin_z);
  321.  
  322.     BecomeExplosion ();
  323. };
  324.  
  325. void() spike_touch;
  326.  
  327.  
  328. /*
  329. ===============
  330. launch_spike
  331.  
  332. Used for both the player and the ogre
  333. ===============
  334. */
  335. void(vector org, vector dir) launch_spike =
  336. {
  337.     newmis = spawn ();
  338.     newmis.owner = self;
  339.     newmis.movetype = MOVETYPE_FLYMISSILE;
  340.     newmis.solid = SOLID_BBOX;
  341.  
  342.     newmis.angles = vectoangles(dir);
  343.     
  344.     newmis.touch = spike_touch;
  345.     newmis.classname = "spike";
  346.     newmis.think = SUB_Remove;
  347.     newmis.nextthink = time + 6;
  348.     setmodel (newmis, "progs/spike.mdl");
  349.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  350.     setorigin (newmis, org);
  351.  
  352.     newmis.velocity = dir * 1000;
  353. };
  354.  
  355. void(float ox) W_FireSpikes =
  356. {
  357.     local vector    dir;
  358.     local entity    old;
  359.     
  360.     makevectors (self.v_angle);
  361.     
  362.  
  363.     if (self.ammo_nails < 1)
  364.     {
  365.         W_SetCurrentAmmo ();
  366.         return;
  367.     }
  368.  
  369.     sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  370.     self.attack_finished = time + 0.2;
  371.     self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  372.     dir = aim (self, 1000);
  373.     launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
  374.  
  375.     self.punchangle_x = -2;
  376. };
  377.  
  378.  
  379.  
  380. .float hit_z;
  381. void() spike_touch =
  382. {
  383. local float rand;
  384.     if (other == self.owner)
  385.         return;
  386.  
  387.     if (other.solid == SOLID_TRIGGER)
  388.         return;    // trigger field, do nothing
  389.  
  390.     if (pointcontents(self.origin) == CONTENT_SKY)
  391.     {
  392.         remove(self);
  393.         return;
  394.     }
  395.     
  396. // hit something that bleeds
  397.     if (other.takedamage)
  398.     {
  399.         spawn_touchblood (9);
  400.         T_Damage (other, self, self.owner, 9);
  401.     }
  402.     else
  403.     {
  404.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  405.         
  406.         if (self.classname == "wizspike")
  407.             WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
  408.         else if (self.classname == "knightspike")
  409.             WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
  410.         else
  411.             WriteByte (MSG_BROADCAST, TE_SPIKE);
  412.         WriteCoord (MSG_BROADCAST, self.origin_x);
  413.         WriteCoord (MSG_BROADCAST, self.origin_y);
  414.         WriteCoord (MSG_BROADCAST, self.origin_z);
  415.     }
  416.  
  417.     remove(self);
  418.  
  419. };
  420. void() superspike_touch =
  421. {
  422. local float rand;
  423.     if (other == self.owner)
  424.         return;
  425.  
  426.     if (other.solid == SOLID_TRIGGER)
  427.         return;    // trigger field, do nothing
  428.  
  429.     if (pointcontents(self.origin) == CONTENT_SKY)
  430.     {
  431.         remove(self);
  432.         return;
  433.     }
  434.     
  435. // hit something that bleeds
  436.     if (other.takedamage)
  437.     {
  438.         spawn_touchblood (18);
  439.         T_Damage (other, self, self.owner, 18);
  440.     }
  441.     else
  442.     {
  443.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  444.         WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
  445.         WriteCoord (MSG_BROADCAST, self.origin_x);
  446.         WriteCoord (MSG_BROADCAST, self.origin_y);
  447.         WriteCoord (MSG_BROADCAST, self.origin_z);
  448.     }
  449.  
  450.     remove(self);
  451.  
  452. };
  453.  
  454.  
  455. /*
  456. ===============
  457. launch_magic  (Scrag)
  458. ===============
  459. */
  460. void(vector org, vector dir) launch_magic =
  461. {
  462.     newmis = spawn ();
  463.     newmis.owner = self;
  464.     newmis.movetype = MOVETYPE_FLYMISSILE;
  465.     newmis.solid = SOLID_BBOX;
  466.  
  467.     newmis.angles = vectoangles(dir);
  468.     
  469.     newmis.touch = spike_touch;
  470.         newmis.classname = "wizspike";
  471.     newmis.think = SUB_Remove;
  472.     newmis.nextthink = time + 6;
  473.         setmodel (newmis, "progs/w_spike.mdl");
  474.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  475.     setorigin (newmis, org);
  476.  
  477.         newmis.velocity = dir * 1400;
  478. };
  479.  
  480. void(vector arm) FireMagic =
  481. {
  482.         local vector    dir, arm;
  483.     local entity    old;
  484.     
  485.     makevectors (self.v_angle);
  486.     
  487.     self.attack_finished = time + 0.2;
  488.     dir = aim (self, 1000);
  489.         launch_magic (self.origin + arm, dir);
  490.  
  491.     self.punchangle_x = -2;
  492. };
  493.  
  494.  
  495.  
  496. .float hit_z;
  497. void() magic_touch =
  498. {
  499. local float rand;
  500.     if (other == self.owner)
  501.         return;
  502.  
  503.     if (other.solid == SOLID_TRIGGER)
  504.         return;    // trigger field, do nothing
  505.  
  506.     if (pointcontents(self.origin) == CONTENT_SKY)
  507.     {
  508.         remove(self);
  509.         return;
  510.     }
  511.     
  512. // hit something that bleeds
  513.     if (other.takedamage)
  514.     {
  515.         spawn_touchblood (9);
  516.         T_Damage (other, self, self.owner, 9);
  517.     }
  518.     else
  519.     {
  520.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  521.         
  522.             WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
  523.         WriteCoord (MSG_BROADCAST, self.origin_x);
  524.         WriteCoord (MSG_BROADCAST, self.origin_y);
  525.         WriteCoord (MSG_BROADCAST, self.origin_z);
  526.     }
  527.  
  528.     remove(self);
  529.  
  530. };
  531. void() laser_touch;
  532.  
  533. /*
  534. ===============
  535. launch_laser    (Enforcer)
  536.  
  537. ===============
  538. */
  539. void(vector org, vector dir) launch_laser =
  540. {
  541.     newmis = spawn ();
  542.     newmis.owner = self;
  543.     newmis.movetype = MOVETYPE_FLYMISSILE;
  544.     newmis.solid = SOLID_BBOX;
  545.  
  546.     newmis.angles = vectoangles(dir);
  547.     
  548.         newmis.touch = laser_touch;
  549.         newmis.classname = "spike";
  550.     newmis.think = SUB_Remove;
  551.     newmis.nextthink = time + 6;
  552.         setmodel (newmis, "progs/laser.mdl");
  553.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  554.     setorigin (newmis, org);
  555.  
  556.         newmis.velocity = dir * 2000;
  557. };
  558.  
  559. void() FireLaser =
  560. {
  561.         local vector    dir, arm;
  562.     local entity    old;
  563.     
  564.     makevectors (self.v_angle);
  565.     
  566.     self.attack_finished = time + 0.2;
  567.     dir = aim (self, 1000);
  568.         sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
  569.         launch_laser (self.origin + '0 0 16', dir);
  570.  
  571.         self.punchangle_x = -3;
  572. };
  573.  
  574.  
  575.  
  576. .float hit_z;
  577. void() laser_touch =
  578. {
  579. local float rand;
  580.     if (other == self.owner)
  581.         return;
  582.  
  583.     if (other.solid == SOLID_TRIGGER)
  584.         return;    // trigger field, do nothing
  585.  
  586.     if (pointcontents(self.origin) == CONTENT_SKY)
  587.     {
  588.         remove(self);
  589.         return;
  590.     }
  591.  
  592.     sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC);
  593.  
  594.   // hit something that bleeds
  595.     if (other.takedamage)
  596.     {
  597.                 spawn_touchblood (15);
  598.                 T_Damage (other, self, self.owner, 15);
  599.     }
  600.     else
  601.     {
  602.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  603.         
  604.                         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  605.         WriteCoord (MSG_BROADCAST, self.origin_x);
  606.         WriteCoord (MSG_BROADCAST, self.origin_y);
  607.         WriteCoord (MSG_BROADCAST, self.origin_z);
  608.     }
  609.  
  610.     remove(self);
  611.  
  612. };
  613. /*
  614. ===============================================================================
  615.  
  616. LIGHTNING
  617.  
  618. ===============================================================================
  619. */
  620.  
  621. /*
  622. =================
  623. LightningDamage
  624. =================
  625. */
  626. void(vector p1, vector p2, entity from, float damage) LightningDamage =
  627. {
  628.     local entity        e1, e2;
  629.     local vector        f;
  630.     
  631.     f = p2 - p1;
  632.     normalize (f);
  633.     f_x = 0 - f_y;
  634.     f_y = f_x;
  635.     f_z = 0;
  636.     f = f*16;
  637.  
  638.     e1 = e2 = world;
  639.  
  640.     traceline (p1, p2, FALSE, self);
  641.     if (trace_ent.takedamage)
  642.     {
  643.         particle (trace_endpos, '0 0 100', 225, damage*4);
  644.         T_Damage (trace_ent, from, from, damage);
  645.         if (self.classname == "player")
  646.         {
  647.             if (other.classname == "player")
  648.                 trace_ent.velocity_z = trace_ent.velocity_z + 400;
  649.         }
  650.     }
  651.     e1 = trace_ent;
  652.  
  653.     traceline (p1 + f, p2 + f, FALSE, self);
  654.     if (trace_ent != e1 && trace_ent.takedamage)
  655.     {
  656.         particle (trace_endpos, '0 0 100', 225, damage*4);
  657.         T_Damage (trace_ent, from, from, damage);
  658.     }
  659.     e2 = trace_ent;
  660.  
  661.     traceline (p1 - f, p2 - f, FALSE, self);
  662.     if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
  663.     {
  664.         particle (trace_endpos, '0 0 100', 225, damage*4);
  665.         T_Damage (trace_ent, from, from, damage);
  666.     }
  667. };
  668.  
  669.  
  670. void() W_FireLightning =
  671. {
  672.     local    vector        org;
  673.  
  674.     if (self.ammo_cells < 1)
  675.     {
  676.         self.weapon = W_BestWeapon ();
  677.         W_SetCurrentAmmo ();
  678.         return;
  679.     }
  680.  
  681. // explode if under water
  682.     if (self.waterlevel > 1)
  683.     {
  684.         T_RadiusDamage (self, self, 35*self.ammo_cells, world);
  685.         self.ammo_cells = 0;
  686.         W_SetCurrentAmmo ();
  687.         return;
  688.     }
  689.  
  690.     if (self.t_width < time)
  691.     {
  692.         sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  693.         self.t_width = time + 0.6;
  694.     }
  695.     self.punchangle_x = -2;
  696.  
  697.     self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  698.  
  699.     org = self.origin + '0 0 16';
  700.     
  701.     traceline (org, org + v_forward*600, TRUE, self);
  702.  
  703.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  704.     WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  705.     WriteEntity (MSG_BROADCAST, self);
  706.     WriteCoord (MSG_BROADCAST, org_x);
  707.     WriteCoord (MSG_BROADCAST, org_y);
  708.     WriteCoord (MSG_BROADCAST, org_z);
  709.     WriteCoord (MSG_BROADCAST, trace_endpos_x);
  710.     WriteCoord (MSG_BROADCAST, trace_endpos_y);
  711.     WriteCoord (MSG_BROADCAST, trace_endpos_z);
  712.  
  713.     LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
  714. };
  715.  
  716.  
  717.  
  718.  
  719. /*
  720. ===============================================================================
  721.  
  722. PLAYER WEAPON USE
  723.  
  724. ===============================================================================
  725. */
  726.  
  727. void() W_SetCurrentAmmo =
  728. {
  729.     player_run ();        // get out of any weapon firing states
  730.  
  731.         if (self.effects & EF_WIZARD)
  732.         {
  733.         self.currentammo = 0;
  734.                 self.weaponmodel = "";
  735.         self.weaponframe = 0;
  736.         }
  737.         else if (self.effects & EF_DEMON)
  738.         {
  739.         self.currentammo = 0;
  740.                 self.weaponmodel = "";
  741.         self.weaponframe = 0;
  742.         }
  743.         else if (self.effects & EF_GRUNT)
  744.         {
  745.                 self.currentammo = 0;
  746.                 self.weaponmodel = "progs/v_shot.mdl";
  747.                 self.weaponframe = 0;
  748.         }
  749.         else if (self.effects & EF_ENFORCER)
  750.         {
  751.                 self.currentammo = 0;
  752.                 self.weaponmodel = "progs/v_nail2.mdl";
  753.                 self.weaponframe = 0;
  754.         }
  755.         else if (self.effects & EF_KNIGHT)
  756.         {
  757.                 self.currentammo = 0;
  758.                 self.weaponmodel = "progs/v_axe.mdl";
  759.                 self.weaponframe = 0;
  760.         }
  761.         else if (self.effects & EF_HKNIGHT)
  762.         {
  763.                 self.currentammo = 0;
  764.                 self.weaponmodel = "progs/v_axe.mdl";
  765.                 self.weaponframe = 0;
  766.         }
  767.         else if (self.effects & EF_OGRE)
  768.         {
  769.                 self.currentammo = 0;
  770.                 self.weaponmodel = "progs/v_rock.mdl";
  771.                 self.weaponframe = 0;
  772.         }
  773.  
  774.         else
  775.     {
  776.         self.currentammo = 0;
  777.                 self.weaponmodel = "";
  778.         self.weaponframe = 0;
  779.     }
  780. };
  781.  
  782. float() W_BestWeapon =
  783. {
  784.     return IT_AXE;
  785. };
  786.  
  787.  
  788. float() W_CheckNoAmmo =
  789. {
  790.     if (self.currentammo > 0)
  791.         return TRUE;
  792.  
  793.     if (self.weapon == IT_AXE)
  794.         return TRUE;
  795.     
  796.     W_SetCurrentAmmo ();
  797.     
  798. // drop the weapon down
  799.     return FALSE;
  800. };
  801.  
  802. /*
  803. ============
  804. W_Attack
  805.  
  806. An attack impulse can be triggered now
  807. ============
  808. */
  809. void()  player_dattack;
  810. void()  player_gattack;
  811. void() player_kattack;
  812. void() player_oattack;
  813. void() player_ogren;
  814. void() player_wattack;
  815. void() player_eattack;
  816. void() player_hkattack;
  817. void() player_hksword;
  818. void() player_sattack;
  819.  
  820.  
  821. void() W_Attack =
  822. {
  823.     local    float    r;
  824.  
  825.     makevectors    (self.v_angle);            // calculate forward angle for velocity
  826.     self.show_hostile = time + 1;    // wake monsters up
  827.  
  828.         if (self.effects & EF_DEMON)
  829.         {
  830.                 player_dattack();
  831.                 self.attack_finished = time + 1.0;
  832.         }
  833.         else if (self.effects & EF_WIZARD)
  834.         {
  835.                 player_wattack();
  836.                 self.attack_finished = time + 1.9;
  837.         }
  838.         else if (self.effects & EF_SHALRATH)
  839.         {
  840.                 player_sattack();
  841.                 self.attack_finished = time + 2.0;
  842.         }
  843.         else if (self.effects & EF_GRUNT)
  844.         {
  845.                 player_gattack();
  846.                 self.attack_finished = time + 0.7;
  847.         }
  848.         else if (self.effects & EF_ENFORCER)
  849.         {
  850.                 player_eattack();
  851.                 self.attack_finished = time + 0.5;
  852.         }
  853.         else if (self.effects & EF_KNIGHT)
  854.         {
  855.                 player_kattack();
  856.                 self.attack_finished = time + 1.0;
  857.         }
  858.         else if (self.effects & EF_HKNIGHT)
  859.         {
  860.                 player_hksword();
  861.                 self.attack_finished = time + 1.0;
  862.         }
  863.         else if (self.effects & EF_OGRE)
  864.         {
  865.                 player_oattack();
  866.                 self.attack_finished = time + 1.0;
  867.         }
  868. };
  869.  
  870. /*
  871. ============
  872. W_ChangeWeapon
  873.  
  874. ============
  875. */
  876. void() W_ChangeWeapon =
  877. {
  878. return;     // don't need it
  879. };
  880.  
  881. /*
  882. ============
  883. CheatCommand
  884. ============
  885. */
  886. void() CheatCommand =
  887. {
  888.     if (deathmatch || coop)
  889.         return;
  890.  
  891.     self.items = self.items | IT_KEY1 | IT_KEY2;
  892.     self.impulse = 0;
  893.     W_SetCurrentAmmo ();
  894. };
  895.  
  896. /*
  897. ============
  898. CycleWeaponCommand
  899.  
  900. Go to the next weapon with ammo
  901. ============
  902. */
  903. void() CycleWeaponCommand =
  904. {
  905. return; 
  906. };
  907.  
  908. /*
  909. ============
  910. ServerflagsCommand
  911.  
  912. Just for development
  913. ============
  914. */
  915. void() ServerflagsCommand =
  916. {
  917.     serverflags = serverflags * 2 + 1;
  918. };
  919.  
  920. void() QuadCheat =
  921. {
  922.     if (deathmatch || coop)
  923.         return;
  924.     self.super_time = 1;
  925.     self.super_damage_finished = time + 30;
  926.     self.items = self.items | IT_QUAD;
  927.     dprint ("quad cheat\n");
  928. };
  929.  
  930. /*
  931. ==================
  932. FireAlternate
  933. ==================
  934. */
  935. void() FireAlternate =
  936. {
  937.         if(self.effects & EF_OGRE)
  938.     {
  939.                 player_ogren();
  940.         self.attack_finished = time + 1.0;        
  941.     }
  942.         else if(self.effects & EF_HKNIGHT)
  943.     {
  944.                 player_hkattack();
  945.         self.attack_finished = time + 1.0;        
  946.     }
  947.      
  948. };
  949.  
  950.  
  951. /*
  952. ============
  953. ImpulseCommands
  954.  
  955. ============
  956. */
  957. void() ImpulseCommands =
  958. {
  959.     if (self.impulse >= 1 && self.impulse <= 8)
  960.         W_ChangeWeapon ();
  961.  
  962.     if (self.impulse == 9)
  963.         CheatCommand ();
  964.     if (self.impulse == 11)
  965.         ServerflagsCommand ();
  966.  
  967.         if (self.impulse == 20)
  968.                 FireAlternate();
  969.  
  970.     if (self.impulse == 255)
  971.         QuadCheat ();
  972.         
  973.     self.impulse = 0;
  974. };
  975.  
  976. /*
  977. ============
  978. W_WeaponFrame
  979.  
  980. Called every frame so impulse events can be handled as well as possible
  981. ============
  982. */
  983. void() W_WeaponFrame =
  984. {
  985.     if (time < self.attack_finished)
  986.         return;
  987.  
  988.     ImpulseCommands ();
  989.     
  990. // check for attack
  991.     if (self.button0)
  992.     {
  993.         SuperDamageSound ();
  994.         W_Attack ();
  995.     }
  996. };
  997.  
  998. /*
  999. ========
  1000. SuperDamageSound
  1001.  
  1002. Plays sound if needed
  1003. ========
  1004. */
  1005. void() SuperDamageSound =
  1006. {
  1007.     if (self.super_damage_finished > time)
  1008.     {
  1009.         if (self.super_sound < time)
  1010.         {
  1011.             self.super_sound = time + 1;
  1012.             sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
  1013.         }
  1014.     }
  1015.     return;
  1016. };
  1017.  
  1018.  
  1019.  
  1020.