home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / das_dm10 / items.qc < prev    next >
Encoding:
Text File  |  1996-08-13  |  29.6 KB  |  1,367 lines

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