home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / patch / mbq067 / items.qc < prev    next >
Encoding:
Text File  |  1996-08-24  |  31.2 KB  |  1,454 lines

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