home *** CD-ROM | disk | FTP | other *** search
/ Hráč 1997 February / Hrac_09_1997-02_cd.bin / UTILS / QUAKE / EXTRA / KILLER90.ZIP / SRC / ITEMS.QC < prev    next >
Text File  |  1996-12-06  |  31KB  |  1,416 lines

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