home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / patch / mbq120 / items.qc < prev    next >
Encoding:
Text File  |  1996-09-01  |  30.8 KB  |  1,472 lines

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