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

173 lines
6.3 KiB
Plaintext

/*======================================================================
Entity State System
-------------------
When Quake first came out there were strict limitations on how many entities
could exist and be active at the same time. The quick fix solution to this
problem was to use the killtargets key so that entities could be removed.
This was a very powerful feature with very few restrictions on what it
could affect or destroy at the same time.
The idea of the entity state system is to create a way to safely switch
entities on, off or have then temporarily disabled. This will help prevent
situations where entity chains are broken or strange errors occur because
the touch function does not have an entity anymore.
The entity state is a new key on entities which is designed to work in a
passive mode until it is activated. All the entities listed below have a
default value so that any existing map will still work as before.
There are two methods for changing the entity state and the first method
is an extra key on triggers entities (trigger _once, _multi, _relay etc)
The ON state (default) will allow the entity to work as designed, be
toggled and physically exist as per its setup.
The OFF state will block all of the designed functionality and hide
the entity from interaction with the player.
The DISABLE state blocks any toggle ability or entity functionality
and turns off any visual aids like animated textures.
The second method is via a brand new set of entities which can affect
multiple targets at once and are much easier (visually) to see what is
going on because most editors draw target lines.
======================================================================*/
//----------------------------------------------------------------------
// These entity states are monitored and updated by the entity
void() entity_state_on = {
if (self.estate_on) self.estate_on();
else self.estate = ESTATE_ON;
};
void() entity_state_off = {
if (self.estate_off) self.estate_off();
else self.estate = ESTATE_OFF;
};
void() entity_state_disable = {
if (self.estate_disable) self.estate_disable();
self.estate = ESTATE_DISABLE;
};
void() entity_state_reset = {
if (self.estate_reset) self.estate_reset();
};
void() entity_state_aframe = {
// Only switch frames if the entity has a function defintion
// This will restrict to entities designed for this change
if (self.estate_aframe) {
if (other.state == 0) self.frame = 0;
else self.frame = 1;
}
};
//----------------------------------------------------------------------
void() entity_state_use =
{
// Does the firing entity have specific state requests?
if (other.estate_trigger) {
if (other.estate_trigger & ESTATE_ON) entity_state_on();
else if (other.estate_trigger & ESTATE_OFF) entity_state_off();
else if (other.estate_trigger & ESTATE_DISABLE) entity_state_disable();
else if (other.estate_trigger & ESTATE_RESET) entity_state_reset();
else if (other.estate_trigger & ESTATE_AFRAME) entity_state_aframe();
}
else {
// Check if disabled first
if (self.estate == ESTATE_DISABLE) return;
// Check for USE function
if (self.estate_use) self.estate_use();
// entity has a TOGGLE function
else if (self.estate == ESTATE_OFF) entity_state_on();
else entity_state_off();
}
};
//======================================================================
/*QUAKED trigger_entitystate_x (.7 .5 1) (-8 -8 -16) (8 8 16) x
Switch the target(s) entity state X
-------- KEYS --------
target : target entities to switch x
target2 : more target(s) to affect
-------- SPAWNFLAGS --------
-------- NOTES --------
Switch the target(s) entity state X
======================================================================*/
void(string targstr) trigger_entitystate_target =
{
local entity t, stemp, otemp;
// Start looking for targets to update
t = find(world, targetname, targstr);
stemp = self; otemp = other; // Store self/other
while(t) {
// Entity states cannot be applied to players or monsters
if ( !(t.flags & FL_CLIENT) && !(t.flags & FL_MONSTER)) {
// Only change the state to ON/OFF/DISABLE
if (t.use != SUB_Null) {
if (t.use) {
self = t; other = stemp; // Switch self/other
entity_state_use(); // Update entity state
self = stemp; other = otemp; // Restore self/other
}
}
}
// Are there anymore targets left in the list?
t = find(t, targetname, targstr);
}
};
//----------------------------------------------------------------------
void() trigger_entitystate_use =
{
// Check for multiple target commands
if (self.target != "") trigger_entitystate_target(self.target);
if (self.target2 != "") trigger_entitystate_target(self.target2);
};
//----------------------------------------------------------------------
void() trigger_entitystate_off =
{
self.classtype = CT_ESTATE;
if (self.target == "") dprint("\b[ENTSTATE]\b Missing target!\n");
if (self.targetname != "") self.use = trigger_entitystate_use;
self.estate_trigger = ESTATE_OFF;
};
//----------------------------------------------------------------------
void() trigger_entitystate_on =
{
self.classtype = CT_ESTATE;
if (self.target == "") dprint("\b[ENTSTATE]\b Missing target!\n");
if (self.targetname != "") self.use = trigger_entitystate_use;
self.estate_trigger = ESTATE_ON;
};
//----------------------------------------------------------------------
void() trigger_entitystate_disable =
{
self.classtype = CT_ESTATE;
if (self.target == "") dprint("\b[ENTSTATE]\b Missing target!\n");
if (self.targetname != "") self.use = trigger_entitystate_use;
self.estate_trigger = ESTATE_DISABLE;
};
//----------------------------------------------------------------------
void() trigger_entitystate_reset =
{
self.classtype = CT_ESTATE;
if (self.target == "") dprint("\b[ENTSTATE]\b Missing target!\n");
if (self.targetname != "") self.use = trigger_entitystate_use;
self.estate_trigger = ESTATE_RESET;
};
//----------------------------------------------------------------------
void() trigger_entitystate_aframe =
{
self.classtype = CT_ESTATE;
if (self.target == "") dprint("\b[ENTSTATE]\b Missing target!\n");
if (self.targetname != "") self.use = trigger_entitystate_use;
self.estate_trigger = ESTATE_AFRAME;
};