djcev.com

//

Git Repos / fte_dogmode / qc / base_item.qc

Last update to this file was on 2024-11-20 at 23:54.

Show base_item.qc

//==============================================================================
// base_item.qc -- top-level item pickups
//==============================================================================

//======================================================================
// constants
//======================================================================

#ifdef SSQC
const float ITEM_SPAWNSILENT = 32; // item spawnflags
const float ITEM_SPAWNED = 64;
const float ITEM_SUSPENDED = 128;
const float ITEM_RESPAWNDM = 16384;
const float ITEM_DONTDROP = 8388608;

const float ITEM_ALPHA_WAITSPAWN = 0.00001; // alpha values (respawn feedback)
const float ITEM_ALPHA_NEARSPAWN = 0.2;
const float ITEM_ALPHA_OPAQUE = 1.0;

const string ITEM_SOUND_SPAWN = "items/respawn.ogg";
#endif

//======================================================================
// fields
//======================================================================

// Supa, Quoth respawning items support
//
// Respawn item like in DM if 'ritem' TRUE, override respawn time
// with 'respawndelay' if set, inc 'cnt' with each respawn and if
// 'respawncount' is set we'll remove the item if cnt > respawncount
// remember that SUB_Regen is already set on every item that can
// respawn, all we need to do is give a nextthink time in order
// to trigger it

#ifdef SSQC
.float ritem; // legacy SP item respawn flag
.float respawndelay; // legacy SP respawn delay
.float respawncount; // legacy SP respawn limit

.vector particles_offset;
#endif

//======================================================================
// forward declarations
//======================================================================

#ifdef SSQC
void(entity actor) base_item_drop_stuff;
float(entity item, float delay_sp, float delay_dm) base_item_check_respawn;
void() base_item_think_respawn;
void() base_item_think_nearspawn;
void() base_item_think_rhull;
void() base_item_think_place;
void() base_item_use_delayspawn;
void(entity e) base_item_init;
strip void() base_item;
#endif

//------------------------------------------------------------------------------

//----------------------------------------------------------------------
// class base_item: base_mapentity
// {
#ifdef SSQC
//==============================================================
// Static Helper Functions
//==============================================================

//--------------------------------------------------------------
// DropStuff -- dumptruck_ds
// set drops_item on a monster to a number:
//
// 1 = Silver Key
// 2 = Gold Key
// 3 = Health Vial
// 4 = Armor Shard
// 5 = Health Vial & Armor Shard
// 6 = random combination of 3 Vials and/or Shards
//
// TODO CEV this should probably be outside of base_item
//--------------------------------------------------------------
void(entity actor) base_item_drop_stuff =
{
switch (actor.drop_item)
{
case 0:
// drop nothing
break;
case 1:
item_key1_drop (self);
break;
case 2:
item_key2_drop (self);
break;
case 3:
item_health_vial_drop (self);
break;
case 4:
item_armor_shard_drop (self);
break;
case 5:
item_health_vial_drop (self);
item_armor_shard_drop (self);
break;
case 6:
local float rand_drop = rint(random() * 3);
if (rand_drop == 1)
{
item_armor_shard_drop (self);
item_health_vial_drop (self);
item_health_vial_drop (self);
}
else if (rand_drop == 2)
{
item_armor_shard_drop (self);
item_armor_shard_drop (self);
item_health_vial_drop (self);
}
else if (rand_drop == 0)
{
item_armor_shard_drop (self);
item_armor_shard_drop (self);
item_armor_shard_drop (self);
}
else
{
item_health_vial_drop (self);
item_health_vial_drop (self);
item_health_vial_drop (self);
}
break;
default:
dprint (sprintf("base_item_drop_stuff: "
"unhandled drop_item %g\n",
actor.drop_item));
}
};

//==============================================================
// Subs
//==============================================================

//--------------------------------------------------------------
// CheckItemRespawn -- was in items.qc
//--------------------------------------------------------------
float(entity item, float delay_sp, float delay_dm)
base_item_check_respawn =
{
// DM rules first
if (deathmatch == 1)
{
if (delay_dm > 5.0)
{
item.alpha = ITEM_ALPHA_WAITSPAWN;
item.think = base_item_think_nearspawn;
item.nextthink = time + delay_dm - 5.0;
}
else
{
item.alpha = ITEM_ALPHA_NEARSPAWN;
item.nextthink = time + delay_dm;
}

item.nextthink = time + delay_dm;
setmodel (item, item.mdl);
return TRUE;
}

if (deathmatch)
{
dprint (sprintf("base_item_check_respawn: unhandled "
"deathmatch state %f\n", deathmatch));
return FALSE;
}

// Supa, SP respawning items support
// respawn item if true, otherwise abort
if (!item.ritem)
return FALSE;

// inc before check to account for zero indexing
item.cnt = item.cnt + 1;

// limited respawns
if (item.respawncount && item.respawncount < item.cnt)
return FALSE;

// okay, we're clear to set up a respawn
if (item.respawndelay)
{
// custom respawn delay
if (item.respawndelay > 5.0)
{
item.alpha = ITEM_ALPHA_WAITSPAWN;
item.think = base_item_think_nearspawn;
item.nextthink = time + item.respawndelay - 5.0;
}
else
{
item.alpha = ITEM_ALPHA_NEARSPAWN;
item.nextthink = time + item.respawndelay;
}
}
else
{
if (delay_sp > 5.0)
{
item.alpha = ITEM_ALPHA_WAITSPAWN;
item.think = base_item_think_nearspawn;
item.nextthink = time + delay_sp - 5.0;
}
else
{
item.alpha = ITEM_ALPHA_NEARSPAWN;
item.nextthink = time + delay_sp;
}
}

setmodel (item, item.mdl);
return TRUE;
};

