home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1997 January / CD_shareware_1-97.iso / DOS / JUEGOS / CHASEROC.ZIP / WEAPONS.QC < prev   
Encoding:
Text File  |  1996-09-30  |  49.4 KB  |  2,310 lines

  1. /*
  2. */
  3. void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
  4. void () player_run;
  5. void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
  6. void(vector org, vector vel, float damage) SpawnBlood;
  7. void() SuperDamageSound;
  8.  
  9. /*
  10.    #####################
  11.    ### chase cam mod ###
  12. (start date, more new functions, also lines added in client.qc
  13. they all are seperated with blank lines and have // ### chase cam mod ###
  14. lines above them)
  15. Rob Albin, 09 Sep 96
  16. orig functions modified:
  17.      none
  18. orig functions with added code:
  19.     void() W_SetCurrentAmmo =
  20.     void() ImpulseCommands =
  21. new functions:
  22.     void() Start_chase_cam =
  23.     void() Remove_chase_cam =
  24.     void() Keep_cam_chasing_owner =
  25.     void() Toggle_chase_cam =
  26. */
  27.  
  28. // message protocol defines
  29. float SVC_SETVIEWPORT    = 5;
  30. float SVC_SETVIEWANGLES    = 10;
  31.  
  32. // free player entity variable
  33. // '.float speed'  bit-flag defines:
  34. float GUIDEDMIS_ON  = 16;
  35. float CHSCAM_ALT    = 8;
  36. float CHSCAM_ON     = 4;
  37. float LASERTARG_LIT = 2;
  38. float LASERTARG_ON  = 1;
  39.  
  40. // #####################
  41.  
  42.  
  43. // called by worldspawn
  44. void() W_Precache =
  45. {
  46.     precache_sound ("weapons/r_exp3.wav");    // new rocket explosion
  47.     precache_sound ("weapons/rocket1i.wav");    // spike gun
  48.     precache_sound ("weapons/sgun1.wav");
  49.     precache_sound ("weapons/guncock.wav");    // player shotgun
  50.     precache_sound ("weapons/ric1.wav");    // ricochet (used in c code)
  51.     precache_sound ("weapons/ric2.wav");    // ricochet (used in c code)
  52.     precache_sound ("weapons/ric3.wav");    // ricochet (used in c code)
  53.     precache_sound ("weapons/spike2.wav");    // super spikes
  54.     precache_sound ("weapons/tink1.wav");    // spikes tink (used in c code)
  55.     precache_sound ("weapons/grenade.wav");    // grenade launcher
  56.     precache_sound ("weapons/bounce.wav");        // grenade bounce
  57.     precache_sound ("weapons/shotgn2.wav");    // super shotgun
  58. };
  59.  
  60. float() crandom =
  61. {
  62.     return 2*(random() - 0.5);
  63. };
  64.  
  65. /*
  66. ================
  67. W_FireAxe
  68. ================
  69. */
  70. void() W_FireAxe =
  71. {
  72.     local    vector    source;
  73.     local    vector    org;
  74.  
  75.     makevectors (self.v_angle);
  76.     source = self.origin + '0 0 16';
  77.     traceline (source, source + v_forward*64, FALSE, self);
  78.     if (trace_fraction == 1.0)
  79.         return;
  80.     
  81.     org = trace_endpos - v_forward*4;
  82.  
  83.     if (trace_ent.takedamage)
  84.     {
  85.         trace_ent.axhitme = 1;
  86.         SpawnBlood (org, '0 0 0', 20);
  87.         T_Damage (trace_ent, self, self, 20);
  88.     }
  89.     else
  90.     {    // hit wall
  91.         sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  92.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  93.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  94.         WriteCoord (MSG_BROADCAST, org_x);
  95.         WriteCoord (MSG_BROADCAST, org_y);
  96.         WriteCoord (MSG_BROADCAST, org_z);
  97.     }
  98. };
  99.  
  100.  
  101. //============================================================================
  102.  
  103.  
  104. vector() wall_velocity =
  105. {
  106.     local vector    vel;
  107.     
  108.     vel = normalize (self.velocity);
  109.     vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
  110.     vel = vel + 2*trace_plane_normal;
  111.     vel = vel * 200;
  112.     
  113.     return vel;
  114. };
  115.  
  116.  
  117. /*
  118. ================
  119. SpawnMeatSpray
  120. ================
  121. */
  122. void(vector org, vector vel) SpawnMeatSpray =
  123. {
  124.     local    entity missile, mpuff;
  125.     local    vector    org;
  126.  
  127.     missile = spawn ();
  128.     missile.owner = self;
  129.     missile.movetype = MOVETYPE_BOUNCE;
  130.     missile.solid = SOLID_NOT;
  131.  
  132.     makevectors (self.angles);
  133.  
  134.     missile.velocity = vel;
  135.     missile.velocity_z = missile.velocity_z + 250 + 50*random();
  136.  
  137.     missile.avelocity = '3000 1000 2000';
  138.     
  139. // set missile duration
  140.     missile.nextthink = time + 1;
  141.     missile.think = SUB_Remove;
  142.  
  143.     setmodel (missile, "progs/zom_gib.mdl");
  144.     setsize (missile, '0 0 0', '0 0 0');        
  145.     setorigin (missile, org);
  146. };
  147.  
  148. /*
  149. ================
  150. SpawnBlood
  151. ================
  152. */
  153. void(vector org, vector vel, float damage) SpawnBlood =
  154. {
  155.     particle (org, vel*0.1, 73, damage*2);
  156. };
  157.  
  158. /*
  159. ================
  160. spawn_touchblood
  161. ================
  162. */
  163. void(float damage) spawn_touchblood =
  164. {
  165.     local vector    vel;
  166.  
  167.     vel = wall_velocity () * 0.2;
  168.     SpawnBlood (self.origin + vel*0.01, vel, damage);
  169. };
  170.  
  171.  
  172. /*
  173. ================
  174. SpawnChunk
  175. ================
  176. */
  177. void(vector org, vector vel) SpawnChunk =
  178. {
  179.     particle (org, vel*0.02, 0, 10);
  180. };
  181.  
  182. /*
  183. ==============================================================================
  184.  
  185. MULTI-DAMAGE
  186.  
  187. Collects multiple small damages into a single damage
  188.  
  189. ==============================================================================
  190. */
  191.  
  192. entity    multi_ent;
  193. float    multi_damage;
  194.  
  195. void() ClearMultiDamage =
  196. {
  197.     multi_ent = world;
  198.     multi_damage = 0;
  199. };
  200.  
  201. void() ApplyMultiDamage =
  202. {
  203.     if (!multi_ent)
  204.         return;
  205.     T_Damage (multi_ent, self, self, multi_damage);
  206. };
  207.  
  208. void(entity hit, float damage) AddMultiDamage =
  209. {
  210.     if (!hit)
  211.         return;
  212.     
  213.     if (hit != multi_ent)
  214.     {
  215.         ApplyMultiDamage ();
  216.         multi_damage = damage;
  217.         multi_ent = hit;
  218.     }
  219.     else
  220.         multi_damage = multi_damage + damage;
  221. };
  222.  
  223. /*
  224. ==============================================================================
  225.  
  226. BULLETS
  227.  
  228. ==============================================================================
  229. */
  230.  
  231. /*
  232. ================
  233. TraceAttack
  234. ================
  235. */
  236. void(float damage, vector dir) TraceAttack =
  237. {
  238.     local    vector    vel, org;
  239.     
  240.     vel = normalize(dir + v_up*crandom() + v_right*crandom());
  241.     vel = vel + 2*trace_plane_normal;
  242.     vel = vel * 200;
  243.  
  244.     org = trace_endpos - dir*4;
  245.  
  246.     if (trace_ent.takedamage)
  247.     {
  248.         SpawnBlood (org, vel*0.2, damage);
  249.         AddMultiDamage (trace_ent, damage);
  250.     }
  251.     else
  252.     {
  253.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  254.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  255.         WriteCoord (MSG_BROADCAST, org_x);
  256.         WriteCoord (MSG_BROADCAST, org_y);
  257.         WriteCoord (MSG_BROADCAST, org_z);
  258.     }
  259. };
  260.  
  261. /*
  262. ================
  263. FireBullets
  264.  
  265. Used by shotgun, super shotgun, and enemy soldier firing
  266. Go to the trouble of combining multiple pellets into a single damage call.
  267. ================
  268. */
  269. void(float shotcount, vector dir, vector spread) FireBullets =
  270. {
  271.     local    vector direction;
  272.     local    vector    src;
  273.     
  274.     makevectors(self.v_angle);
  275.  
  276.     src = self.origin + v_forward*10;
  277.     src_z = self.absmin_z + self.size_z * 0.7;
  278.  
  279.     ClearMultiDamage ();
  280.     while (shotcount > 0)
  281.     {
  282.         direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
  283.  
  284.         traceline (src, src + direction*2048, FALSE, self);
  285.         if (trace_fraction != 1.0)
  286.             TraceAttack (4, direction);
  287.  
  288.         shotcount = shotcount - 1;
  289.     }
  290.     ApplyMultiDamage ();
  291. };
  292.  
  293. /*
  294. ================
  295. W_FireShotgun
  296. ================
  297. */
  298. void() W_FireShotgun =
  299. {
  300.     local vector dir;
  301.  
  302.     sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);    
  303.  
  304.     self.punchangle_x = -2;
  305.     
  306.     self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  307.     dir = aim (self, 100000);
  308.     FireBullets (6, dir, '0.04 0.04 0');
  309. };
  310.  
  311.  
  312. /*
  313. ================
  314. W_FireSuperShotgun
  315. ================
  316. */
  317. void() W_FireSuperShotgun =
  318. {
  319.     local vector dir;
  320.  
  321.     if (self.currentammo == 1)
  322.     {
  323.         W_FireShotgun ();
  324.         return;
  325.     }
  326.         
  327.     sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);    
  328.  
  329.     self.punchangle_x = -4;
  330.     
  331.     self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  332.     dir = aim (self, 100000);
  333.     FireBullets (14, dir, '0.14 0.08 0');
  334. };
  335.  
  336.  
  337. /*
  338. ==============================================================================
  339.  
  340. ROCKETS
  341.  
  342. ==============================================================================
  343. */
  344.  
  345. void()    s_explode1    =    [0,        s_explode2] {};
  346. void()    s_explode2    =    [1,        s_explode3] {};
  347. void()    s_explode3    =    [2,        s_explode4] {};
  348. void()    s_explode4    =    [3,        s_explode5] {};
  349. void()    s_explode5    =    [4,        s_explode6] {};
  350. void()    s_explode6    =    [5,        SUB_Remove] {};
  351.  
  352. void() BecomeExplosion =
  353. {
  354.     self.movetype = MOVETYPE_NONE;
  355.     self.velocity = '0 0 0';
  356.     self.touch = SUB_Null;
  357.     setmodel (self, "progs/s_explod.spr");
  358.     self.solid = SOLID_NOT;
  359.     s_explode1 ();
  360. };
  361.  
  362. void() T_MissileTouch =
  363. {
  364.     local float    damg;
  365.  
  366.     if (other == self.owner)
  367.         return;        // don't explode on owner
  368.  
  369.     if (pointcontents(self.origin) == CONTENT_SKY)
  370.     {
  371.         remove(self);
  372.         return;
  373.     }
  374.  
  375.     damg = 100 + random()*20;
  376.     
  377.     if (other.health)
  378.     {
  379.         if (other.classname == "monster_shambler")
  380.             damg = damg * 0.5;    // mostly immune
  381.         T_Damage (other, self, self.owner, damg );
  382.     }
  383.  
  384.     // don't do radius damage to the other, because all the damage
  385.     // was done in the impact
  386.     T_RadiusDamage (self, self.owner, 120, other);
  387.  
  388. //    sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  389.     self.origin = self.origin - 8*normalize(self.velocity);
  390.  
  391.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  392.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  393.     WriteCoord (MSG_BROADCAST, self.origin_x);
  394.     WriteCoord (MSG_BROADCAST, self.origin_y);
  395.     WriteCoord (MSG_BROADCAST, self.origin_z);
  396.  
  397.     BecomeExplosion ();
  398. };
  399.  
  400.  
  401.  
  402. /*
  403. ================
  404. W_FireRocket
  405. ================
  406. */
  407.  
  408. /*
  409. // ##########################
  410. // ### Guided missile mod ###
  411. // Rob Albin, 29 Sep 96
  412.  
  413.    modified original functions:
  414.       void() W_FireRocket =
  415.       void() W_Attack =
  416. */
  417.  
  418.  
  419. // original W_FireRocket() function...
  420. /*
  421. void() W_FireRocket =
  422. {
  423.     local    entity missile, mpuff;
  424.     
  425.     self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  426.     
  427.     sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  428.  
  429.     self.punchangle_x = -2;
  430.  
  431.     missile = spawn ();
  432.     missile.owner = self;
  433.     missile.movetype = MOVETYPE_FLYMISSILE;
  434.     missile.solid = SOLID_BBOX;
  435.     missile.classname = "missile";
  436.         
  437. // set missile speed    
  438.  
  439.     makevectors (self.v_angle);
  440.     missile.velocity = aim(self, 1000);
  441.     missile.velocity = missile.velocity * 1000;
  442.     missile.angles = vectoangles(missile.velocity);
  443.     
  444.     missile.touch = T_MissileTouch;
  445.     
  446. // set missile duration
  447.     missile.nextthink = time + 5;
  448.     missile.think = SUB_Remove;
  449.  
  450.     setmodel (missile, "progs/missile.mdl");
  451.     setsize (missile, '0 0 0', '0 0 0');        
  452.     setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  453. };
  454. */
  455.  
  456. // default speed is ~1/3 normal rocket velocity
  457. float guided_missile_vel = 300;
  458.  
  459. void() W_SetCurrentAmmo;
  460.  
  461. float    modelindex_eyes, modelindex_player;
  462.  
  463. // called by player entity
  464. void() Guided_Mis_owner_vanish =
  465. {
  466.  
  467.    self.takedamage = DAMAGE_NO;
  468.    self.solid = SOLID_NOT;
  469.    self.movetype = MOVETYPE_NONE;
  470.  
  471.    setmodel (self, "");
  472.    modelindex_eyes = self.modelindex;
  473.    modelindex_player = self.modelindex;
  474.  
  475.    setsize (self, VEC_ORIGIN, VEC_ORIGIN);
  476.  
  477.    /*
  478.    local entity fake;
  479.    fake = spawn();
  480.    fake.owner = e;
  481.  
  482.    fake.takedamage = DAMAGE_NO;
  483.    // fake.takedamage = DAMAGE_AIM;
  484.    fake.health = fake.owner.health;
  485.    fake.solid = SOLID_NOT;
  486.    // fake.solid = SOLID_SLIDEBOX;
  487.    fake.movetype = MOVETYPE_NONE;
  488.    fake.angles = fake.owner.angles;
  489.    fake.fixangle = TRUE;      // turn this way immediately
  490.  
  491.    setmodel (fake, "progs/player.mdl");
  492.    setsize (fake, VEC_HULL_MIN, VEC_HULL_MAX);
  493.    setorigin( fake, fake.owner.origin );
  494.  
  495.    fake.nextthink = time + 5;
  496.    fake.think = SUB_Remove;
  497.    */
  498.  
  499.  
  500. };
  501.  
  502. // called only by missile entities
  503. void() Guided_Mis_owner_appear =
  504. {
  505.    self.owner.takedamage = DAMAGE_AIM;
  506.    self.owner.solid = SOLID_SLIDEBOX;
  507.    self.owner.movetype = MOVETYPE_WALK;
  508.    self.owner.angles_x = self.ammo_shells;
  509.    self.owner.angles_y = self.ammo_nails;
  510.    self.owner.fixangle = TRUE;      // turn this way immediately
  511.  
  512. // oh, this is a hack!
  513.    setmodel (self.owner, "progs/eyes.mdl");
  514.    modelindex_eyes = self.owner.modelindex;
  515.  
  516.    setmodel (self.owner, "progs/player.mdl");
  517.    modelindex_player = self.owner.modelindex;
  518.  
  519.    setsize (self.owner, VEC_HULL_MIN, VEC_HULL_MAX);
  520.  
  521. };
  522.  
  523.  
  524. void() GM_WatchExplosionEnd =
  525. {
  526.    local entity e;
  527.  
  528.    // turn off bit flag
  529.    if ( (self.owner.speed & GUIDEDMIS_ON) )
  530.       self.owner.speed = self.owner.speed - GUIDEDMIS_ON;
  531.  
  532.    Guided_Mis_owner_appear();
  533.    setorigin( self.owner, self.oldorigin );
  534.  
  535.    msg_entity = self.owner;                         // target of message
  536.    WriteByte (MSG_ONE, SVC_SETVIEWPORT);  
  537.    WriteEntity (MSG_ONE, self.owner);           // view port
  538.  
  539.     e = self;
  540.    self = self.owner;
  541.    W_SetCurrentAmmo ();
  542.     self = e;
  543.  
  544.    remove( self );
  545.  
  546. };
  547.  
  548.  
  549.  
  550. void() GM_WatchExplosion =
  551. {
  552.    local entity e;
  553.  
  554.    e = spawn();
  555.    e.classname = "missile";
  556.    e.owner = self.owner;
  557.  
  558.    e.solid = SOLID_NOT;
  559.    e.movetype = MOVETYPE_NONE;
  560.  
  561.    setmodel (e, "progs/s_explod.spr");
  562.    setsize (e, '0 0 0', '0 0 0');    
  563.    setorigin (e, self.origin);
  564.  
  565.    e.nextthink = time + 0.1;
  566.    e.think = s_explode1;
  567.  
  568.    self.velocity = '0 0 0';
  569.    self.solid = SOLID_NOT;
  570.    self.movetype = MOVETYPE_NONE;
  571.    self.touch = SUB_Null;
  572.  
  573.    makevectors (self.owner.v_angle);
  574.    traceline( self.origin, self.origin - (v_forward * 120), TRUE, self.owner );
  575.    setorigin( self, trace_endpos );
  576.  
  577.    self.nextthink = time + 1;
  578.    self.think = GM_WatchExplosionEnd;
  579.  
  580. };
  581.  
  582.  
  583. void() T_Guided_MissileTouch =
  584. {
  585.     local float    damg;
  586.  
  587.     if (other == self.owner)
  588.         return;        // don't explode on owner
  589.  
  590.  
  591.    if (pointcontents(self.origin) == CONTENT_SKY)
  592.     {
  593.       GM_WatchExplosionEnd();
  594.       // remove(self);
  595.         return;
  596.     }
  597.  
  598.     damg = 100 + random()*20;
  599.     
  600.     if (other.health)
  601.     {
  602.         if (other.classname == "monster_shambler")
  603.             damg = damg * 0.5;    // mostly immune
  604.         T_Damage (other, self, self.owner, damg );
  605.     }
  606.  
  607.     // don't do radius damage to the other, because all the damage
  608.     // was done in the impact
  609.     T_RadiusDamage (self, self.owner, 120, other);
  610.  
  611. //    sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  612.     self.origin = self.origin - 8*normalize(self.velocity);
  613.  
  614.    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  615.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  616.     WriteCoord (MSG_BROADCAST, self.origin_x);
  617.     WriteCoord (MSG_BROADCAST, self.origin_y);
  618.     WriteCoord (MSG_BROADCAST, self.origin_z);
  619.  
  620.    GM_WatchExplosion();
  621.  
  622. };
  623.  
  624. void() Guided_MissileSteer =
  625. {
  626.    self.nextthink = 0.1;
  627.    makevectors (self.owner.v_angle);
  628.    self.velocity = v_forward * guided_missile_vel;
  629.  
  630.    setorigin( self.owner, self.origin );
  631.    self.angles = vectoangles(self.velocity);
  632.  
  633. };
  634.  
  635.  
  636. // opt:
  637. // TRUE = fire guided missile
  638. // FALSE = fire standard rocket
  639. void( float opt ) W_FireRocket =
  640. {
  641.     local    entity missile, mpuff;
  642.     
  643.     
  644.     sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  645.  
  646.  
  647.     missile = spawn ();
  648.     missile.owner = self;
  649.     missile.movetype = MOVETYPE_FLYMISSILE;
  650.     missile.solid = SOLID_BBOX;
  651.     missile.classname = "missile";
  652.         
  653. // set missile speed    
  654.  
  655.     makevectors (self.v_angle);
  656.     
  657.    if (opt)
  658.    {
  659.       self.currentammo = self.ammo_rockets = self.ammo_rockets - 5;
  660.       missile.velocity = aim(self, guided_missile_vel);
  661.       missile.velocity = missile.velocity * guided_missile_vel;
  662.       missile.touch = T_Guided_MissileTouch;
  663.       missile.nextthink = 0.1;
  664.       missile.think = Guided_MissileSteer;
  665.  
  666.       msg_entity = missile.owner;                         // target of message
  667.       WriteByte (MSG_ONE, SVC_SETVIEWPORT);  
  668.       WriteEntity (MSG_ONE, missile);           // view port
  669.  
  670.         self.weaponmodel = "";
  671.         self.weaponframe = 0;
  672.  
  673.       Guided_Mis_owner_vanish();
  674.       missile.oldorigin = missile.owner.origin;
  675.       missile.ammo_shells = missile.owner.angles_x;
  676.       missile.ammo_nails = missile.owner.angles_y;
  677.  
  678.       // turn on bit flag
  679.       self.speed = self.speed | GUIDEDMIS_ON;
  680.    }
  681.    else
  682.    {
  683.       self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  684.       self.punchangle_x = -2;
  685.       missile.velocity = aim(self, 1000);
  686.       missile.velocity = missile.velocity * 1000;
  687.  
  688.       missile.touch = T_MissileTouch;
  689.  
  690.    // set missile duration
  691.       missile.nextthink = time + 5;
  692.       missile.think = SUB_Remove;
  693.    }
  694.     missile.angles = vectoangles(missile.velocity);
  695.  
  696.     setmodel (missile, "progs/missile.mdl");
  697.     setsize (missile, '0 0 0', '0 0 0');        
  698.     setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  699. };
  700.  
  701. // called by new impulse
  702. void() W_FireGuidedMissile =
  703. {
  704.    if ( (self.speed & CHSCAM_ON) )
  705.    {
  706.       sprint( self, "Not in chase view...\n" );
  707.       return;
  708.    }
  709.    if (! (self.items & IT_ROCKET_LAUNCHER) )
  710.    {
  711.       sprint( self, "No rocket launcher...\n" );
  712.       return;
  713.    }
  714.    if (self.ammo_rockets < 5)
  715.    {
  716.       sprint( self, "Not enough rockets...\n" );
  717.       return;
  718.    }
  719.    if ( (self.speed & GUIDEDMIS_ON) )
  720.    {
  721.       return;
  722.    }
  723.  
  724.    if (! (self.weapon & IT_ROCKET_LAUNCHER) )
  725.    {
  726.       self.weapon = IT_ROCKET_LAUNCHER;
  727.       W_SetCurrentAmmo ();
  728.    }
  729.  
  730.    W_FireRocket( TRUE );
  731.  
  732. };
  733.  
  734. // ### Guided missile mod ###
  735. // ##########################
  736.  
  737.  
  738. /*
  739. ===============================================================================
  740.  
  741. LIGHTNING
  742.  
  743. ===============================================================================
  744. */
  745.  
  746. /*
  747. =================
  748. LightningDamage
  749. =================
  750. */
  751. void(vector p1, vector p2, entity from, float damage) LightningDamage =
  752. {
  753.     local entity        e1, e2;
  754.     local vector        f;
  755.     
  756.     f = p2 - p1;
  757.     normalize (f);
  758.     f_x = 0 - f_y;
  759.     f_y = f_x;
  760.     f_z = 0;
  761.     f = f*16;
  762.  
  763.     e1 = e2 = world;
  764.  
  765.     traceline (p1, p2, FALSE, self);
  766.     if (trace_ent.takedamage)
  767.     {
  768.         particle (trace_endpos, '0 0 100', 225, damage*4);
  769.         T_Damage (trace_ent, from, from, damage);
  770.         if (self.classname == "player")
  771.         {
  772.             if (other.classname == "player")
  773.                 trace_ent.velocity_z = trace_ent.velocity_z + 400;
  774.         }
  775.     }
  776.     e1 = trace_ent;
  777.  
  778.     traceline (p1 + f, p2 + f, FALSE, self);
  779.     if (trace_ent != e1 && trace_ent.takedamage)
  780.     {
  781.         particle (trace_endpos, '0 0 100', 225, damage*4);
  782.         T_Damage (trace_ent, from, from, damage);
  783.     }
  784.     e2 = trace_ent;
  785.  
  786.     traceline (p1 - f, p2 - f, FALSE, self);
  787.     if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
  788.     {
  789.         particle (trace_endpos, '0 0 100', 225, damage*4);
  790.         T_Damage (trace_ent, from, from, damage);
  791.     }
  792. };
  793.  
  794.  
  795. void() W_FireLightning =
  796. {
  797.     local    vector        org;
  798.     local    float        cells;
  799.  
  800.     if (self.ammo_cells < 1)
  801.     {
  802.         self.weapon = W_BestWeapon ();
  803.         W_SetCurrentAmmo ();
  804.         return;
  805.     }
  806.  
  807. // explode if under water
  808.     if (self.waterlevel > 1)
  809.     {
  810.         cells = self.ammo_cells;
  811.         self.ammo_cells = 0;
  812.         T_RadiusDamage (self, self, 35*cells, world);
  813.         W_SetCurrentAmmo ();
  814.         return;
  815.     }
  816.  
  817.     if (self.t_width < time)
  818.     {
  819.         sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  820.         self.t_width = time + 0.6;
  821.     }
  822.     self.punchangle_x = -2;
  823.  
  824.     self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  825.  
  826.     org = self.origin + '0 0 16';
  827.     
  828.     traceline (org, org + v_forward*600, TRUE, self);
  829.  
  830.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  831.     WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  832.     WriteEntity (MSG_BROADCAST, self);
  833.     WriteCoord (MSG_BROADCAST, org_x);
  834.     WriteCoord (MSG_BROADCAST, org_y);
  835.     WriteCoord (MSG_BROADCAST, org_z);
  836.     WriteCoord (MSG_BROADCAST, trace_endpos_x);
  837.     WriteCoord (MSG_BROADCAST, trace_endpos_y);
  838.     WriteCoord (MSG_BROADCAST, trace_endpos_z);
  839.  
  840.     LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
  841. };
  842.  
  843.  
  844. //=============================================================================
  845.  
  846.  
  847. void() GrenadeExplode =
  848. {
  849.     T_RadiusDamage (self, self.owner, 120, world);
  850.  
  851.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  852.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  853.     WriteCoord (MSG_BROADCAST, self.origin_x);
  854.     WriteCoord (MSG_BROADCAST, self.origin_y);
  855.     WriteCoord (MSG_BROADCAST, self.origin_z);
  856.  
  857.     BecomeExplosion ();
  858. };
  859.  
  860. void() GrenadeTouch =
  861. {
  862.     if (other == self.owner)
  863.         return;        // don't explode on owner
  864.     if (other.takedamage == DAMAGE_AIM)
  865.     {
  866.         GrenadeExplode();
  867.         return;
  868.     }
  869.     sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);    // bounce sound
  870.     if (self.velocity == '0 0 0')
  871.         self.avelocity = '0 0 0';
  872. };
  873.  
  874. /*
  875. ================
  876. W_FireGrenade
  877. ================
  878. */
  879. void() W_FireGrenade =
  880. {
  881.     local    entity missile, mpuff;
  882.     
  883.     self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  884.     
  885.     sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  886.  
  887.     self.punchangle_x = -2;
  888.  
  889.     missile = spawn ();
  890.     missile.owner = self;
  891.     missile.movetype = MOVETYPE_BOUNCE;
  892.     missile.solid = SOLID_BBOX;
  893.     missile.classname = "grenade";
  894.         
  895. // set missile speed    
  896.  
  897.     makevectors (self.v_angle);
  898.  
  899.     if (self.v_angle_x)
  900.         missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  901.     else
  902.     {
  903.         missile.velocity = aim(self, 10000);
  904.         missile.velocity = missile.velocity * 600;
  905.         missile.velocity_z = 200;
  906.     }
  907.  
  908.     missile.avelocity = '300 300 300';
  909.  
  910.     missile.angles = vectoangles(missile.velocity);
  911.     
  912.     missile.touch = GrenadeTouch;
  913.     
  914. // set missile duration
  915.     missile.nextthink = time + 2.5;
  916.     missile.think = GrenadeExplode;
  917.  
  918.     setmodel (missile, "progs/grenade.mdl");
  919.     setsize (missile, '0 0 0', '0 0 0');        
  920.     setorigin (missile, self.origin);
  921. };
  922.  
  923.  
  924. //=============================================================================
  925.  
  926. void() spike_touch;
  927. void() superspike_touch;
  928.  
  929.  
  930. /*
  931. ===============
  932. launch_spike
  933.  
  934. Used for both the player and the ogre
  935. ===============
  936. */
  937. void(vector org, vector dir) launch_spike =
  938. {
  939.     newmis = spawn ();
  940.     newmis.owner = self;
  941.     newmis.movetype = MOVETYPE_FLYMISSILE;
  942.     newmis.solid = SOLID_BBOX;
  943.  
  944.     newmis.angles = vectoangles(dir);
  945.     
  946.     newmis.touch = spike_touch;
  947.     newmis.classname = "spike";
  948.     newmis.think = SUB_Remove;
  949.     newmis.nextthink = time + 6;
  950.     setmodel (newmis, "progs/spike.mdl");
  951.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  952.     setorigin (newmis, org);
  953.  
  954.     newmis.velocity = dir * 1000;
  955. };
  956.  
  957. void() W_FireSuperSpikes =
  958. {
  959.     local vector    dir;
  960.     local entity    old;
  961.     
  962.     sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
  963.     self.attack_finished = time + 0.2;
  964.     self.currentammo = self.ammo_nails = self.ammo_nails - 2;
  965.     dir = aim (self, 1000);
  966.     launch_spike (self.origin + '0 0 16', dir);
  967.     newmis.touch = superspike_touch;
  968.     setmodel (newmis, "progs/s_spike.mdl");
  969.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  970.     self.punchangle_x = -2;
  971. };
  972.  
  973. void(float ox) W_FireSpikes =
  974. {
  975.     local vector    dir;
  976.     local entity    old;
  977.     
  978.     makevectors (self.v_angle);
  979.     
  980.     if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
  981.     {
  982.         W_FireSuperSpikes ();
  983.         return;
  984.     }
  985.  
  986.     if (self.ammo_nails < 1)
  987.     {
  988.         self.weapon = W_BestWeapon ();
  989.         W_SetCurrentAmmo ();
  990.         return;
  991.     }
  992.  
  993.     sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  994.     self.attack_finished = time + 0.2;
  995.     self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  996.     dir = aim (self, 1000);
  997.     launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
  998.  
  999.     self.punchangle_x = -2;
  1000. };
  1001.  
  1002.  
  1003.  
  1004. .float hit_z;
  1005. void() spike_touch =
  1006. {
  1007. local float rand;
  1008.     if (other == self.owner)
  1009.         return;
  1010.  
  1011.     if (other.solid == SOLID_TRIGGER)
  1012.         return;    // trigger field, do nothing
  1013.  
  1014.     if (pointcontents(self.origin) == CONTENT_SKY)
  1015.     {
  1016.         remove(self);
  1017.         return;
  1018.     }
  1019.     
  1020. // hit something that bleeds
  1021.     if (other.takedamage)
  1022.     {
  1023.         spawn_touchblood (9);
  1024.         T_Damage (other, self, self.owner, 9);
  1025.     }
  1026.     else
  1027.     {
  1028.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1029.         
  1030.         if (self.classname == "wizspike")
  1031.             WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
  1032.         else if (self.classname == "knightspike")
  1033.             WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
  1034.         else
  1035.             WriteByte (MSG_BROADCAST, TE_SPIKE);
  1036.         WriteCoord (MSG_BROADCAST, self.origin_x);
  1037.         WriteCoord (MSG_BROADCAST, self.origin_y);
  1038.         WriteCoord (MSG_BROADCAST, self.origin_z);
  1039.     }
  1040.  
  1041.     remove(self);
  1042.  
  1043. };
  1044.  
  1045. void() superspike_touch =
  1046. {
  1047. local float rand;
  1048.     if (other == self.owner)
  1049.         return;
  1050.  
  1051.     if (other.solid == SOLID_TRIGGER)
  1052.         return;    // trigger field, do nothing
  1053.  
  1054.     if (pointcontents(self.origin) == CONTENT_SKY)
  1055.     {
  1056.         remove(self);
  1057.         return;
  1058.     }
  1059.     
  1060. // hit something that bleeds
  1061.     if (other.takedamage)
  1062.     {
  1063.         spawn_touchblood (18);
  1064.         T_Damage (other, self, self.owner, 18);
  1065.     }
  1066.     else
  1067.     {
  1068.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1069.         WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
  1070.         WriteCoord (MSG_BROADCAST, self.origin_x);
  1071.         WriteCoord (MSG_BROADCAST, self.origin_y);
  1072.         WriteCoord (MSG_BROADCAST, self.origin_z);
  1073.     }
  1074.  
  1075.     remove(self);
  1076.  
  1077. };
  1078.  
  1079.  
  1080. /*
  1081. ===============================================================================
  1082.  
  1083. PLAYER WEAPON USE
  1084.  
  1085. ===============================================================================
  1086. */
  1087.  
  1088. void() W_SetCurrentAmmo =
  1089. {
  1090.     player_run ();        // get out of any weapon firing states
  1091.  
  1092.     self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
  1093.     
  1094.     if (self.weapon == IT_AXE)
  1095.     {
  1096.         self.currentammo = 0;
  1097.         self.weaponmodel = "progs/v_axe.mdl";
  1098.         self.weaponframe = 0;
  1099.     }
  1100.     else if (self.weapon == IT_SHOTGUN)
  1101.     {
  1102.         self.currentammo = self.ammo_shells;
  1103.         self.weaponmodel = "progs/v_shot.mdl";
  1104.         self.weaponframe = 0;
  1105.         self.items = self.items | IT_SHELLS;
  1106.     }
  1107.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1108.     {
  1109.         self.currentammo = self.ammo_shells;
  1110.         self.weaponmodel = "progs/v_shot2.mdl";
  1111.         self.weaponframe = 0;
  1112.         self.items = self.items | IT_SHELLS;
  1113.     }
  1114.     else if (self.weapon == IT_NAILGUN)
  1115.     {
  1116.         self.currentammo = self.ammo_nails;
  1117.         self.weaponmodel = "progs/v_nail.mdl";
  1118.         self.weaponframe = 0;
  1119.         self.items = self.items | IT_NAILS;
  1120.     }
  1121.     else if (self.weapon == IT_SUPER_NAILGUN)
  1122.     {
  1123.         self.currentammo = self.ammo_nails;
  1124.         self.weaponmodel = "progs/v_nail2.mdl";
  1125.         self.weaponframe = 0;
  1126.         self.items = self.items | IT_NAILS;
  1127.     }
  1128.     else if (self.weapon == IT_GRENADE_LAUNCHER)
  1129.     {
  1130.         self.currentammo = self.ammo_rockets;
  1131.         self.weaponmodel = "progs/v_rock.mdl";
  1132.         self.weaponframe = 0;
  1133.         self.items = self.items | IT_ROCKETS;
  1134.     }
  1135.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1136.     {
  1137.         self.currentammo = self.ammo_rockets;
  1138.         self.weaponmodel = "progs/v_rock2.mdl";
  1139.         self.weaponframe = 0;
  1140.         self.items = self.items | IT_ROCKETS;
  1141.     }
  1142.     else if (self.weapon == IT_LIGHTNING)
  1143.     {
  1144.         self.currentammo = self.ammo_cells;
  1145.         self.weaponmodel = "progs/v_light.mdl";
  1146.         self.weaponframe = 0;
  1147.         self.items = self.items | IT_CELLS;
  1148.     }
  1149.     else
  1150.     {
  1151.         self.currentammo = 0;
  1152.         self.weaponmodel = "";
  1153.         self.weaponframe = 0;
  1154.     }
  1155.  
  1156.     // ### chase cam mod ###
  1157.     if ( (self.speed & CHSCAM_ON) )
  1158.     {
  1159.         self.weaponmodel = "";
  1160.         self.weaponframe = 0;
  1161.     }
  1162.  
  1163. };
  1164.  
  1165. float() W_BestWeapon =
  1166. {
  1167.     local    float    it;
  1168.     
  1169.     it = self.items;
  1170.  
  1171.     if(self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
  1172.         return IT_LIGHTNING;
  1173.     else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
  1174.         return IT_SUPER_NAILGUN;
  1175.     else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
  1176.         return IT_SUPER_SHOTGUN;
  1177.     else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
  1178.         return IT_NAILGUN;
  1179.     else if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
  1180.         return IT_SHOTGUN;
  1181.         
  1182. /*
  1183.     if(self.ammo_rockets >= 1 && (it & IT_ROCKET_LAUNCHER) )
  1184.         return IT_ROCKET_LAUNCHER;
  1185.     else if(self.ammo_rockets >= 1 && (it & IT_GRENADE_LAUNCHER) )
  1186.         return IT_GRENADE_LAUNCHER;
  1187.  
  1188. */
  1189.  
  1190.     return IT_AXE;
  1191. };
  1192.  
  1193. float() W_CheckNoAmmo =
  1194. {
  1195.     if (self.currentammo > 0)
  1196.         return TRUE;
  1197.  
  1198.     if (self.weapon == IT_AXE)
  1199.         return TRUE;
  1200.     
  1201.     self.weapon = W_BestWeapon ();
  1202.  
  1203.     W_SetCurrentAmmo ();
  1204.     
  1205. // drop the weapon down
  1206.     return FALSE;
  1207. };
  1208.  
  1209. /*
  1210. ============
  1211. W_Attack
  1212.  
  1213. An attack impulse can be triggered now
  1214. ============
  1215. */
  1216. void()    player_axe1;
  1217. void()    player_axeb1;
  1218. void()    player_axec1;
  1219. void()    player_axed1;
  1220. void()    player_shot1;
  1221. void()    player_nail1;
  1222. void()    player_light1;
  1223. void()    player_rocket1;
  1224.  
  1225. void() W_Attack =
  1226. {
  1227.     local    float    r;
  1228.  
  1229.    // ### guided missile mod ###
  1230.    if ( (self.speed & GUIDEDMIS_ON) )
  1231.       return;
  1232.  
  1233.     if (!W_CheckNoAmmo ())
  1234.         return;
  1235.  
  1236.     makevectors    (self.v_angle);            // calculate forward angle for velocity
  1237.     self.show_hostile = time + 1;    // wake monsters up
  1238.  
  1239.     if (self.weapon == IT_AXE)
  1240.     {
  1241.         sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
  1242.         r = random();
  1243.         if (r < 0.25)
  1244.             player_axe1 ();
  1245.         else if (r<0.5)
  1246.             player_axeb1 ();
  1247.         else if (r<0.75)
  1248.             player_axec1 ();
  1249.         else
  1250.             player_axed1 ();
  1251.         self.attack_finished = time + 0.5;
  1252.     }
  1253.     else if (self.weapon == IT_SHOTGUN)
  1254.     {
  1255.         player_shot1 ();
  1256.         W_FireShotgun ();
  1257.         self.attack_finished = time + 0.5;
  1258.     }
  1259.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1260.     {
  1261.         player_shot1 ();
  1262.         W_FireSuperShotgun ();
  1263.         self.attack_finished = time + 0.7;
  1264.     }
  1265.     else if (self.weapon == IT_NAILGUN)
  1266.     {
  1267.         player_nail1 ();
  1268.     }
  1269.     else if (self.weapon == IT_SUPER_NAILGUN)
  1270.     {
  1271.         player_nail1 ();
  1272.     }
  1273.     else if (self.weapon == IT_GRENADE_LAUNCHER)
  1274.     {
  1275.         player_rocket1();
  1276.         W_FireGrenade();
  1277.         self.attack_finished = time + 0.6;
  1278.     }
  1279.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1280.     {
  1281.         player_rocket1();
  1282.  
  1283.       // ### guided missile mod ###
  1284.       // W_FireRocket(); //original line
  1285.       W_FireRocket( FALSE );
  1286.  
  1287.       self.attack_finished = time + 0.8;
  1288.     }
  1289.     else if (self.weapon == IT_LIGHTNING)
  1290.     {
  1291.         player_light1();
  1292.         self.attack_finished = time + 0.1;
  1293.         sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
  1294.     }
  1295. };
  1296.  
  1297.  
  1298.  
  1299.  
  1300.  
  1301. /*
  1302. ============
  1303. W_ChangeWeapon
  1304.  
  1305. ============
  1306. */
  1307. void() W_ChangeWeapon =
  1308. {
  1309.     local    float    it, am, fl;
  1310.     
  1311.     it = self.items;
  1312.     am = 0;
  1313.     
  1314.     if (self.impulse == 1)
  1315.     {
  1316.         fl = IT_AXE;
  1317.     }
  1318.     else if (self.impulse == 2)
  1319.     {
  1320.         fl = IT_SHOTGUN;
  1321.         if (self.ammo_shells < 1)
  1322.             am = 1;
  1323.     }
  1324.     else if (self.impulse == 3)
  1325.     {
  1326.         fl = IT_SUPER_SHOTGUN;
  1327.         if (self.ammo_shells < 2)
  1328.             am = 1;
  1329.     }        
  1330.     else if (self.impulse == 4)
  1331.     {
  1332.         fl = IT_NAILGUN;
  1333.         if (self.ammo_nails < 1)
  1334.             am = 1;
  1335.     }
  1336.     else if (self.impulse == 5)
  1337.     {
  1338.         fl = IT_SUPER_NAILGUN;
  1339.         if (self.ammo_nails < 2)
  1340.             am = 1;
  1341.     }
  1342.     else if (self.impulse == 6)
  1343.     {
  1344.         fl = IT_GRENADE_LAUNCHER;
  1345.         if (self.ammo_rockets < 1)
  1346.             am = 1;
  1347.     }
  1348.     else if (self.impulse == 7)
  1349.     {
  1350.         fl = IT_ROCKET_LAUNCHER;
  1351.         if (self.ammo_rockets < 1)
  1352.             am = 1;
  1353.     }
  1354.     else if (self.impulse == 8)
  1355.     {
  1356.         fl = IT_LIGHTNING;
  1357.         if (self.ammo_cells < 1)
  1358.             am = 1;
  1359.     }
  1360.  
  1361.     self.impulse = 0;
  1362.     
  1363.     if (!(self.items & fl))
  1364.     {    // don't have the weapon or the ammo
  1365.         sprint (self, "no weapon.\n");
  1366.         return;
  1367.     }
  1368.     
  1369.     if (am)
  1370.     {    // don't have the ammo
  1371.         sprint (self, "not enough ammo.\n");
  1372.         return;
  1373.     }
  1374.  
  1375. //
  1376. // set weapon, set ammo
  1377. //
  1378.     self.weapon = fl;        
  1379.     W_SetCurrentAmmo ();
  1380. };
  1381.  
  1382. /*
  1383. ============
  1384. CheatCommand
  1385. ============
  1386. */
  1387. void() CheatCommand =
  1388. {
  1389.     if (deathmatch || coop)
  1390.         return;
  1391.  
  1392.     self.ammo_rockets = 100;
  1393.     self.ammo_nails = 200;
  1394.     self.ammo_shells = 100;
  1395.     self.items = self.items | 
  1396.         IT_AXE |
  1397.         IT_SHOTGUN |
  1398.         IT_SUPER_SHOTGUN |
  1399.         IT_NAILGUN |
  1400.         IT_SUPER_NAILGUN |
  1401.         IT_GRENADE_LAUNCHER |
  1402.         IT_ROCKET_LAUNCHER |
  1403.         IT_KEY1 | IT_KEY2;
  1404.  
  1405.     self.ammo_cells = 200;
  1406.     self.items = self.items | IT_LIGHTNING;
  1407.  
  1408.     self.weapon = IT_ROCKET_LAUNCHER;
  1409.     self.impulse = 0;
  1410.     W_SetCurrentAmmo ();
  1411. };
  1412.  
  1413. /*
  1414. ============
  1415. CycleWeaponCommand
  1416.  
  1417. Go to the next weapon with ammo
  1418. ============
  1419. */
  1420. void() CycleWeaponCommand =
  1421. {
  1422.     local    float    it, am;
  1423.     
  1424.     it = self.items;
  1425.     self.impulse = 0;
  1426.     
  1427.     while (1)
  1428.     {
  1429.         am = 0;
  1430.  
  1431.         if (self.weapon == IT_LIGHTNING)
  1432.         {
  1433.             self.weapon = IT_AXE;
  1434.         }
  1435.         else if (self.weapon == IT_AXE)
  1436.         {
  1437.             self.weapon = IT_SHOTGUN;
  1438.             if (self.ammo_shells < 1)
  1439.                 am = 1;
  1440.         }
  1441.         else if (self.weapon == IT_SHOTGUN)
  1442.         {
  1443.             self.weapon = IT_SUPER_SHOTGUN;
  1444.             if (self.ammo_shells < 2)
  1445.                 am = 1;
  1446.         }        
  1447.         else if (self.weapon == IT_SUPER_SHOTGUN)
  1448.         {
  1449.             self.weapon = IT_NAILGUN;
  1450.             if (self.ammo_nails < 1)
  1451.                 am = 1;
  1452.         }
  1453.         else if (self.weapon == IT_NAILGUN)
  1454.         {
  1455.             self.weapon = IT_SUPER_NAILGUN;
  1456.             if (self.ammo_nails < 2)
  1457.                 am = 1;
  1458.         }
  1459.         else if (self.weapon == IT_SUPER_NAILGUN)
  1460.         {
  1461.             self.weapon = IT_GRENADE_LAUNCHER;
  1462.             if (self.ammo_rockets < 1)
  1463.                 am = 1;
  1464.         }
  1465.         else if (self.weapon == IT_GRENADE_LAUNCHER)
  1466.         {
  1467.             self.weapon = IT_ROCKET_LAUNCHER;
  1468.             if (self.ammo_rockets < 1)
  1469.                 am = 1;
  1470.         }
  1471.         else if (self.weapon == IT_ROCKET_LAUNCHER)
  1472.         {
  1473.             self.weapon = IT_LIGHTNING;
  1474.             if (self.ammo_cells < 1)
  1475.                 am = 1;
  1476.         }
  1477.     
  1478.         if ( (it & self.weapon) && am == 0)
  1479.         {
  1480.             W_SetCurrentAmmo ();
  1481.             return;
  1482.         }
  1483.     }
  1484.  
  1485. };
  1486.  
  1487. /*
  1488. ============
  1489. CycleWeaponReverseCommand
  1490.  
  1491. Go to the prev weapon with ammo
  1492. ============
  1493. */
  1494. void() CycleWeaponReverseCommand =
  1495. {
  1496.     local    float    it, am;
  1497.     
  1498.     it = self.items;
  1499.     self.impulse = 0;
  1500.  
  1501.     while (1)
  1502.     {
  1503.         am = 0;
  1504.  
  1505.         if (self.weapon == IT_LIGHTNING)
  1506.         {
  1507.             self.weapon = IT_ROCKET_LAUNCHER;
  1508.             if (self.ammo_rockets < 1)
  1509.                 am = 1;
  1510.         }
  1511.         else if (self.weapon == IT_ROCKET_LAUNCHER)
  1512.         {
  1513.             self.weapon = IT_GRENADE_LAUNCHER;
  1514.             if (self.ammo_rockets < 1)
  1515.                 am = 1;
  1516.         }
  1517.         else if (self.weapon == IT_GRENADE_LAUNCHER)
  1518.         {
  1519.             self.weapon = IT_SUPER_NAILGUN;
  1520.             if (self.ammo_nails < 2)
  1521.                 am = 1;
  1522.         }
  1523.         else if (self.weapon == IT_SUPER_NAILGUN)
  1524.         {
  1525.             self.weapon = IT_NAILGUN;
  1526.             if (self.ammo_nails < 1)
  1527.                 am = 1;
  1528.         }
  1529.         else if (self.weapon == IT_NAILGUN)
  1530.         {
  1531.             self.weapon = IT_SUPER_SHOTGUN;
  1532.             if (self.ammo_shells < 2)
  1533.                 am = 1;
  1534.         }        
  1535.         else if (self.weapon == IT_SUPER_SHOTGUN)
  1536.         {
  1537.             self.weapon = IT_SHOTGUN;
  1538.             if (self.ammo_shells < 1)
  1539.                 am = 1;
  1540.         }
  1541.         else if (self.weapon == IT_SHOTGUN)
  1542.         {
  1543.             self.weapon = IT_AXE;
  1544.         }
  1545.         else if (self.weapon == IT_AXE)
  1546.         {
  1547.             self.weapon = IT_LIGHTNING;
  1548.             if (self.ammo_cells < 1)
  1549.                 am = 1;
  1550.         }
  1551.     
  1552.         if ( (it & self.weapon) && am == 0)
  1553.         {
  1554.             W_SetCurrentAmmo ();
  1555.             return;
  1556.         }
  1557.     }
  1558.  
  1559. };
  1560.  
  1561. /*
  1562. ============
  1563. ServerflagsCommand
  1564.  
  1565. Just for development
  1566. ============
  1567. */
  1568. void() ServerflagsCommand =
  1569. {
  1570.     serverflags = serverflags * 2 + 1;
  1571. };
  1572.  
  1573. void() QuadCheat =
  1574. {
  1575.     if (deathmatch || coop)
  1576.         return;
  1577.     self.super_time = 1;
  1578.     self.super_damage_finished = time + 30;
  1579.     self.items = self.items | IT_QUAD;
  1580.     dprint ("quad cheat\n");
  1581. };
  1582.  
  1583. // #####################
  1584. // ### chase cam mod ###
  1585. // main code block
  1586.  
  1587. void() Keep_cam_chasing_owner;
  1588. void( float opt ) Remove_chase_cam;
  1589.  
  1590. // defaults reset every time level starts
  1591. float chasecam_alt, chasecam_dist = 72, chasecam_zofs = 24;
  1592.  
  1593.  
  1594. // Resets weapon model after changing view
  1595. // called by chase cam or player entities
  1596. void( entity player_ent ) Chase_cam_setweapon =
  1597. {
  1598.    local entity e;
  1599.  
  1600.     e = self;
  1601.    self = player_ent;
  1602.    W_SetCurrentAmmo ();
  1603.     self = e;
  1604. };
  1605.  
  1606. // called either by player or chase cam entities (to restart)
  1607. void( entity cam_owner ) Start_chase_cam =
  1608. {
  1609.  
  1610.     local entity    chase_cam;
  1611.  
  1612.     chase_cam = spawn();
  1613.  
  1614.    chase_cam.owner=cam_owner;
  1615.  
  1616.     // turn on bit-flag
  1617.    chase_cam.owner.speed = chase_cam.owner.speed | CHSCAM_ON;
  1618.     
  1619.    chase_cam.solid = SOLID_NOT;
  1620.     chase_cam.movetype = MOVETYPE_FLYMISSILE;
  1621.     
  1622.  
  1623.    chase_cam.angles = chase_cam.owner.angles;
  1624.  
  1625.     setmodel (chase_cam, "progs/eyes.mdl" );
  1626.     setsize (chase_cam, '0 0 0', '0 0 0');
  1627.    setorigin( chase_cam, chase_cam.owner.origin );
  1628.     chase_cam.classname = "chase_cam";
  1629.     
  1630.     chase_cam.nextthink = time + 0.1;    
  1631.     chase_cam.think = Keep_cam_chasing_owner;
  1632.  
  1633.    msg_entity = chase_cam.owner;                         // target of message
  1634.     WriteByte (MSG_ONE, SVC_SETVIEWPORT);  
  1635.     WriteEntity (MSG_ONE, chase_cam);           // view port
  1636.  
  1637.    Chase_cam_setweapon( cam_owner );
  1638.  
  1639.    // distance clipping
  1640.    chase_cam.ammo_shells = chasecam_dist;
  1641.    // offset choice
  1642.    chase_cam.ammo_cells = 0;
  1643.  
  1644. };
  1645.  
  1646. // secondary think for cam entities
  1647. void() Reable_chase_cam =
  1648. {
  1649.    self.nextthink = time + 0.1;
  1650.  
  1651.    // debug
  1652.    // sprint( self.owner, "Reable_chase_cam was called\n" );
  1653.  
  1654.    // clears bug of not being able to hit fire to restart
  1655.    // after dying in water
  1656.    if (self.owner.health <= 0)
  1657.    {
  1658.       remove( self );
  1659.       return;
  1660.    }
  1661.  
  1662.    if (  self.owner.waterlevel )
  1663.       return;
  1664.  
  1665.    Start_chase_cam( self.owner );
  1666.    remove( self );
  1667.  
  1668. };
  1669.  
  1670. // called only by chase cam entities
  1671. // opt values
  1672. // TRUE = remove completely
  1673. // FALSE = remove view but keep alive with Reable_chase_cam();
  1674. void( float opt ) Remove_chase_cam =
  1675. {
  1676.     // turn off bit-flag
  1677.    if ( (self.owner.speed & CHSCAM_ON) )
  1678.       self.owner.speed = self.owner.speed - CHSCAM_ON;
  1679.  
  1680.    // makes entity appear gone even if going into keep alive state
  1681.    setmodel( self, "" );
  1682.    self.velocity = '0 0 0';
  1683.     
  1684.    // set view-point back to normal
  1685.     msg_entity = self.owner;      // target of message
  1686.     WriteByte (MSG_ONE, SVC_SETVIEWPORT);  
  1687.     WriteEntity (MSG_ONE, self.owner);           // view port
  1688.  
  1689.    Chase_cam_setweapon( self.owner );
  1690.  
  1691.    if ( !opt )
  1692.    {
  1693.       self.nextthink = time + 0.1;
  1694.       self.think = Reable_chase_cam;
  1695.    }
  1696.    else
  1697.       remove( self );
  1698.  
  1699. };
  1700.  
  1701. /*
  1702. ###########
  1703. main think function for cam entities
  1704.  self.ammo_shells = distance clipping
  1705.  self.ammo_nails = hang-up flag
  1706. ###########
  1707. */
  1708.  
  1709. void() Alt_cam_chasing_owner;
  1710.  
  1711. void() Keep_cam_chasing_owner =
  1712. {
  1713.    local vector goal, dir;
  1714.    local float  dist, cap,
  1715.                 f_f;
  1716.  
  1717.    self.nextthink = time + 0.1; 
  1718.  
  1719.    // check if player toggled
  1720.     // or in water
  1721.    if ( (self.owner.speed & CHSCAM_ALT))
  1722.     {
  1723.       self.think = Alt_cam_chasing_owner;
  1724.         return;
  1725.     }
  1726.  
  1727.    if ( self.owner.waterlevel )
  1728.    {
  1729.       if (self.owner.health > 0)
  1730.       {
  1731.          Remove_chase_cam( FALSE );
  1732.          return;
  1733.       }
  1734.    }
  1735.     
  1736.    // get player velocity relative to player's
  1737.    // current yaw
  1738.    // f_f (based on running calcs (maxspeed = 400)
  1739.    //  (back ~= 640, forward ~= 0)
  1740.    dir_y = self.owner.v_angle_y;
  1741.    makevectors( dir );
  1742.    f_f = vlen( (v_forward * 320) - self.owner.velocity );
  1743.  
  1744.    // held for use after second makevectors call for
  1745.    // v_forward based only on yaw
  1746.    dir = v_forward;
  1747.  
  1748.    /*
  1749.    local string s;
  1750.    sprint( self.owner, "\n\n f_f = " );
  1751.    s = ftos( f_f );
  1752.    sprint( self.owner, s );
  1753.    sprint( self.owner, "\n f_r = " );
  1754.    s = ftos( f_r );
  1755.    sprint( self.owner, s );
  1756.    sprint( self.owner, "\n" );
  1757.    */
  1758.  
  1759.    makevectors( self.owner.v_angle );
  1760.  
  1761.    // set spot before clipping
  1762.    goal = self.owner.origin - (v_forward * self.ammo_shells);
  1763.  
  1764.    if (self.owner.v_angle_x > 16)
  1765.    {
  1766.       // dir is first v_forward based on yaw only
  1767.       goal = goal + (dir * (self.owner.v_angle_x - 16) );
  1768.       cap = chasecam_zofs - ((self.owner.v_angle_x - 16) * 0.3);
  1769.       if (cap < 0) cap = 0;
  1770.       goal_z = goal_z + cap;
  1771.    }
  1772.    else
  1773.       goal_z = goal_z + chasecam_zofs;
  1774.  
  1775.    traceline (self.owner.origin, goal, FALSE, self.owner);
  1776.  
  1777.    // avoids most hang-ups along walls
  1778.    goal = trace_endpos + ( v_forward * 2 );
  1779.  
  1780.    // for fading from walls and up-aim auto rising
  1781.    self.ammo_shells = 8 + vlen(trace_endpos - self.owner.origin);
  1782.  
  1783.  
  1784.    // clip from ceiling if too close
  1785.    traceline (goal, goal + '0 0 32', FALSE, self.owner );
  1786.    if (trace_fraction < 1 )
  1787.    {
  1788.       dir = trace_endpos - '0 0 32';
  1789.  
  1790.       traceline (goal, goal - '0 0 32', FALSE, self.owner );
  1791.       if (trace_fraction == 1)
  1792.          goal = dir;
  1793.    }
  1794.  
  1795.  
  1796.    dir = normalize(goal - self.origin);
  1797.    dist = vlen(goal - self.origin);
  1798.  
  1799.    traceline( self.origin, goal, FALSE, self.owner );
  1800.    if ( trace_fraction == 1 )
  1801.     {
  1802.       self.angles = self.owner.angles;
  1803.  
  1804.       cap = dist * 0.2;
  1805.  
  1806.       if (cap > 5.2)
  1807.          self.velocity = dir * dist * 5.2;
  1808.       else if (cap > 1)
  1809.          self.velocity = dir * dist * cap;
  1810.       else
  1811.          self.velocity = dir * dist;
  1812.  
  1813.       // tighten up if owner running backwards
  1814.       if ( f_f > 560)
  1815.       {
  1816.          self.velocity = self.velocity * 2;
  1817.       }
  1818.       
  1819.    }
  1820.     else
  1821.       setorigin( self, goal );
  1822.  
  1823.    // fade back from walls
  1824.    self.ammo_shells = self.ammo_shells + 4;
  1825.    if (self.ammo_shells > chasecam_dist)
  1826.       self.ammo_shells = chasecam_dist;
  1827.  
  1828.    // respawn if missile ent. get's hung up
  1829.    if( self.oldorigin == self.origin )
  1830.    {
  1831.       if( dist > 30 )
  1832.          self.ammo_nails = self.ammo_nails + 1;
  1833.  
  1834.    }
  1835.    if( self.ammo_nails > 3 )
  1836.    {
  1837.       Start_chase_cam( self.owner );
  1838.       remove( self );
  1839.       return;
  1840.    }
  1841.    self.oldorigin = self.origin;
  1842.  
  1843. };
  1844.  
  1845. /*
  1846. ###############
  1847.  self.ammo_cells = view offset direction
  1848.    0 = up
  1849.    1 = left
  1850.    2 = right
  1851. ###############
  1852. */
  1853. void() Alt_cam_chasing_owner =
  1854. {
  1855.    local vector goal, dir;
  1856.    local float  dist, cap,
  1857.                 f_f,  f_r;
  1858.  
  1859.    self.nextthink = time + 0.1; 
  1860.  
  1861.    // check if player toggled
  1862.     // or in water
  1863.    if (! (self.owner.speed & CHSCAM_ON))
  1864.     {
  1865.       if( (self.owner.speed & CHSCAM_ALT) )
  1866.          self.owner.speed = self.owner.speed - CHSCAM_ALT;
  1867.       Remove_chase_cam( TRUE );
  1868.       return;
  1869.     }
  1870.  
  1871.    if ( self.owner.waterlevel )
  1872.    {
  1873.       if (self.owner.health > 0)
  1874.       {
  1875.          Remove_chase_cam( FALSE );
  1876.          return;
  1877.       }
  1878.    }
  1879.     
  1880.    // get player velocity relative to player's
  1881.    // current yaw
  1882.    // f_f (based on running calcs (maxspeed = 400)
  1883.    //  (back ~= 640, forward ~= 0)
  1884.    // f_r
  1885.    //  (left ~= 640, right ~= 0)
  1886.    dir_y = self.owner.v_angle_y;
  1887.    makevectors( dir );
  1888.    f_f = vlen( (v_forward * 320) - self.owner.velocity );
  1889.    f_r = vlen( (v_right * 320) - self.owner.velocity );
  1890.  
  1891.    // held for use after second makevectors call for
  1892.    // v_forward based only on yaw
  1893.    dir = v_forward;
  1894.  
  1895.    /*
  1896.    local string s;
  1897.    sprint( self.owner, "\n\n f_f = " );
  1898.    s = ftos( f_f );
  1899.    sprint( self.owner, s );
  1900.    sprint( self.owner, "\n f_r = " );
  1901.    s = ftos( f_r );
  1902.    sprint( self.owner, s );
  1903.    sprint( self.owner, "\n" );
  1904.    */
  1905.  
  1906.    if (f_f < 160 || self.owner.v_angle_x < -45)
  1907.       self.ammo_cells = 0;
  1908.    else if (f_r < 80)
  1909.       self.ammo_cells = 1;
  1910.    else if (f_r > 560)
  1911.       self.ammo_cells = 2;
  1912.  
  1913.  
  1914.    makevectors( self.owner.v_angle );
  1915.  
  1916.    // set spot before clipping
  1917.    goal = self.owner.origin - (v_forward * self.ammo_shells);
  1918.  
  1919.    if (!self.ammo_cells)
  1920.    {
  1921.       if (self.owner.v_angle_x > 16)
  1922.       {
  1923.          // dir is first v_forward based on yaw only
  1924.          goal = goal + (dir * (self.owner.v_angle_x - 16) );
  1925.          cap = chasecam_zofs - ((self.owner.v_angle_x - 16) * 0.3);
  1926.          if (cap < 0) cap = 0;
  1927.          goal_z = goal_z + cap;
  1928.       }
  1929.       else
  1930.          goal_z = goal_z + chasecam_zofs;
  1931.    }
  1932.    else if (self.ammo_cells == 1)
  1933.       goal = goal - (v_right * (chasecam_zofs));
  1934.    else
  1935.       goal = goal + (v_right * (chasecam_zofs));
  1936.  
  1937.  
  1938.    traceline (self.owner.origin, goal, FALSE, self.owner);
  1939.  
  1940.    // avoids most hang-ups along walls
  1941.    goal = trace_endpos + ( v_forward * 2 );
  1942.  
  1943.    // for fading from walls and up-aim auto rising
  1944.    self.ammo_shells = 8 + vlen(trace_endpos - self.owner.origin);
  1945.  
  1946.  
  1947.    // clip from ceiling if too close
  1948.    traceline (goal, goal + '0 0 32', FALSE, self.owner );
  1949.    if (trace_fraction < 1 )
  1950.    {
  1951.       dir = trace_endpos - '0 0 32';
  1952.  
  1953.       traceline (goal, goal - '0 0 32', FALSE, self.owner );
  1954.       if (trace_fraction == 1)
  1955.          goal = dir;
  1956.    }
  1957.  
  1958.  
  1959.    dir = normalize(goal - self.origin);
  1960.    dist = vlen(goal - self.origin);
  1961.  
  1962.    traceline( self.origin, goal, FALSE, self.owner );
  1963.    if ( trace_fraction == 1 )
  1964.     {
  1965.       self.angles = self.owner.angles;
  1966.  
  1967.       cap = dist * 0.2;
  1968.  
  1969.       if (cap > 5.2)
  1970.          self.velocity = dir * dist * 5.2;
  1971.       else if (cap > 1)
  1972.          self.velocity = dir * dist * cap;
  1973.       else
  1974.          self.velocity = dir * dist;
  1975.  
  1976.       // tighten up if owner running backwards
  1977.       if ( f_f > 560)
  1978.       {
  1979.          self.velocity = self.velocity * 2;
  1980.       }
  1981.       
  1982.    }
  1983.     else
  1984.       setorigin( self, goal );
  1985.  
  1986.    // fade back from walls
  1987.    self.ammo_shells = self.ammo_shells + 4;
  1988.    if (self.ammo_shells > chasecam_dist)
  1989.       self.ammo_shells = chasecam_dist;
  1990.  
  1991.    // respawn if missile ent. get's hung up
  1992.    if( self.oldorigin == self.origin )
  1993.    {
  1994.       if( dist > 30 )
  1995.          self.ammo_nails = self.ammo_nails + 1;
  1996.  
  1997.    }
  1998.    if( self.ammo_nails > 3 )
  1999.    {
  2000.       Start_chase_cam( self.owner );
  2001.       remove( self );
  2002.       return;
  2003.    }
  2004.    self.oldorigin = self.origin;
  2005.  
  2006. };
  2007.  
  2008.  
  2009. // called by player only
  2010. void() Toggle_chase_cam =
  2011. {
  2012.  
  2013.    if (self.waterlevel)
  2014.       return;
  2015.  
  2016.    // don't activate if currently flying a missile
  2017.    if ( (self.speed & GUIDEDMIS_ON) )
  2018.       return;
  2019.  
  2020.    if( (self.speed & CHSCAM_ON) )
  2021.     {
  2022.         // will be noticed by next think
  2023.         // of player's chase cam entity
  2024.  
  2025.       if( (self.speed & CHSCAM_ALT) )
  2026.       {
  2027.          self.speed = self.speed - CHSCAM_ALT;
  2028.          self.speed = self.speed - CHSCAM_ON;
  2029.       }
  2030.       else
  2031.       {
  2032.          sprint( self, "View tracking: strafing\n" );
  2033.          self.speed = self.speed | CHSCAM_ALT;
  2034.       }
  2035.     }
  2036.     else
  2037.       Start_chase_cam( self );
  2038.         
  2039. };
  2040.  
  2041. ////////////////////////////////////////////
  2042. // laser targeter functions
  2043.  
  2044. // targeter ent. think function
  2045.  
  2046. void() LaserTargeterTrack = {
  2047.    local vector src;
  2048.  
  2049.    if (! (self.owner.speed & LASERTARG_ON))
  2050.    {
  2051.       if( (self.owner.speed & LASERTARG_LIT) )
  2052.       {
  2053.          self.owner.speed = self.owner.speed | LASERTARG_ON;
  2054.          self.effects = self.effects | EF_DIMLIGHT;
  2055.       }
  2056.       else
  2057.       {
  2058.          remove( self );
  2059.          return;
  2060.       }
  2061.    }
  2062.  
  2063.    makevectors( self.owner.v_angle );
  2064.     
  2065.    src = self.owner.origin + v_forward * 10;
  2066.    src_z = self.owner.absmin_z + self.owner.size_z * 0.7;
  2067.  
  2068.    traceline( src,  src + v_forward * 2048, FALSE, self.owner);
  2069.  
  2070.    setorigin( self, (0.1 * src + 0.9 * trace_endpos) );
  2071.  
  2072.    self.nextthink = time + 0.05;
  2073.  
  2074. };
  2075.  
  2076. void( entity targ_owner ) LaserTargeterToggle =
  2077. {
  2078.  
  2079.    local entity e;
  2080.  
  2081.    if( (targ_owner.speed & LASERTARG_ON) )
  2082.    {
  2083.       if( (targ_owner.speed & LASERTARG_LIT) )
  2084.          targ_owner.speed = targ_owner.speed - LASERTARG_LIT;
  2085.       else
  2086.          targ_owner.speed = targ_owner.speed | LASERTARG_LIT;
  2087.  
  2088.       targ_owner.speed = targ_owner.speed - LASERTARG_ON;
  2089.    }
  2090.    else
  2091.    {
  2092.       targ_owner.speed = targ_owner.speed | LASERTARG_ON;
  2093.       
  2094.       e = spawn();
  2095.       e.owner = targ_owner;
  2096.  
  2097.       e.movetype = MOVETYPE_NONE;
  2098.       e.solid = SOLID_NOT;
  2099.  
  2100.       setmodel( e, "progs/s_bubble.spr" );
  2101.       setsize( e, VEC_ORIGIN, VEC_ORIGIN );    
  2102.       setorigin( e, e.owner.origin );
  2103.  
  2104.       if( (e.owner.speed & LASERTARG_LIT) )
  2105.          e.effects = e.effects | EF_DIMLIGHT;
  2106.  
  2107.       e.nextthink = time + 0.1;
  2108.       e.think = LaserTargeterTrack;
  2109.  
  2110.     }
  2111.  
  2112. };
  2113. ////////////////////////////////////////////
  2114.  
  2115.  
  2116. void() Chase_cam_lvlstart_think =
  2117. {
  2118.  
  2119.    local string s;
  2120.  
  2121.    if ( (self.owner.speed & CHSCAM_ON) )
  2122.       Start_chase_cam( self.owner );
  2123.    if ( (self.owner.speed & LASERTARG_ON) )
  2124.    {
  2125.       self.owner.speed = self.owner.speed - LASERTARG_ON;
  2126.       LaserTargeterToggle( self.owner );
  2127.    }
  2128.  
  2129.    remove( self );
  2130.  
  2131. };
  2132.  
  2133.  
  2134. // called in CLIENT.QC by void() PutClientInServer
  2135. // player.speed is set and saved between levels using parm16
  2136. // in CLIENT.QC
  2137. void() Chase_cam_level_start =
  2138. {
  2139.  
  2140.    local entity e;
  2141.  
  2142.       e = spawn();
  2143.       e.owner = self;
  2144.  
  2145.       e.movetype = MOVETYPE_NONE;
  2146.       e.solid = SOLID_NOT;
  2147.  
  2148.       setmodel( e, "" );
  2149.       setsize( e, VEC_ORIGIN, VEC_ORIGIN );    
  2150.       setorigin( e, e.owner.origin );
  2151.  
  2152.       e.nextthink = time + 0.2;
  2153.       e.think = Chase_cam_lvlstart_think;
  2154.  
  2155. };
  2156.  
  2157.  
  2158. // ### chase cam mod ###
  2159. // #####################
  2160.  
  2161.  
  2162.  
  2163.  
  2164. // ######################
  2165. // ### Multiskin v1.1 ###
  2166.  
  2167. void( float imp ) Choose_multiskin =
  2168. {
  2169.    if (imp == 200)
  2170.    {
  2171.         self.skin = self.skin + 1;
  2172.         if (self.skin == 19)
  2173.          self.skin = 0;
  2174.    }
  2175.    else
  2176.    {
  2177.         self.skin = self.skin - 1;
  2178.       if (self.skin == -1)
  2179.          self.skin = 18;
  2180.    }
  2181.  
  2182.    if (self.skin == 0)
  2183.       centerprint(self, "SKIN: the Good Guy Himself (1)");
  2184.    else if (self.skin == 1)
  2185.       centerprint(self, "SKIN: Duke Nukem 3d (2)");
  2186.    else if (self.skin == 2)
  2187.       centerprint(self, "SKIN: Mr. Toad (3)");
  2188.    else if (self.skin == 3)
  2189.       centerprint(self, "SKIN: the Stormtrooper (4)");
  2190.    else if (self.skin == 4)
  2191.       centerprint(self, "SKIN: Max (5)");
  2192.    else if (self.skin == 5)
  2193.       centerprint(self, "SKIN: the Terminator (6)");
  2194.    else if (self.skin == 6)
  2195.       centerprint(self, "SKIN: Judge Dredd (7)");
  2196.    else if (self.skin == 7)
  2197.       centerprint(self, "SKIN: Camouflaged soldier (8)");
  2198.    else if (self.skin == 8)
  2199.       centerprint(self, "SKIN: Captain Picard (9)");
  2200.    else if (self.skin == 9)
  2201.       centerprint(self, "SKIN: the Wizzard (10)");
  2202.    else if (self.skin == 10)
  2203.       centerprint(self,"SKIN: the Predator (11)");
  2204.    else if (self.skin == 11)
  2205.       centerprint(self,"SKIN: Skeleton (12)");
  2206.    else if (self.skin == 12)
  2207.       centerprint(self,"SKIN: Wan-Fu (13)");
  2208.    else if (self.skin == 13)
  2209.       centerprint(self,"SKIN: Henry Rollins (14)");
  2210.    else if (self.skin == 14)
  2211.       centerprint(self,"SKIN: He-Man (15)");
  2212.    else if (self.skin == 15)
  2213.       centerprint(self,"SKIN: Boba (16)");
  2214.    else if (self.skin == 16)
  2215.       centerprint(self,"SKIN: Superman (17)");
  2216.    else if (self.skin == 17)
  2217.       centerprint(self,"SKIN: NYPD Cop (18)");
  2218.    else if (self.skin == 18)
  2219.       centerprint(self,"SKIN: Red/Yellow women dude (19)");
  2220. };
  2221.  
  2222. // ### Multiskin v1.1 ###
  2223. // ######################
  2224.  
  2225.  
  2226.  
  2227. /*
  2228. ============
  2229. ImpulseCommands
  2230.  
  2231. ============
  2232. */
  2233. void() ImpulseCommands =
  2234. {
  2235.     if (self.impulse >= 1 && self.impulse <= 8)
  2236.         W_ChangeWeapon ();
  2237.  
  2238.     if (self.impulse == 9)
  2239.         CheatCommand ();
  2240.     if (self.impulse == 10)
  2241.         CycleWeaponCommand ();
  2242.     if (self.impulse == 11)
  2243.         ServerflagsCommand ();
  2244.     if (self.impulse == 12)
  2245.         CycleWeaponReverseCommand ();
  2246.  
  2247.    // ### chase cam mods ###
  2248.    if ( self.impulse == 30)
  2249.       Toggle_chase_cam(); // Toggle view
  2250.    if ( self.impulse == 31)  // laser targeter toggle
  2251.       LaserTargeterToggle( self );
  2252.  
  2253.    // ### guided missile mod ###
  2254.    if ( self.impulse == 32)  // guided missile fire
  2255.       W_FireGuidedMissile();
  2256.  
  2257.    // ### Multiskin v1.1 ###
  2258.    if ( self.impulse == 200 || self.impulse == 201 )
  2259.       Choose_multiskin( self.impulse );
  2260.  
  2261.     if (self.impulse == 255)
  2262.         QuadCheat ();
  2263.         
  2264.     self.impulse = 0;
  2265. };
  2266.  
  2267. /*
  2268. ============
  2269. W_WeaponFrame
  2270.  
  2271. Called every frame so impulse events can be handled as well as possible
  2272. ============
  2273. */
  2274. void() W_WeaponFrame =
  2275. {
  2276.     if (time < self.attack_finished)
  2277.         return;
  2278.  
  2279.     ImpulseCommands ();
  2280.     
  2281. // check for attack
  2282.     if (self.button0)
  2283.     {
  2284.         SuperDamageSound ();
  2285.         W_Attack ();
  2286.     }
  2287. };
  2288.  
  2289. /*
  2290. ========
  2291. SuperDamageSound
  2292.  
  2293. Plays sound if needed
  2294. ========
  2295. */
  2296. void() SuperDamageSound =
  2297. {
  2298.     if (self.super_damage_finished > time)
  2299.     {
  2300.         if (self.super_sound < time)
  2301.         {
  2302.             self.super_sound = time + 1;
  2303.             sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
  2304.         }
  2305.     }
  2306.     return;
  2307. };
  2308.  
  2309.  
  2310.