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

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