3381 lines
128 KiB
Plaintext
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();
|
|
};
|