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