home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / sgqcver3 / items.qc < prev    next >
Encoding:
Text File  |  1996-08-23  |  30.7 KB  |  1,422 lines

  1. void() W_SetCurrentAmmo;
  2.  
  3. float(entity e) CheckEntity =
  4. {
  5.     if (e.classname == "weapon_nailgun")
  6.         return TRUE;
  7.     else if (e.classname == "weapon_supernailgun")
  8.         return TRUE;
  9.     else if (e.classname == "weapon_supershotgun")
  10.         return TRUE;
  11.     else if (e.classname == "weapon_rocketlauncher")
  12.         return TRUE;
  13.     else if (e.classname == "weapon_grenadelauncher")
  14.         return TRUE;
  15.     else if (e.classname == "weapon_lightning")
  16.         return TRUE;
  17.     else if (e.classname == "item_cells")
  18.         return TRUE;
  19.     else if (e.classname == "item_spikes")
  20.         return TRUE;
  21.     else if (e.classname == "item_shells")
  22.         return TRUE;
  23.     else if (e.classname == "item_rockets")
  24.         return TRUE;
  25.     else if (e.classname == "item_health")
  26.         return TRUE;
  27.     else if (e.classname == "item_artifact_invulnerability")
  28.         return TRUE;
  29.     else if (e.classname == "item_artifact_invisibility")
  30.         return TRUE;
  31.     else if (e.classname == "item_artifact_envirosuit")
  32.         return TRUE;
  33.     else if (e.classname == "item_artifact_super_damage")
  34.         return TRUE;
  35.     else if (e.classname == "item_armor1")
  36.         return TRUE;
  37.     else if (e.classname == "item_armor2")
  38.         return TRUE;
  39.     else if (e.classname == "item_armor3")
  40.         return TRUE;
  41.     return FALSE;
  42. };
  43.  
  44. void() SUB_regen =
  45. {
  46.     local vector vTemp;
  47.     local float fItemCount;
  48.     local entity eTemp;
  49.  
  50.         if (sg_mods & FL_RANDOM)
  51.         {
  52.                 self.model = self.mdl;          // restore original model
  53.                 self.solid = SOLID_TRIGGER;     // allow it to be touched again
  54.                 sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  55.                 fItemCount=random()*19;
  56.                 eTemp=findradius(self.origin,10000);
  57.                 while (fItemCount>0)
  58.                 {
  59.                         eTemp=eTemp.chain;
  60.                         fItemCount=fItemCount - 1;
  61.                         if (!eTemp.chain)
  62.                         {
  63.                                 setorigin (self,self.origin);
  64.                                 return;
  65.             }
  66.         }
  67.                 while (CheckEntity(eTemp)!=TRUE)
  68.                         eTemp=eTemp.chain;
  69.                 vTemp=eTemp.origin;
  70.                 setorigin (eTemp,self.origin);
  71.                 setorigin (self, vTemp);
  72.         }
  73.         else
  74.         {
  75.                 self.model = self.mdl;          // restore original model
  76.                 self.solid = SOLID_TRIGGER;     // allow it to be touched again
  77.                 sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  78.                 setorigin (self, self.origin);
  79.         }
  80. };
  81.  
  82.  
  83.  
  84. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  85. prints a warning message when spawned
  86. */
  87. void() noclass =
  88. {
  89.     dprint ("noclass spawned at");
  90.     dprint (vtos(self.origin));
  91.     dprint ("\n");
  92.     remove (self);
  93. };
  94.  
  95.  
  96.  
  97. /*
  98. ============
  99. PlaceItem
  100.  
  101. plants the object on the floor
  102. ============
  103. */
  104. void() PlaceItem =
  105. {
  106.     local float    oldz;
  107.  
  108.     self.mdl = self.model;        // so it can be restored on respawn
  109.     self.flags = FL_ITEM;        // make extra wide
  110.     self.solid = SOLID_TRIGGER;
  111.     self.movetype = MOVETYPE_TOSS;    
  112.     self.velocity = '0 0 0';
  113.     self.origin_z = self.origin_z + 6;
  114.     oldz = self.origin_z;
  115.     if (!droptofloor())
  116.     {
  117.         dprint ("Bonus item fell out of level at ");
  118.         dprint (vtos(self.origin));
  119.         dprint ("\n");
  120.         remove(self);
  121.         return;
  122.     }
  123. };
  124.  
  125. /*
  126. ============
  127. StartItem
  128.  
  129. Sets the clipping size and plants the object on the floor
  130. ============
  131. */
  132. void() StartItem =
  133. {
  134.     self.nextthink = time + 0.2;    // items start after other solids
  135.     self.think = PlaceItem;
  136. };
  137.  
  138. /*
  139. =========================================================================
  140.  
  141. HEALTH BOX
  142.  
  143. =========================================================================
  144. */
  145. //
  146. // T_Heal: add health to an entity, limiting health to max_health
  147. // "ignore" will ignore max_health limit
  148. //
  149. float (entity e, float healamount, float ignore) T_Heal =
  150. {
  151.     if (e.health <= 0)
  152.         return 0;
  153.     if ((!ignore) && (e.health >= other.max_health))
  154.         return 0;
  155.     healamount = ceil(healamount);
  156.  
  157.     e.health = e.health + healamount;
  158.     if ((!ignore) && (e.health >= other.max_health))
  159.         e.health = other.max_health;
  160.         
  161.     if (e.health > 250)
  162.         e.health = 250;
  163.     return 1;
  164. };
  165.  
  166. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  167. Health box. Normally gives 25 points.
  168. Rotten box heals 5-10 points,
  169. megahealth will add 100 health, then 
  170. rot you down to your maximum health limit, 
  171. one point per second.
  172. */
  173.  
  174. float    H_ROTTEN = 1;
  175. float    H_MEGA = 2;
  176. .float    healamount, healtype;
  177. void() health_touch;
  178. void() item_megahealth_rot;
  179.  
  180. void() item_health =
  181. {    
  182.     self.touch = health_touch;
  183.  
  184.     if (self.spawnflags & H_ROTTEN)
  185.     {
  186.         precache_model("maps/b_bh10.bsp");
  187.  
  188.         precache_sound("items/r_item1.wav");
  189.         setmodel(self, "maps/b_bh10.bsp");
  190.         self.noise = "items/r_item1.wav";
  191.         self.healamount = 15;
  192.         self.healtype = 0;
  193.     }
  194.     else
  195.     if (self.spawnflags & H_MEGA)
  196.     {
  197.         precache_model("maps/b_bh100.bsp");
  198.         precache_sound("items/r_item2.wav");
  199.         setmodel(self, "maps/b_bh100.bsp");
  200.         self.noise = "items/r_item2.wav";
  201.         self.healamount = 100;
  202.         self.healtype = 2;
  203.     }
  204.     else
  205.     {
  206.         precache_model("maps/b_bh25.bsp");
  207.         precache_sound("items/health1.wav");
  208.         setmodel(self, "maps/b_bh25.bsp");
  209.         self.noise = "items/health1.wav";
  210.         self.healamount = 25;
  211.         self.healtype = 1;
  212.     }
  213.     setsize (self, '0 0 0', '32 32 56');
  214.     StartItem ();
  215. };
  216.  
  217.  
  218. void() health_touch =
  219. {
  220.     local    float amount;
  221.     local    string    s;
  222.     
  223.     if (other.classname != "player")
  224.         return;
  225.     
  226.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  227.     {
  228.         if (other.health >= 250)
  229.             return;
  230.         if (!T_Heal(other, self.healamount, 1))
  231.             return;
  232.     }
  233.     else
  234.     {
  235.         if (!T_Heal(other, self.healamount, 0))
  236.             return;
  237.     }
  238.     
  239.     sprint(other, "You receive ");
  240.     s = ftos(self.healamount);
  241.     sprint(other, s);
  242.     sprint(other, " health\n");
  243.     
  244. // health touch sound
  245.     sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  246.  
  247.     stuffcmd (other, "bf\n");
  248.     
  249.     self.model = string_null;
  250.     self.solid = SOLID_NOT;
  251.  
  252.     // Megahealth = rot down the player's super health
  253.     if (self.healtype == 2)
  254.     {
  255.         other.items = other.items | IT_SUPERHEALTH;
  256.         self.nextthink = time + 5;
  257.         self.think = item_megahealth_rot;
  258.         self.owner = other;
  259.     }
  260.     else
  261.     {
  262.         if (deathmatch != 2)        // deathmatch 2 is the silly old rules
  263.         {
  264.             if (deathmatch)
  265.                 self.nextthink = time + 20;
  266.             self.think = SUB_regen;
  267.         }
  268.     }
  269.     
  270.     activator = other;
  271.     SUB_UseTargets();                // fire all targets / killtargets
  272. };    
  273.  
  274. void() item_megahealth_rot =
  275. {
  276.     other = self.owner;
  277.     
  278.     if (other.health > other.max_health)
  279.     {
  280.         other.health = other.health - 1;
  281.         self.nextthink = time + 1;
  282.         return;
  283.     }
  284.  
  285. // it is possible for a player to die and respawn between rots, so don't
  286. // just blindly subtract the flag off
  287.     other.items = other.items - (other.items & IT_SUPERHEALTH);
  288.     
  289.     if (deathmatch == 1)    // deathmatch 2 is silly old rules
  290.     {
  291.         self.nextthink = time + 20;
  292.         self.think = SUB_regen;
  293.     }
  294. };
  295.  
  296. /*
  297. ===============================================================================
  298.  
  299. ARMOR
  300.  
  301. ===============================================================================
  302. */
  303.  
  304. void() armor_touch;
  305.  
  306. void() armor_touch =
  307. {
  308.     local    float    type, value, bit;
  309.     
  310.     if (other.health <= 0)
  311.         return;
  312.     if (other.classname != "player")
  313.         return;
  314.  
  315.     if (self.classname == "item_armor1")
  316.     {
  317.         type = 0.3;
  318.         value = 100;
  319.         bit = IT_ARMOR1;
  320.     }
  321.     if (self.classname == "item_armor2")
  322.     {
  323.         type = 0.6;
  324.         value = 150;
  325.         bit = IT_ARMOR2;
  326.     }
  327.     if (self.classname == "item_armorInv")
  328.     {
  329.         type = 0.8;
  330.         value = 200;
  331.         bit = IT_ARMOR3;
  332.     }
  333.     if (other.armortype*other.armorvalue >= type*value)
  334.         return;
  335.         
  336.     other.armortype = type;
  337.     other.armorvalue = value;
  338.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  339.  
  340.     self.solid = SOLID_NOT;
  341.     self.model = string_null;
  342.     if (deathmatch == 1)
  343.         self.nextthink = time + 20;
  344.     self.think = SUB_regen;
  345.  
  346.     sprint(other, "You got armor\n");
  347. // armor touch sound
  348.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  349.     stuffcmd (other, "bf\n");
  350.     
  351.     activator = other;
  352.     SUB_UseTargets();                // fire all targets / killtargets
  353. };
  354.  
  355.  
  356. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  357. */
  358.  
  359. void() item_armor1 =
  360. {
  361.     self.touch = armor_touch;
  362.         precache_model ("progs/armor.mdl");
  363.         setmodel (self, "progs/armor.mdl");
  364.     self.skin = 0;
  365.     setsize (self, '-16 -16 0', '16 16 56');
  366.     StartItem ();
  367. };
  368.  
  369. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  370. */
  371.  
  372. void() item_armor2 =
  373. {
  374.     self.touch = armor_touch;
  375.         precache_model ("progs/armor.mdl");
  376.         setmodel (self, "progs/armor.mdl");
  377.     self.skin = 1;
  378.     setsize (self, '-16 -16 0', '16 16 56');
  379.     StartItem ();
  380. };
  381.  
  382. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  383. */
  384.  
  385. void() item_armorInv =
  386. {
  387.     self.touch = armor_touch;
  388.         precache_model ("progs/armor.mdl");
  389.         setmodel (self, "progs/armor.mdl");
  390.     self.skin = 2;
  391.     setsize (self, '-16 -16 0', '16 16 56');
  392.     StartItem ();
  393. };
  394.  
  395. /*
  396. ===============================================================================
  397.  
  398. WEAPONS
  399.  
  400. ===============================================================================
  401. */
  402.  
  403. void() bound_other_ammo =
  404. {
  405.     if (other.ammo_shells > 100)
  406.         other.ammo_shells = 100;
  407.     if (other.ammo_nails > 200)
  408.         other.ammo_nails = 200;
  409.     if (other.ammo_rockets > 100)
  410.         other.ammo_rockets = 100;        
  411.     if (other.ammo_cells > 100)
  412.         other.ammo_cells = 100;        
  413. };
  414.  
  415.  
  416. float(float w) RankForWeapon =
  417. {
  418.     if (w == IT_LIGHTNING)
  419.         return 1;
  420.     if (w == IT_ROCKET_LAUNCHER)
  421.         return 2;
  422.     if (w == IT_SUPER_NAILGUN)
  423.         return 3;
  424.     if (w == IT_GRENADE_LAUNCHER)
  425.         return 4;
  426.     if (w == IT_SUPER_SHOTGUN)
  427.         return 5;
  428.     if (w == IT_NAILGUN)
  429.         return 6;
  430.     return 7;
  431. };
  432.  
  433. /*
  434. =============
  435. Deathmatch_Weapon
  436.  
  437. Deathmatch weapon change rules for picking up a weapon
  438.  
  439. .float        ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  440. =============
  441. */
  442. void(float old, float new) Deathmatch_Weapon =
  443. {
  444.     local float or, nr;
  445.  
  446. // change self.weapon if desired
  447.     or = RankForWeapon (self.weapon);
  448.     nr = RankForWeapon (new);
  449.     if ( nr < or )
  450.         self.weapon = new;
  451. };
  452.  
  453. /*
  454. =============
  455. weapon_touch
  456. =============
  457. */
  458. float() W_BestWeapon;
  459.  
  460. void() weapon_touch =
  461. {
  462.     local    float    hadammo, best, new, old;
  463.     local    entity    stemp;
  464.     local    float    leave;
  465.  
  466.     if (!(other.flags & FL_CLIENT))
  467.         return;
  468.  
  469. // if the player was using his best weapon, change up to the new one if better        
  470.     stemp = self;
  471.     self = other;
  472.     best = W_BestWeapon();
  473.     self = stemp;
  474.  
  475.     if (deathmatch == 2 || coop)
  476.         leave = 1;
  477.     else
  478.         leave = 0;
  479.     
  480.     if (self.classname == "weapon_nailgun")
  481.     {
  482.         if (leave && (other.items & IT_NAILGUN) )
  483.             return;
  484.         hadammo = other.ammo_nails;            
  485.         new = IT_NAILGUN;
  486.         other.ammo_nails = other.ammo_nails + 30;
  487.     }
  488.     else if (self.classname == "weapon_supernailgun")
  489.     {
  490.         if (leave && (other.items & IT_SUPER_NAILGUN) )
  491.             return;
  492.         hadammo = other.ammo_rockets;            
  493.         new = IT_SUPER_NAILGUN;
  494.         other.ammo_nails = other.ammo_nails + 30;
  495.     }
  496.     else if (self.classname == "weapon_supershotgun")
  497.     {
  498.         if (leave && (other.items & IT_SUPER_SHOTGUN) )
  499.             return;
  500.         hadammo = other.ammo_rockets;            
  501.         new = IT_SUPER_SHOTGUN;
  502.         other.ammo_shells = other.ammo_shells + 5;
  503.     }
  504.     else if (self.classname == "weapon_rocketlauncher")
  505.     {
  506.         if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  507.             return;
  508.         hadammo = other.ammo_rockets;            
  509.         new = IT_ROCKET_LAUNCHER;
  510.         other.ammo_rockets = other.ammo_rockets + 5;
  511.     }
  512.     else if (self.classname == "weapon_grenadelauncher")
  513.     {
  514.         if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  515.             return;
  516.         hadammo = other.ammo_rockets;            
  517.         new = IT_GRENADE_LAUNCHER;
  518.         other.ammo_rockets = other.ammo_rockets + 5;
  519.     }
  520.     else if (self.classname == "weapon_lightning")
  521.     {
  522.         if (leave && (other.items & IT_LIGHTNING) )
  523.             return;
  524.         hadammo = other.ammo_rockets;            
  525.         new = IT_LIGHTNING;
  526.         other.ammo_cells = other.ammo_cells + 15;
  527.     }
  528.     else
  529.         objerror ("weapon_touch: unknown classname");
  530.  
  531.     sprint (other, "You got the ");
  532.     sprint (other, self.netname);
  533.     sprint (other, "\n");
  534. // weapon touch sound
  535.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  536.     stuffcmd (other, "bf\n");
  537.  
  538.     bound_other_ammo ();
  539.  
  540. // change to the weapon
  541.     old = other.items;
  542.     other.items = other.items | new;
  543.     
  544.     stemp = self;
  545.     self = other;
  546.  
  547.     if (!deathmatch)
  548.         self.weapon = new;
  549.     else
  550.         Deathmatch_Weapon (old, new);
  551.  
  552.     W_SetCurrentAmmo();
  553.  
  554.     self = stemp;
  555.  
  556.     if (leave)
  557.         return;
  558.  
  559. // remove it in single player, or setup for respawning in deathmatch
  560.     self.model = string_null;
  561.     self.solid = SOLID_NOT;
  562.     if (deathmatch == 1)
  563.         self.nextthink = time + 30;
  564.     self.think = SUB_regen;
  565.     
  566.     activator = other;
  567.     SUB_UseTargets();                // fire all targets / killtargets
  568. };
  569.  
  570.  
  571. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  572. */
  573.  
  574. void() weapon_supershotgun =
  575. {
  576.     precache_model ("progs/g_shot.mdl");
  577.     setmodel (self, "progs/g_shot.mdl");
  578.     self.weapon = IT_SUPER_SHOTGUN;
  579.     self.netname = "Double-barrelled Shotgun";
  580.     self.touch = weapon_touch;
  581.     setsize (self, '-16 -16 0', '16 16 56');
  582.     StartItem ();
  583. };
  584.  
  585. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  586. */
  587.  
  588. void() weapon_nailgun =
  589. {
  590.     precache_model ("progs/g_nail.mdl");
  591.     setmodel (self, "progs/g_nail.mdl");
  592.     self.weapon = IT_NAILGUN;
  593.     self.netname = "nailgun";
  594.     self.touch = weapon_touch;
  595.     setsize (self, '-16 -16 0', '16 16 56');
  596.     StartItem ();
  597. };
  598.  
  599. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  600. */
  601.  
  602. void() weapon_supernailgun =
  603. {
  604.     precache_model ("progs/g_nail2.mdl");
  605.     setmodel (self, "progs/g_nail2.mdl");
  606.     self.weapon = IT_SUPER_NAILGUN;
  607.     self.netname = "Super Nailgun";
  608.     self.touch = weapon_touch;
  609.     setsize (self, '-16 -16 0', '16 16 56');
  610.     StartItem ();
  611. };
  612.  
  613. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  614. */
  615.  
  616. void() weapon_grenadelauncher =
  617. {
  618.     precache_model ("progs/g_rock.mdl");
  619.     setmodel (self, "progs/g_rock.mdl");
  620.     self.weapon = 3;
  621.     self.netname = "Grenade Launcher";
  622.     self.touch = weapon_touch;
  623.     setsize (self, '-16 -16 0', '16 16 56');
  624.     StartItem ();
  625. };
  626.  
  627. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  628. */
  629.  
  630. void() weapon_rocketlauncher =
  631. {
  632.     precache_model ("progs/g_rock2.mdl");
  633.     setmodel (self, "progs/g_rock2.mdl");
  634.     self.weapon = 3;
  635.     self.netname = "Rocket Launcher";
  636.     self.touch = weapon_touch;
  637.     setsize (self, '-16 -16 0', '16 16 56');
  638.     StartItem ();
  639. };
  640.  
  641.  
  642. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  643. */
  644.  
  645. void() weapon_lightning =
  646. {
  647.     precache_model ("progs/g_light.mdl");
  648.     setmodel (self, "progs/g_light.mdl");
  649.     self.weapon = 3;
  650.     self.netname = "Thunderbolt";
  651.     self.touch = weapon_touch;
  652.     setsize (self, '-16 -16 0', '16 16 56');
  653.     StartItem ();
  654. };
  655.  
  656.  
  657. /*
  658. ===============================================================================
  659.  
  660. AMMO
  661.  
  662. ===============================================================================
  663. */
  664.  
  665. void() ammo_touch =
  666. {
  667. local entity    stemp;
  668. local float        best;
  669.  
  670.     if (other.classname != "player")
  671.         return;
  672.     if (other.health <= 0)
  673.         return;
  674.  
  675. // if the player was using his best weapon, change up to the new one if better        
  676.     stemp = self;
  677.     self = other;
  678.     best = W_BestWeapon();
  679.     self = stemp;
  680.  
  681.  
  682. // shotgun
  683.     if (self.weapon == 1)
  684.     {
  685.         if (other.ammo_shells >= 100)
  686.             return;
  687.         other.ammo_shells = other.ammo_shells + self.aflag;
  688.     }
  689.  
  690. // spikes
  691.     if (self.weapon == 2)
  692.     {
  693.         if (other.ammo_nails >= 200)
  694.             return;
  695.         other.ammo_nails = other.ammo_nails + self.aflag;
  696.     }
  697.  
  698. //    rockets
  699.     if (self.weapon == 3)
  700.     {
  701.         if (other.ammo_rockets >= 100)
  702.             return;
  703.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  704.     }
  705.  
  706. //    cells
  707.     if (self.weapon == 4)
  708.     {
  709.         if (other.ammo_cells >= 200)
  710.             return;
  711.         other.ammo_cells = other.ammo_cells + self.aflag;
  712.     }
  713.  
  714.     bound_other_ammo ();
  715.     
  716.     sprint (other, "You got the ");
  717.     sprint (other, self.netname);
  718.     sprint (other, "\n");
  719. // ammo touch sound
  720.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  721.     stuffcmd (other, "bf\n");
  722.  
  723. // change to a better weapon if appropriate
  724.  
  725.     if ( other.weapon == best )
  726.     {
  727.         stemp = self;
  728.         self = other;
  729.         self.weapon = W_BestWeapon();
  730.         W_SetCurrentAmmo ();
  731.         self = stemp;
  732.     }
  733.  
  734. // if changed current ammo, update it
  735.     stemp = self;
  736.     self = other;
  737.     W_SetCurrentAmmo();
  738.     self = stemp;
  739.  
  740. // remove it in single player, or setup for respawning in deathmatch
  741.     self.model = string_null;
  742.     self.solid = SOLID_NOT;
  743.     if (deathmatch == 1)
  744.         self.nextthink = time + 30;
  745.     
  746.     self.think = SUB_regen;
  747.  
  748.     activator = other;
  749.     SUB_UseTargets();                // fire all targets / killtargets
  750. };
  751.  
  752.  
  753.  
  754.  
  755. float WEAPON_BIG2 = 1;
  756.  
  757. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  758. */
  759.  
  760. void() item_shells =
  761. {
  762.     self.touch = ammo_touch;
  763.  
  764.     if (self.spawnflags & WEAPON_BIG2)
  765.     {
  766.         precache_model ("maps/b_shell1.bsp");
  767.         setmodel (self, "maps/b_shell1.bsp");
  768.         self.aflag = 40;
  769.     }
  770.     else
  771.     {
  772.         precache_model ("maps/b_shell0.bsp");
  773.         setmodel (self, "maps/b_shell0.bsp");
  774.         self.aflag = 20;
  775.     }
  776.     self.weapon = 1;
  777.     self.netname = "shells";
  778.     setsize (self, '0 0 0', '32 32 56');
  779.     StartItem ();
  780. };
  781.  
  782. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  783. */
  784.  
  785. void() item_spikes =
  786. {
  787.     self.touch = ammo_touch;
  788.  
  789.     if (self.spawnflags & WEAPON_BIG2)
  790.     {
  791.         precache_model ("maps/b_nail1.bsp");
  792.         setmodel (self, "maps/b_nail1.bsp");
  793.         self.aflag = 50;
  794.     }
  795.     else
  796.     {
  797.         precache_model ("maps/b_nail0.bsp");
  798.         setmodel (self, "maps/b_nail0.bsp");
  799.         self.aflag = 25;
  800.     }
  801.     self.weapon = 2;
  802.     self.netname = "nails";
  803.     setsize (self, '0 0 0', '32 32 56');
  804.     StartItem ();
  805. };
  806.  
  807. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  808. */
  809.  
  810. void() item_rockets =
  811. {
  812.     self.touch = ammo_touch;
  813.  
  814.     if (self.spawnflags & WEAPON_BIG2)
  815.     {
  816.         precache_model ("maps/b_rock1.bsp");
  817.         setmodel (self, "maps/b_rock1.bsp");
  818.         self.aflag = 10;
  819.     }
  820.     else
  821.     {
  822.         precache_model ("maps/b_rock0.bsp");
  823.         setmodel (self, "maps/b_rock0.bsp");
  824.         self.aflag = 5;
  825.     }
  826.     self.weapon = 3;
  827.     self.netname = "rockets";
  828.     setsize (self, '0 0 0', '32 32 56');
  829.     StartItem ();
  830. };
  831.  
  832.  
  833. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  834. */
  835.  
  836. void() item_cells =
  837. {
  838.     self.touch = ammo_touch;
  839.  
  840.     if (self.spawnflags & WEAPON_BIG2)
  841.     {
  842.         precache_model ("maps/b_batt1.bsp");
  843.         setmodel (self, "maps/b_batt1.bsp");
  844.         self.aflag = 12;
  845.     }
  846.     else
  847.     {
  848.         precache_model ("maps/b_batt0.bsp");
  849.         setmodel (self, "maps/b_batt0.bsp");
  850.         self.aflag = 6;
  851.     }
  852.     self.weapon = 4;
  853.     self.netname = "cells";
  854.     setsize (self, '0 0 0', '32 32 56');
  855.     StartItem ();
  856. };
  857.  
  858.  
  859. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  860. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  861. */
  862.  
  863. float WEAPON_SHOTGUN = 1;
  864. float WEAPON_ROCKET = 2;
  865. float WEAPON_SPIKES = 4;
  866. float WEAPON_BIG = 8;
  867. void() item_weapon =
  868. {
  869.     self.touch = ammo_touch;
  870.  
  871.     if (self.spawnflags & WEAPON_SHOTGUN)
  872.     {
  873.         if (self.spawnflags & WEAPON_BIG)
  874.         {
  875.             precache_model ("maps/b_shell1.bsp");
  876.             setmodel (self, "maps/b_shell1.bsp");
  877.             self.aflag = 40;
  878.         }
  879.         else
  880.         {
  881.             precache_model ("maps/b_shell0.bsp");
  882.             setmodel (self, "maps/b_shell0.bsp");
  883.             self.aflag = 20;
  884.         }
  885.         self.weapon = 1;
  886.         self.netname = "shells";
  887.     }
  888.  
  889.     if (self.spawnflags & WEAPON_SPIKES)
  890.     {
  891.         if (self.spawnflags & WEAPON_BIG)
  892.         {
  893.             precache_model ("maps/b_nail1.bsp");
  894.             setmodel (self, "maps/b_nail1.bsp");
  895.             self.aflag = 40;
  896.         }
  897.         else
  898.         {
  899.             precache_model ("maps/b_nail0.bsp");
  900.             setmodel (self, "maps/b_nail0.bsp");
  901.             self.aflag = 20;
  902.         }
  903.         self.weapon = 2;
  904.         self.netname = "spikes";
  905.     }
  906.  
  907.     if (self.spawnflags & WEAPON_ROCKET)
  908.     {
  909.         if (self.spawnflags & WEAPON_BIG)
  910.         {
  911.             precache_model ("maps/b_rock1.bsp");
  912.             setmodel (self, "maps/b_rock1.bsp");
  913.             self.aflag = 10;
  914.         }
  915.         else
  916.         {
  917.             precache_model ("maps/b_rock0.bsp");
  918.             setmodel (self, "maps/b_rock0.bsp");
  919.             self.aflag = 5;
  920.         }
  921.         self.weapon = 3;
  922.         self.netname = "rockets";
  923.     }
  924.     
  925.     setsize (self, '0 0 0', '32 32 56');
  926.     StartItem ();
  927. };
  928.  
  929.  
  930. /*
  931. ===============================================================================
  932.  
  933. KEYS
  934.  
  935. ===============================================================================
  936. */
  937.  
  938. void() key_touch =
  939. {
  940. local entity    stemp;
  941. local float        best;
  942.  
  943.     if (other.classname != "player")
  944.         return;
  945.     if (other.health <= 0)
  946.         return;
  947.     if (other.items & self.items)
  948.         return;
  949.  
  950.     sprint (other, "You got the ");
  951.     sprint (other, self.netname);
  952.     sprint (other,"\n");
  953.  
  954.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  955.     stuffcmd (other, "bf\n");
  956.     other.items = other.items | self.items;
  957.  
  958.     if (!coop)
  959.     {    
  960.         self.solid = SOLID_NOT;
  961.         self.model = string_null;
  962.     }
  963.  
  964.     activator = other;
  965.     SUB_UseTargets();                // fire all targets / killtargets
  966. };
  967.  
  968.  
  969. void() key_setsounds =
  970. {
  971.     if (world.worldtype == 0)
  972.     {
  973.         precache_sound ("misc/medkey.wav");
  974.         self.noise = "misc/medkey.wav";
  975.     }
  976.     if (world.worldtype == 1)
  977.     {
  978.         precache_sound ("misc/runekey.wav");
  979.         self.noise = "misc/runekey.wav";
  980.     }
  981.     if (world.worldtype == 2)
  982.     {
  983.         precache_sound2 ("misc/basekey.wav");
  984.         self.noise = "misc/basekey.wav";
  985.     }
  986. };
  987.  
  988. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  989. SILVER key
  990. In order for keys to work
  991. you MUST set your maps
  992. worldtype to one of the
  993. following:
  994. 0: medieval
  995. 1: metal
  996. 2: base
  997. */
  998.  
  999. void() item_key1 =
  1000. {
  1001.     if (world.worldtype == 0)
  1002.     {
  1003.         precache_model ("progs/w_s_key.mdl");
  1004.         setmodel (self, "progs/w_s_key.mdl");
  1005.         self.netname = "silver key";
  1006.     }
  1007.     else if (world.worldtype == 1)
  1008.     {
  1009.         precache_model ("progs/m_s_key.mdl");
  1010.         setmodel (self, "progs/m_s_key.mdl");
  1011.         self.netname = "silver runekey";
  1012.     }
  1013.     else if (world.worldtype == 2)
  1014.     {
  1015.         precache_model2 ("progs/b_s_key.mdl");
  1016.         setmodel (self, "progs/b_s_key.mdl");
  1017.         self.netname = "silver keycard";
  1018.     }
  1019.     key_setsounds();
  1020.     self.touch = key_touch;
  1021.     self.items = IT_KEY1;
  1022.     setsize (self, '-16 -16 -24', '16 16 32');
  1023.     StartItem ();
  1024. };
  1025.  
  1026. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  1027. GOLD key
  1028. In order for keys to work
  1029. you MUST set your maps
  1030. worldtype to one of the
  1031. following:
  1032. 0: medieval
  1033. 1: metal
  1034. 2: base
  1035. */
  1036.  
  1037. void() item_key2 =
  1038. {
  1039.     if (world.worldtype == 0)
  1040.     {
  1041.         precache_model ("progs/w_g_key.mdl");
  1042.         setmodel (self, "progs/w_g_key.mdl");
  1043.         self.netname = "gold key";
  1044.     }
  1045.     if (world.worldtype == 1)
  1046.     {
  1047.         precache_model ("progs/m_g_key.mdl");
  1048.         setmodel (self, "progs/m_g_key.mdl");
  1049.         self.netname = "gold runekey";
  1050.     }
  1051.     if (world.worldtype == 2)
  1052.     {
  1053.         precache_model2 ("progs/b_g_key.mdl");
  1054.         setmodel (self, "progs/b_g_key.mdl");
  1055.         self.netname = "gold keycard";
  1056.     }
  1057.     key_setsounds();
  1058.     self.touch = key_touch;
  1059.     self.items = IT_KEY2;
  1060.     setsize (self, '-16 -16 -24', '16 16 32');
  1061.     StartItem ();
  1062. };
  1063.  
  1064.  
  1065.  
  1066. /*
  1067. ===============================================================================
  1068.  
  1069. END OF LEVEL RUNES
  1070.  
  1071. ===============================================================================
  1072. */
  1073.  
  1074. void() sigil_touch =
  1075. {
  1076. local entity    stemp;
  1077. local float        best;
  1078.  
  1079.     if (other.classname != "player")
  1080.         return;
  1081.     if (other.health <= 0)
  1082.         return;
  1083.  
  1084.     centerprint (other, "You got the rune!");
  1085.  
  1086.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1087.     stuffcmd (other, "bf\n");
  1088.     self.solid = SOLID_NOT;
  1089.     self.model = string_null;
  1090.     serverflags = serverflags | (self.spawnflags & 15);
  1091.     self.classname = "";        // so rune doors won't find it
  1092.     
  1093.     activator = other;
  1094.     SUB_UseTargets();                // fire all targets / killtargets
  1095. };
  1096.  
  1097.  
  1098. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1099. End of level sigil, pick up to end episode and return to jrstart.
  1100. */
  1101.  
  1102. void() item_sigil =
  1103. {
  1104.     if (!self.spawnflags)
  1105.         objerror ("no spawnflags");
  1106.  
  1107.     precache_sound ("misc/runekey.wav");
  1108.     self.noise = "misc/runekey.wav";
  1109.  
  1110.     if (self.spawnflags & 1)
  1111.     {
  1112.         precache_model ("progs/end1.mdl");
  1113.         setmodel (self, "progs/end1.mdl");
  1114.     }
  1115.     if (self.spawnflags & 2)
  1116.     {
  1117.         precache_model2 ("progs/end2.mdl");
  1118.         setmodel (self, "progs/end2.mdl");
  1119.     }
  1120.     if (self.spawnflags & 4)
  1121.     {
  1122.         precache_model2 ("progs/end3.mdl");
  1123.         setmodel (self, "progs/end3.mdl");
  1124.     }
  1125.     if (self.spawnflags & 8)
  1126.     {
  1127.         precache_model2 ("progs/end4.mdl");
  1128.         setmodel (self, "progs/end4.mdl");
  1129.     }
  1130.     
  1131.     self.touch = sigil_touch;
  1132.     setsize (self, '-16 -16 -24', '16 16 32');
  1133.     StartItem ();
  1134. };
  1135.  
  1136. /*
  1137. ===============================================================================
  1138.  
  1139. POWERUPS
  1140.  
  1141. ===============================================================================
  1142. */
  1143.  
  1144. void() powerup_touch;
  1145.  
  1146.  
  1147. void() powerup_touch =
  1148. {
  1149. local entity    stemp;
  1150. local float        best;
  1151.  
  1152.     if (other.classname != "player")
  1153.         return;
  1154.     if (other.health <= 0)
  1155.         return;
  1156.  
  1157.     sprint (other, "You got the ");
  1158.     sprint (other, self.netname);
  1159.     sprint (other,"\n");
  1160.  
  1161.     if (deathmatch)
  1162.     {
  1163.         self.mdl = self.model;
  1164.         
  1165.         if ((self.classname == "item_artifact_invulnerability") ||
  1166.             (self.classname == "item_artifact_invisibility"))
  1167.             self.nextthink = time + 60*5;
  1168.         else
  1169.             self.nextthink = time + 60;
  1170.         
  1171.         self.think = SUB_regen;
  1172.     }    
  1173.  
  1174.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1175.     stuffcmd (other, "bf\n");
  1176.     self.solid = SOLID_NOT;
  1177.     other.items = other.items | self.items;
  1178.     self.model = string_null;
  1179.  
  1180. // do the apropriate action
  1181.     if (self.classname == "item_artifact_envirosuit")
  1182.     {
  1183.         other.rad_time = 1;
  1184.         other.radsuit_finished = time + 30;
  1185.     }
  1186.     
  1187.     if (self.classname == "item_artifact_invulnerability")
  1188.     {
  1189.         other.invincible_time = 1;
  1190.         other.invincible_finished = time + 30;
  1191.     }
  1192.     
  1193.     if (self.classname == "item_artifact_invisibility")
  1194.     {
  1195.         other.invisible_time = 1;
  1196.         other.invisible_finished = time + 30;
  1197.     }
  1198.  
  1199.     if (self.classname == "item_artifact_super_damage")
  1200.     {
  1201.         other.super_time = 1;
  1202.         other.super_damage_finished = time + 30;
  1203.     }    
  1204.  
  1205.     activator = other;
  1206.     SUB_UseTargets();                // fire all targets / killtargets
  1207. };
  1208.  
  1209.  
  1210.  
  1211. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1212. Player is invulnerable for 30 seconds
  1213. */
  1214. void() item_artifact_invulnerability =
  1215. {
  1216.     self.touch = powerup_touch;
  1217.  
  1218.     precache_model ("progs/invulner.mdl");
  1219.     precache_sound ("items/protect.wav");
  1220.     precache_sound ("items/protect2.wav");
  1221.     precache_sound ("items/protect3.wav");
  1222.     self.noise = "items/protect.wav";
  1223.     setmodel (self, "progs/invulner.mdl");
  1224.     self.netname = "Pentagram of Protection";
  1225.     self.items = IT_INVULNERABILITY;
  1226.     setsize (self, '-16 -16 -24', '16 16 32');
  1227.     StartItem ();
  1228. };
  1229.  
  1230. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1231. Player takes no damage from water or slime for 30 seconds
  1232. */
  1233. void() item_artifact_envirosuit =
  1234. {
  1235.     self.touch = powerup_touch;
  1236.  
  1237.     precache_model ("progs/suit.mdl");
  1238.     precache_sound ("items/suit.wav");
  1239.     precache_sound ("items/suit2.wav");
  1240.     self.noise = "items/suit.wav";
  1241.     setmodel (self, "progs/suit.mdl");
  1242.     self.netname = "Biosuit";
  1243.     self.items = IT_SUIT;
  1244.     setsize (self, '-16 -16 -24', '16 16 32');
  1245.     StartItem ();
  1246. };
  1247.  
  1248.  
  1249. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1250. Player is invisible for 30 seconds
  1251. */
  1252. void() item_artifact_invisibility =
  1253. {
  1254.     self.touch = powerup_touch;
  1255.  
  1256.     precache_model ("progs/invisibl.mdl");
  1257.     precache_sound ("items/inv1.wav");
  1258.     precache_sound ("items/inv2.wav");
  1259.     precache_sound ("items/inv3.wav");
  1260.     self.noise = "items/inv1.wav";
  1261.     setmodel (self, "progs/invisibl.mdl");
  1262.     self.netname = "Ring of Shadows";
  1263.     self.items = IT_INVISIBILITY;
  1264.     setsize (self, '-16 -16 -24', '16 16 32');
  1265.     StartItem ();
  1266. };
  1267.  
  1268.  
  1269. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1270. The next attack from the player will do 4x damage
  1271. */
  1272. void() item_artifact_super_damage =
  1273. {
  1274.     self.touch = powerup_touch;
  1275.  
  1276.     precache_model ("progs/quaddama.mdl");
  1277.     precache_sound ("items/damage.wav");
  1278.     precache_sound ("items/damage2.wav");
  1279.     precache_sound ("items/damage3.wav");
  1280.     self.noise = "items/damage.wav";
  1281.     setmodel (self, "progs/quaddama.mdl");
  1282.     self.netname = "Quad Damage";
  1283.     self.items = IT_QUAD;
  1284.     setsize (self, '-16 -16 -24', '16 16 32');
  1285.     StartItem ();
  1286. };
  1287.  
  1288.  
  1289.  
  1290. /*
  1291. ===============================================================================
  1292.  
  1293. PLAYER BACKPACKS
  1294.  
  1295. ===============================================================================
  1296. */
  1297. void() BackpackTouch =
  1298. {
  1299.     local string    s;
  1300.     local    float    best;
  1301.     local        entity    stemp;
  1302.     
  1303.     if (other.classname != "player")
  1304.         return;
  1305.     if (other.health <= 0)
  1306.         return;
  1307.         
  1308. // if the player was using his best weapon, change up to the new one if better        
  1309.     stemp = self;
  1310.     self = other;
  1311.     best = W_BestWeapon();
  1312.     self = stemp;
  1313.  
  1314. // change weapons
  1315.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1316.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1317.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1318.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1319.  
  1320.     other.items = other.items | self.items;
  1321.     
  1322.     bound_other_ammo ();
  1323.  
  1324.     sprint (other, "You get ");
  1325.  
  1326.     if (self.ammo_shells)
  1327.     {
  1328.         s = ftos(self.ammo_shells);
  1329.         sprint (other, s);
  1330.         sprint (other, " shells  ");
  1331.     }
  1332.     if (self.ammo_nails)
  1333.     {
  1334.         s = ftos(self.ammo_nails);
  1335.         sprint (other, s);
  1336.         sprint (other, " nails ");
  1337.     }
  1338.     if (self.ammo_rockets)
  1339.     {
  1340.         s = ftos(self.ammo_rockets);
  1341.         sprint (other, s);
  1342.         sprint (other, " rockets  ");
  1343.     }
  1344.     if (self.ammo_cells)
  1345.     {
  1346.         s = ftos(self.ammo_cells);
  1347.         sprint (other, s);
  1348.         sprint (other, " cells  ");
  1349.     }
  1350.     
  1351.     sprint (other, "\n");
  1352. // backpack touch sound
  1353.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1354.     stuffcmd (other, "bf\n");
  1355.  
  1356. // change to a better weapon if appropriate
  1357.     if ( other.weapon == best )
  1358.     {
  1359.         stemp = self;
  1360.         self = other;
  1361.         self.weapon = W_BestWeapon();
  1362.         self = stemp;
  1363.     }
  1364.  
  1365.     
  1366.     remove(self);
  1367.     
  1368.     self = other;
  1369.     W_SetCurrentAmmo ();
  1370. };
  1371.  
  1372. /*
  1373. ===============
  1374. DropBackpack
  1375. ===============
  1376. */
  1377.  
  1378. //Had to have it so I could use it here.
  1379. void() backpack_explode;
  1380.  
  1381. void() DropBackpack =
  1382. {
  1383.     local entity    item;
  1384.  
  1385.     if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
  1386.         return;    // nothing in it
  1387.  
  1388.     item = spawn();
  1389.  
  1390.     item.origin = self.origin - '0 0 24';
  1391.     
  1392.     item.items = self.weapon;
  1393.     item.ammo_shells = self.ammo_shells;
  1394.     item.ammo_nails = self.ammo_nails;
  1395.     item.ammo_rockets = self.ammo_rockets;
  1396.     item.ammo_cells = self.ammo_cells;
  1397.  
  1398.     item.velocity_z = 300;
  1399.     item.velocity_x = -100 + (random() * 200);
  1400.     item.velocity_y = -100 + (random() * 200);
  1401.     
  1402.     item.flags = FL_ITEM;
  1403.         item.solid = SOLID_SLIDEBOX;
  1404.     item.movetype = MOVETYPE_TOSS;
  1405.     setmodel (item, "progs/backpack.mdl");
  1406.     setsize (item, '-16 -16 0', '16 16 56');
  1407.     item.touch = BackpackTouch;
  1408.  
  1409. //Shoot em if you got em.
  1410.         if ( (item.ammo_rockets > 0) && (sg_mods & FL_BACKEX) )
  1411.         {
  1412.                 item.health = 30;
  1413.                 item.th_die = backpack_explode;
  1414.                 item.takedamage = DAMAGE_AIM;
  1415.         }
  1416.         else
  1417.                 item.takedamage = DAMAGE_NO;
  1418.     
  1419.     item.nextthink = time + 120;    // remove after 2 minutes
  1420.     item.think = SUB_Remove;
  1421. };
  1422.