home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / q1source_amy / qw / progs / items.qc < prev    next >
Encoding:
Text File  |  1997-08-12  |  36.0 KB  |  1,661 lines

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