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
Date | Commit Message | Author | + | - |
---|---|---|---|---|
2024-11-20 | pmove refactor into prepoc macros, view bobbing | cev | +6 | -2 |
2024-06-15 | Major update, committing as-is, will have bugs | cev | +15 | -6 |
2024-03-24 | 2nd pass refactor, rework QC class structure | cev | +182 | -255 |
2024-01-31 | Class based monster refactor & start projectiles | cev | +20 | -5 |
2024-01-13 | Refactored items into classes, fix teleporttrain | cev | +414 | -14 |
2024-01-09 | Continue OO / Class-based refactor | cev | +64 |
Return to the top of this page or return to the overview of this repo.