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

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