Rework env_global, entities communicating with it as well as support for

changetarget/changedelay in trigger_changelevel, which will make Hazard
Course its last level work in terms of elevator shenanigans.
This commit is contained in:
Marco Cawthorne 2022-01-10 23:48:14 -08:00
parent ec9432fe73
commit 33795822a9
Signed by: eukara
GPG key ID: C196CD8BA993248A
9 changed files with 256 additions and 41 deletions

View file

@ -66,6 +66,7 @@ server/prop_static.qc
server/point_camera.qc
server/targ_speaker.qc
server/target_cdaudio.qc
server/env_global.qc
server/trigger_auto.qc
server/trigger_autosave.qc
server/trigger_cdaudio.qc
@ -85,7 +86,6 @@ server/trigger_relay.qc
server/env_shooter.qc
server/gibshooter.qc
server/env_beverage.qc
//server/env_global.qc
server/env_laser.qc
server/item_food.qc
server/speaker.qc

View file

@ -41,8 +41,6 @@ enum
GLOBAL_DEAD
};
const string CENVGLOBAL_CVAR = "env_global_data";
class env_global:NSPointTrigger
{
string m_strGlobalState;
@ -50,19 +48,49 @@ class env_global:NSPointTrigger
int m_iInitialState;
void(void) env_global;
virtual void(int) Trigger;
/* overrides */
virtual void(float) Save;
virtual void(string,string) Restore;
virtual void(entity, int) Trigger;
virtual void(string, string) SpawnKey;
virtual int(string) GlobalPresent;
virtual void(string, int) AddNewGlobal;
virtual void(string, int) SetGlobal;
virtual int(string) GetGlobal;
virtual void(string, string) SpawnKey;
};
void
env_global::Trigger(int state)
env_global::Save(float handle)
{
int iOldValue = GetGlobal(m_strGlobalState);
SaveString(handle, "globalstate", m_strGlobalState);
SaveInt(handle, "triggermode", m_iTriggerMode);
SaveInt(handle, "initialstate", m_iInitialState);
super::Save(handle);
}
void
env_global::Restore(string strKey, string strValue)
{
switch (strKey) {
case "globalstate":
m_strGlobalState = ReadString(strValue);
break;
case "triggermode":
m_iTriggerMode = ReadInt(strValue);
break;
case "initialstate":
m_iInitialState = ReadInt(strValue);
break;
default:
super::Restore(strKey, strValue);
}
}
void
env_global::Trigger(entity act, int state)
{
int iOldValue = GetGlobalValue(m_strGlobalState);
int iNewValue = 0;
switch(m_iTriggerMode) {
@ -95,7 +123,7 @@ env_global::Trigger(int state)
int
env_global::GlobalPresent(string strName)
{
for (int i = 1; i < (tokenize(cvar_string(CENVGLOBAL_CVAR)) - 1); i += 2) {
for (int i = 0; i < (tokenize(cvar_string(CENVGLOBAL_CVAR))); i += 2) {
if (argv(i) == strName) {
return (1);
}
@ -106,29 +134,20 @@ env_global::GlobalPresent(string strName)
void
env_global::AddNewGlobal(string strName, int iValue)
{
cvar_set(CENVGLOBAL_CVAR, sprintf("%s %s %i", cvar_string(CENVGLOBAL_CVAR), strName, iValue));
print("AddNewGLobal\n");
localcmd(sprintf("set %s \"%s %s %i\"\n", CENVGLOBAL_CVAR, cvar_string(CENVGLOBAL_CVAR), strName, iValue));
}
void
env_global::SetGlobal(string strName, int iValue) {
string strNewData = "";
for (int i = 1; i < (tokenize(cvar_string(CENVGLOBAL_CVAR)) - 1); i += 2) {
print("SetGlobal\n");
for (int i = 0; i < (tokenize(cvar_string(CENVGLOBAL_CVAR))); i += 2) {
if (argv(i) != strName) {
strNewData = sprintf("%s %s %s", strNewData, argv(i), argv(i+1));
}
}
cvar_set(CENVGLOBAL_CVAR, sprintf("%s %s %i", strNewData, strName, iValue));
}
int
env_global::GetGlobal(string strName)
{
for (int i = 1; i < (tokenize(cvar_string(CENVGLOBAL_CVAR)) - 1); i += 2) {
if (argv(i) == strName) {
return stoi(argv(i+1));
}
}
return (0);
localcmd(sprintf("set %s \"%s %s %i\"\n", CENVGLOBAL_CVAR, strNewData, strName, iValue));
}
void

View file

@ -80,18 +80,16 @@ enum
class func_button:NSSurfacePropEntity
{
int m_iState;
float m_flSpeed;
float m_flLip;
int m_iState;
vector m_vecPos1;
vector m_vecPos2;
float m_flNextTrigger;
vector m_vecDest;
float m_flWait;
float m_flDelay;
vector m_vecPos1;
vector m_vecPos2;
vector m_vecDest;
vector m_vecMoveDir;
string m_strSndPressed;
string m_strSndUnpressed;
@ -118,6 +116,90 @@ class func_button:NSSurfacePropEntity
virtual void(string, string) SpawnKey;
};
void
func_button::Save(float handle)
{
SaveInt(handle, "state", m_iState);
SaveFloat(handle, "speed", m_flSpeed);
SaveFloat(handle, "lip", m_flLip);
SaveFloat(handle, "next_trigger", m_flNextTrigger);
SaveFloat(handle, "wait", m_flWait);
SaveFloat(handle, "delay", m_flDelay);
SaveVector(handle, "pos1", m_vecPos1);
SaveVector(handle, "pos2", m_vecPos2);
SaveVector(handle, "dest", m_vecDest);
SaveVector(handle, "movedir", m_vecMoveDir);
SaveString(handle, "snd_pressed", m_strSndPressed);
SaveString(handle, "snd_unpressed", m_strSndUnpressed);
SaveString(handle, "on_pressed", m_strOnPressed);
SaveString(handle, "on_damaged", m_strOnDamaged);
SaveString(handle, "on_uselocked", m_strOnUseLocked);
SaveString(handle, "on_in", m_strOnIn);
SaveString(handle, "on_out", m_strOnOut);
super::Save(handle);
}
void
func_button::Restore(string strKey, string strValue)
{
switch (strKey) {
case "state":
m_iState = ReadInt(strValue);
break;
case "speed":
m_flSpeed = ReadFloat(strValue);
break;
case "lip":
m_flLip = ReadFloat(strValue);
break;
case "next_trigger":
m_flNextTrigger = ReadFloat(strValue);
break;
case "wait":
m_flWait = ReadFloat(strValue);
break;
case "delay":
m_flDelay = ReadFloat(strValue);
break;
case "pos1":
m_vecPos1 = ReadVector(strValue);
break;
case "pos2":
m_vecPos2 = ReadVector(strValue);
break;
case "dest":
m_vecDest = ReadVector(strValue);
break;
case "movedir":
m_vecMoveDir = ReadVector(strValue);
break;
case "snd_pressed":
m_strSndPressed = ReadString(strValue);
break;
case "snd_unpressed":
m_strSndUnpressed = ReadString(strValue);
break;
case "on_pressed":
m_strOnPressed = ReadString(strValue);
break;
case "on_damaged":
m_strOnDamaged = ReadString(strValue);
break;
case "on_uselocked":
m_strOnUseLocked = ReadString(strValue);
break;
case "on_in":
m_strOnIn = ReadString(strValue);
break;
case "on_out":
m_strOnOut = ReadString(strValue);
break;
default:
super::Restore(strKey, strValue);
}
}
void
func_button::Arrived(void)
{
@ -207,7 +289,9 @@ func_button::MoveAway(void)
void
func_button::Trigger(entity act, int state)
{
if (GetMaster() == FALSE)
return;
UseOutput(act, m_strOnUseLocked);
if (m_flNextTrigger > time) {

View file

@ -22,6 +22,7 @@ state for it to trigger its target.
"targetname" : Name
"target" : Target when triggered.
"killtarget" : Target to kill when triggered.
"globalstate" : env_global variable to track.
"delay" : Delay until we trigger our target.
-------- TRIVIA --------
@ -30,19 +31,57 @@ This entity was introduced in Half-Life (1998).
class multisource:NSPointTrigger
{
string m_strGlobalState;
void(void) multisource;
virtual void(float) Save;
virtual void(string, string) Restore;
virtual void(void) Respawn;
virtual int(void) QueryTargets;
virtual int(void) GetValue;
virtual void(entity, int) Trigger;
virtual void(string, string) SpawnKey;
};
void
multisource::Save(float handle)
{
SaveString(handle, "globalstate", m_strGlobalState);
super::Save(handle);
}
void
multisource::Restore(string strKey, string strValue)
{
switch (strKey) {
case "globalstate":
m_strGlobalState = ReadString(strValue);
break;
default:
super::Restore(strKey, strValue);
}
}
int
multisource::GetValue(void)
{
return QueryTargets();
}
int
multisource::QueryTargets(void)
{
entity a;
int out = TRUE;
/* ENV_GLOBAL QUERY */
if (m_strGlobalState)
if (GetGlobalValue(m_strGlobalState) == 0)
return FALSE;
else
return TRUE;
/* normal triggers */
for (a = world; (a = find(a, ::target, targetname));) {
NSEntity tTemp = (NSEntity) a;
@ -88,8 +127,21 @@ multisource::Respawn(void)
m_iValue = FALSE;
}
void
multisource::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
case "globalstate":
m_strGlobalState = strValue;
break;
default:
super::SpawnKey(strKey, strValue);
}
}
void
multisource::multisource(void)
{
m_strGlobalState = __NULL__;
super::NSPointTrigger();
}

View file

@ -35,6 +35,7 @@ This entity was introduced in Half-Life (1998).
class trigger_auto:NSPointTrigger
{
string m_strGlobalState;
int m_iTriggerState;
float m_flDelay;
@ -54,6 +55,7 @@ trigger_auto::Save(float handle)
{
SaveInt(handle, "triggerstate", m_iTriggerState);
SaveFloat(handle, "delay", m_flDelay);
SaveString(handle, "globalstate", m_strGlobalState);
super::Save(handle);
}
@ -67,6 +69,11 @@ trigger_auto::Restore(string strKey, string strValue)
case "delay":
m_flDelay = ReadFloat(strValue);
break;
case "globalstate":
m_strGlobalState = ReadString(strValue);
think = Processing;
nextthink = time + 0.2f;
break;
default:
super::Restore(strKey, strValue);
}
@ -75,6 +82,10 @@ trigger_auto::Restore(string strKey, string strValue)
void
trigger_auto::Processing(void)
{
if (m_strGlobalState)
if (GetGlobalValue(m_strGlobalState) == 0)
return;
UseTargets(this, m_iTriggerState, m_flDelay);
if (spawnflags & 1) {
@ -94,6 +105,9 @@ void
trigger_auto::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
case "globalstate":
m_strGlobalState = strValue;
break;
case "triggerstate":
m_iTriggerState = stoi(strValue);
break;

View file

@ -46,9 +46,34 @@ enumflags
LC_USEONLY
};
string(string cmd) readcmd = #0;
void
ChangeTarget_Activate(void)
{
static void Finalize(void) {
string ctarg = cvar_string("_bsp_changetarget");
if (ctarg) {
for (entity a = world; (a = find(a, ::targetname, ctarg));) {
NSEntity t = (NSEntity)a;
if (t.Trigger)
t.Trigger(self, TRIG_TOGGLE);
}
}
readcmd("set _bsp_changetarget \"\"\n");
readcmd("set _bsp_changedelay \"\"\n");
}
entity foo = spawn();
float cdel = cvar("_bsp_changedelay");
foo.think = Finalize;
foo.nextthink = time + 0.1f + cdel;
}
class trigger_changelevel:NSBrushTrigger
{
float m_flChangeDelay;
string m_strChangeTarget;
string m_strMap;
string m_strLandmark;
string m_strOnLevelChange;
@ -72,6 +97,7 @@ class trigger_changelevel:NSBrushTrigger
void
trigger_changelevel::Save(float handle)
{
SaveString(handle, "changetarget", m_strChangeTarget);
SaveFloat(handle, "changedelay", m_flChangeDelay);
SaveString(handle, "map", m_strMap);
SaveString(handle, "landmark", m_strLandmark);
@ -84,6 +110,9 @@ void
trigger_changelevel::Restore(string strKey, string strValue)
{
switch (strKey) {
case "changetarget":
m_strChangeTarget = ReadString(strValue);
break;
case "changedelay":
m_flChangeDelay = ReadFloat(strValue);
break;
@ -124,6 +153,7 @@ trigger_changelevel::Change(void)
if (!m_strLandmark) {
dprint(sprintf("^2trigger_changelevel::^3Change^7: Change to `%s`\n",
m_strMap));
parm_string = m_strChangeTarget;
changelevel(m_strMap);
return;
}
@ -173,14 +203,10 @@ trigger_changelevel::Trigger(entity act, int unused)
/* eActivator == player who triggered the damn thing */
m_activator = act;
if (m_flChangeDelay) {
dprint(sprintf("^2trigger_changelevel::^3Trigger^7: Delayed change to `%s` in %d sec/s\n", m_strMap, m_flChangeDelay));
think = Change;
nextthink = time + m_flChangeDelay;
} else {
dprint(sprintf("^2trigger_changelevel::^3Trigger^7: Change to `%s` requested\n", m_strMap));
Change();
}
readcmd(sprintf("set _bsp_changetarget %S\n", m_strChangeTarget));
readcmd(sprintf("set _bsp_changedelay %f\n", m_flChangeDelay));
Change();
}
void
@ -218,6 +244,9 @@ void
trigger_changelevel::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
case "changetarget":
m_strChangeTarget = strValue;
break;
case "map":
m_strMap = strValue;
break;
@ -240,6 +269,8 @@ trigger_changelevel::SpawnKey(string strKey, string strValue)
void
trigger_changelevel::trigger_changelevel(void)
{
m_strChangeTarget = __NULL__;
super::NSBrushTrigger();
if (m_strOnLevelChange)

View file

@ -22,6 +22,8 @@
Use NSEntity as a basis for your classes.
*/
#define CENVGLOBAL_CVAR "env_global_data"
class NSTrigger:NSIO
{
void(void) NSTrigger;
@ -45,6 +47,7 @@ class NSTrigger:NSIO
/* master feature */
virtual int(void) GetValue;
virtual int(void) GetMaster;
virtual int(string) GetGlobalValue;
/* overrides */
virtual void(float) Save;

View file

@ -73,6 +73,17 @@ NSTrigger::GetValue(void)
return m_iValue;
}
int
NSTrigger::GetGlobalValue(string strName)
{
for (int i = 0; i < (tokenize(cvar_string(CENVGLOBAL_CVAR))); i += 2) {
if (argv(i) == strName) {
return stoi(argv(i+1));
}
}
return (0);
}
int
NSTrigger::GetMaster(void)
{
@ -85,12 +96,12 @@ NSTrigger::GetMaster(void)
return (1);
}
t = (NSTrigger)find(world, ::target, m_strMaster);
t = (NSTrigger)find(world, ::targetname, m_strMaster);
/* we couldn't find it, so let's not even bother going further */
if (!t) {
print(sprintf("^2%s::^3GetMaster^7: Invalid master, return success\n",
this.classname));
print(sprintf("^2%s::^3GetMaster^7: Invalid master (%s), return success\n",
this.classname, m_strMaster));
return (1);
}

View file

@ -503,6 +503,7 @@ initents(void)
Plugin_InitEnts();
Mapcycle_Init();
Vote_Init();
ChangeTarget_Activate();
g_ents_initialized = TRUE;
}