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

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