home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / asmoqc11 / items.qc < prev    next >
Encoding:
Text File  |  1996-07-28  |  32.4 KB  |  1,489 lines

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