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