home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / lasergn1 / items.qc < prev    next >
Encoding:
Text File  |  1996-07-26  |  28.7 KB  |  1,366 lines

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