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