// w_items.qc: items the player can pick up string() key_1_name = { switch(world.worldtype) { case WORLD_MEDIEVAL: return "silver key"; case WORLD_METAL: return "silver runekey"; case WORLD_BASE: return "silver keycard"; default: return string_null; } }; string() key_2_name = { switch(world.worldtype) { case WORLD_MEDIEVAL: return "gold key"; case WORLD_METAL: return "gold runekey"; case WORLD_BASE: return "gold keycard"; default: return string_null; } }; /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD BE .8 .3 .4 IN COLOR */ void() sub_regen = { self.model = self.mdl; // restore original model self.solid = SOLID_TRIGGER; // allow it to be touched again sound(self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM); // play respawn sound set_origin(self, self.origin); }; /*QUAKED noclass(0 0 0) (-8 -8 -8) (8 8 8) prints a warning message when spawned */ void() noclass = { print_dbg("noclass spawned at", vtos(self.origin), "\n"); remove(self); }; /* ============ place_item plants the object on the floor ============ */ void() place_item = { float oldz; self.mdl = self.model; // so it can be restored on respawn self.flags = FL_ITEM; // make extra wide self.solid = SOLID_TRIGGER; self.movetype = MOVETYPE_TOSS; self.velocity = VEC_ORIGIN; self.origin_z = self.origin_z + 6; oldz = self.origin_z; if(!drop_to_floor()) { print_dbg("Bonus item fell out of level at ", vtos(self.origin), "\n"); remove(self); return; } }; /* ============ start_item Sets the clipping size and plants the object on the floor ============ */ void() start_item = { self.nextthink = time + 0.2; // items start after other solids self.think = place_item; }; /* ========================================================================= HEALTH BOX ========================================================================= */ // // ent_heal: add health to an entity, limiting health to max_health // "ignore" will ignore max_health limit // float(entity e, float healamount, float ignore) ent_heal = { if(e.health <= 0 || (!ignore && e.health >= other.max_health)) { return 0; } healamount = ceil(healamount); e.health = e.health + healamount; if(!ignore && e.health >= other.max_health) { e.health = other.max_health; } if(e.health > 250) { e.health = 250; } return 1; }; void() item_megahealth_rot = { other = self.owner; if(other.health > other.max_health) { other.health = other.health - 1; self.nextthink = time + 1; return; } // it is possible for a player to die and respawn between rots, so don't // just blindly subtract the flag off other.items = other.items - (other.items & IT_SUPERHEALTH); if(deathmatch == 1) { // deathmatch 2 is silly old rules self.nextthink = time + 20; self.think = sub_regen; } }; void() health_touch = { float amount; if(other.classname != "player") { return; } if(self.healtype == 2) { // Megahealth? Ignore max_health... if(other.health >= 250 || !ent_heal(other, self.healamount, TRUE)) { return; } } else if(!ent_heal(other, self.healamount, FALSE)) { return; } print_cl(other, "You receive ", ftos(self.healamount), " health\n"); // health touch sound sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM); cmd_client(other, "bf\n"); self.model = string_null; self.solid = SOLID_NOT; // Megahealth = rot down the player's super health if(self.healtype == 2) { other.items = other.items | IT_SUPERHEALTH; self.nextthink = time + 5; self.think = item_megahealth_rot; self.owner = other; } else { if(deathmatch != 2) { // deathmatch 2 is the silly old rules if(deathmatch) { self.nextthink = time + 20; } self.think = sub_regen; } } activator = other; sub_use_targets(); // fire all targets / killtargets }; /*QUAKED item_health(.3 .3 1) (0 0 0) (32 32 32) rotten megahealth Health box. Normally gives 25 points. Rotten box heals 15 points, Megahealth will add 100 health, then rot you down to your maximum health limit, one point per second. */ void() item_health = { self.touch = health_touch; if(self.spawnflags & HEALTH_ROTTEN) { precache_model("maps/b_bh10.bsp"); precache_sound("items/r_item1.wav"); set_model(self, "maps/b_bh10.bsp"); self.noise = "items/r_item1.wav"; self.healamount = 15; self.healtype = 0; } else if(self.spawnflags & HEALTH_MEGA) { precache_model("maps/b_bh100.bsp"); precache_sound("items/r_item2.wav"); set_model(self, "maps/b_bh100.bsp"); self.noise = "items/r_item2.wav"; self.healamount = 100; self.healtype = 2; } else { precache_model("maps/b_bh25.bsp"); precache_sound("items/health1.wav"); set_model(self, "maps/b_bh25.bsp"); self.noise = "items/health1.wav"; self.healamount = 25; self.healtype = 1; } set_size(self, VEC_ORIGIN, '32 32 56'); start_item(); }; /* =============================================================================== ARMOR =============================================================================== */ void() armor_touch = { float type, value, bit; if(other.health <= 0 || other.classname != "player") { return; } switch(self.classname) { case "item_armor1": type = 0.3; value = 100; bit = IT_ARMOR1; break; case "item_armor2": type = 0.6; value = 150; bit = IT_ARMOR2; break; case "item_armorInv": type = 0.8; value = 200; bit = IT_ARMOR3; break; } if(other.armortype * other.armorvalue >= type * value) { return; } other.armortype = type; other.armorvalue = value; other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit; self.solid = SOLID_NOT; self.model = string_null; if(deathmatch == 1) { self.nextthink = time + 20; } self.think = sub_regen; print_cl(other, "You got armor\n"); // armor touch sound sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); cmd_client(other, "bf\n"); activator = other; sub_use_targets(); // fire all targets / killtargets }; /*QUAKED item_armor1(0 .5 .8) (-16 -16 0) (16 16 32) */ void() item_armor1 = { self.touch = armor_touch; precache_model("progs/armor.mdl"); set_model(self, "progs/armor.mdl"); self.skin = 0; set_size(self, '-16 -16 0', '16 16 56'); start_item(); }; /*QUAKED item_armor2(0 .5 .8) (-16 -16 0) (16 16 32) */ void() item_armor2 = { self.touch = armor_touch; precache_model("progs/armor.mdl"); set_model(self, "progs/armor.mdl"); self.skin = 1; set_size(self, '-16 -16 0', '16 16 56'); start_item(); }; /*QUAKED item_armorInv(0 .5 .8) (-16 -16 0) (16 16 32) */ void() item_armorInv = { self.touch = armor_touch; precache_model("progs/armor.mdl"); set_model(self, "progs/armor.mdl"); self.skin = 2; set_size(self, '-16 -16 0', '16 16 56'); start_item(); }; /* =============================================================================== WEAPONS =============================================================================== */ void(entity e) bound_ammo = { if(e.ammo_shells > AMMAX_SHELLS) { e.ammo_shells = AMMAX_SHELLS; } if(e.ammo_nails > AMMAX_NAILS) { e.ammo_nails = AMMAX_NAILS; } if(e.ammo_rockets > AMMAX_ROCKETS) { e.ammo_rockets = AMMAX_ROCKETS; } if(e.ammo_cells > AMMAX_CELLS) { e.ammo_cells = AMMAX_CELLS; } }; float(float w) wep_rank_for_weapon = { switch(w) { case IT_LIGHTNING: if(self.waterlevel <= 1) { return 1; } case IT_ROCKET_LAUNCHER: return 2; case IT_SUPER_NAILGUN: return 3; case IT_GRENADE_LAUNCHER: return 4; case IT_SUPER_SHOTGUN: return 5; case IT_NAILGUN: return 6; default: return 7; } }; /* ============= wep_deathmatch_weapon Deathmatch weapon change rules for picking up a weapon ============= */ void(float old, float new) wep_deathmatch_weapon = { float or, nr; // change self.weapon if desired or = wep_rank_for_weapon(self.weapon); nr = wep_rank_for_weapon(new); if(nr < or) { self.weapon = new; } }; /* ============= weapon_touch ============= */ void() weapon_touch = { float hadammo, best, new, old; entity stemp; float leave; if(!(other.flags & FL_CLIENT)) { return; } // if the player was using their best weapon, change up to the new one if // better stemp = self; self = other; best = wep_best_weapon(); self = stemp; leave = (deathmatch == 2 || coop); switch(self.classname) { case "weapon_nailgun": if(leave && other.items & IT_NAILGUN) { return; } hadammo = other.ammo_nails; new = IT_NAILGUN; other.ammo_nails = other.ammo_nails + 30; break; case "weapon_supernailgun": if(leave && other.items & IT_SUPER_NAILGUN) { return; } hadammo = other.ammo_rockets; new = IT_SUPER_NAILGUN; other.ammo_nails = other.ammo_nails + 30; break; case "weapon_supershotgun": if(leave && other.items & IT_SUPER_SHOTGUN) { return; } hadammo = other.ammo_rockets; new = IT_SUPER_SHOTGUN; other.ammo_shells = other.ammo_shells + 5; break; case "weapon_rocketlauncher": if(leave && other.items & IT_ROCKET_LAUNCHER) { return; } hadammo = other.ammo_rockets; new = IT_ROCKET_LAUNCHER; other.ammo_rockets = other.ammo_rockets + 5; break; case "weapon_grenadelauncher": if(leave && other.items & IT_GRENADE_LAUNCHER) { return; } hadammo = other.ammo_rockets; new = IT_GRENADE_LAUNCHER; other.ammo_rockets = other.ammo_rockets + 5; break; case "weapon_lightning": if(leave && other.items & IT_LIGHTNING) { return; } hadammo = other.ammo_rockets; new = IT_LIGHTNING; other.ammo_cells = other.ammo_cells + 15; break; default: error_obj("weapon_touch: unknown classname"); } print_cl(other, "You got the ", self.netname, "\n"); // weapon touch sound sound(other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM); cmd_client(other, "bf\n"); bound_ammo(other); // change to the weapon old = other.items; other.items = other.items | new; stemp = self; self = other; wep_deathmatch_weapon(old, new); wep_set_current_ammo(); self = stemp; if(leave) { return; } // remove it in single player, or setup for respawning in deathmatch self.model = string_null; self.solid = SOLID_NOT; if(deathmatch == 1) { self.nextthink = time + 30; } self.think = sub_regen; activator = other; sub_use_targets(); // fire all targets / killtargets }; /*QUAKED weapon_supershotgun(0 .5 .8) (-16 -16 0) (16 16 32) */ void() weapon_supershotgun = { precache_model("progs/g_shot.mdl"); set_model(self, "progs/g_shot.mdl"); self.weapon = IT_SUPER_SHOTGUN; self.netname = WEPNAME_SUPER_SHOTGUN; self.touch = weapon_touch; set_size(self, '-16 -16 0', '16 16 56'); start_item(); }; /*QUAKED weapon_nailgun(0 .5 .8) (-16 -16 0) (16 16 32) */ void() weapon_nailgun = { precache_model("progs/g_nail.mdl"); set_model(self, "progs/g_nail.mdl"); self.weapon = IT_NAILGUN; self.netname = WEPNAME_NAILGUN; self.touch = weapon_touch; set_size(self, '-16 -16 0', '16 16 56'); start_item(); }; /*QUAKED weapon_supernailgun(0 .5 .8) (-16 -16 0) (16 16 32) */ void() weapon_supernailgun = { precache_model("progs/g_nail2.mdl"); set_model(self, "progs/g_nail2.mdl"); self.weapon = IT_SUPER_NAILGUN; self.netname = WEPNAME_SUPER_NAILGUN; self.touch = weapon_touch; set_size(self, '-16 -16 0', '16 16 56'); start_item(); }; /*QUAKED weapon_grenadelauncher(0 .5 .8) (-16 -16 0) (16 16 32) */ void() weapon_grenadelauncher = { precache_model("progs/g_rock.mdl"); set_model(self, "progs/g_rock.mdl"); self.weapon = 3; self.netname = WEPNAME_GRENADE_LAUNCHER; self.touch = weapon_touch; set_size(self, '-16 -16 0', '16 16 56'); start_item(); }; /*QUAKED weapon_rocketlauncher(0 .5 .8) (-16 -16 0) (16 16 32) */ void() weapon_rocketlauncher = { precache_model("progs/g_rock2.mdl"); set_model(self, "progs/g_rock2.mdl"); self.weapon = 3; self.netname = WEPNAME_ROCKET_LAUNCHER; self.touch = weapon_touch; set_size(self, '-16 -16 0', '16 16 56'); start_item(); }; /*QUAKED weapon_lightning(0 .5 .8) (-16 -16 0) (16 16 32) */ void() weapon_lightning = { precache_model("progs/g_light.mdl"); set_model(self, "progs/g_light.mdl"); self.weapon = 3; self.netname = WEPNAME_LIGHTNING; self.touch = weapon_touch; set_size(self, '-16 -16 0', '16 16 56'); start_item(); }; /* =============================================================================== AMMO =============================================================================== */ void(.float ammo, float max) distribute_ammo = { entity pl, stemp; if(sc_dist_ammo) { pl = find(world, classname, "player"); while(pl != world) { pl.ammo += self.aflag; bound_ammo(pl); stemp = self; self = pl; wep_set_current_ammo(); self = stemp; pl = find(pl, classname, "player"); } } else { if(other.ammo >= max) { return; } other.ammo += self.aflag; bound_ammo(other); } }; void() ammo_touch = { entity stemp; float best; if(other.classname != "player" || other.health <= 0) { return; } // if the player was using their best weapon, change up to the new one if // better stemp = self; self = other; best = wep_best_weapon(); self = stemp; switch(self.weapon) { case AMTYPE_SHELLS: distribute_ammo(ammo_shells, AMMAX_SHELLS); break; case AMTYPE_NAILS: distribute_ammo(ammo_nails, AMMAX_NAILS); break; case AMTYPE_ROCKETS: distribute_ammo(ammo_rockets, AMMAX_ROCKETS); break; case AMTYPE_CELLS: distribute_ammo(ammo_cells, AMMAX_CELLS); break; } print_cl(other, "You got the ", self.netname, "\n"); // ammo touch sound sound(other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM); cmd_client(other, "bf\n"); // change to a better weapon if appropriate if(other.weapon == best) { stemp = self; self = other; self.weapon = wep_best_weapon(); wep_set_current_ammo(); self = stemp; } // if changed current ammo, update it stemp = self; self = other; wep_set_current_ammo(); self = stemp; // remove it in single player, or setup for respawning in deathmatch self.model = string_null; self.solid = SOLID_NOT; if(deathmatch == 1) { self.nextthink = time + 30; } self.think = sub_regen; activator = other; sub_use_targets(); // fire all targets / killtargets }; /*QUAKED item_shells(0 .5 .8) (0 0 0) (32 32 32) big */ void() item_shells = { self.touch = ammo_touch; if(self.spawnflags & AMMO_BIG) { precache_model("maps/b_shell1.bsp"); set_model(self, "maps/b_shell1.bsp"); self.aflag = 40; } else { precache_model("maps/b_shell0.bsp"); set_model(self, "maps/b_shell0.bsp"); self.aflag = 20; } self.weapon = 1; self.netname = "shells"; set_size(self, VEC_ORIGIN, '32 32 56'); start_item(); }; /*QUAKED item_spikes(0 .5 .8) (0 0 0) (32 32 32) big */ void() item_spikes = { self.touch = ammo_touch; if(self.spawnflags & AMMO_BIG) { precache_model("maps/b_nail1.bsp"); set_model(self, "maps/b_nail1.bsp"); self.aflag = 50; } else { precache_model("maps/b_nail0.bsp"); set_model(self, "maps/b_nail0.bsp"); self.aflag = 25; } self.weapon = 2; self.netname = "nails"; set_size(self, VEC_ORIGIN, '32 32 56'); start_item(); }; /*QUAKED item_rockets(0 .5 .8) (0 0 0) (32 32 32) big */ void() item_rockets = { self.touch = ammo_touch; if(self.spawnflags & AMMO_BIG) { precache_model("maps/b_rock1.bsp"); set_model(self, "maps/b_rock1.bsp"); self.aflag = 10; } else { precache_model("maps/b_rock0.bsp"); set_model(self, "maps/b_rock0.bsp"); self.aflag = 5; } self.weapon = 3; self.netname = "rockets"; set_size(self, VEC_ORIGIN, '32 32 56'); start_item(); }; /*QUAKED item_cells(0 .5 .8) (0 0 0) (32 32 32) big */ void() item_cells = { self.touch = ammo_touch; if(self.spawnflags & AMMO_BIG) { precache_model("maps/b_batt1.bsp"); set_model(self, "maps/b_batt1.bsp"); self.aflag = 12; } else { precache_model("maps/b_batt0.bsp"); set_model(self, "maps/b_batt0.bsp"); self.aflag = 6; } self.weapon = 4; self.netname = "cells"; set_size(self, VEC_ORIGIN, '32 32 56'); start_item(); }; /* =============================================================================== KEYS =============================================================================== */ void() key_touch = { entity stemp; float best; if(other.classname != "player" || other.health <= 0 || other.items & self.items) { return; } print_cl(other, "You got the ", self.netname, "\n"); sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM); cmd_client(other, "bf\n"); other.items |= self.items; if(!coop) { self.solid = SOLID_NOT; self.model = string_null; } activator = other; sub_use_targets(); // fire all targets / killtargets }; void() key_setsounds = { switch(world.worldtype) { case WORLD_MEDIEVAL: precache_sound("misc/medkey.wav"); self.noise = "misc/medkey.wav"; break; case WORLD_METAL: precache_sound("misc/runekey.wav"); self.noise = "misc/runekey.wav"; break; case WORLD_BASE: precache_sound2("misc/basekey.wav"); self.noise = "misc/basekey.wav"; break; } }; /*QUAKED item_key1(0 .5 .8) (-16 -16 -24) (16 16 32) SILVER key In order for keys to work you MUST set your maps worldtype to one of the following: 0: medieval 1: metal 2: base */ void() item_key1 = { self.netname = key_1_name(); switch(world.worldtype) { case WORLD_MEDIEVAL: precache_model("progs/w_s_key.mdl"); set_model(self, "progs/w_s_key.mdl"); break; case WORLD_METAL: precache_model("progs/m_s_key.mdl"); set_model(self, "progs/m_s_key.mdl"); break; case WORLD_BASE: precache_model2("progs/b_s_key.mdl"); set_model(self, "progs/b_s_key.mdl"); break; } key_setsounds(); self.touch = key_touch; self.items = IT_KEY1; set_size(self, '-16 -16 -24', '16 16 32'); start_item(); }; /*QUAKED item_key2(0 .5 .8) (-16 -16 -24) (16 16 32) GOLD key In order for keys to work you MUST set your maps worldtype to one of the following: 0: medieval 1: metal 2: base */ void() item_key2 = { self.netname = key_2_name(); switch(world.worldtype) { case WORLD_MEDIEVAL: precache_model("progs/w_g_key.mdl"); set_model(self, "progs/w_g_key.mdl"); break; case WORLD_METAL: precache_model("progs/m_g_key.mdl"); set_model(self, "progs/m_g_key.mdl"); break; case WORLD_BASE: precache_model2("progs/b_g_key.mdl"); set_model(self, "progs/b_g_key.mdl"); break; } key_setsounds(); self.touch = key_touch; self.items = IT_KEY2; set_size(self, '-16 -16 -24', '16 16 32'); start_item(); }; /* =============================================================================== END OF LEVEL RUNES =============================================================================== */ void() sigil_touch = { entity stemp; float best; if(other.classname != "player" || other.health <= 0) { return; } print_center(other, "You got the rune!"); sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM); cmd_client(other, "bf\n"); self.solid = SOLID_NOT; self.model = string_null; serverflags = serverflags | (self.spawnflags & 15); self.classname = string_null; // so rune doors won't find it activator = other; sub_use_targets(); // fire all targets / killtargets }; /*QUAKED item_sigil(0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4 End of level sigil, pick up to end episode and return to jrstart. */ void() item_sigil = { if(!self.spawnflags) { error_obj("no spawnflags"); } precache_sound("misc/runekey.wav"); self.noise = "misc/runekey.wav"; if(self.spawnflags & SIGIL_1) { precache_model("progs/end1.mdl"); set_model(self, "progs/end1.mdl"); } if(self.spawnflags & SIGIL_2) { precache_model2("progs/end2.mdl"); set_model(self, "progs/end2.mdl"); } if(self.spawnflags & SIGIL_3) { precache_model2("progs/end3.mdl"); set_model(self, "progs/end3.mdl"); } if(self.spawnflags & SIGIL_4) { precache_model2("progs/end4.mdl"); set_model(self, "progs/end4.mdl"); } self.touch = sigil_touch; set_size(self, '-16 -16 -24', '16 16 32'); start_item(); }; /* =============================================================================== POWERUPS =============================================================================== */ void() powerup_touch = { entity stemp; float best; if(other.classname != "player" || other.health <= 0) { return; } print_cl(other, "You got the ", self.netname, "\n"); if(deathmatch) { self.mdl = self.model; if(self.classname == "item_artifact_invulnerability" || self.classname == "item_artifact_invisibility") { self.nextthink = time + 60 * 5; } else { self.nextthink = time + 60; } self.think = sub_regen; } sound(other, CHAN_VOICE, self.noise, 1, ATTN_NORM); cmd_client(other, "bf\n"); self.solid = SOLID_NOT; other.items = other.items | self.items; self.model = string_null; // do the apropriate action if(self.classname == "item_artifact_envirosuit") { other.rad_time = 1; other.radsuit_finished = time + 30; } if(self.classname == "item_artifact_invulnerability") { other.invincible_time = 1; other.invincible_finished = time + 30; } if(self.classname == "item_artifact_invisibility") { other.invisible_time = 1; other.invisible_finished = time + 30; } if(self.classname == "item_artifact_super_damage") { other.super_time = 1; other.super_damage_finished = time + 30; } activator = other; sub_use_targets(); // fire all targets / killtargets }; /*QUAKED item_artifact_invulnerability(0 .5 .8) (-16 -16 -24) (16 16 32) Player is invulnerable for 30 seconds */ void() item_artifact_invulnerability = { self.touch = powerup_touch; precache_model("progs/invulner.mdl"); precache_sound("items/protect.wav"); precache_sound("items/protect2.wav"); precache_sound("items/protect3.wav"); self.noise = "items/protect.wav"; set_model(self, "progs/invulner.mdl"); self.netname = "Pentagram of Protection"; self.items = IT_INVULNERABILITY; set_size(self, '-16 -16 -24', '16 16 32'); start_item(); }; /*QUAKED item_artifact_envirosuit(0 .5 .8) (-16 -16 -24) (16 16 32) Player takes no damage from water or slime for 30 seconds */ void() item_artifact_envirosuit = { self.touch = powerup_touch; precache_model("progs/suit.mdl"); precache_sound("items/suit.wav"); precache_sound("items/suit2.wav"); self.noise = "items/suit.wav"; set_model(self, "progs/suit.mdl"); self.netname = "Biosuit"; self.items = IT_SUIT; set_size(self, '-16 -16 -24', '16 16 32'); start_item(); }; /*QUAKED item_artifact_invisibility(0 .5 .8) (-16 -16 -24) (16 16 32) Player is invisible for 30 seconds */ void() item_artifact_invisibility = { self.touch = powerup_touch; precache_model("progs/invisibl.mdl"); precache_sound("items/inv1.wav"); precache_sound("items/inv2.wav"); precache_sound("items/inv3.wav"); self.noise = "items/inv1.wav"; set_model(self, "progs/invisibl.mdl"); self.netname = "Ring of Shadows"; self.items = IT_INVISIBILITY; set_size(self, '-16 -16 -24', '16 16 32'); start_item(); }; /*QUAKED item_artifact_super_damage(0 .5 .8) (-16 -16 -24) (16 16 32) The next attack from the player will do 4x damage */ void() item_artifact_super_damage = { self.touch = powerup_touch; precache_model("progs/quaddama.mdl"); precache_sound("items/damage.wav"); precache_sound("items/damage2.wav"); precache_sound("items/damage3.wav"); self.noise = "items/damage.wav"; set_model(self, "progs/quaddama.mdl"); self.netname = "Quad Damage"; self.items = IT_QUAD; set_size(self, '-16 -16 -24', '16 16 32'); start_item(); }; /* =============================================================================== PLAYER BACKPACKS =============================================================================== */ void() backpack_touch = { float best, old, new; entity stemp; float acount; if(other.classname != "player" || other.health <= 0) { return; } acount = 0; print_cl(other, "You get "); if(self.weapon && (other.items & self.weapon) == 0) { acount = 1; print_cl(other, "the ", self.netname); } // if the player was using their best weapon, change up to the new one if // better stemp = self; self = other; best = wep_best_weapon(); self = stemp; // change weapons other.ammo_shells = other.ammo_shells + self.ammo_shells; other.ammo_nails = other.ammo_nails + self.ammo_nails; other.ammo_rockets = other.ammo_rockets + self.ammo_rockets; other.ammo_cells = other.ammo_cells + self.ammo_cells; new = self.items; if(!new) { new = other.weapon; } old = other.items; other.items = other.items | new; bound_ammo(other); if(self.ammo_shells) { if(acount) { print_cl(other, ", "); } acount = 1; print_cl(other, ftos(self.ammo_shells), " shells"); } if(self.ammo_nails) { if(acount) { print_cl(other, ", "); } acount = 1; print_cl(other, ftos(self.ammo_nails), " nails"); } if(self.ammo_rockets) { if(acount) { print_cl(other, ", "); } acount = 1; print_cl(other, ftos(self.ammo_rockets), " rockets"); } if(self.ammo_cells) { if(acount) { print_cl(other, ", "); } acount = 1; print_cl(other, ftos(self.ammo_cells), " cells"); } if(self.items & IT_KEY1) { if(acount) { print_cl(other, ", "); } acount = 1; print_cl(other, key_1_name()); } if(self.items & IT_KEY2) { if(acount) { print_cl(other, ", "); } acount = 1; print_cl(other, key_2_name()); } print_cl(other, "\n"); // backpack touch sound sound(other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM); cmd_client(other, "bf\n"); // remove the backpack, change self to the player remove(self); self = other; // change to the weapon wep_deathmatch_weapon(old, new); wep_set_current_ammo(); }; /* =============== drop_backpack =============== */ entity() drop_backpack = { entity item; item = spawn(); item.origin = self.origin - '0 0 24'; item.items = self.weapon | (self.items & (IT_KEY1 | IT_KEY2)); item.weapon = self.weapon; switch(item.weapon) { case IT_AXE: item.netname = WEPNAME_AXE; break; case IT_SHOTGUN: item.netname = WEPNAME_SHOTGUN; break; case IT_SUPER_SHOTGUN: item.netname = WEPNAME_SUPER_SHOTGUN; break; case IT_NAILGUN: item.netname = WEPNAME_NAILGUN; break; case IT_SUPER_NAILGUN: item.netname = WEPNAME_SUPER_NAILGUN; break; case IT_GRENADE_LAUNCHER: item.netname = WEPNAME_GRENADE_LAUNCHER; break; case IT_ROCKET_LAUNCHER: item.netname = WEPNAME_ROCKET_LAUNCHER; break; case IT_LIGHTNING: item.netname = WEPNAME_LIGHTNING; break; default: item.netname = string_null; break; } item.ammo_shells = self.ammo_shells; item.ammo_nails = self.ammo_nails; item.ammo_rockets = self.ammo_rockets; item.ammo_cells = self.ammo_cells; item.velocity_z = 300; item.velocity_x = -100 + (random() * 200); item.velocity_y = -100 + (random() * 200); item.flags = FL_ITEM; item.solid = SOLID_TRIGGER; item.movetype = MOVETYPE_TOSS; set_model(item, "progs/backpack.mdl"); set_size(item, '-16 -16 0', '16 16 56'); item.touch = backpack_touch; item.nextthink = time + 120; // remove after 2 minutes item.think = sub_remove; return item; };