home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / qnitems / items.qc < prev    next >
Encoding:
Text File  |  1996-08-01  |  30.6 KB  |  1,411 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. };
  227.  
  228. /*
  229. ===============================================================================
  230.  
  231. ARMOR
  232.  
  233. ===============================================================================
  234. */
  235.  
  236. void() armor_touch;
  237.  
  238. void() armor_touch =
  239. {
  240.     local    float    type, value, bit;
  241.     
  242.     if (other.health <= 0)
  243.         return;
  244.     if (other.classname != "player")
  245.         return;
  246.  
  247.     if (self.classname == "item_armor1")
  248.     {
  249.         type = 0.3;
  250.         value = 100;
  251.         bit = IT_ARMOR1;
  252.     }
  253.     if (self.classname == "item_armor2")
  254.     {
  255.         type = 0.6;
  256.         value = 150;
  257.         bit = IT_ARMOR2;
  258.     }
  259.     if (self.classname == "item_armorInv")
  260.     {
  261.         type = 0.8;
  262.         value = 200;
  263.         bit = IT_ARMOR3;
  264.     }
  265.     if (other.armortype*other.armorvalue >= type*value)
  266.         return;
  267.         
  268.     other.armortype = type;
  269.     other.armorvalue = value;
  270.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  271.  
  272.     self.solid = SOLID_NOT;
  273.     self.model = string_null;
  274.     if (deathmatch == 1)
  275.         self.nextthink = time + 20;
  276.     self.think = SUB_regen;
  277.  
  278.     sprint(other, "You got armor\n");
  279. // armor touch sound
  280.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  281.     stuffcmd (other, "bf\n");
  282.     
  283.     activator = other;
  284.     SUB_UseTargets();                // fire all targets / killtargets
  285. };
  286.  
  287.  
  288. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  289. */
  290.  
  291. void() item_armor1 =
  292. {
  293.     self.touch = armor_touch;
  294.     precache_model ("progs/armor.mdl");
  295.     setmodel (self, "progs/armor.mdl");
  296.     self.skin = 0;
  297.     setsize (self, '-16 -16 0', '16 16 56');
  298.     StartItem ();
  299. };
  300.  
  301. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  302. */
  303.  
  304. void() item_armor2 =
  305. {
  306.     self.touch = armor_touch;
  307.     precache_model ("progs/armor.mdl");
  308.     setmodel (self, "progs/armor.mdl");
  309.     self.skin = 1;
  310.     setsize (self, '-16 -16 0', '16 16 56');
  311.     StartItem ();
  312. };
  313.  
  314. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  315. */
  316.  
  317. void() item_armorInv =
  318. {
  319.     self.touch = armor_touch;
  320.     precache_model ("progs/armor.mdl");
  321.     setmodel (self, "progs/armor.mdl");
  322.     self.skin = 2;
  323.     setsize (self, '-16 -16 0', '16 16 56');
  324.     StartItem ();
  325. };
  326.  
  327. /*
  328. ===============================================================================
  329.  
  330. WEAPONS
  331.  
  332. ===============================================================================
  333. */
  334.  
  335. void() bound_other_ammo =
  336. {
  337.     if (other.ammo_shells > 100)
  338.         other.ammo_shells = 100;
  339.     if (other.ammo_nails > 200)
  340.         other.ammo_nails = 200;
  341.     if (other.ammo_rockets > 100)
  342.         other.ammo_rockets = 100;        
  343.         if (other.ammo_cells > 200)
  344.                 other.ammo_cells = 200;
  345. /*
  346. MOD:
  347. These changes has been added to make sure you never
  348. can have more then 9 of the same power-up.
  349. Oh yeah, you can have up to 200 cells now.
  350. It shoulden't be too hard to change it back to 100.
  351. */
  352.  
  353.         if (other.ammo_item_invincible > 9)
  354.                 other.ammo_item_invincible = 9;
  355.         if (other.ammo_item_invisible > 9)
  356.                 other.ammo_item_invisible = 9;
  357.         if (other.ammo_item_super_damage > 9)
  358.                 other.ammo_item_super_damage = 9;
  359.         if (other.ammo_item_radsuit > 9)
  360.                 other.ammo_item_radsuit = 9;
  361. };
  362.  
  363.  
  364. float(float w) RankForWeapon =
  365. {
  366.     if (w == IT_LIGHTNING)
  367.         return 1;
  368.     if (w == IT_ROCKET_LAUNCHER)
  369.         return 2;
  370.     if (w == IT_SUPER_NAILGUN)
  371.         return 3;
  372.     if (w == IT_GRENADE_LAUNCHER)
  373.         return 4;
  374.     if (w == IT_SUPER_SHOTGUN)
  375.         return 5;
  376.     if (w == IT_NAILGUN)
  377.         return 6;
  378.     return 7;
  379. };
  380.  
  381. /*
  382. =============
  383. Deathmatch_Weapon
  384.  
  385. Deathmatch weapon change rules for picking up a weapon
  386.  
  387. .float        ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  388. =============
  389. */
  390. void(float old, float new) Deathmatch_Weapon =
  391. {
  392.     local float or, nr;
  393.  
  394. // change self.weapon if desired
  395.     or = RankForWeapon (self.weapon);
  396.     nr = RankForWeapon (new);
  397.     if ( nr < or )
  398.         self.weapon = new;
  399. };
  400.  
  401. /*
  402. =============
  403. weapon_touch
  404. =============
  405. */
  406. float() W_BestWeapon;
  407.  
  408. void() weapon_touch =
  409. {
  410.     local    float    hadammo, best, new, old;
  411.     local    entity    stemp;
  412.     local    float    leave;
  413.  
  414.     if (!(other.flags & FL_CLIENT))
  415.         return;
  416.  
  417. // if the player was using his best weapon, change up to the new one if better        
  418.     stemp = self;
  419.     self = other;
  420.     best = W_BestWeapon();
  421.     self = stemp;
  422.  
  423.     if (deathmatch == 2 || coop)
  424.         leave = 1;
  425.     else
  426.         leave = 0;
  427.     
  428.     if (self.classname == "weapon_nailgun")
  429.     {
  430.         if (leave && (other.items & IT_NAILGUN) )
  431.             return;
  432.         hadammo = other.ammo_nails;            
  433.         new = IT_NAILGUN;
  434.         other.ammo_nails = other.ammo_nails + 30;
  435.     }
  436.     else if (self.classname == "weapon_supernailgun")
  437.     {
  438.         if (leave && (other.items & IT_SUPER_NAILGUN) )
  439.             return;
  440.         hadammo = other.ammo_rockets;            
  441.         new = IT_SUPER_NAILGUN;
  442.         other.ammo_nails = other.ammo_nails + 30;
  443.     }
  444.     else if (self.classname == "weapon_supershotgun")
  445.     {
  446.         if (leave && (other.items & IT_SUPER_SHOTGUN) )
  447.             return;
  448.         hadammo = other.ammo_rockets;            
  449.         new = IT_SUPER_SHOTGUN;
  450.         other.ammo_shells = other.ammo_shells + 5;
  451.     }
  452.     else if (self.classname == "weapon_rocketlauncher")
  453.     {
  454.         if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  455.             return;
  456.         hadammo = other.ammo_rockets;            
  457.         new = IT_ROCKET_LAUNCHER;
  458.         other.ammo_rockets = other.ammo_rockets + 5;
  459.     }
  460.     else if (self.classname == "weapon_grenadelauncher")
  461.     {
  462.         if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  463.             return;
  464.         hadammo = other.ammo_rockets;            
  465.         new = IT_GRENADE_LAUNCHER;
  466.         other.ammo_rockets = other.ammo_rockets + 5;
  467.     }
  468.     else if (self.classname == "weapon_lightning")
  469.     {
  470.         if (leave && (other.items & IT_LIGHTNING) )
  471.             return;
  472.         hadammo = other.ammo_rockets;            
  473.         new = IT_LIGHTNING;
  474.         other.ammo_cells = other.ammo_cells + 15;
  475.     }
  476.     else
  477.         objerror ("weapon_touch: unknown classname");
  478.  
  479.     sprint (other, "You got the ");
  480.     sprint (other, self.netname);
  481.     sprint (other, "\n");
  482. // weapon touch sound
  483.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  484.     stuffcmd (other, "bf\n");
  485.  
  486.     bound_other_ammo ();
  487.  
  488. // change to the weapon
  489.     old = other.items;
  490.     other.items = other.items | new;
  491.     
  492.     stemp = self;
  493.     self = other;
  494.  
  495.     if (!deathmatch)
  496.         self.weapon = new;
  497.     else
  498.         Deathmatch_Weapon (old, new);
  499.  
  500.     W_SetCurrentAmmo();
  501.  
  502.     self = stemp;
  503.  
  504.     if (leave)
  505.         return;
  506.  
  507. // remove it in single player, or setup for respawning in deathmatch
  508.     self.model = string_null;
  509.     self.solid = SOLID_NOT;
  510.     if (deathmatch == 1)
  511.         self.nextthink = time + 30;
  512.     self.think = SUB_regen;
  513.     
  514.     activator = other;
  515.     SUB_UseTargets();                // fire all targets / killtargets
  516. };
  517.  
  518.  
  519. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  520. */
  521.  
  522. void() weapon_supershotgun =
  523. {
  524.     precache_model ("progs/g_shot.mdl");
  525.     setmodel (self, "progs/g_shot.mdl");
  526.     self.weapon = IT_SUPER_SHOTGUN;
  527.     self.netname = "Double-barrelled Shotgun";
  528.     self.touch = weapon_touch;
  529.     setsize (self, '-16 -16 0', '16 16 56');
  530.     StartItem ();
  531. };
  532.  
  533. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  534. */
  535.  
  536. void() weapon_nailgun =
  537. {
  538.     precache_model ("progs/g_nail.mdl");
  539.     setmodel (self, "progs/g_nail.mdl");
  540.     self.weapon = IT_NAILGUN;
  541.     self.netname = "nailgun";
  542.     self.touch = weapon_touch;
  543.     setsize (self, '-16 -16 0', '16 16 56');
  544.     StartItem ();
  545. };
  546.  
  547. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  548. */
  549.  
  550. void() weapon_supernailgun =
  551. {
  552.     precache_model ("progs/g_nail2.mdl");
  553.     setmodel (self, "progs/g_nail2.mdl");
  554.     self.weapon = IT_SUPER_NAILGUN;
  555.     self.netname = "Super Nailgun";
  556.     self.touch = weapon_touch;
  557.     setsize (self, '-16 -16 0', '16 16 56');
  558.     StartItem ();
  559. };
  560.  
  561. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  562. */
  563.  
  564. void() weapon_grenadelauncher =
  565. {
  566.     precache_model ("progs/g_rock.mdl");
  567.     setmodel (self, "progs/g_rock.mdl");
  568.     self.weapon = 3;
  569.     self.netname = "Grenade Launcher";
  570.     self.touch = weapon_touch;
  571.     setsize (self, '-16 -16 0', '16 16 56');
  572.     StartItem ();
  573. };
  574.  
  575. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  576. */
  577.  
  578. void() weapon_rocketlauncher =
  579. {
  580.     precache_model ("progs/g_rock2.mdl");
  581.     setmodel (self, "progs/g_rock2.mdl");
  582.     self.weapon = 3;
  583.     self.netname = "Rocket Launcher";
  584.     self.touch = weapon_touch;
  585.     setsize (self, '-16 -16 0', '16 16 56');
  586.     StartItem ();
  587. };
  588.  
  589.  
  590. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  591. */
  592.  
  593. void() weapon_lightning =
  594. {
  595.     precache_model ("progs/g_light.mdl");
  596.     setmodel (self, "progs/g_light.mdl");
  597.     self.weapon = 3;
  598.     self.netname = "Thunderbolt";
  599.     self.touch = weapon_touch;
  600.     setsize (self, '-16 -16 0', '16 16 56');
  601.     StartItem ();
  602. };
  603.  
  604.  
  605. /*
  606. ===============================================================================
  607.  
  608. AMMO
  609.  
  610. ===============================================================================
  611. */
  612.  
  613. void() ammo_touch =
  614. {
  615. local entity    stemp;
  616. local float        best;
  617.  
  618.     if (other.classname != "player")
  619.         return;
  620.     if (other.health <= 0)
  621.         return;
  622.  
  623. // if the player was using his best weapon, change up to the new one if better        
  624.     stemp = self;
  625.     self = other;
  626.     best = W_BestWeapon();
  627.     self = stemp;
  628.  
  629.  
  630. // shotgun
  631.     if (self.weapon == 1)
  632.     {
  633.         if (other.ammo_shells >= 100)
  634.             return;
  635.         other.ammo_shells = other.ammo_shells + self.aflag;
  636.     }
  637.  
  638. // spikes
  639.     if (self.weapon == 2)
  640.     {
  641.         if (other.ammo_nails >= 200)
  642.             return;
  643.         other.ammo_nails = other.ammo_nails + self.aflag;
  644.     }
  645.  
  646. //    rockets
  647.     if (self.weapon == 3)
  648.     {
  649.         if (other.ammo_rockets >= 100)
  650.             return;
  651.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  652.     }
  653.  
  654. //    cells
  655.     if (self.weapon == 4)
  656.     {
  657.         if (other.ammo_cells >= 200)
  658.             return;
  659.         other.ammo_cells = other.ammo_cells + self.aflag;
  660.     }
  661.  
  662.     bound_other_ammo ();
  663.     
  664.     sprint (other, "You got the ");
  665.     sprint (other, self.netname);
  666.     sprint (other, "\n");
  667. // ammo touch sound
  668.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  669.     stuffcmd (other, "bf\n");
  670.  
  671. // change to a better weapon if appropriate
  672.  
  673.     if ( other.weapon == best )
  674.     {
  675.         stemp = self;
  676.         self = other;
  677.         self.weapon = W_BestWeapon();
  678.         W_SetCurrentAmmo ();
  679.         self = stemp;
  680.     }
  681.  
  682. // if changed current ammo, update it
  683.     stemp = self;
  684.     self = other;
  685.     W_SetCurrentAmmo();
  686.     self = stemp;
  687.  
  688. // remove it in single player, or setup for respawning in deathmatch
  689.     self.model = string_null;
  690.     self.solid = SOLID_NOT;
  691.     if (deathmatch == 1)
  692.         self.nextthink = time + 30;
  693.     
  694.     self.think = SUB_regen;
  695.  
  696.     activator = other;
  697.     SUB_UseTargets();                // fire all targets / killtargets
  698. };
  699.  
  700.  
  701.  
  702.  
  703. float WEAPON_BIG2 = 1;
  704.  
  705. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  706. */
  707.  
  708. void() item_shells =
  709. {
  710.     self.touch = ammo_touch;
  711.  
  712.     if (self.spawnflags & WEAPON_BIG2)
  713.     {
  714.         precache_model ("maps/b_shell1.bsp");
  715.         setmodel (self, "maps/b_shell1.bsp");
  716.         self.aflag = 40;
  717.     }
  718.     else
  719.     {
  720.         precache_model ("maps/b_shell0.bsp");
  721.         setmodel (self, "maps/b_shell0.bsp");
  722.         self.aflag = 20;
  723.     }
  724.     self.weapon = 1;
  725.     self.netname = "shells";
  726.     setsize (self, '0 0 0', '32 32 56');
  727.     StartItem ();
  728. };
  729.  
  730. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  731. */
  732.  
  733. void() item_spikes =
  734. {
  735.     self.touch = ammo_touch;
  736.  
  737.     if (self.spawnflags & WEAPON_BIG2)
  738.     {
  739.         precache_model ("maps/b_nail1.bsp");
  740.         setmodel (self, "maps/b_nail1.bsp");
  741.         self.aflag = 50;
  742.     }
  743.     else
  744.     {
  745.         precache_model ("maps/b_nail0.bsp");
  746.         setmodel (self, "maps/b_nail0.bsp");
  747.         self.aflag = 25;
  748.     }
  749.     self.weapon = 2;
  750.     self.netname = "nails";
  751.     setsize (self, '0 0 0', '32 32 56');
  752.     StartItem ();
  753. };
  754.  
  755. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  756. */
  757.  
  758. void() item_rockets =
  759. {
  760.     self.touch = ammo_touch;
  761.  
  762.     if (self.spawnflags & WEAPON_BIG2)
  763.     {
  764.         precache_model ("maps/b_rock1.bsp");
  765.         setmodel (self, "maps/b_rock1.bsp");
  766.         self.aflag = 10;
  767.     }
  768.     else
  769.     {
  770.         precache_model ("maps/b_rock0.bsp");
  771.         setmodel (self, "maps/b_rock0.bsp");
  772.         self.aflag = 5;
  773.     }
  774.     self.weapon = 3;
  775.     self.netname = "rockets";
  776.     setsize (self, '0 0 0', '32 32 56');
  777.     StartItem ();
  778. };
  779.  
  780.  
  781. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  782. */
  783.  
  784. void() item_cells =
  785. {
  786.     self.touch = ammo_touch;
  787.  
  788.     if (self.spawnflags & WEAPON_BIG2)
  789.     {
  790.         precache_model ("maps/b_batt1.bsp");
  791.         setmodel (self, "maps/b_batt1.bsp");
  792.         self.aflag = 12;
  793.     }
  794.     else
  795.     {
  796.         precache_model ("maps/b_batt0.bsp");
  797.         setmodel (self, "maps/b_batt0.bsp");
  798.         self.aflag = 6;
  799.     }
  800.     self.weapon = 4;
  801.     self.netname = "cells";
  802.     setsize (self, '0 0 0', '32 32 56');
  803.     StartItem ();
  804. };
  805.  
  806.  
  807. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  808. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  809. */
  810.  
  811. float WEAPON_SHOTGUN = 1;
  812. float WEAPON_ROCKET = 2;
  813. float WEAPON_SPIKES = 4;
  814. float WEAPON_BIG = 8;
  815. void() item_weapon =
  816. {
  817.     self.touch = ammo_touch;
  818.  
  819.     if (self.spawnflags & WEAPON_SHOTGUN)
  820.     {
  821.         if (self.spawnflags & WEAPON_BIG)
  822.         {
  823.             precache_model ("maps/b_shell1.bsp");
  824.             setmodel (self, "maps/b_shell1.bsp");
  825.             self.aflag = 40;
  826.         }
  827.         else
  828.         {
  829.             precache_model ("maps/b_shell0.bsp");
  830.             setmodel (self, "maps/b_shell0.bsp");
  831.             self.aflag = 20;
  832.         }
  833.         self.weapon = 1;
  834.         self.netname = "shells";
  835.     }
  836.  
  837.     if (self.spawnflags & WEAPON_SPIKES)
  838.     {
  839.         if (self.spawnflags & WEAPON_BIG)
  840.         {
  841.             precache_model ("maps/b_nail1.bsp");
  842.             setmodel (self, "maps/b_nail1.bsp");
  843.             self.aflag = 40;
  844.         }
  845.         else
  846.         {
  847.             precache_model ("maps/b_nail0.bsp");
  848.             setmodel (self, "maps/b_nail0.bsp");
  849.             self.aflag = 20;
  850.         }
  851.         self.weapon = 2;
  852.         self.netname = "spikes";
  853.     }
  854.  
  855.     if (self.spawnflags & WEAPON_ROCKET)
  856.     {
  857.         if (self.spawnflags & WEAPON_BIG)
  858.         {
  859.             precache_model ("maps/b_rock1.bsp");
  860.             setmodel (self, "maps/b_rock1.bsp");
  861.             self.aflag = 10;
  862.         }
  863.         else
  864.         {
  865.             precache_model ("maps/b_rock0.bsp");
  866.             setmodel (self, "maps/b_rock0.bsp");
  867.             self.aflag = 5;
  868.         }
  869.         self.weapon = 3;
  870.         self.netname = "rockets";
  871.     }
  872.     
  873.     setsize (self, '0 0 0', '32 32 56');
  874.     StartItem ();
  875. };
  876.  
  877.  
  878. /*
  879. ===============================================================================
  880.  
  881. KEYS
  882.  
  883. ===============================================================================
  884. */
  885.  
  886. void() key_touch =
  887. {
  888. local entity    stemp;
  889. local float        best;
  890.  
  891.     if (other.classname != "player")
  892.         return;
  893.     if (other.health <= 0)
  894.         return;
  895.     if (other.items & self.items)
  896.         return;
  897.  
  898.     sprint (other, "You got the ");
  899.     sprint (other, self.netname);
  900.     sprint (other,"\n");
  901.  
  902.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  903.     stuffcmd (other, "bf\n");
  904.     other.items = other.items | self.items;
  905.  
  906.     if (!coop)
  907.     {    
  908.         self.solid = SOLID_NOT;
  909.         self.model = string_null;
  910.     }
  911.  
  912.     activator = other;
  913.     SUB_UseTargets();                // fire all targets / killtargets
  914. };
  915.  
  916.  
  917. void() key_setsounds =
  918. {
  919.     if (world.worldtype == 0)
  920.     {
  921.         precache_sound ("misc/medkey.wav");
  922.         self.noise = "misc/medkey.wav";
  923.     }
  924.     if (world.worldtype == 1)
  925.     {
  926.         precache_sound ("misc/runekey.wav");
  927.         self.noise = "misc/runekey.wav";
  928.     }
  929.     if (world.worldtype == 2)
  930.     {
  931.         precache_sound2 ("misc/basekey.wav");
  932.         self.noise = "misc/basekey.wav";
  933.     }
  934. };
  935.  
  936. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  937. SILVER key
  938. In order for keys to work
  939. you MUST set your maps
  940. worldtype to one of the
  941. following:
  942. 0: medieval
  943. 1: metal
  944. 2: base
  945. */
  946.  
  947. void() item_key1 =
  948. {
  949.     if (world.worldtype == 0)
  950.     {
  951.         precache_model ("progs/w_s_key.mdl");
  952.         setmodel (self, "progs/w_s_key.mdl");
  953.         self.netname = "silver key";
  954.     }
  955.     else if (world.worldtype == 1)
  956.     {
  957.         precache_model ("progs/m_s_key.mdl");
  958.         setmodel (self, "progs/m_s_key.mdl");
  959.         self.netname = "silver runekey";
  960.     }
  961.     else if (world.worldtype == 2)
  962.     {
  963.         precache_model2 ("progs/b_s_key.mdl");
  964.         setmodel (self, "progs/b_s_key.mdl");
  965.         self.netname = "silver keycard";
  966.     }
  967.     key_setsounds();
  968.     self.touch = key_touch;
  969.     self.items = IT_KEY1;
  970.     setsize (self, '-16 -16 -24', '16 16 32');
  971.     StartItem ();
  972. };
  973.  
  974. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  975. GOLD key
  976. In order for keys to work
  977. you MUST set your maps
  978. worldtype to one of the
  979. following:
  980. 0: medieval
  981. 1: metal
  982. 2: base
  983. */
  984.  
  985. void() item_key2 =
  986. {
  987.     if (world.worldtype == 0)
  988.     {
  989.         precache_model ("progs/w_g_key.mdl");
  990.         setmodel (self, "progs/w_g_key.mdl");
  991.         self.netname = "gold key";
  992.     }
  993.     if (world.worldtype == 1)
  994.     {
  995.         precache_model ("progs/m_g_key.mdl");
  996.         setmodel (self, "progs/m_g_key.mdl");
  997.         self.netname = "gold runekey";
  998.     }
  999.     if (world.worldtype == 2)
  1000.     {
  1001.         precache_model2 ("progs/b_g_key.mdl");
  1002.         setmodel (self, "progs/b_g_key.mdl");
  1003.         self.netname = "gold keycard";
  1004.     }
  1005.     key_setsounds();
  1006.     self.touch = key_touch;
  1007.     self.items = IT_KEY2;
  1008.     setsize (self, '-16 -16 -24', '16 16 32');
  1009.     StartItem ();
  1010. };
  1011.  
  1012.  
  1013.  
  1014. /*
  1015. ===============================================================================
  1016.  
  1017. END OF LEVEL RUNES
  1018.  
  1019. ===============================================================================
  1020. */
  1021.  
  1022. void() sigil_touch =
  1023. {
  1024. local entity    stemp;
  1025. local float        best;
  1026.  
  1027.     if (other.classname != "player")
  1028.         return;
  1029.     if (other.health <= 0)
  1030.         return;
  1031.  
  1032.     centerprint (other, "You got the rune!");
  1033.  
  1034.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1035.     stuffcmd (other, "bf\n");
  1036.     self.solid = SOLID_NOT;
  1037.     self.model = string_null;
  1038.     serverflags = serverflags | (self.spawnflags & 15);
  1039.     self.classname = "";        // so rune doors won't find it
  1040.     
  1041.     activator = other;
  1042.     SUB_UseTargets();                // fire all targets / killtargets
  1043. };
  1044.  
  1045.  
  1046. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1047. End of level sigil, pick up to end episode and return to jrstart.
  1048. */
  1049.  
  1050. void() item_sigil =
  1051. {
  1052.     if (!self.spawnflags)
  1053.         objerror ("no spawnflags");
  1054.  
  1055.     precache_sound ("misc/runekey.wav");
  1056.     self.noise = "misc/runekey.wav";
  1057.  
  1058.     if (self.spawnflags & 1)
  1059.     {
  1060.         precache_model ("progs/end1.mdl");
  1061.         setmodel (self, "progs/end1.mdl");
  1062.     }
  1063.     if (self.spawnflags & 2)
  1064.     {
  1065.         precache_model2 ("progs/end2.mdl");
  1066.         setmodel (self, "progs/end2.mdl");
  1067.     }
  1068.     if (self.spawnflags & 4)
  1069.     {
  1070.         precache_model2 ("progs/end3.mdl");
  1071.         setmodel (self, "progs/end3.mdl");
  1072.     }
  1073.     if (self.spawnflags & 8)
  1074.     {
  1075.         precache_model2 ("progs/end4.mdl");
  1076.         setmodel (self, "progs/end4.mdl");
  1077.     }
  1078.     
  1079.     self.touch = sigil_touch;
  1080.     setsize (self, '-16 -16 -24', '16 16 32');
  1081.     StartItem ();
  1082. };
  1083.  
  1084. /*
  1085. ===============================================================================
  1086.  
  1087. POWERUPS
  1088.  
  1089. ===============================================================================
  1090. */
  1091.  
  1092. void() powerup_touch;
  1093.  
  1094.  
  1095. void() powerup_touch =
  1096. {
  1097. local entity    stemp;
  1098. local float        best;
  1099.  
  1100.     if (other.classname != "player")
  1101.         return;
  1102.     if (other.health <= 0)
  1103.         return;
  1104.  
  1105.     sprint (other, "You got the ");
  1106.     sprint (other, self.netname);
  1107.     sprint (other,"\n");
  1108.  
  1109.     if (deathmatch)
  1110.     {
  1111.         self.mdl = self.model;
  1112.         
  1113.         if ((self.classname == "item_artifact_invulnerability") ||
  1114.             (self.classname == "item_artifact_invisibility"))
  1115.             self.nextthink = time + 60*5;
  1116.         else
  1117.             self.nextthink = time + 60;
  1118.         
  1119.         self.think = SUB_regen;
  1120.     }    
  1121.  
  1122.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1123.     stuffcmd (other, "bf\n");
  1124.     self.solid = SOLID_NOT;
  1125.     other.items = other.items | self.items;
  1126.     self.model = string_null;
  1127.  
  1128. // do the apropriate action
  1129.  
  1130. /*
  1131. MOD:
  1132. I clipped out the part where the items effects come into
  1133. action and instead it just increments your item count.
  1134. The code I hope is pretty self-explanitory.
  1135. */
  1136.  
  1137.     if (self.classname == "item_artifact_envirosuit")
  1138.     {
  1139.                 other.ammo_item_radsuit = other.ammo_item_radsuit + 1;
  1140.                 return;
  1141.         }
  1142.     
  1143.     if (self.classname == "item_artifact_invulnerability")
  1144.     {
  1145.                 other.ammo_item_invincible = other.ammo_item_invincible + 1;
  1146.                 return;
  1147.     }
  1148.     
  1149.     if (self.classname == "item_artifact_invisibility")
  1150.     {
  1151.                 other.ammo_item_invisible = other.ammo_item_invisible + 1;
  1152.                 return;
  1153.         }
  1154.  
  1155.     if (self.classname == "item_artifact_super_damage")
  1156.     {
  1157.                 other.ammo_item_super_damage = other.ammo_item_super_damage + 1;
  1158.                 return;
  1159.         }
  1160. /*
  1161. MOD:
  1162. Checks to see if you have more then 9 power ups.
  1163. */
  1164.         bound_other_ammo ();           
  1165.     activator = other;
  1166.     SUB_UseTargets();                // fire all targets / killtargets
  1167. };
  1168.  
  1169.  
  1170.  
  1171. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1172. Player is invulnerable for 30 seconds
  1173. */
  1174. void() item_artifact_invulnerability =
  1175. {
  1176.     self.touch = powerup_touch;
  1177.  
  1178.     precache_model ("progs/invulner.mdl");
  1179.         precache_sound ("items/r_item2.wav"); // MOD: was changed to fit in
  1180.         self.noise = "items/r_item2.wav"; // MOD: was changed to fit in
  1181.         setmodel (self, "progs/invulner.mdl");
  1182.     self.netname = "Pentagram of Protection";
  1183.         setsize (self, '-16 -16 -24', '16 16 32');
  1184.     StartItem ();
  1185. };
  1186.  
  1187. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1188. Player takes no damage from water or slime for 30 seconds
  1189. */
  1190. void() item_artifact_envirosuit =
  1191. {
  1192.     self.touch = powerup_touch;
  1193.  
  1194.     precache_model ("progs/suit.mdl");
  1195.         precache_sound ("items/r_item2.wav"); // MOD: was changed to fit in
  1196.         self.noise = "items/r_item2.wav"; // MOD: was changed to fit in
  1197.     setmodel (self, "progs/suit.mdl");
  1198.     self.netname = "Biosuit";
  1199.         setsize (self, '-16 -16 -24', '16 16 32');
  1200.     StartItem ();
  1201. };
  1202.  
  1203.  
  1204. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1205. Player is invisible for 30 seconds
  1206. */
  1207. void() item_artifact_invisibility =
  1208. {
  1209.     self.touch = powerup_touch;
  1210.  
  1211.     precache_model ("progs/invisibl.mdl");
  1212.         precache_sound ("items/r_item2.wav"); // MOD: was changed to fit in
  1213.         self.noise = "items/r_item2.wav"; // MOD: was changed to fit in
  1214.     setmodel (self, "progs/invisibl.mdl");
  1215.     self.netname = "Ring of Shadows";
  1216.         setsize (self, '-16 -16 -24', '16 16 32');
  1217.     StartItem ();
  1218. };
  1219.  
  1220.  
  1221. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1222. The next attack from the player will do 4x damage
  1223. */
  1224. void() item_artifact_super_damage =
  1225. {
  1226.     self.touch = powerup_touch;
  1227.  
  1228.     precache_model ("progs/quaddama.mdl");
  1229.         precache_sound ("items/r_item2.wav"); // MOD: was changed to fit in
  1230.         self.noise = "items/r_item2.wav"; // MOD: was changed to fit in
  1231.     setmodel (self, "progs/quaddama.mdl");
  1232.     self.netname = "Quad Damage";
  1233.     setsize (self, '-16 -16 -24', '16 16 32');
  1234.     StartItem ();
  1235. };
  1236.  
  1237.  
  1238.  
  1239. /*
  1240. ===============================================================================
  1241.  
  1242. PLAYER BACKPACKS
  1243.  
  1244. ===============================================================================
  1245. */
  1246.  
  1247. void() BackpackTouch =
  1248. {
  1249.     local string    s;
  1250.     local    float    best;
  1251.     local        entity    stemp;
  1252.     
  1253.     if (other.classname != "player")
  1254.         return;
  1255.     if (other.health <= 0)
  1256.         return;
  1257.         
  1258. // if the player was using his best weapon, change up to the new one if better        
  1259.     stemp = self;
  1260.     self = other;
  1261.     best = W_BestWeapon();
  1262.     self = stemp;
  1263.  
  1264. // change weapons
  1265.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1266.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1267.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1268.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1269. /*
  1270. MOD:
  1271. Just like the weapons, give objects to player.
  1272. */
  1273.         other.ammo_item_super_damage = other.ammo_item_super_damage +  self.ammo_item_super_damage;
  1274.         other.ammo_item_invincible = other.ammo_item_invincible + self.ammo_item_invincible;
  1275.         other.ammo_item_invisible = other.ammo_item_invisible + self.ammo_item_invisible;
  1276.         other.ammo_item_radsuit = other.ammo_item_radsuit + self.ammo_item_radsuit;
  1277.  
  1278.  
  1279.     other.items = other.items | self.items;
  1280.     
  1281.     bound_other_ammo ();
  1282.  
  1283.     sprint (other, "You get ");
  1284.  
  1285.     if (self.ammo_shells)
  1286.     {
  1287.         s = ftos(self.ammo_shells);
  1288.         sprint (other, s);
  1289.         sprint (other, " shells  ");
  1290.     }
  1291.     if (self.ammo_nails)
  1292.     {
  1293.         s = ftos(self.ammo_nails);
  1294.         sprint (other, s);
  1295.         sprint (other, " nails ");
  1296.     }
  1297.     if (self.ammo_rockets)
  1298.     {
  1299.         s = ftos(self.ammo_rockets);
  1300.         sprint (other, s);
  1301.         sprint (other, " rockets  ");
  1302.     }
  1303.     if (self.ammo_cells)
  1304.     {
  1305.         s = ftos(self.ammo_cells);
  1306.         sprint (other, s);
  1307.         sprint (other, " cells  ");
  1308.     }
  1309.  
  1310.     if (self.ammo_cells)
  1311.     {
  1312.         s = ftos(self.ammo_cells);
  1313.         sprint (other, s);
  1314.         sprint (other, " cells  ");
  1315.     }
  1316.  
  1317. /*
  1318. MOD:
  1319. Tells you if you got any power-ups in that backpack.
  1320. */
  1321.  
  1322.         if (self.ammo_item_super_damage)
  1323.     {
  1324.                 sprint (other, "  a Quad Damage  ");
  1325.     }
  1326.         if (self.ammo_item_invincible)
  1327.     {
  1328.                 sprint (other, "  a Pentagram of Protection  ");
  1329.     }
  1330.         if (self.ammo_item_invisible)
  1331.     {
  1332.                 sprint (other, "  the Ring of Shadows  ");
  1333.     }
  1334.         if (self.ammo_item_radsuit)
  1335.     {
  1336.                 sprint (other, "  a Biosuit  ");
  1337.     }
  1338.  
  1339.         sprint ( other, "\n");
  1340. // backpack touch sound
  1341.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1342.     stuffcmd (other, "bf\n");
  1343.  
  1344. // change to a better weapon if appropriate
  1345.     if ( other.weapon == best )
  1346.     {
  1347.         stemp = self;
  1348.         self = other;
  1349.         self.weapon = W_BestWeapon();
  1350.         self = stemp;
  1351.     }
  1352.  
  1353.     
  1354.     remove(self);
  1355.     
  1356.     self = other;
  1357.     W_SetCurrentAmmo ();
  1358. };
  1359.  
  1360. /*
  1361. ===============
  1362. DropBackpack
  1363. ===============
  1364. */
  1365. void() DropBackpack =
  1366. {
  1367.     local entity    item;
  1368.  
  1369.         if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells + self.ammo_item_super_damage + self.ammo_item_invisible + self.ammo_item_invincible + self.ammo_item_radsuit))
  1370.         return;    // nothing in it
  1371.  
  1372.     item = spawn();
  1373.     item.origin = self.origin - '0 0 24';
  1374.     
  1375.     item.items = self.weapon;
  1376.  
  1377.     item.ammo_shells = self.ammo_shells;
  1378.     item.ammo_nails = self.ammo_nails;
  1379.     item.ammo_rockets = self.ammo_rockets;
  1380.     item.ammo_cells = self.ammo_cells;
  1381.  
  1382. /*
  1383. MOD:
  1384.         If unused power ups present, put
  1385.         one in backpack
  1386. */
  1387.  
  1388.         if (self.ammo_item_super_damage > 0)
  1389.                 item.ammo_item_super_damage = 1;
  1390.         if (self.ammo_item_invincible > 0)
  1391.                 item.ammo_item_invincible = 1;
  1392.         if (self.ammo_item_invisible > 0)
  1393.                 item.ammo_item_invisible = 1;
  1394.         if (self.ammo_item_radsuit > 0)
  1395.                 item.ammo_item_radsuit = 1;
  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_TRIGGER;
  1403.     item.movetype = MOVETYPE_TOSS;
  1404.     setmodel (item, "progs/backpack.mdl");
  1405.     setsize (item, '-16 -16 0', '16 16 56');
  1406.     item.touch = BackpackTouch;
  1407.     
  1408.     item.nextthink = time + 120;    // remove after 2 minutes
  1409.     item.think = SUB_Remove;
  1410. };
  1411.