Files
quakemapping/mod_xj18/my_progs/items.qc
2020-01-07 11:54:38 +01:00

3381 lines
128 KiB
Plaintext

/*======================================================================
ITEM FUNCTIONS
======================================================================*/
float ITEM_RESPAWN = 16; // Item will respawn
float ITEM_FLOATING = 32; // Spawn floating
float ITEM_NOEFFECTS = 128; // Disable particles and effects
float H_ROTTEN = 1; // Rotten
float H_MEGA = 2; // Mega Health
float A_LARGE = 1; // Used by ammo boxes
float A_LID = 2; // Display Lid
float ITEM_CKEY1 = 1; // Arcane Key 1
float ITEM_CKEY2 = 2; // Arcane Key 2
float ITEM_CKEY3 = 4; // Arcane Key 3
float ITEM_CKEY4 = 8; // Arcane Key 4
float BACKPACK_SHELLS = 1;
float BACKPACK_NAILS = 2;
float BACKPACK_ROCKETS = 4;
float BACKPACK_CELLS = 8;
float BACKPACK_GRNTYPE = 1;
float BACKPACK_YELTYPE = 2;
float BACKPACK_REDTYPE = 4;
// Various bounding boxes for items
// vector VEC_ORID_MIN = '0 0 0';
// vector VEC_ORID_MAX = '32 32 56';
vector VEC_HEAL_MIN = '-16 -16 0';
vector VEC_HEAL_MAX = '16 16 56';
vector VEC_WPNS_MIN = '-16 -16 0';
vector VEC_WPNS_MAX = '16 16 56';
vector VEC_AMMO_MIN = '-16 -16 0';
vector VEC_AMMO_MAX = '16 16 56';
vector VEC_KEYS_MIN = '-16 -16 -24';
vector VEC_KEYS_MAX = '16 16 32';
vector VEC_POWR_MIN = '-16 -16 -24';
vector VEC_POWR_MAX = '16 16 32';
// Default respawn timers for items
float RESPAWN_HEALTH = 20; // 15,25,100+
float RESPAWN_ARMOR = 20; // Green, Yellow, Red
float RESPAWN_WEAPON = 30; // SG -> LG
float RESPAWN_AMMO = 30; // Shells,Nails,Rockets,Cells
float RESPAWN_KEY = 60; // Gold,Silver,Custom
float RESPAWN_RUNE = 60; // Sigil/runes
float RESPAWN_ARTIFACT1 = 60; // Quad + Suit
float RESPAWN_ARTIFACT2 = 300; // Pent + Invisibilty
float RESPAWN_BACKPACK = 30; // Random Ammo Drop
float RESPAWN_COOP = 5; // Default timer for coop
float RESPAWN_PARTICLES = 32; // Particle burst for ring/center
float RESPAWN_EXPTIME = 1; // Particles burst lifetime
float RESPAWN_EXPRADIUS = 12; // Particle ring radius
float MODEL_ANIM_SPEED = 3;
float MODEL_ANIM_RANGE = 3;
//----------------------------------------------------------------------
// Some items have pickup conditions which prevent targets
// from firing when coop mode is active, show console warning
//----------------------------------------------------------------------
void() item_coopcheck =
{
if (self.target != "" || self.target2 != "") {
dprint("\b[Coop]\b (");
dprint(self.classname);
dprint(") unreliable target(s) in coop!\n");
}
};
//----------------------------------------------------------------------
// Check floor under item and animated skin for new BASE health boxes
//----------------------------------------------------------------------
void() item_thinkloop =
{
// Check for entity states
if (self.estate & ESTATE_BLOCK) return;
// Has the item been turned off?
if (self.attack_finished > time) return;
// Has the item removal timer been reached?
if (self.item_expired > 0 && self.item_expired < time) remove(self);
if (self.item_skinanim > 0) {
self.item_skincycle = self.item_skincycle + 1;
if (self.item_skincycle > MODEL_ANIM_SPEED) {
self.item_skincycle = 0;
self.item_skinanim_no = self.item_skinanim_no + 1;
if (self.item_skinanim_no > MODEL_ANIM_RANGE) {
self.item_skinanim_no = 0;
}
}
// Update skin
self.skin = self.item_skinanim_no;
}
// Check floor below item (global function)
if (self.item_flrcheck > 0) {
ent_floorcheck(self, self.item_flrcheck);
// Record any movement for respawn function
self.oldorigin = self.origin;
}
// Keep checking
self.think = item_thinkloop;
self.nextthink = time + 0.1;
};
void() item_estate_setup;
//----------------------------------------------------------------------
void() item_reset =
{
// Reset trigger_once conditions
self.attack_finished = 0;
if (!self.estate_on) item_estate_setup();
self.estate_on();
};
//----------------------------------------------------------------------
void() item_finished =
{
// Check for coop respawn options
if (coop > 0) {
if (self.classgroup == CG_WEAPON) {
if (coop_weapons == TRUE)
self.spawnflags = self.spawnflags - (self.spawnflags & ITEM_RESPAWN);
else if (coop_weapons == FALSE && self.respawn_time > 0) {
self.respawn_time = RESPAWN_COOP;
self.spawnflags = self.spawnflags | ITEM_RESPAWN;
}
}
else if (self.classgroup == CG_HEALTH) {
if (coop_health == FALSE)
self.spawnflags = self.spawnflags - (self.spawnflags & ITEM_RESPAWN);
else if (coop_health == TRUE && self.respawn_time > 0)
self.spawnflags = self.spawnflags | ITEM_RESPAWN;
}
else if (self.classgroup == CG_AMMOITEM) {
if (coop_ammoboxes == FALSE)
self.spawnflags = self.spawnflags - (self.spawnflags & ITEM_RESPAWN);
else if (coop_ammoboxes == TRUE && self.respawn_time > 0)
self.spawnflags = self.spawnflags | ITEM_RESPAWN;
}
else if (self.classgroup == CG_ARTIFACT) {
if (coop_powerups == FALSE)
self.spawnflags = self.spawnflags - (self.spawnflags & ITEM_RESPAWN);
else if (coop_powerups == TRUE && self.respawn_time > 0)
self.spawnflags = self.spawnflags | ITEM_RESPAWN;
}
}
self.attack_finished = LARGE_TIMER;
if (!self.estate_off) item_estate_setup();
self.estate_off();
};
//----------------------------------------------------------------------
void() item_respawn =
{
// Classic quake re-spawn sound
sound (self, CHAN_VOICE, SOUND_RESPAWN, 1, ATTN_NORM);
// Are particles enabled?
if (query_configflag(SVR_PARTICLES)) {
// Switch off any respawn emitter
if (self.respawn_part.classtype == CT_PARTICLEEMIT)
misc_particle_off(self.respawn_part);
if (self.respawn_style & PARTICLE_BURST_RING)
particle_ring(self.origin + self.respawn_ofs, '0 0 4', '4 4 16', RESPAWN_EXPRADIUS, RESPAWN_PARTICLES, RESPAWN_EXPTIME, self.respawn_style );
else if (self.respawn_style & PARTICLE_BURST_CENTER)
particle_explode(self.origin + self.respawn_ofs, RESPAWN_PARTICLES*2, RESPAWN_EXPTIME, self.respawn_style, self.respawn_style);
}
self.alpha = 1;
self.estate_reset();
};
//----------------------------------------------------------------------
// Re-direction for map hacks (not used normally)
//----------------------------------------------------------------------
void() SUB_regen = {
// self.model = self.mdl;
// self.solid = SOLID_TRIGGER;
sound (self, CHAN_VOICE, SOUND_RESPAWN, 1, ATTN_NORM);
// setorigin (self, self.origin);
item_reset();
};
//----------------------------------------------------------------------
void() alphafade_item_respawn =
{
if (self.waitmin > time) {
self.speed = 1 - ((self.waitmin - time) / self.respawn_time);
self.alpha = 0.1 + ((self.speed*0.4)*random());
// If respawn effect active, modify total particles
if (self.respawn_part.part_style == PARTICLE_STYLE_RESPAWN) {
self.respawn_part.part_limit = rint(RESPAWN_PARTICLES * self.speed);
}
self.think = alphafade_item_respawn;
self.nextthink = time + 0.1;
}
else item_respawn();
};
//----------------------------------------------------------------------
void() start_item_respawn =
{
// Is the item being respawned at the moment?
if (self.waitmin > time) return;
// Is the item setup to instantly respawn?
if (self.respawn_trig == TRUE && self.spawnflags & ITEM_RESPAWN) {
// Check for any respawn quantity counts
if (self.respawn_count > 0) {
self.respawn_count = self.respawn_count - 1;
if (self.respawn_count == 0)
self.spawnflags = self.spawnflags - (self.spawnflags & ITEM_RESPAWN);
}
// Instantly spawn item
item_respawn();
}
else {
// deathmatch 2 is the silly old rules
if (deathmatch == 1 || self.spawnflags & ITEM_RESPAWN) {
setmodel(self,self.mdl);
setsize (self, self.bbmins, self.bbmaxs);
self.waitmin = time + self.respawn_time;
self.alpha = 0.1;
// Check for any respawn quantity counts
if (self.respawn_count > 0) {
self.respawn_count = self.respawn_count - 1;
if (self.respawn_count == 0)
self.spawnflags = self.spawnflags - (self.spawnflags & ITEM_RESPAWN);
}
// Are particles enabled?
if (query_configflag(SVR_PARTICLES)) {
// Switch off any particle emitters
if (self.part_emitter) misc_particle_off(self.part_emitter);
// Is there any need for respawn effect?
if (self.respawn_effect) {
// If emitter does not exist? create one, else switch on
if (self.respawn_part.classtype == CT_PARTICLEEMIT)
misc_particle_on(self.respawn_part);
else self.respawn_part = spawn_pemitter(self, self, PARTICLE_STYLE_RESPAWN, PARTICLE_START_ON);
}
}
// Switch on gradual alpha fade
alphafade_item_respawn();
}
}
};
//----------------------------------------------------------------------
void() check_item_respawn =
{
// Respawn feature is waiting for trigger
if (!self.respawn_trig) start_item_respawn();
};
//----------------------------------------------------------------------
void() item_use =
{
// Check for any trigger respawn conditions first
// Respawn spawnflag, trigger condition and not trigger once
if (self.spawnflags & ITEM_RESPAWN && self.respawn_trig &&
self.estate == ESTATE_OFF) start_item_respawn();
else {
// usual trigger blocks, OFF, DISABLE and trigger_ONCE
if (self.estate & ESTATE_BLOCK) return;
if (self.attack_finished > time) return;
// Was item setup to be floating?
if(self.spawnflags & ITEM_FLOATING){
// Removed checkbottom check, it often fails and leaves
// items floating in midair when they should fall
// if (!checkbottom(self)) - left for comment only
// A quick toss of the item
self.movetype = MOVETYPE_TOSS;
self.origin_z = self.origin_z + 4;
self.flags = self.flags - (self.flags & FL_ONGROUND);
}
}
};
//----------------------------------------------------------------------
void() item_touch =
{
if (self.touchedvoid) {entity_hide(self); return;}
if (self.estate & ESTATE_BLOCK) return;
if ( !(other.flags & FL_CLIENT) ) return;
if ( other.health < 1 ) return;
if ( other.flags & FL_NOTARGET ) return;
if (self.attack_finished > time) return;
self.touch2(); // defined by item function
};
//----------------------------------------------------------------------
void() item_restore =
{
// Ammo boxes can have special animation frames or lids!
if (self.classgroup == CG_AMMOITEM) {
// Any LID (shells/spikes) defined?
if (self.spawnflags & A_LID && self.attachment) {
// Setup LID attachment entity (match angles/origin)
self.attachment.solid = SOLID_NOT;
self.attachment.movetype = self.movetype;
setmodel(self.attachment, self.headmdl);
// Give the lid the same bbox setup so it can move
setsize (self.attachment, self.mins, self.maxs);
// Start lid off the ground and remove ground flag
// This will let the lid naturally settle on the surface
setorigin(self.attachment, self.origin + '0 0 1');
self.attachment.flags = self.attachment.flags - (self.attachment.flags & FL_ONGROUND);
// Match angle and stored frame setup from ammo box
self.attachment.angles = self.angles;
// lid frame options 0=random, 1-7=exact
// Always generate a new lid position for respawning items
if (self.frame_box == 0) self.attachment.frame = rint(1 + random()*6);
else if (self.frame_box > 7) self.frame_box = 1;
if (self.frame_box > 0) self.attachment.frame = self.frame_box;
// LID has different skins for shells and spikes
if (self.classtype == CT_AMMOSHELLS) self.attachment.skin = self.skin;
else self.attachment.skin = 2 + self.skin;
}
// Any special frames (rockets/plasma) defined?
else if (self.frame_override) {
// frame options -1=random 0=nothing, 1-7=exact
// Always generate a new frame number for respawning items
if (self.frame_box == -1) self.frame = rint(1 + random()*6);
else if (self.frame_box > 7) self.frame_box = 1;
if (self.frame_box > 0) self.frame = self.frame_box;
}
}
// Setup animated textures for old style ID health boxes
// Check floor under item for any changes
if (self.item_flrcheck > 0 || self.item_skinanim > 0) {
self.nextthink = time + random()*0.5;
self.think = item_thinkloop;
}
};
//----------------------------------------------------------------------
void() item_delay =
{
if (self.touchedvoid) {entity_hide(self); return;}
if (self.estate == ESTATE_DISABLE) return;
//----------------------------------------------------------------------
// Check for Axe / Shotgun / LG upgrade monster spawn exceptions?
if (self.upgrade_axe || self.upgrade_ssg || self.upgrade_lg) {
// Has ANY player (server test not individual)
// picked up the relevant upgrade weapons?
if (self.upgrade_axe && !query_configflag(SVR_UPDAXE) ) return;
if (self.upgrade_ssg && !query_configflag(SVR_UPDSSG) ) return;
if (self.upgrade_lg && !query_configflag(SVR_UPDLG) ) return;
}
// Reset use function and any touch/skin triggers
self.estate_use = item_use;
self.touch = item_touch;
self.attack_finished = 0;
self.estate = ESTATE_ON;
// Setup enough parameters to test drop to floor
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_TRIGGER;
setmodel(self,self.mdl);
setsize (self, self.bbmins, self.bbmaxs);
setorigin(self, self.oldorigin);
self.velocity = '0 0 0';
// Finalize item location (check drop to floor)
if(self.spawnflags & ITEM_FLOATING) {
// Cannot check the floor of an item if its floating!?!
if (self.item_flrcheck > 0) self.item_flrcheck = 0;
}
else {
self.movetype = MOVETYPE_TOSS;
self.velocity = '0 0 0';
self.origin_z = self.origin_z + 6;
// ID originally use a droptofloor test for space check
// Tried a pointcontents check but it can allows things
// to fall through the floor and just keep going
// if (pointcontents(self.origin) == CONTENT_SOLID) {
if (!droptofloor()) {
dprint ("\n\b[Item]\b "); dprint (self.classname);
dprint (" stuck at ("); dprint (vtos(self.origin)); dprint (")\n");
spawn_marker(self.origin, SPNMARK_YELLOW);
remove(self);
return;
}
}
// If check floor under item enabled, workout distance check
// The bottom of the bounding box + 16 for large step
if (self.item_flrcheck > 0) {
self.item_flrcheck = fabs(self.mins_z) + 16;
}
// Spawn particle emitter if particles active and not blocked
if (query_configflag(SVR_PARTICLES) == SVR_PARTICLES) {
if (!(self.spawnflags & ITEM_NOEFFECTS) && self.part_active > 0) {
self.part_emitter = spawn_pemitter(self, self, self.part_active, PARTICLE_START_ON);
}
}
// Finally setup entity ready for use
self.oldorigin = self.origin;
// Remove the START OFF functionality
if (self.spawnflags & ENT_STARTOFF) {
self.spawnflags = self.spawnflags - ENT_STARTOFF;
// Check for respawn effect?
if (self.spawnflags & ITEM_RESPAWN) start_item_respawn();
else item_restore();
}
else item_restore();
};
//----------------------------------------------------------------------
void() item_on =
{
self.estate = ESTATE_ON;
self.movetype = MOVETYPE_NONE;
// Restore any effect flags settings (various dlight glows)
if (self.savedeffects > 0) self.effects = self.savedeffects;
// Check for delayed/trigger_once functionality?
if (self.spawnflags & ENT_STARTOFF || self.attack_finished > time)
self.solid = SOLID_NOT;
else {
// Restore movement, solid and model parameters
if(self.spawnflags & ITEM_FLOATING) self.movetype = MOVETYPE_NONE;
else self.movetype = MOVETYPE_TOSS;
self.solid = SOLID_TRIGGER;
setmodel(self,self.mdl);
setsize (self, self.bbmins, self.bbmaxs);
self.velocity = '0 0 0';
// Restore particle emitter
if (self.part_emitter) misc_particle_on(self.part_emitter);
// Setup touch/damage/bounding box functionality
self.think = SUB_Null;
item_restore();
}
};
//----------------------------------------------------------------------
void() item_off =
{
self.estate = ESTATE_OFF;
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_NOT;
setmodel(self,"");
self.effects = 0;
setsize(self, VEC_ORIGIN, VEC_ORIGIN);
// If item was setup to float then it will be trigger item
// Don't reset origin as it might have fallen somewhere better
if( !(self.spawnflags & ITEM_FLOATING) ) setorigin(self, self.oldorigin);
if (self.attachment) {
setmodel(self.attachment,"");
setsize(self.attachment, VEC_ORIGIN, VEC_ORIGIN);
}
};
//----------------------------------------------------------------------
void() item_estate_setup =
{
// Setup Entity State functionality
if (self.targetname != "") self.use = entity_state_use;
self.estate_on = item_on;
self.estate_off = item_off;
self.estate_use = item_delay;
self.estate_reset = item_reset;
};
//----------------------------------------------------------------------
void() item_start =
{
self.oldorigin = self.origin; // Save origin
self.movetype = MOVETYPE_NONE; // Static item, no movement
self.flags = self.flags | FL_ITEM;
// Warning if effects flag is active before spawning
if (self.effects) {
dprint("\b[ITEM]\b Effects flag active\n");
self.savedeffects = self.effects;
}
// Reset effects flag because some engines will show effects
// This is especially obvious for delay spawned items
self.effects = 0;
// Check for spawning conditions (nightmare, coop)
if (check_nightmare() == TRUE) return;
if (check_coop() == TRUE) return;
// Cannot have multiple upgrade restrictions on items
remove_duplicate_upgrades();
// Check for Axe / Shotgun item exceptions?
if (self.upgrade_axe || self.upgrade_ssg) {
if ( !(self.spawnflags & ENT_STARTOFF) ) {
dprint("\b[ITEM]\b need spawn delay for axe/shotgun\n");
spawn_marker(self.origin, SPNMARK_YELLOW);
remove(self);
return;
}
}
// If respawn timer negative then wait for a trigger
if (self.respawn_time < 0) self.respawn_trig = TRUE;
// Respawn times < 1 break sound and particle spawners
if (self.respawn_time > 0 && self.respawn_time < 1) self.respawn_time = 1;
// Cannot start with a negative number for counting down
if (self.respawn_count < 0) self.respawn_count = 1;
// Override default item pickup sound with silence?
// It would have been good to offer the other sounds (1-6)
// on all items, but there is a good chance that a mapper
// has left a rogue sounds key on some item somewhere!
if (self.sounds == 4) self.noise = SOUND_EMPTY;
// Setup Entity State functionality
item_estate_setup();
if (self.spawnflags & ENT_STARTOFF) self.estate_off();
else {
// delay drop to floor to make sure all doors have been spawned
// spread think times so they don't all happen at same time
self.nextthink = time + 0.1 + random()*0.5;
self.think = self.estate_use;
}
};
/*======================================================================
HEALTH FLASK/BOX
targ - entity to receive healing
t_healamount - the quanity to heal entity with
ignore - whether to ignore max health amount
returns FALSE if cannot heal entity by healamount
returns TRUE if healamount applied
======================================================================*/
float (entity targ, float t_healamount, float ignore) T_Heal =
{
if (targ.health <= 0) return FALSE;
if ((!ignore) && (targ.health >= other.max_health)) return FALSE;
t_healamount = ceil(t_healamount);
targ.health = targ.health + t_healamount;
if ((!ignore) && (targ.health >= other.max_health))
targ.health = other.max_health;
if (targ.health > HEAL_MEGAMAX) targ.health = HEAL_MEGAMAX;
// Healing the player negates some debuffs
ResetDebuffBurning(targ);
ResetDebuffPoisoned(targ);
return TRUE;
};
//----------------------------------------------------------------------
void() item_megahealth_rot =
{
// Check for maximum health limit
if (self.owner.health > self.owner.max_health) {
self.owner.health = self.owner.health - 1;
self.nextthink = time + 1;
}
else {
// it is possible for a player to die and respawn between rots
// Double check player has megahealth before removing it
if (self.owner.items & IT_SUPERHEALTH)
self.owner.items = self.owner.items - IT_SUPERHEALTH;
// Check to see if item can respawn
self.alpha = 0.1;
check_item_respawn();
}
};
//----------------------------------------------------------------------
void() health_touch =
{
local string s;
// Megahealth? Ignore max_health...
if (self.classtype == CT_HEALMEGA) {
if (other.health >= HEAL_MEGAMAX) return;
if (!T_Heal(other, self.healamount, 1)) return;
}
else {
if (!T_Heal(other, self.healamount, 0)) return;
}
sprint(other, "You receive ");
s = ftos(self.healamount);
sprint(other, s);
sprint(other, " health\n");
if (self.noise != SOUND_EMPTY)
sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
item_finished();
// Megahealth = rot down the player's super health
// Need to wait for megahealth to finish before respawn
if (self.classtype == CT_HEALMEGA) {
other.items = other.items | IT_SUPERHEALTH;
self.nextthink = time + 5;
self.think = item_megahealth_rot;
self.owner = other;
}
else check_item_respawn();
activator = other;
SUB_UseTargets();
};
/*======================================================================
/*QUAKED item_health (0.3 0.3 1) (-16 -16 0) (16 16 32) ROTTEN MEGA x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/health_25.mdl"); }
15, 25 or 100 Health
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
angle : = -1 Random rotation everytime spawned (default)
skin_override : Override world type 1=Base Green, 2=Medieval Wood
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
ROTTEN : 15 health
MEGA : MegaHealth +100 health, rot down to 100
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Health box gives 15, 25 or 100 points depending on spawnflags.
======================================================================*/
void() item_health =
{
if (self.spawnflags & H_ROTTEN) {
// worldtype 0 = medieval, 1 = metal, 2 = base
if ((world.worldtype < 2 && !self.skin_override) || self.skin_override == 1) {
// New Medieval style red flask
self.mdl = "progs/health_15.mdl";
self.respawn_style = PARTICLE_BURST_RED + PARTICLE_BURST_RING;
}
else {
// Original ID pickup model
self.mdl = "progs/health_15b.mdl";
self.respawn_style = PARTICLE_BURST_WHITE + PARTICLE_BURST_RING;
}
self.noise = SOUND_HEAL15;
self.healamount = HEAL_ROT;
self.classtype = CT_HEALROT;
self.respawn_effect = TRUE;
self.respawn_ofs = '0 0 16';
}
else if (self.spawnflags & H_MEGA) {
// worldtype 0 = medieval, 1 = metal, 2 = base
if ((world.worldtype < 2 && !self.skin_override) || self.skin_override == 1) {
// New Medieval style red flask
self.mdl = "progs/health_100.mdl";
self.respawn_style = PARTICLE_BURST_RED + PARTICLE_BURST_RING;
}
else {
// Original ID pickup model
self.mdl = "progs/health_100b.mdl";
self.respawn_style = PARTICLE_BURST_WHITE + PARTICLE_BURST_RING;
self.item_skinanim = TRUE;
}
self.noise = SOUND_HEAL100;
self.healamount = HEAL_MEGA;
self.classtype = CT_HEALMEGA;
self.part_active = PARTICLE_STYLE_MEGAH;
self.respawn_effect = TRUE;
self.respawn_ofs = '0 0 28';
}
else {
// worldtype 0 = medieval, 1 = metal, 2 = base
if ((world.worldtype < 2 && !self.skin_override) || self.skin_override == 1)
{
// New Medieval style red flask
self.mdl = "progs/health_25.mdl";
self.respawn_style = PARTICLE_BURST_RED + PARTICLE_BURST_RING;
self.respawn_ofs = '0 0 24';
}
else {
// Original ID pickup model
self.mdl = "progs/health_25b.mdl";
self.respawn_style = PARTICLE_BURST_WHITE + PARTICLE_BURST_RING;
self.respawn_ofs = '0 0 16';
self.item_skinanim = TRUE;
}
self.noise = SOUND_HEAL25;
self.healamount = HEAL_NORM;
self.classtype = CT_HEALNORM;
self.respawn_effect = TRUE;
}
precache_model(self.mdl);
precache_sound(self.noise);
// Query console variable 'temp1' for model upgrade option.
// Cannot use global vars because they don't exist at this point
// Move the new centered ammo models to match old ammo origin
// The default is to move all ammo items to suit original id maps
if (query_configflag(SVR_ITEMOFFSET) == FALSE) {
self.oldorigin = self.origin + '16 16 0';
setorigin(self, self.oldorigin);
}
// Setting the angle key in the editor to UP/DOWN/0 = random rotation
if (self.angles_y <= 0) self.angles_y = rint(random()*359);
self.touch2 = health_touch;
self.classgroup = CG_HEALTH;
self.bbmins = VEC_HEAL_MIN;
self.bbmaxs = VEC_HEAL_MAX;
if (self.respawn_time == 0) self.respawn_time = RESPAWN_HEALTH;
// Check for coop errors
item_coopcheck();
item_start ();
};
//======================================================================
// armor_touch
//======================================================================
void() armor_touch =
{
if (other.armortype*other.armorvalue >= self.armortype*self.armorvalue) return;
other.armortype = self.armortype;
other.armorvalue = self.armorvalue;
other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + self.items;
sprint(other, "You got armor\n");
if (self.noise != SOUND_EMPTY)
sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
item_finished();
check_item_respawn();
activator = other;
SUB_UseTargets();
};
//----------------------------------------------------------------------
void() item_armor_setup =
{
self.classgroup = CG_ARMOR;
self.part_active = PARTICLE_STYLE_ARMOR;
self.touch2 = armor_touch;
self.bbmins = '-16 -16 0';
self.bbmaxs = '16 16 56';
if (self.respawn_time == 0) self.respawn_time = RESPAWN_ARMOR;
self.noise = "items/armor1.wav";
// Check for coop errors
item_coopcheck();
item_start ();
};
/*======================================================================
/*QUAKED item_armor1 (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/armour.mdl"); }
Green Armour with 100 points of protection
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Green Armour with 100 points of protection
======================================================================*/
void() item_armor1 =
{
self.mdl = "progs/armour.mdl";
precache_model (self.mdl);
self.skin = 0;
self.classtype = CT_ARMOR1;
self.items = IT_ARMOR1;
self.armortype = ARMOR_GRN_TYPE;
self.armorvalue = ARMOR_GRN_VALUE;
self.respawn_effect = TRUE;
self.respawn_style = PARTICLE_BURST_GREEN + PARTICLE_BURST_RING;
self.respawn_ofs = '0 0 24';
item_armor_setup();
};
/*======================================================================
/*QUAKED item_armor2 (0 0.5 0.8) (-16 -16 0) (16 16 56) x BLUESKIN x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/armour.mdl"); }
Yellow Armour with 150 points of protection
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
BLUESKIN : Display a blue skin instead
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Yellow Armour with 150 points of protection
======================================================================*/
void() item_armor2 =
{
self.mdl = "progs/armour.mdl";
precache_model (self.mdl);
self.classtype = CT_ARMOR2;
self.items = IT_ARMOR2;
self.armortype = ARMOR_YEL_TYPE;
self.armorvalue = ARMOR_YEL_VALUE;
self.respawn_effect = TRUE;
self.respawn_ofs = '0 0 24';
// Setup alternative colour
if (self.spawnflags & ARMOR_BLUE) {
self.respawn_style = PARTICLE_BURST_BLUE + PARTICLE_BURST_RING;
self.skin = 3;
}
else {
self.respawn_style = PARTICLE_BURST_YELLOW + PARTICLE_BURST_RING;
self.skin = 1;
}
item_armor_setup();
};
/*======================================================================
/*QUAKED item_armorInv (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/armour.mdl"); }
Red Armour with 200 points of protection
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Red Armour with 200 points of protection
======================================================================*/
void() item_armorInv =
{
self.mdl = "progs/armour.mdl";
precache_model (self.mdl);
self.skin = 2;
self.classtype = CT_ARMORINV;
self.items = IT_ARMOR3;
self.armortype = ARMOR_RED_TYPE;
self.armorvalue = ARMOR_RED_VALUE;
self.respawn_effect = TRUE;
self.respawn_style = PARTICLE_BURST_RED + PARTICLE_BURST_RING;
self.respawn_ofs = '0 0 24';
item_armor_setup();
};
/*======================================================================
Deathmatch Weapon Rules
======================================================================*/
float(float w) DM_RankForWeapon =
{
if (w == IT_LIGHTNING) return 1;
if (w == IT_ROCKET_LAUNCHER) return 2;
if (w == IT_SUPER_NAILGUN) return 3;
if (w == IT_GRENADE_LAUNCHER) return 4;
if (w == IT_SUPER_SHOTGUN) return 5;
if (w == IT_NAILGUN) return 6;
return 7; // Axe
};
//----------------------------------------------------------------------
void(float old, float new) DM_Weapon =
{
local float oldrank, newrank;
// change self.weapon if desired
oldrank = DM_RankForWeapon (self.weapon);
newrank = DM_RankForWeapon (new);
if ( newrank < oldrank ) self.weapon = new;
};
//----------------------------------------------------------------------
void(entity targ) bound_other_ammo =
{
if (targ.ammo_shells > AMMO_MAXSHELLS) targ.ammo_shells = AMMO_MAXSHELLS;
if (targ.ammo_nails > AMMO_MAXNAILS) targ.ammo_nails = AMMO_MAXNAILS;
if (targ.ammo_rockets > AMMO_MAXROCKETS) targ.ammo_rockets = AMMO_MAXROCKETS;
if (targ.ammo_cells > AMMO_MAXCELLS) targ.ammo_cells = AMMO_MAXCELLS;
};
//----------------------------------------------------------------------
void() weapon_touch =
{
local float pickupweapon, pickupammo, moditem;
//----------------------------------------------------------------------
if (self.classtype == CT_UPGRADE_AXE) {
pickupweapon = IT_UPGRADE_AXE;
// Deathmatch players cannot constantly pickup weapons
if (deathmatch > 0 && other.moditems & pickupweapon) return;
// Update serverflag and highlight as MOD weapon
update_configflag(SVR_UPDAXE, TRUE);
moditem = TRUE;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_SHOTGUN) {
pickupweapon = IT_SHOTGUN;
// Deathmatch players cannot constantly pickup weapons
if (deathmatch > 0 && other.items & pickupweapon) return;
// Coop players can use weapon spawns as ammo dispensers
if (coop > 0 && other.items & pickupweapon) {
if (other.ammo_shells > AMMO_MAXSHELLS*0.5) pickupammo = 0;
else pickupammo = AMMO_SHELLS_WPN;
}
else pickupammo = AMMO_SHELLS_WPN;
other.ammo_shells = other.ammo_shells + pickupammo;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_UPGRADE_SSG) {
pickupweapon = IT_UPGRADE_SSG;
// Deathmatch players cannot constantly pickup weapons
if (deathmatch > 0 && other.moditems & pickupweapon) return;
// Coop players can use weapon spawns as ammo dispensers
if (coop > 0 && other.moditems & pickupweapon) {
if (other.ammo_shells > AMMO_MAXSHELLS*0.5) pickupammo = 0;
else pickupammo = AMMO_SHELLS_WPN;
}
else pickupammo = AMMO_SHELLS_WPN;
other.ammo_shells = other.ammo_shells + pickupammo;
// Update serverflag and highlight as MOD weapon
update_configflag(SVR_UPDSSG, TRUE);
moditem = TRUE;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_SUPER_SHOTGUN) {
pickupweapon = IT_SUPER_SHOTGUN;
// Deathmatch players cannot constantly pickup weapons
if (deathmatch > 0 && other.items & pickupweapon) return;
// Coop players can use weapon spawns as ammo dispensers
if (coop > 0 && other.items & pickupweapon) {
if (other.ammo_shells > AMMO_MAXSHELLS*0.5) pickupammo = 0;
else pickupammo = AMMO_SHELLS_WPN;
}
else pickupammo = AMMO_SHELLS_WPN;
other.ammo_shells = other.ammo_shells + pickupammo;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_NAILGUN) {
pickupweapon = IT_NAILGUN;
// Deathmatch players cannot constantly pickup weapons
if (deathmatch > 0 && other.items & pickupweapon) return;
// Coop players can use weapon spawns as ammo dispensers
if (coop > 0 && other.items & pickupweapon) {
if (other.ammo_nails > AMMO_MAXNAILS*0.5) pickupammo = 0;
else pickupammo = AMMO_NAILS_WPN;
}
else pickupammo = AMMO_NAILS_WPN;
other.ammo_nails = other.ammo_nails + pickupammo;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_SUPER_NAILGUN) {
pickupweapon = IT_SUPER_NAILGUN;
// Deathmatch players cannot constantly pickup weapons
if (deathmatch > 0 && other.items & pickupweapon) return;
// Coop players can use weapon spawns as ammo dispensers
if (coop > 0 && other.items & pickupweapon) {
if (other.ammo_nails > AMMO_MAXNAILS*0.5) pickupammo = 0;
else pickupammo = AMMO_NAILS_WPN;
}
else pickupammo = AMMO_NAILS_WPN;
other.ammo_nails = other.ammo_nails + pickupammo;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_GRENADE_LAUNCHER) {
pickupweapon = IT_GRENADE_LAUNCHER;
// Deathmatch players cannot constantly pickup weapons
if (deathmatch > 0 && other.items & pickupweapon) return;
// Coop players can use weapon spawns as ammo dispensers
if (coop > 0 && other.items & pickupweapon) {
if (other.ammo_rockets > AMMO_MAXROCKETS*0.5) pickupammo = 0;
else pickupammo = AMMO_ROCKETS_WPN;
}
else pickupammo = AMMO_ROCKETS_WPN;
other.ammo_rockets = other.ammo_rockets + pickupammo;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_ROCKET_LAUNCHER) {
pickupweapon = IT_ROCKET_LAUNCHER;
// Deathmatch players cannot constantly pickup weapons
if (deathmatch > 0 && other.items & pickupweapon) return;
// Coop players can use weapon spawns as ammo dispensers
if (coop > 0 && other.items & pickupweapon) {
if (other.ammo_rockets > AMMO_MAXROCKETS*0.5) pickupammo = 0;
else pickupammo = AMMO_ROCKETS_WPN;
}
else pickupammo = AMMO_ROCKETS_WPN;
other.ammo_rockets = other.ammo_rockets + pickupammo;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_UPGRADE_LG) {
pickupweapon = IT_UPGRADE_LG;
// Deathmatch players cannot constantly pickup weapons
if (deathmatch > 0 && other.moditems & pickupweapon) return;
// Coop players can use weapon spawns as ammo dispensers
if (coop > 0 && other.moditems & pickupweapon) {
if (other.ammo_cells > AMMO_MAXCELLS*0.5) pickupammo = 0;
else pickupammo = AMMO_CELLS_WPN;
}
else pickupammo = AMMO_CELLS_WPN;
other.ammo_cells = other.ammo_cells + pickupammo;
// Update serverflag and highlight as MOD weapon
update_configflag(SVR_UPDLG, TRUE);
moditem = TRUE;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_LIGHTNING) {
pickupweapon = IT_LIGHTNING;
// Deathmatch players cannot constantly pickup weapons
if (deathmatch > 0 && other.items & pickupweapon) return;
// Coop players can use weapon spawns as ammo dispensers
if (coop > 0 && other.items & pickupweapon) {
if (other.ammo_cells > AMMO_MAXCELLS*0.5) pickupammo = 0;
else pickupammo = AMMO_CELLS_WPN;
}
else pickupammo = AMMO_CELLS_WPN;
other.ammo_cells = other.ammo_cells + pickupammo;
}
//----------------------------------------------------------------------
else return;
if (self.classtype == CT_UPGRADE_AXE && other.moditems & IT_UPGRADE_AXE)
sprint (other, "You got another axe to grind\n");
else if (self.classtype == CT_SUPER_SHOTGUN && other.moditems & IT_UPGRADE_SSG)
sprint (other, "You got a handful of Shells\n");
else if (self.classtype == CT_UPGRADE_SSG && other.moditems & IT_UPGRADE_SSG)
sprint (other, "You got triple barrel boomstick\n");
else if (self.classtype == CT_LIGHTNING && other.moditems & IT_UPGRADE_LG)
sprint (other, "You got some AAA batteries\n");
else if (self.classtype == CT_UPGRADE_LG && other.moditems & IT_UPGRADE_LG)
sprint (other, "You got another burst of plasma\n");
else {
sprint (other, "You got the ");
sprint (other, self.netname);
sprint (other, "\n");
}
// weapon touch sound
if (self.noise != SOUND_EMPTY)
sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
// Make sure no ammo is over limits
bound_other_ammo (other);
// Stop the player switching to weapons already got
if (deathmatch > 0) {
// Check for new shadow axe and SG and skip weapon switch
if (moditem && pickupweapon == IT_UPGRADE_AXE && other.moditems & pickupweapon) pickupweapon = FALSE;
else if (pickupweapon == IT_SHOTGUN && other.items & pickupweapon) pickupweapon = FALSE;
// Stop switching to a lower tier weapon (DM Rules)
// if (DM_RankForWeapon(other.weapon) < DM_RankForWeapon(new)) new = FALSE;
}
// Skip any weapon switch if no new weapon
if (pickupweapon != FALSE) {
// change to the weapon and add to inventory
other.items = other.items | pickupweapon;
if (moditem) other.moditems = other.moditems | pickupweapon;
// Check for best weapon (DM only) and switch to it!
if (deathmatch) DM_Weapon (other.weapon, pickupweapon);
else other.weapon = pickupweapon;
W_SetCurrentAmmo(other);
}
// hide item and check for respawn
item_finished();
check_item_respawn();
activator = other;
SUB_UseTargets();
// Triggers events work once in co-op
if (coop > 0) { self.target = ""; self.target2 = ""; }
};
/*======================================================================
WEAPONS
======================================================================*/
void() weapon_start =
{
self.classgroup = CG_WEAPON;
self.touch2 = weapon_touch;
self.bbmins = VEC_WPNS_MIN;
self.bbmaxs = VEC_WPNS_MAX;
if (self.respawn_time == 0) self.respawn_time = RESPAWN_WEAPON;
self.noise = "weapons/pkup.wav";
item_start ();
};
/*======================================================================
/*QUAKED weapon_upgrade_axe (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/g_shadaxe.mdl"); }
Shadow Axe, extra dmg and gib zombies
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Shadow Axe, extra dmg and gib zombies
======================================================================*/
void() weapon_upgrade_axe =
{
self.mdl = MODEL_GWEAP_UPAXE;
precache_model (self.mdl);
self.weapon = IT_UPGRADE_AXE;
self.skin = 4;
self.classtype = CT_UPGRADE_AXE;
self.netname = "Shadow Axe";
if (self.upgrade_axe != 0) self.upgrade_axe = FALSE;
weapon_start();
};
/*======================================================================
/*QUAKED weapon_upgrade_ssg (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/g_shot3.mdl"); }
The Widowmaker Shotgun, extra dmg, triple shot
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
The Widowmaker Shotgun, extra dmg, triple shot
======================================================================*/
void() weapon_upgrade_ssg =
{
self.mdl = MODEL_GWEAP_UPSSG;
precache_model (self.mdl);
self.weapon = IT_UPGRADE_SSG;
self.classtype = CT_UPGRADE_SSG;
self.netname = "Widowmaker Shotgun";
if (self.upgrade_ssg != 0) self.upgrade_ssg = FALSE;
weapon_start();
};
/*======================================================================
/*QUAKED weapon_upgrade_lg (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/g_plasma.mdl"); }
The Plasma Gun, direct & splashdamage
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
The Plasma Gun, direct & splashdamage
======================================================================*/
void() weapon_upgrade_lg =
{
self.mdl = MODEL_GWEAP_UPLG;
precache_model (self.mdl);
self.weapon = IT_UPGRADE_LG;
self.classtype = CT_UPGRADE_LG;
self.netname = "Plasma Gun";
if (self.upgrade_lg != 0) self.upgrade_lg = FALSE;
weapon_start();
};
/*======================================================================
/*QUAKED weapon_shotgun (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/g_shotgun.mdl"); }
Single barrel Shotgun
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Single barrel Shotgun
======================================================================*/
void() weapon_shotgun =
{
self.mdl = MODEL_GWEAP_SG;
precache_model (self.mdl);
self.weapon = IT_SHOTGUN;
self.classtype = CT_SHOTGUN;
self.netname = "Sawn-off Shotgun";
weapon_start();
};
/*======================================================================
/*QUAKED weapon_supershotgun (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/g_shot.mdl"); }
Super Shotgun
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Super Shotgun
======================================================================*/
void() weapon_supershotgun =
{
// Query console variable 'temp1' for model upgrade option.
// Cannot use global vars because they don't exist at this point
if (query_configflag(SVR_UPDSSG)) { weapon_upgrade_ssg(); return; }
self.mdl = MODEL_GWEAP_SSG;
precache_model (self.mdl);
precache_model (MODEL_GWEAP_UPSSG); // New Shotgun (pre-cache)
self.weapon = IT_SUPER_SHOTGUN;
self.classtype = CT_SUPER_SHOTGUN;
self.netname = "Double-barrelled Shotgun";
weapon_start();
};
/*======================================================================
/*QUAKED weapon_nailgun (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/g_nail.mdl"); }
Perforator (Nailgun)
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Perforator (Nailgun)
======================================================================*/
void() weapon_nailgun =
{
self.mdl = MODEL_GWEAP_NG;
precache_model (self.mdl);
self.weapon = IT_NAILGUN;
self.classtype = CT_NAILGUN;
self.netname = "Nailgun";
weapon_start();
};
/*======================================================================
/*QUAKED weapon_supernailgun (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/g_nail2.mdl"); }
Super Perforator (Super Nailgun)
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Super Perforator (Super Nailgun)
======================================================================*/
void() weapon_supernailgun =
{
self.mdl = MODEL_GWEAP_SNG;
precache_model (self.mdl);
self.weapon = IT_SUPER_NAILGUN;
self.classtype = CT_SUPER_NAILGUN;
self.netname = "Super Nailgun";
weapon_start();
};
/*======================================================================
/*QUAKED weapon_grenadelauncher (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/g_rock.mdl"); }
Grenade Launcher
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Grenade Launcher
======================================================================*/
void() weapon_grenadelauncher =
{
self.mdl = MODEL_GWEAP_GL;
precache_model (self.mdl);
self.weapon = IT_GRENADE_LAUNCHER;
self.classtype = CT_GRENADE_LAUNCHER;
self.netname = "Grenade Launcher";
weapon_start();
};
/*======================================================================
/*QUAKED weapon_rocketlauncher (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/g_rock2.mdl"); }
Rocket Launcher
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Rocket Launcher
======================================================================*/
void() weapon_rocketlauncher =
{
self.mdl = MODEL_GWEAP_RL;
precache_model (self.mdl);
self.weapon = IT_ROCKET_LAUNCHER;
self.classtype = CT_ROCKET_LAUNCHER;
self.netname = "Rocket Launcher";
weapon_start();
};
/*======================================================================
/*QUAKED weapon_lightning (0 0.5 0.8) (-16 -16 0) (16 16 56) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/g_light.mdl"); }
Thunderbolt Cannon
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Thunderbolt Cannon
======================================================================*/
void() weapon_lightning =
{
// Query console variable 'temp1' for model upgrade option.
// Cannot use global vars because they don't exist at this point
if (query_configflag(SVR_UPDLG)) { weapon_upgrade_lg(); return; }
self.mdl = MODEL_GWEAP_LG;
precache_model (self.mdl);
self.weapon = IT_LIGHTNING;
self.classtype = CT_LIGHTNING;
self.netname = "Thunderbolt";
weapon_start();
};
/*======================================================================
AMMO
======================================================================*/
void() ammo_touch =
{
local float best;
//----------------------------------------------------------------------
if (self.classtype == CT_AMMOSHELLS) {
if (other.ammo_shells >= AMMO_MAXSHELLS) return;
other.ammo_shells = other.ammo_shells + self.aflag;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_AMMONAILS) {
if (other.ammo_nails >= AMMO_MAXNAILS) return;
other.ammo_nails = other.ammo_nails + self.aflag;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_AMMOROCKETS) {
if (other.ammo_rockets >= AMMO_MAXROCKETS) return;
other.ammo_rockets = other.ammo_rockets + self.aflag;
}
//----------------------------------------------------------------------
else if (self.classtype == CT_AMMOCELLS) {
if (other.ammo_cells >= AMMO_MAXCELLS) return;
other.ammo_cells = other.ammo_cells + self.aflag;
}
// Check/cap ammo limits
bound_other_ammo (other);
sprint (other, "You got the ");
sprint (other, self.netname);
sprint (other, "\n");
if (self.noise != SOUND_EMPTY)
sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
// if the player was using his best weapon,
// change up to the new one if better
best = W_BestWeapon(other);
// change to a better weapon if appropriate
if ( other.weapon == best ) {
other.weapon = W_BestWeapon(other);
W_SetCurrentAmmo (other);
}
// if changed current ammo, update it
W_SetCurrentAmmo(other);
// hide item and check for respawn
item_finished();
check_item_respawn();
activator = other;
SUB_UseTargets();
};
/*======================================================================
Setup all Ammo with global parameters
======================================================================*/
void() item_ammo_setup =
{
self.frame = 0;
self.touch2 = ammo_touch;
self.classgroup = CG_AMMOITEM;
self.bbmins = VEC_AMMO_MIN;
self.bbmaxs = VEC_AMMO_MAX;
if (self.respawn_time == 0) self.respawn_time = RESPAWN_AMMO;
self.noise = "weapons/lock4.wav";
// Query console variable 'temp1' for model upgrade option.
// Cannot use global vars because they don't exist at this point
// Move the new centered ammo models to match old ammo origin
// The default is to move all ammo items to suit original id maps
if (!query_configflag(SVR_ITEMOFFSET)) {
self.oldorigin = self.origin + '16 16 0';
setorigin(self, self.oldorigin);
}
// Override the world theme skin type
if (self.skin_override > 0 && self.skin_override < 3)
self.skin = self.skin_override - 1;
// Switch to medieval (wood) skin for medieval/metal theme maps
else if (world.worldtype < 2) self.skin = 1;
// Setting the angle key in the editor to UP/DOWN = random rotation
if (self.angles_y <= 0) self.angles_y = rint(random()*359);
// Setup lid attachment entity (defined in item setup)
if (self.spawnflags & A_LID) {
self.attachment = spawn();
self.attachment.owner = self;
setorigin(self.attachment, self.origin);
self.attachment.solid = SOLID_NOT;
self.attachment.movetype = MOVETYPE_NONE;
}
// Check for coop errors
item_coopcheck();
item_start ();
};
/*======================================================================
/*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) BIG
/*QUAKED item_shells (0 .5 .8) (-16 -16 0) (16 16 32) BIG LID x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/ammo_shells0.mdl"); }
20 or 40 Shells
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
frame_box : special animation frame number for LID (1-7)
skin_override : Override world type 1=Base Green, 2=Medieval Wood
aflag : Ammo quantity override
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
BIG : Double Ammo and different model
LID : Extra LID model positioned with box
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
20 or 40 Shells for the Shotgun (SG), SuperShotgun (SSG) and Upgrade
======================================================================*/
void() item_shells =
{
if (self.spawnflags & A_LARGE) {
self.mdl = "progs/ammo_shells1.mdl";
self.headmdl = "progs/ammo_lidlarge.mdl";
if (self.aflag < 1) self.aflag = AMMO_SHELLS_LGR;
}
else {
self.mdl = "progs/ammo_shells0.mdl";
self.headmdl = "progs/ammo_lidsmall.mdl";
if (self.aflag < 1) self.aflag = AMMO_SHELLS_SML;
}
precache_model (self.mdl);
precache_model (self.headmdl);
self.classtype = CT_AMMOSHELLS;
self.netname = "box of shells";
self.respawn_style = PARTICLE_BURST_YELLOW + PARTICLE_BURST_RING;
self.respawn_ofs = '0 0 24';
self.respawn_effect = TRUE;
self.frame_override = FALSE;
item_ammo_setup();
};
/*======================================================================
/*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) BIG
/*QUAKED item_spikes (0 .5 .8) (-16 -16 0) (16 16 32) BIG LID x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/ammo_nails0.mdl"); }
25 or 50 Spikes
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
frame_box : special animation frame number for LID (1-7)
skin_override : Override world type 1=Base Green, 2=Medieval Wood
aflag : Ammo quantity override
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
BIG : Double Ammo and different model
LID : Extra LID model positioned with box
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
25 or 50 Spikes for the Perforator (NG) and Super Perforator (SNG)
======================================================================*/
void() item_spikes =
{
if (self.spawnflags & A_LARGE) {
self.mdl = "progs/ammo_nails1.mdl";
self.headmdl = "progs/ammo_lidlarge.mdl";
if (self.aflag < 1) self.aflag = AMMO_NAILS_LGR;
}
else {
self.mdl = "progs/ammo_nails0.mdl";
self.headmdl = "progs/ammo_lidsmall.mdl";
if (self.aflag < 1) self.aflag = AMMO_NAILS_SML;
}
precache_model (self.mdl);
precache_model (self.headmdl);
self.classtype = CT_AMMONAILS;
self.netname = "box of nails";
self.respawn_style = PARTICLE_BURST_WHITE + PARTICLE_BURST_RING;
self.respawn_ofs = '0 0 24';
self.respawn_effect = TRUE;
self.frame_override = FALSE;
item_ammo_setup();
};
/*======================================================================
/*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) BIG
/*QUAKED item_rockets (0 .5 .8) (-16 -16 0) (16 16 32) BIG x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/ammo_rockets0.mdl"); }
5 or 10 Rockets
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
frame_box : special animation frame number for box of ammo (1-7)
skin_override : Override world type 1=Base Green, 2=Medieval Wood
aflag : Ammo quantity override
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
BIG : Double Ammo and different model
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
5 or 10 Rockets for the Grenade (GL) or Rocket Launcher (RL)
======================================================================*/
void() item_rockets =
{
if (self.spawnflags & A_LARGE) {
self.mdl = "progs/ammo_rockets1.mdl";
if (self.aflag < 1) self.aflag = AMMO_ROCKETS_LGR;
}
else {
self.mdl = "progs/ammo_rockets0.mdl";
if (self.aflag < 1) self.aflag = AMMO_ROCKETS_SML;
}
precache_model (self.mdl);
self.classtype = CT_AMMOROCKETS;
self.netname = "box of rockets";
self.spawnflags = self.spawnflags - (self.spawnflags & A_LID);
self.respawn_style = PARTICLE_BURST_WHITE + PARTICLE_BURST_RING;
self.respawn_ofs = '0 0 24';
self.respawn_effect = TRUE;
self.frame_override = TRUE;
item_ammo_setup();
};
/*======================================================================
/*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) BIG
/*QUAKED item_cells (0 .5 .8) (-16 -16 0) (16 16 32) BIG x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/ammo_battery0.mdl"); }
6 or 12 Medieval Battery
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
skin_override : Override world type 1=Base Green, 2=Medieval Wood
aflag : Ammo quantity override
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
BIG : Double Ammo and different model
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
6 or 12 Medieval Battery (cells) for the Thunderbolt (LG)
======================================================================*/
void() item_cells =
{
if (self.spawnflags & A_LARGE) {
self.mdl = "progs/ammo_battery1.mdl";
if (self.aflag < 1) self.aflag = AMMO_CELLS_LGR;
}
else {
self.mdl = "progs/ammo_battery0.mdl";
if (self.aflag < 1) self.aflag = AMMO_CELLS_SML;
}
precache_model (self.mdl);
self.classtype = CT_AMMOCELLS;
self.netname = "battery";
self.spawnflags = self.spawnflags - (self.spawnflags & A_LID);
self.respawn_style = PARTICLE_BURST_GREEN + PARTICLE_BURST_RING;
self.respawn_ofs = '0 0 24';
self.respawn_effect = TRUE;
self.frame_override = FALSE;
item_ammo_setup();
};
/*======================================================================
/*QUAKED item_plasma (0 .5 .8) (0 0 0) (32 32 32) BIG
/*QUAKED item_plasma (0 .5 .8) (-16 -16 0) (16 16 32) BIG x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/ammo_cells0.mdl"); }
6 or 12 Cells
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
frame_box : special animation frame number for box of ammo (1-7)
skin_override : Override world type 1=Base Green, 2=Medieval Wood
aflag : Ammo quantity override
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
BIG : Double Ammo and different model
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
6 or 12 Cells for the Thunderbolt (LG)
======================================================================*/
void() item_plasma =
{
if (self.spawnflags & A_LARGE) {
self.mdl = "progs/ammo_cells1.mdl";
if (self.aflag < 1) self.aflag = AMMO_CELLS_LGR;
}
else {
self.mdl = "progs/ammo_cells0.mdl";
if (self.aflag < 1) self.aflag = AMMO_CELLS_SML;
}
precache_model (self.mdl);
self.classtype = CT_AMMOCELLS;
self.netname = "box of cells";
self.spawnflags = self.spawnflags - (self.spawnflags & A_LID);
self.respawn_style = PARTICLE_BURST_BLUE + PARTICLE_BURST_RING;
self.respawn_ofs = '0 0 24';
self.respawn_effect = TRUE;
self.frame_override = TRUE;
item_ammo_setup();
};
/*======================================================================
KEYS (Silver, Gold and Custom)
======================================================================*/
void() key_touchbindmsg =
{
sound (self.enemy, CHAN_VOICE, SOUND_TALK, 1, ATTN_NORM);
centerprint(self.enemy, "Press 'i' Key to open Inventory\nTo see what \bArcane keys\b you have!\n");
};
//----------------------------------------------------------------------
void() key_touch =
{
// Check if the player has the custom key already?
if (self.classtype == CT_CUSTOMKEY) {
if (other.moditems & self.moditems) return;
}
else {
// Check if the player has the silver/gold key already?
if ( other.items & self.items ) return;
}
sprint (other, "You got the ");
sprint (other, self.netname);
sprint (other,"\n");
if (self.noise != SOUND_EMPTY)
sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
// Add key to player inventory (items / customkey)
if (self.moditems > 0) {
other.moditems = other.moditems | self.moditems;
// Store the key netname on the player/client for door ref later
if (self.moditems & IT_CKEY1) other.ckeyname1 = self.netname;
else if (self.moditems & IT_CKEY2) other.ckeyname2 = self.netname;
else if (self.moditems & IT_CKEY3) other.ckeyname3 = self.netname;
else other.ckeyname4 = self.netname;
}
// Add silver/gold key to player inventory
else other.items = other.items | self.items;
// Setup respawn for co-op
if (coop > 0 && self.respawn_time > 0) {
self.respawn_time = RESPAWN_COOP;
self.spawnflags = self.spawnflags | ITEM_RESPAWN;
}
// hide item and check for respawn
item_finished();
check_item_respawn();
activator = other;
SUB_UseTargets();
// Triggers events work once in co-op
if (coop > 0) self.target = "";
// Warn player about new key binding for inventory (first time only)
if (self.moditems > 0 && other.ckeyhint == FALSE) {
self.enemy = other; // Store for later
other.ckeyhint = TRUE; // Only works once
self.think = key_touchbindmsg;
self.nextthink = time + 3;
}
};
//----------------------------------------------------------------------
void() key_setup =
{
if (self.noise == "") {
if (self.worldtype == 1) self.noise = "misc/runekey.wav";
else if (self.worldtype == 2) self.noise = "misc/basekey.wav";
else self.noise = "misc/medkey.wav";
}
precache_sound (self.noise);
self.touch2 = key_touch;
self.classgroup = CG_KEY;
self.bbmins = VEC_KEYS_MIN;
self.bbmaxs = VEC_KEYS_MAX;
if (self.respawn_time == 0) self.respawn_time = RESPAWN_KEY;
// Check for coop errors
item_coopcheck();
item_start();
};
/*======================================================================
/*QUAKED item_key1 (0 0.5 0.8) (-16 -16 -24) (16 16 32) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/key_silver.mdl"); }
SILVER key, changes based on worldtype on worldspawn
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
SILVER key, changes based on worldtype on worldspawn
======================================================================*/
void() item_key1 =
{
// Check for any self worldtype override
if (!self.worldtype) self.worldtype = world.worldtype;
if (self.worldtype == 0) {
self.mdl = "progs/key_medieval.mdl"; // progs/w_s_key.mdl
self.netname = "silver key";
}
else if (self.worldtype == 1) {
self.mdl = "progs/key_runic.mdl"; // progs/m_s_key.mdl
self.netname = "silver runekey";
}
else if (self.worldtype == 2) {
self.mdl = "progs/key_base.mdl"; // progs/b_s_key.mdl
self.netname = "silver keycard";
}
precache_model (self.mdl);
self.skin = 2;
self.items = IT_KEY1;
self.classtype = CT_SILVERKEY;
self.part_active = PARTICLE_STYLE_KEYSILVER;
self.respawn_style = PARTICLE_BURST_BLUE + PARTICLE_BURST_CENTER;
self.respawn_ofs = '0 0 20';
key_setup();
};
/*======================================================================
/*QUAKED item_key2 (0 0.5 0.8) (-16 -16 -24) (16 16 32) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/key_gold.mdl"); }
GOLD key, changes based on worldtype on worldspawn
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
GOLD key, changes based on worldtype on worldspawn
======================================================================*/
void() item_key2 =
{
// Check for any self worldtype override
if (!self.worldtype) self.worldtype = world.worldtype;
if (self.worldtype == 0) {
self.mdl = "progs/key_medieval.mdl"; // progs/w_g_key.mdl
self.netname = "gold key";
}
if (self.worldtype == 1) {
self.mdl = "progs/key_runic.mdl"; // progs/m_g_key.mdl
self.netname = "gold runekey";
}
if (self.worldtype == 2) {
self.mdl = "progs/key_base.mdl"; // progs/b_g_key.mdl
self.netname = "gold keycard";
}
precache_model (self.mdl);
self.skin = 6;
self.items = IT_KEY2;
self.classtype = CT_GOLDKEY;
self.part_active = PARTICLE_STYLE_KEYGOLD;
self.respawn_style = PARTICLE_BURST_YELLOW + PARTICLE_BURST_CENTER;
self.respawn_ofs = '0 0 20';
key_setup();
};
/*======================================================================
/*QUAKED item_keyx (0 .5 .8) (-16 -16 -24) (16 16 32) CKEY1 CKEY2 CKEY3 CKEY4 RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/key_medieval.mdl"); }
Custom key
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
mdl : model name to load/display (progs/model.mdl)
netname : XXX Part of pickup string "You got the XXX"
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
Ckey1 : Custom Key type 1
Ckey2 : Custom Key type 2
Ckey3 : Custom Key type 3
Ckey4 : Custom Key type 4
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Custom key
======================================================================*/
void() item_keyx =
{
// Check for any self worldtype override
if (!self.worldtype) self.worldtype = world.worldtype;
// Can't have a custom key without a custom model!?!
if (self.mdl == "") {
dprint("\b[CUSTOM KEY]\b Missing model\n");
spawn_marker(self.origin, SPNMARK_YELLOW);
remove(self);
return;
}
precache_model (self.mdl);
// Setup custom key reference number (must exist)
if (self.spawnflags & ITEM_CKEY1) {
self.moditems = IT_CKEY1;
if (self.netname == "") self.netname = "Arcane Key 1";
}
else if (self.spawnflags & ITEM_CKEY2) {
self.moditems = IT_CKEY2;
if (self.netname == "") self.netname = "Arcane Key 2";
}
else if (self.spawnflags & ITEM_CKEY3) {
self.moditems = IT_CKEY3;
if (self.netname == "") self.netname = "Arcane Key 3";
}
else if (self.spawnflags & ITEM_CKEY4) {
self.moditems = IT_CKEY4;
if (self.netname == "") self.netname = "Arcane Key 4";
}
else {
dprint("\b[CUSTOM KEY]\b Missing spawnflag key number!\n");
spawn_marker(self.origin, SPNMARK_YELLOW);
remove(self);
return;
}
self.classtype = CT_CUSTOMKEY;
self.items = IT_KEY1 | IT_KEY2;
if (self.exactskin > 0) self.skin = self.exactskin;
// Check for any AD defined particle effects
if (self.message2 == "KEYGOLD") self.part_active = PARTICLE_STYLE_KEYGOLD;
else if (self.message2 == "KEYSILVER") self.part_active = PARTICLE_STYLE_KEYSILVER;
else if (self.message2 == "KEYRED") self.part_active = PARTICLE_STYLE_KEYRED;
else if (self.message2 == "KEYGREEN") self.part_active = PARTICLE_STYLE_KEYGREEN;
else if (self.message2 == "KEYPURPLE") self.part_active = PARTICLE_STYLE_KEYPURPLE;
else if (self.message2 == "KEYWHITE") self.part_active = PARTICLE_STYLE_KEYWHITE;
else self.part_active = 0;
// Default respawn parameters, clear message2 just in case
self.respawn_style = PARTICLE_BURST_WHITE + PARTICLE_BURST_CENTER;
if (!self.respawn_ofs) self.respawn_ofs = '0 0 20';
self.message2 = "";
key_setup();
};
/*======================================================================
/*QUAKED item_custom (0 .5 .8) (-16 -16 -24) (16 16 32) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/key_base.mdl"); }
Custom Pickup Item
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
mdl : model name to load/display (progs/model.mdl)
netname : XXX Part of pickup string "You got the XXX"
noise1 : Custom pickup sound (def=weapons/lock4.wav)
pos1 : Pickup bounding box minimum (def=-16 -16 -24)
pos2 : Pickup bounding box maximum (def=16 16 32)
bodyfadeaway : Model will fade away on pickup
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count: Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
part_active : = 1 Enable particle burst on pickup
part_ofs : Particle Origin Offset (def='0 0 0')
part_tcount : Particle Quantity (def=20)
part_life : Particle Life Time (def=2s)
part_style : 1=yellow, 2=green, 3=red, 4=blue, 5=purple, 6=fire, 7=white
part_movetype : 2=center, 3=up, 4=shockwave, 5=skull, 6=lost, 7=minotaur
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Custom Pickup Item
======================================================================*/
void() item_custom_touch =
{
sprint (other, "You got the ");
sprint (other, self.netname);
sprint (other,"\n");
if (self.noise != SOUND_EMPTY)
sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
// Check for a particle pickup burst (can be blocked)
if (self.part_style > 0 && !(self.spawnflags & ITEM_NOEFFECTS))
misc_particle_burst_use();
// Once only, fade away function
if (self.bodyfadeaway == TRUE) {
self.use = self.touch = SUB_Null;
self.think = model_fade;
self.nextthink = time + 0.1;
self.ltime = self.nextthink;
self.wait = self.delay = 0;
}
else {
// Do not remove/respawn in co-op
if (!coop) {
item_finished();
check_item_respawn();
}
}
activator = other;
SUB_UseTargets();
};
//----------------------------------------------------------------------
void() item_custom =
{
if (self.mdl == "") self.mdl = MODEL_BROKEN;
if (self.noise == "") self.noise = "weapons/lock4.wav";
precache_model (self.mdl);
precache_sound (self.noise);
self.classtype = CT_CUSTOMITEM;
// Essentially this item is used like a key
// pickup, collect and trigger an event
self.classgroup = CG_KEY;
if (self.netname == "") self.netname = "Custom Item";
if (self.respawn_time == 0) self.respawn_time = RESPAWN_KEY;
// Check for a particle burst setup
if (self.part_active == TRUE) misc_particle_burst_setup();
self.part_active = 0; // Must clear this afterward
// Setup random rotation, will be ignored if spinning model
if (self.angles_y <= 0) self.angles_y = rint(random()*359);
// Setup different skin options
if (self.exactskin > 0) self.skin = self.exactskin;
else if (self.randomskin > 1) self.skin = rint(random()*(self.randomskin-1));
if (self.skin < 0) self.skin = 0; // Double check no negatives
self.touch2 = item_custom_touch;
if (CheckZeroVector(self.pos1)) self.bbmins = VEC_KEYS_MIN;
else self.bbmins = self.pos1;
if (CheckZeroVector(self.pos2)) self.bbmaxs = VEC_KEYS_MAX;
else self.bbmaxs = self.pos2;
item_start();
};
/*======================================================================
/*QUAKED item_sigil (0 0.5 0.8) (-16 -16 -24) (16 16 32) Ep1 Ep2 Ep3 Ep4 RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/key_rune1.mdl"); }
End of episode sigil / rune
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
EP1 : Episode 1 Rune
EP2 : Episode 2 Rune
EP3 : Episode 3 Rune
EP4 : Episode 4 Rune
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
End of episode sigil. If the player is in possession of a sigil, then the next time
the player changes levels, all func_episodegate entities for that episode will appear.
This is used to block access to slipgates that lead to episodes that the player has
already completed. If the player is in possession of the item_sigil for all four
episodes, then the func_bossgate entity will NOT appear. This is used to grant
access to the final boss once the player has completed all episodes.
======================================================================*/
void() sigil_touch =
{
if (query_configflag(self.customkey)) return;
centerprint (other, "You got the rune!");
if (self.noise != SOUND_EMPTY)
sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
// Add rune to server! not player
update_configflag(self.customkey, TRUE);
// DP has special effect for sigil being picked up
if (ext_dppart) pointparticles(particleeffectnum(DPP_SIGILPICKUP), self.origin, '0 0 0', 1);
// hide item and check for respawn
item_finished();
check_item_respawn();
// This odd classname assignment does nothing, old code
//self.classname = string_null;
activator = other;
SUB_UseTargets();
};
//----------------------------------------------------------------------
void() item_sigil =
{
if (!self.spawnflags) {
dprint("\b[SIGIL]\b No Rune type selected!?!\n");
spawn_marker(self.origin, SPNMARK_YELLOW);
return;
}
// Based on what spawn key is selected, update model/spawnflag
// This will make sure only one rune is selected at once
// Also allow for the spawnflags to have other parameters
if (self.spawnflags & SVR_RUNE_KEY1) {
self.mdl = "progs/key_rune1.mdl";
self.customkey = SVR_RUNE_KEY1;
}
else if (self.spawnflags & SVR_RUNE_KEY2) {
self.mdl = "progs/key_rune2.mdl";
self.customkey = SVR_RUNE_KEY2;
}
else if (self.spawnflags & SVR_RUNE_KEY3) {
self.mdl = "progs/key_rune3.mdl";
self.customkey = SVR_RUNE_KEY3;
}
else if (self.spawnflags & SVR_RUNE_KEY4) {
self.mdl = "progs/key_rune4.mdl";
self.customkey = SVR_RUNE_KEY4;
}
precache_model (self.mdl);
if (self.noise == "") self.noise = "misc/runekey.wav";
precache_sound (self.noise);
self.touch2 = sigil_touch;
self.classtype = CT_RUNEKEY;
self.classgroup = CG_RUNE;
self.part_active = PARTICLE_STYLE_SIGIL;
self.bbmins = VEC_KEYS_MIN;
self.bbmaxs = VEC_KEYS_MAX;
if (self.respawn_time == 0) self.respawn_time = RESPAWN_RUNE;
self.respawn_style = PARTICLE_BURST_PURPLE + PARTICLE_BURST_CENTER;
self.respawn_ofs = '0 0 16';
// Check for coop errors
item_coopcheck();
item_start();
};
/*======================================================================
/*QUAKED item_artifact_tomeofpower (0 .5 .8) (-16 -16 -24) (16 16 32) x x x x x FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/key_tome.mdl"); }
Custom event trigger
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
target : trigger targets to fire when item touched
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
noise : Custom pickup sound
-------- SPAWNFLAGS --------
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Custom event trigger
======================================================================*/
void() tomeofpower_touch =
{
sprint (other, "You got the ");
sprint (other, self.netname);
sprint (other,"\n");
if (self.noise != SOUND_EMPTY)
sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
// This is a trigger once condition (regardless of coop)
item_finished();
activator = other;
SUB_UseTargets();
};
//----------------------------------------------------------------------
void() item_artifact_tomeofpower =
{
self.mdl = "progs/artifact_tome.mdl";
precache_model (self.mdl);
if (self.noise == "") self.noise = "misc/medkey.wav";
precache_sound (self.noise);
self.classtype = CT_ARTTOME;
self.classgroup = CG_ARTIFACT;
self.moditems = IT_ARTTOME;
self.netname = "Tome of Power";
self.touch2 = tomeofpower_touch;
self.bbmins = VEC_POWR_MIN;
self.bbmaxs = VEC_POWR_MAX;
self.part_active = PARTICLE_STYLE_TOMEOFP;
item_start();
};
/*======================================================================
ARTIFACTS - suit, pent, invis, quad, sharpshooter, nailpiercer, westsuit
======================================================================*/
void() artifact_touch =
{
//----------------------------------------------------------------------
// Existing artifacts
//----------------------------------------------------------------------
if (self.classtype == CT_ARTSUIT) {
other.rad_time = TRUE;
other.radsuit_finished = time + self.cnt;
ResetDebuffBurning(other);
ResetDebuffPoisoned(other);
// Remove any wetsuit artifact
other.moditems = other.moditems - (other.moditems & IT_ARTWETSUIT);
other.wetsuit_finished = 0;
other.wetsuit_time = 0;
}
else if (self.classtype == CT_ARTPENT) {
other.invincible_time = TRUE;
other.invincible_finished = time + self.cnt;
ResetDebuffSystem(other);
}
else if (self.classtype == CT_ARTINVS) {
other.invisible_time = TRUE;
other.invisible_finished = time + self.cnt;
other.invisible_sound = time + 1;
}
else if (self.classtype == CT_ARTQUAD) {
other.super_time = TRUE;
other.super_damage_finished = time + self.cnt;
}
else if (self.classtype == CT_ARTSHARP) {
other.sharpshoot_time = TRUE;
other.sharpshoot_finished = time + self.cnt;
}
else if (self.classtype == CT_ARTPIERCE) {
other.nailpiercer_time = TRUE;
other.nailpiercer_finished = time + self.cnt;
}
else if (self.classtype == CT_ARTWETSUIT) {
other.wetsuit_time = TRUE;
other.wetsuit_finished = time + self.cnt;
other.wetsuit_sound = time + 2;
// Remove any envsuit artifact
other.items = other.items - (other.items & IT_SUIT);
other.radsuit_finished = 0;
other.rad_time = 0;
}
else return;
//----------------------------------------------------------------------
// Pickup sound and initial screen flash
//----------------------------------------------------------------------
sprint (other, "You got the ");
sprint (other, self.netname);
sprint (other,"\n");
if (self.noise != SOUND_EMPTY)
sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
// Update player item flags (regular + mod)
other.items = other.items | self.items;
other.moditems = other.moditems | self.moditems;
// hide item and check for respawn
item_finished();
check_item_respawn();
activator = other;
SUB_UseTargets();
};
/*======================================================================
setup all artifacts with similiar configurations
======================================================================*/
void() artifact_setup =
{
self.touch2 = artifact_touch;
self.classgroup = CG_ARTIFACT;
self.bbmins = VEC_POWR_MIN;
self.bbmaxs = VEC_POWR_MAX;
// Allow for custom artifact timer
if (self.cnt < 1) self.cnt = POWERUP_TIMER;
// Setup skin override
if (self.exactskin < 1) self.exactskin = 0;
self.skin = self.exactskin;
// Setup artifact default respawn timers
if (self.respawn_time == 0) {
if (self.classtype == CT_ARTPENT || self.classtype == CT_ARTINVS)
self.respawn_time = RESPAWN_ARTIFACT2;
else self.respawn_time = RESPAWN_ARTIFACT1;
}
item_start ();
};
/*======================================================================
/*QUAKED item_artifact_envirosuit (0 0.5 0.8) (-16 -16 -24) (16 16 32) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/artifact_envsuit.mdl"); }
Player takes no damage from water or slime for 30 seconds
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
exactskin : 0=Original, 1=Green, 2=Brown, 3=Aqua, 4=Blue
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count: Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
cnt : Duration override of artifact (default = 30s)
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Player takes no damage from water or slime for 30 seconds
Immume from Wraith Healing Debuff but take small damage instead
======================================================================*/
void() item_artifact_envirosuit =
{
// cshifts 0,255,0,20
self.mdl = "progs/artifact_envsuit.mdl";
precache_model (self.mdl);
self.noise = SOUND_ARTSUIT1;
self.noise1 = SOUND_ARTSUIT2;
precache_sound (self.noise);
precache_sound (self.noise1);
self.netname = "Environment Suit";
self.items = IT_SUIT;
self.classtype = CT_ARTSUIT;
self.part_active = PARTICLE_STYLE_SUIT;
self.respawn_style = PARTICLE_BURST_GREEN + PARTICLE_BURST_CENTER;
self.respawn_ofs = '0 0 28';
artifact_setup();
};
/*======================================================================
/*QUAKED item_artifact_wetsuit (0 0.5 0.8) (-16 -16 -24) (16 16 32) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/artifact_wetsuit.mdl"); }
Player takes no damage from water for 5 mins (300s)
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
exactskin : 0=Original, 1=Green, 2=Brown, 3=Aqua, 4=Blue
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count: Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
cnt : Duration override of artifact (default = 300s)
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Player takes no damage from water for 5 mins (300s)
Immume from Wraith Healing Debuff but take small damage instead
======================================================================*/
void() item_artifact_wetsuit =
{
// cshifts 0,255,0,20
self.mdl = "progs/artifact_wetsuit.mdl";
precache_model (self.mdl);
self.noise = SOUND_ARTWETS1;
self.noise1 = SOUND_ARTWETS2;
self.noise2 = SOUND_ARTWETS3;
self.noise3 = SOUND_ARTWETS3B;
precache_sound (self.noise);
precache_sound (self.noise1);
precache_sound (self.noise2);
precache_sound (self.noise3);
self.netname = "Wet Suit";
self.items = 0;
self.moditems = IT_ARTWETSUIT;
self.classtype = CT_ARTWETSUIT;
self.part_active = PARTICLE_STYLE_WETSUIT;
self.respawn_style = PARTICLE_BURST_BLUE + PARTICLE_BURST_CENTER;
self.respawn_ofs = '0 0 28';
if (self.cnt < 1) self.cnt = 300;
if (self.exactskin < 1) self.exactskin = 4;
artifact_setup();
};
/*======================================================================
/*QUAKED item_artifact_invulnerability (0 0.5 0.8) (-16 -16 -24) (16 16 32) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/artifact_pent.mdl"); }
Player is invulnerable for 30 seconds
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count: Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
cnt : Duration override of artifact (default = 30s)
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Player is invulnerable for 30 seconds
Immume from Wraith Healing Debuff
======================================================================*/
void() item_artifact_invulnerability =
{
// cshifts 255,255,0,30
self.mdl = "progs/artifact_pent.mdl"; // Originally - progs/invulner.mdl
precache_model (self.mdl);
self.noise = SOUND_ARTPENT1;
self.noise1 = SOUND_ARTPENT2;
self.noise2 = SOUND_ARTPENT3;
precache_sound (self.noise);
precache_sound (self.noise1);
precache_sound (self.noise2);
self.netname = "Pentagram of Protection";
self.items = IT_INVULNERABILITY;
self.classtype = CT_ARTPENT;
self.part_active = PARTICLE_STYLE_PENT;
self.respawn_style = PARTICLE_BURST_RED + PARTICLE_BURST_CENTER;
self.respawn_ofs = '0 0 16';
artifact_setup();
};
/*======================================================================
/*QUAKED item_artifact_invisibility (0 0.5 0.8) (-16 -16 -24) (16 16 32) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/artifact_invis.mdl"); }
Player is invisible for 30 seconds
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count: Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
cnt : Duration override of artifact (default = 30s)
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Player is invisible for 30 seconds
======================================================================*/
void() item_artifact_invisibility =
{
// cshifts 100,100,100,100
self.mdl = "progs/artifact_invis.mdl"; // Originally - progs/invisibl.mdl
precache_model (self.mdl);
self.noise = SOUND_ARTINV1;
self.noise1 = SOUND_ARTINV2;
self.noise2 = SOUND_ARTINV3;
precache_sound (self.noise);
precache_sound (self.noise1);
precache_sound (self.noise2);
self.netname = "Ring of Shadows";
self.items = IT_INVISIBILITY;
self.classtype = CT_ARTINVS;
self.part_active = PARTICLE_STYLE_SRING;
self.respawn_style = PARTICLE_BURST_YELLOW + PARTICLE_BURST_CENTER;
self.respawn_ofs = '0 0 6';
artifact_setup();
};
/*======================================================================
/*QUAKED item_artifact_super_damage (0 0.5 0.8) (-16 -16 -24) (16 16 32) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/artifact_quad.mdl"); }
The next attack from the player will do 4x damage
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count: Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
cnt : Duration override of artifact (default = 30s)
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
The next attack from the player will do 4x damage
======================================================================*/
void() item_artifact_super_damage =
{
// cshifts 0,0,255,30
self.mdl = "progs/artifact_quad.mdl"; // Originally - progs/quaddama.mdl
precache_model (self.mdl);
self.noise = SOUND_ARTQUAD1;
self.noise1 = SOUND_ARTQUAD2;
self.noise2 = SOUND_ARTQUAD3;
precache_sound (self.noise);
precache_sound (self.noise1);
precache_sound (self.noise2);
self.netname = "Quad Damage";
self.items = IT_QUAD;
self.classtype = CT_ARTQUAD;
self.part_active = PARTICLE_STYLE_QUAD;
self.respawn_style = PARTICLE_BURST_BLUE + PARTICLE_BURST_CENTER;
self.respawn_ofs = '0 0 16';
artifact_setup();
};
/*======================================================================
/*QUAKED item_artifact_sharp_shooter (0 0.5 0.8) (-16 -16 -24) (16 16 32) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/artifact_sharp.mdl"); }
Reduces the bullet spread of all Shotguns
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count: Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
cnt : Duration override of artifact (default = 30s)
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Reduces the bullet spread of all Shotguns
======================================================================*/
void() item_artifact_sharp_shooter =
{
self.mdl = "progs/artifact_sharp.mdl";
precache_model (self.mdl);
self.noise = SOUND_ARTSHARP1;
self.noise1 = SOUND_ARTSHARP2;
self.noise2 = SOUND_ARTSHARP3;
precache_sound (self.noise);
precache_sound (self.noise1);
precache_sound (self.noise2);
self.netname = "Sharp Shooter";
self.items = IT_QUAD;
self.moditems = IT_ARTSHARP;
self.classtype = CT_ARTSHARP;
self.part_active = PARTICLE_STYLE_SHARP;
self.respawn_style = PARTICLE_BURST_PURPLE + PARTICLE_BURST_CENTER;
self.respawn_ofs = '0 0 16';
artifact_setup();
};
/*======================================================================
/*QUAKED item_artifact_nail_piercer (0 0.5 0.8) (-16 -16 -24) (16 16 32) x x x x RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/artifact_piercer.mdl"); }
All nail attacks will travel through monsters
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
message : centerprint message when item is picked up
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count: Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
cnt : Duration override of artifact (default = 30s)
-------- SPAWNFLAGS --------
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
All nail attacks will travel through monsters
======================================================================*/
void() item_artifact_nail_piercer =
{
self.mdl = "progs/artifact_piercer.mdl";
precache_model (self.mdl);
self.noise = SOUND_ARTNAILP1;
self.noise1 = SOUND_ARTNAILP2;
self.noise2 = SOUND_ARTNAILP3;
precache_sound (self.noise);
precache_sound (self.noise1);
precache_sound (self.noise2);
self.netname = "Nail Piercer";
self.items = IT_QUAD;
self.moditems = IT_ARTPIERCE;
self.classtype = CT_ARTPIERCE;
self.part_active = PARTICLE_STYLE_PIERCE;
self.respawn_style = PARTICLE_BURST_PURPLE + PARTICLE_BURST_CENTER;
self.respawn_ofs = '0 0 16';
artifact_setup();
};
//======================================================================
// ITEM BACKPACKS
// * Dropped from monsters and players
// * Can be setup as an item with random ammo/armour
// * Will monitor ground below so can fall further
//
//======================================================================
float(entity backent, string backtext1, string backtext2, float backcomma) BackpackText =
{
if (backcomma > 0) sprint (backent, ", ");
if (backtext1 != "") sprint (backent, backtext1);
if (backtext2 != "") sprint (backent, backtext2);
return 1;
};
//----------------------------------------------------------------------
void() BackpackTouch =
{
local string s;
local float pickupweapon, acount;
acount = 0;
sprint (other, "You get ");
//----------------------------------------------------------------------
// A Coop player can pickup all of the weapons
// dropped by previous player (go through list)
//----------------------------------------------------------------------
if (coop > 0) {
if (self.moditems & IT_UPGRADE_AXE && !(other.moditems & IT_UPGRADE_AXE)) {
pickupweapon = IT_UPGRADE_AXE;
other.items = other.items | pickupweapon;
acount = BackpackText(other, "ShadowAxe", "", acount);
other.moditems = other.moditems | pickupweapon;
update_configflag(SVR_UPDAXE, TRUE);
}
if (self.items & IT_SHOTGUN && !(other.items & IT_SHOTGUN)) {
pickupweapon = IT_SHOTGUN;
other.items = other.items | pickupweapon;
acount = BackpackText(other, "SG", "", acount);
}
if (self.moditems & IT_UPGRADE_SSG && !(other.moditems & IT_UPGRADE_SSG)) {
pickupweapon = IT_UPGRADE_SSG;
other.items = other.items | pickupweapon;
acount = BackpackText(other, "WidowMaker", "", acount);
other.moditems = other.moditems | pickupweapon;
update_configflag(SVR_UPDSSG, TRUE);
}
else if (self.items & IT_SUPER_SHOTGUN && !(other.items & IT_SUPER_SHOTGUN)) {
pickupweapon = IT_SUPER_SHOTGUN;
other.items = other.items | pickupweapon;
acount = BackpackText(other, "SSG", "", acount);
}
if (self.items & IT_NAILGUN && !(other.items & IT_NAILGUN)) {
pickupweapon = IT_NAILGUN;
other.items = other.items | pickupweapon;
acount = BackpackText(other, "NG", "", acount);
}
if (self.items & IT_SUPER_NAILGUN && !(other.items & IT_SUPER_NAILGUN)) {
pickupweapon = IT_SUPER_NAILGUN;
other.items = other.items | pickupweapon;
acount = BackpackText(other, "SNG", "", acount);
}
if (self.items & IT_GRENADE_LAUNCHER && !(other.items & IT_GRENADE_LAUNCHER)) {
pickupweapon = IT_GRENADE_LAUNCHER;
other.items = other.items | pickupweapon;
acount = BackpackText(other, "GL", "", acount);
}
if (self.items & IT_ROCKET_LAUNCHER && !(other.items & IT_ROCKET_LAUNCHER)) {
pickupweapon = IT_ROCKET_LAUNCHER;
other.items = other.items | pickupweapon;
acount = BackpackText(other, "RL", "", acount);
}
if (self.moditems & IT_UPGRADE_LG && !(other.moditems & IT_UPGRADE_LG)) {
pickupweapon = IT_UPGRADE_LG;
other.items = other.items | pickupweapon;
acount = BackpackText(other, "PlasmaGun", "", acount);
other.moditems = other.moditems | pickupweapon;
update_configflag(SVR_UPDLG, TRUE);
}
else if (self.items & IT_LIGHTNING && !(other.items & IT_LIGHTNING)) {
pickupweapon = IT_LIGHTNING;
other.items = other.items | pickupweapon;
acount = BackpackText(other, "LG", "", acount);
}
}
// DM backpacks have only one weapon
else {
// Setup name of weapon first
if (self.items & IT_LIGHTNING && self.moditems & IT_UPGRADE_LG)
self.netname = "Plasma Gun";
else if (self.items & IT_LIGHTNING) self.netname = "Thunderbolt";
else if (self.items & IT_ROCKET_LAUNCHER) self.netname = "Rocket Launcher";
else if (self.items & IT_GRENADE_LAUNCHER) self.netname = "Grenade Launcher";
else if (self.items & IT_SUPER_NAILGUN) self.netname = "Super Nailgun";
else if (self.items & IT_NAILGUN) self.netname = "Nailgun";
else if (self.items & IT_SUPER_SHOTGUN && self.moditems & IT_UPGRADE_SSG)
self.netname = "Widow Maker Shotgun";
else if (self.items & IT_SUPER_SHOTGUN) self.netname = "Double-barrelled Shotgun";
else if (self.items & IT_SHOTGUN) self.netname = "Shotgun";
else if (self.items & IT_AXE && self.moditems & IT_UPGRADE_AXE)
self.netname = "Shadow Axe";
else if (self.items & IT_AXE) self.netname = "Axe";
else self.netname = "";
// Check if the player has the weapon already?
if ((other.items & self.items) == 0 && self.netname != "") {
other.items = other.items | self.items;
other.moditems = other.moditems | self.moditems;
acount = BackpackText(other, "the", self.netname, acount);
}
}
//----------------------------------------------------------------------
// Calculate random amounts of ammo
//----------------------------------------------------------------------
if (self.count > 0) {
if (self.spawnflags & BACKPACK_SHELLS) self.ammo_shells = rint(1 + random()*self.count);
if (self.spawnflags & BACKPACK_NAILS) self.ammo_nails = rint(1 + random()*self.count);
if (self.spawnflags & BACKPACK_ROCKETS) self.ammo_rockets = rint(1 + random()*self.count);
if (self.spawnflags & BACKPACK_CELLS) self.ammo_cells = rint(1 + random()*self.count);
if (self.armortype == 1) self.armorvalue = rint(1 + random()*self.count);
}
//----------------------------------------------------------------------
// Give ammo to player
//----------------------------------------------------------------------
if (self.ammo_shells > 0) {
other.ammo_shells = other.ammo_shells + self.ammo_shells;
other.items = other.items | IT_SHELLS;
s = ftos(self.ammo_shells);
acount = BackpackText(other, s, " shells", acount);
}
if (self.ammo_nails > 0) {
other.ammo_nails = other.ammo_nails + self.ammo_nails;
other.items = other.items | IT_NAILS;
s = ftos(self.ammo_nails);
acount = BackpackText(other, s, " nails", acount);
}
if (self.ammo_rockets > 0) {
other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
other.items = other.items | IT_ROCKETS;
s = ftos(self.ammo_rockets);
acount = BackpackText(other, s, " rockets", acount);
}
if (self.ammo_cells > 0) {
other.ammo_cells = other.ammo_cells + self.ammo_cells;
other.items = other.items | IT_CELLS;
s = ftos(self.ammo_cells);
acount = BackpackText(other, s, " cells", acount);
}
//----------------------------------------------------------------------
// Check for armor in backpack
//----------------------------------------------------------------------
if (self.armorvalue > 0 && deathmatch == 0) {
// For coop backpacks can be dropped from players
// These can contain huge amounts of armour and needed
// to be treated as upgrade/replace, not the shard system
if (coop > 0 && self.items & IT_ALLARMOR) {
if (other.armortype*other.armorvalue < self.armortype*self.armorvalue) {
other.armortype = self.armortype;
other.armorvalue = self.armorvalue;
other.items = other.items - (other.items & IT_ALLARMOR);
other.items = other.items + (self.items & IT_ALLARMOR);
acount = BackpackText(other, "armor upgraded", "", acount);
}
}
else {
// For Singleplayer backpack items can contain shards
// Shards add to the armour value and can go above limit
// If no armour present (add a green jacket)
other.armorvalue = other.armorvalue + self.armorvalue;
// Yellow armour upgrade
// Only update armour type if green armour present
if (self.armortype == ARMOR_YEL_TYPE) {
if (other.items & IT_ARMOR1 || other.armortype == 0) {
other.items = other.items - (other.items & IT_ARMOR1);
other.items = other.items | IT_ARMOR2;
other.armortype = ARMOR_YEL_TYPE;
}
}
// Red armour upgrade
// Remove previous armour type (hud display flag)
else if (self.armortype == ARMOR_RED_TYPE) {
other.items = other.items - (other.items & IT_ARMOR1);
other.items = other.items - (other.items & IT_ARMOR2);
other.items = other.items | IT_ARMOR3;
other.armortype = ARMOR_RED_TYPE;
}
// Does the player have any armor already?
else if (other.armortype == 0 ) {
// No armor present, give green with armor shards
other.items = other.items | IT_ARMOR1;
other.armortype = ARMOR_GRN_TYPE;
}
if (self.armorvalue > 0) {
s = ftos(self.armorvalue);
acount = BackpackText(other, s, " armor shards", acount);
}
}
}
//----------------------------------------------------------------------
// Check for Silver/Gold/Custom keys if coop active
//----------------------------------------------------------------------
if (coop > 0) {
if (self.items & IT_KEY1) {
other.items = other.items | IT_KEY1;
acount = BackpackText(other, "Silver Key", "", acount);
}
if (self.items & IT_KEY2) {
other.items = other.items | IT_KEY2;
acount = BackpackText(other, "Gold Key", "", acount);
}
if (self.moditems & IT_CKEY1) {
other.moditems = other.moditems | IT_CKEY1;
other.ckeyname1 = self.ckeyname1;
acount = BackpackText(other, self.ckeyname1, "", acount);
}
if (self.moditems & IT_CKEY2) {
other.moditems = other.moditems | IT_CKEY2;
other.ckeyname2 = self.ckeyname2;
acount = BackpackText(other, self.ckeyname2, "", acount);
}
if (self.moditems & IT_CKEY3) {
other.moditems = other.moditems | IT_CKEY3;
other.ckeyname3 = self.ckeyname3;
acount = BackpackText(other, self.ckeyname3, "", acount);
}
if (self.moditems & IT_CKEY4) {
other.moditems = other.moditems | IT_CKEY4;
other.ckeyname4 = self.ckeyname4;
acount = BackpackText(other, self.ckeyname4, "", acount);
}
}
//----------------------------------------------------------------------
// Check for Powerups if coop active
//----------------------------------------------------------------------
if (coop > 0) {
if (self.items & IT_INVISIBILITY) {
other.items = other.items | IT_INVISIBILITY;
acount = BackpackText(other, "InvRing", "", acount);
other.invisible_finished = self.invisible_finished;
other.invisible_time = self.invisible_time;
other.invisible_sound = self.invisible_sound;
}
if (self.items & IT_SUIT) {
other.items = other.items | IT_SUIT;
acount = BackpackText(other, "EnvSuit", "", acount);
other.radsuit_finished = self.radsuit_finished;
other.rad_time = self.rad_time;
}
if (self.items & IT_QUAD) {
other.items = other.items | IT_QUAD;
acount = BackpackText(other, "QuadDam", "", acount);
other.super_damage_finished = self.super_damage_finished;
other.super_time = self.super_time;
other.super_sound = self.super_sound;
}
if (self.moditems & IT_ARTSHARP) {
other.moditems = other.moditems | IT_ARTSHARP;
acount = BackpackText(other, "ShpShoot", "", acount);
other.sharpshoot_finished = self.sharpshoot_finished;
other.sharpshoot_time = self.sharpshoot_time;
other.sharpshooter_sound = self.sharpshooter_sound;
}
if (self.moditems & IT_ARTWETSUIT) {
other.moditems = other.moditems | IT_ARTWETSUIT;
acount = BackpackText(other, "WetSuit", "", acount);
other.wetsuit_finished = self.wetsuit_finished;
other.wetsuit_time = self.wetsuit_time;
other.wetsuit_sound = self.wetsuit_sound;
}
if (self.moditems & IT_ARTPIERCE) {
other.moditems = other.moditems | IT_ARTPIERCE;
acount = BackpackText(other, "Piercer", "", acount);
other.nailpiercer_finished = self.nailpiercer_finished;
other.nailpiercer_time = self.nailpiercer_time;
other.nailpiercer_sound = self.nailpiercer_sound;
}
}
sprint (other, " from a backpack\n");
if (self.noise != SOUND_EMPTY)
sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
// Check ammo limts, change to best weapon and set ammo type
bound_other_ammo (other);
if (deathmatch) other.weapon = W_BestWeapon(other);
W_SetCurrentAmmo (other);
// Random ammo backpacks are actual items
if (self.classtype == CT_AMMORANDOM) {
// hide item and check for respawn
item_finished();
check_item_respawn();
}
// Temporary backpack
else remove(self);
};
//----------------------------------------------------------------------
void() DropBackpack =
{
local entity item;
//----------------------------------------------------------------------
// Check for player because of other items
if (self.classtype != CT_PLAYER) {
if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
return; // nothing in it
}
item = spawn();
item.classtype = CT_AMMOPACK;
item.classgroup = CG_AMMOITEM;
item.classname = "item_backpack";
item.origin = self.origin - '0 0 20';
// No way to cache something different without adding to world.qc
// Default quake sound for backpacks dropped from monsters
item.noise = "weapons/lock4.wav";
//----------------------------------------------------------------------
// Pyro Enforcers drop armor shards instead!!!
//----------------------------------------------------------------------
if (self.classtype == CT_MONPYRO || self.classtype == CT_MONFUMIGATOR)
item.armorvalue = rint(1 + random() * self.ammo_shells);
else {
// Everything else drops ammo
item.ammo_shells = self.ammo_shells;
item.ammo_nails = self.ammo_nails;
item.ammo_rockets = self.ammo_rockets;
item.ammo_cells = self.ammo_cells;
}
//----------------------------------------------------------------------
// Reset backpack inventory before any test
item.items = item.moditems = item.customkey = 0;
//----------------------------------------------------------------------
// If player dropping backpack check for extra stuff
if (self.classtype == CT_PLAYER) {
// Copy over items for coop players to pickup
if (coop > 0) {
// Copy all items + keys
item.items = self.items;
item.moditems = self.moditems;
item.customkey = self.customkey;
// Copy current armour type + value
item.armortype = self.armortype;
item.armorvalue = self.armorvalue;
// Copy over custom key netnames
if (self.moditems & IT_CKEY1) item.ckeyname1 = self.ckeyname1;
if (self.moditems & IT_CKEY2) item.ckeyname2 = self.ckeyname2;
if (self.moditems & IT_CKEY3) item.ckeyname3 = self.ckeyname3;
if (self.moditems & IT_CKEY4) item.ckeyname4 = self.ckeyname4;
//----------------------------------------------------------------------
// Copy over any powerup timers
// Cannot die with invulnerability so not checked!
if (coop_artifacts == TRUE) {
if (self.items & IT_INVISIBILITY) {
item.invisible_finished = self.invisible_finished;
item.invisible_time = self.invisible_time;
item.invisible_sound = self.invisible_sound;
}
if (self.items & IT_SUIT) {
item.radsuit_finished = self.radsuit_finished;
item.rad_time = self.rad_time;
}
if (self.items & IT_QUAD) {
item.super_damage_finished = self.super_damage_finished;
item.super_time = self.super_time;
item.super_sound = self.super_sound;
}
if (self.moditems & IT_ARTSHARP) {
item.sharpshoot_finished = self.sharpshoot_finished;
item.sharpshoot_time = self.sharpshoot_time;
item.sharpshooter_sound = self.sharpshooter_sound;
}
if (self.moditems & IT_ARTWETSUIT) {
item.wetsuit_finished = self.wetsuit_finished;
item.wetsuit_time = self.wetsuit_time;
item.wetsuit_sound = self.wetsuit_sound;
}
if (self.moditems & IT_ARTPIERCE) {
item.nailpiercer_finished = self.nailpiercer_finished;
item.nailpiercer_time = self.nailpiercer_time;
item.nailpiercer_sound = self.nailpiercer_sound;
}
}
}
//----------------------------------------------------------------------
// Default is DM only, current weapon only
else {
// Check for any special MOD weapons
if (self.weapon == IT_AXE && self.moditems & IT_UPGRADE_AXE)
item.moditems = IT_UPGRADE_AXE;
else if (self.weapon == IT_SUPER_SHOTGUN && self.moditems & IT_UPGRADE_SSG)
item.moditems = IT_UPGRADE_SSG;
else if (self.weapon == IT_LIGHTNING && self.moditems & IT_UPGRADE_LG)
item.moditems = IT_UPGRADE_LG;
// Copy over current weapon ONLY to backpack
item.items = self.weapon;
}
}
// Give the backpack some random toss!
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;
setmodel (item, MODEL_BACKPACK);
setsize (item, '-16 -16 0', '16 16 56');
item.touch = item_touch;
item.touch2 = BackpackTouch;
//----------------------------------------------------------------------
// 1=green, 2=blue, 3=red, 4=golden, 5=swampy, 6=white, 7=flesh
// green=shells, blue=cells, red=rockets
//----------------------------------------------------------------------
if (self.classtype == CT_MONDEFENDER) item.skin = 1;
else if (self.classtype == CT_MONARMYGRENADE) item.skin = 1;
else if (self.classtype == CT_MONARMYPLASMA) item.skin = 2;
else if (self.classtype == CT_MONELIMATOR) item.skin = 2;
else if (self.classtype == CT_MONCENTURION) item.skin = 2;
else if (self.classtype == CT_MONARMYROCKET) item.skin = 3;
else if (self.classtype == CT_MONPYRO) item.skin = 4;
else if (self.classtype == CT_MONFUMIGATOR) item.skin = 5;
else if (self.classtype == CT_MONENFORCER) item.skin = 7;
// Default = remove after 2 minutes, stay if coop active
if (coop == 0) item.item_expired = time + 120;
else item.item_expired = 0;
item.item_flrcheck = fabs(item.mins_z) + 16;
item.think = item_thinkloop; // Check floor
item.nextthink = time + 0.3; // Let backpack drop first
};
/*======================================================================
/*QUAKED item_backpack (0 .5 .8) (-16 -16 0) (16 16 56) SHELLS NAILS ROCKETS CELLS RESPAWN FLOAT STARTOFF NOEFFECTS NOT_EASY NOT_NORMAL NOT_HARD NOT_DM
{ model(":progs/w_backpack.mdl"); }
Backpack with random/exact amount of ammo
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
count : random amount of ammo to give (works with spawnflags)
ammo_shells : exact amount of shells
ammo_nails : exact amount of spikes
ammo_rockets : exact amount of rockets
ammo_cells : exact amount of cells
armorvalue : armor shards (gives green armor if none present)
armortype : 1 = random amount of armor shards (uses count)
exactskin : 0=Original, 1=green, 2=blue, 3=red, 4=yellow, 5=swamp, 6=white, 7=pale
upgrade_ssg : = 1 will only spawn if shotgun upgrade active on server
upgrade_axe : = 1 will only spawn if axe upgrade active on server
upgrade_lg : = 1 will only spawn if lightning gun upgrade active on server
noise : pickup sound (def=items/backpack_ammo.wav)
respawn_time : time to wait before respawning (1-x seconds, default varies)
respawn_count : Total amount of times to respawn (counts down to zero)
respawn_trig : = 1 Wait for trigger before respawning
-------- SPAWNFLAGS --------
SHELLS : ammo for SG / SSG / RG
NAILS : ammo for NG / SNG
ROCKETS : ammo for GL / RL
CELLS : ammo for LG
RESPAWN : Can respawn after being picked up
FLOAT : No drop to floor test
STARTOFF : Starts off and waits for trigger
NOEFFECTS : No particle or effects active
-------- NOTES --------
Backpack with random/exact amount of ammo
Cannot be used to drop weapons or armour!
======================================================================*/
void() item_backpack_setup =
{
// Empty netname for backpack routine
self.netname = "";
self.origin = self.origin + '0 0 12';
// reset frame, weapon and armour type, but not value
self.frame = self.weapon = self.items = 0;
self.frame_override = self.frame_box = 0;
// Make sure the ammo/armor quantites are NOT negative!
if (self.ammo_shells < 0) self.ammo_shells = 0;
if (self.ammo_nails < 0) self.ammo_nails = 0;
if (self.ammo_rockets < 0) self.ammo_rockets = 0;
if (self.ammo_cells < 0) self.ammo_cells = 0;
if (self.armorvalue < 0) self.armorvalue = 0;
// Check if exact skin is within range
if(self.exactskin < 0 || self.exactskin > 7) self.exactskin = 0;
self.skin = self.exactskin;
// Check for random ammo setup (uses spawnflags)
if (self.spawnflags & BACKPACK_SHELLS) self.ammo_shells = -1;
if (self.spawnflags & BACKPACK_NAILS) self.ammo_nails = -1;
if (self.spawnflags & BACKPACK_ROCKETS) self.ammo_rockets = -1;
if (self.spawnflags & BACKPACK_CELLS) self.ammo_cells = -1;
if (self.armortype == 1) self.armorvalue = -1;
// setup random quantity (default = 5)
if (self.ammo_shells < 0 || self.ammo_nails < 0 ||
self.ammo_rockets < 0 || self.ammo_cells < 0 ||
self.armorvalue < 0) {
if (!self.count) self.count = 5;
}
// No random ammo required, reset count
else self.count = 0;
// Check backpack has ammo to pickup
if (self.ammo_shells == 0 && self.ammo_nails == 0 &&
self.ammo_rockets == 0 && self.ammo_cells == 0 &&
self.armorvalue == 0) {
dprint("\b[BACKPACK]\b is empty, removing\n");
spawn_marker(self.origin, SPNMARK_YELLOW);
remove(self);
return;
}
item_start ();
};
//----------------------------------------------------------------------
void() item_backpack =
{
self.mdl = MODEL_BACKPACK;
precache_model (self.mdl);
if (self.noise == "") self.noise = "items/backpack_ammo.wav";
precache_sound(self.noise);
self.classtype = CT_AMMORANDOM;
self.classgroup = CG_AMMOITEM;
self.bbmins = '-16 -16 -12';
self.bbmaxs = '16 16 32';
self.part_active = PARTICLE_STYLE_BACKPACK;
if (self.respawn_time == 0) self.respawn_time = RESPAWN_BACKPACK;
self.respawn_ofs = '0 0 12';
self.touch2 = BackpackTouch;
// Match particle effect to skin colour
if (self.exactskin == 1) self.respawn_style = PARTICLE_BURST_GREEN;
else if (self.exactskin == 2) self.respawn_style = PARTICLE_BURST_BLUE;
else if (self.exactskin == 3) self.respawn_style = PARTICLE_BURST_RED;
else if (self.exactskin == 4) self.respawn_style = PARTICLE_BURST_YELLOW;
else if (self.exactskin == 5) self.respawn_style = PARTICLE_BURST_GREEN;
else self.respawn_style = PARTICLE_BURST_WHITE;
self.respawn_style = self.respawn_style | PARTICLE_BURST_CENTER;
// Double checking all the different ammo combinations can be
// time consuming, delay spawn the backpack instead
self.think = item_backpack_setup;
self.nextthink = time + 0.1 + random();
};
//----------------------------------------------------------------------
void() item_backpack_armour =
{
// Default armour amount is 15
if (self.noise == "") self.noise = "items/backpack_armour.wav";
precache_sound(self.noise);
// Check for different armour types
if (self.spawnflags & BACKPACK_GRNTYPE) {
self.armortype = ARMOR_GRN_TYPE; self.exactskin = 1;
if (self.armorvalue < 1) self.armorvalue = 15;
}
else if (self.spawnflags & BACKPACK_YELTYPE) {
self.armortype = ARMOR_YEL_TYPE; self.exactskin = 4;
if (self.armorvalue < 1) self.armorvalue = 30;
}
else if (self.spawnflags & BACKPACK_REDTYPE) {
self.armortype = ARMOR_RED_TYPE; self.exactskin = 3;
if (self.armorvalue < 1) self.armorvalue = 45;
}
// default = shards, no armour type
else {
self.armortype = 0; self.exactskin = 4;
if (self.armorvalue < 1) self.armorvalue = 15;
}
// make sure all ammo is removed from backpack
if (self.spawnflags & BACKPACK_SHELLS) self.spawnflags = self.spawnflags - BACKPACK_SHELLS;
if (self.spawnflags & BACKPACK_NAILS) self.spawnflags = self.spawnflags - BACKPACK_NAILS;
if (self.spawnflags & BACKPACK_ROCKETS) self.spawnflags = self.spawnflags - BACKPACK_ROCKETS;
if (self.spawnflags & BACKPACK_CELLS) self.spawnflags = self.spawnflags - BACKPACK_CELLS;
// Feed back into backpack function
item_backpack();
};