//==============================================================
// Interfacing
//==============================================================

//--------------------------------------------------------------
// SUB_Regen -- was in items.qc
//--------------------------------------------------------------
void() base_item_think_respawn =
{
// restore original model
self.model = self.mdl;
self.alpha = ITEM_ALPHA_OPAQUE;

// allow it to be touched again
self.solid = SOLID_TRIGGER;

// new respawning effects -- CEV
sound (self, CHAN_VOICE, ITEM_SOUND_SPAWN, VOL_HIGH, ATTN_NORM);

setorigin (self, self.origin);
/*
dprint (sprintf("base_item_think_respawn: pos1 %v pos2 %v\n",
self.pos1, self.pos2));
*/
if (self.pos1 || self.pos2)
setsize (self, self.pos1, self.pos2);
};

//--------------------------------------------------------------
void() base_item_think_nearspawn =
{
// bump alpha when 5s remain -- CEV
self.alpha = ITEM_ALPHA_NEARSPAWN;
self.think = base_item_think_respawn;
self.nextthink = time + 5.0;
};

//--------------------------------------------------------------
// RefreshHull -- Supa, restore old hull and lock movement
//--------------------------------------------------------------
void() base_item_think_rhull =
{
dprint ("base_item_think_rhull: fix for bboxes\n");

// dumptruck_ds -- fix for bounding boxes
if (self.pos1 || self.pos2)
setsize (self, self.pos1, self.pos2);
else
setsize (self, '0 0 0', '32 32 56');

self.movetype = MOVETYPE_NONE;
self.velocity = '0 0 0';
};

//--------------------------------------------------------------
// PlaceItem -- plants the object on the floor
//--------------------------------------------------------------
void() base_item_think_place =
{
self.alpha = ITEM_ALPHA_OPAQUE;
self.solid = SOLID_TRIGGER;
self.velocity = '0 0 0';
self.think = base_item_think_respawn;

// make extra wide
self.flags = FL_ITEM;

// so it can be restored on respawn
self.mdl = self.model;

if (!self.pos1 && !self.pos2)
{
self.pos1 = '0 0 0';
self.pos2 = '32 32 56';
}
setsize (self, self.pos1, self.pos2);

if (self.spawnflags & ITEM_SUSPENDED)
{
// ijed Don't drop spawnflag
self.movetype = MOVETYPE_FLY;
}
else
{
// The following hack for item_health was inherited
// from the RMQ code, and was here when the
// func_mapjamx maps were created. It would have been
// nice to remove this code entirely, because progs_dump
// doesn't need it, and it breaks item_health's
// collision with entities that have MOVETYPE_PUSH.
// However, removing this code would cause some of the
// item_health entities in some of the func_mapjamx
// maps to "fall out of the level", because they're
// accidentally touching solid surfaces. So, to
// maintain backwards-compatibility, this code has
// been left in, but will only be run if one of the
// func_mapjamx maps is being played. -- iw
if (known_release == KNOWN_RELEASE_FUNC_MAPJAMX)
{
if (self.classtype == CT_ITEM_HEALTH)
{
// Supa, CTF
// hacking around hull issues..
// void hull for now
setsize (self, '0 0 0', '0 0 0');
self.think = base_item_think_rhull;
self.nextthink = time + 0.2;
}
}

self.movetype = MOVETYPE_TOSS;

if (!(self.spawnflags & ITEM_DONTDROP))
{
setorigin (self, self.origin + '0 0 6');

if (!droptofloor())
{
dprint (sprintf("base_item_think_place"
": bonus item %s fell out of "
"level at %v\n",
self.classname, self.origin));
// TODO CEV
// remove (self);
return;
}
}
}

if (self.spawnflags & ITEM_SPAWNED)
{
// SPAWNED, gb
self.pos1 = self.mins;
self.pos2 = self.maxs;

self.model = "";
self.solid = SOLID_NOT;

if (self.spawnflags & ITEM_DONTDROP)
self.movetype = MOVETYPE_NONE;

self.use = base_item_use_delayspawn;
}
};

//--------------------------------------------------------------
// DelaySpawnItem -- this is from rmq-items.qc
// Makes a SPAWNED item ready for pickup on a trigger event
// - modified a bit -- dumptruck_ds
//--------------------------------------------------------------
void() base_item_use_delayspawn =
{
self.solid = SOLID_TRIGGER;
setmodel (self, self.mdl);
setsize (self, self.pos1, self.pos2);

if (!(self.spawnflags & ITEM_SPAWNSILENT))
// SILENT, gb
// sound (self, CHAN_VOICE, "items/itembk2.wav",
// VOL_HIGH, ATTN_NORM);
spawn_tfog (self.origin + self.particles_offset);

if (self.spawnflags & ITEM_SUSPENDED)
self.movetype = MOVETYPE_FLY;
else
self.movetype = MOVETYPE_TOSS;

self.use = sub_null;
};

//==============================================================
// Constructor & Spawn Functions
//==============================================================

//--------------------------------------------------------------
void(entity e) base_item_init =
{
base_mapentity_init (e);
e.classgroup |= CG_ITEM;

//------------------------------------------------------
// StartItem -- Sets the clipping size and plants the
// object on the floor
//------------------------------------------------------
e.think = base_item_think_place;
// items start after other solids || was 0.2 -- dumptruck_ds
e.nextthink = time + 0.3;
};

//--------------------------------------------------------------
strip void() base_item =
{
base_item_init (self);
};
#endif
// };

Return to the top of this page or return to the overview of this repo.

Log base_item.qc

Return to the top of this page or return to the overview of this repo.