From 33795822a98ab93f3fde668ead3ae29294f8e7b7 Mon Sep 17 00:00:00 2001 From: Marco Hladik Date: Mon, 10 Jan 2022 23:48:14 -0800 Subject: [PATCH] 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. --- src/gs-entbase/server.src | 2 +- src/gs-entbase/server/env_global.qc | 63 ++++++++----- src/gs-entbase/server/func_button.qc | 98 ++++++++++++++++++-- src/gs-entbase/server/multisource.qc | 52 +++++++++++ src/gs-entbase/server/trigger_auto.qc | 14 +++ src/gs-entbase/server/trigger_changelevel.qc | 47 ++++++++-- src/gs-entbase/shared/NSTrigger.h | 3 + src/gs-entbase/shared/NSTrigger.qc | 17 +++- src/server/entry.qc | 1 + 9 files changed, 256 insertions(+), 41 deletions(-) diff --git a/src/gs-entbase/server.src b/src/gs-entbase/server.src index 56467307..23701a19 100644 --- a/src/gs-entbase/server.src +++ b/src/gs-entbase/server.src @@ -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 diff --git a/src/gs-entbase/server/env_global.qc b/src/gs-entbase/server/env_global.qc index eeb7cdc1..3b0d3e0a 100644 --- a/src/gs-entbase/server/env_global.qc +++ b/src/gs-entbase/server/env_global.qc @@ -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 diff --git a/src/gs-entbase/server/func_button.qc b/src/gs-entbase/server/func_button.qc index ece4b8e0..35d13a19 100644 --- a/src/gs-entbase/server/func_button.qc +++ b/src/gs-entbase/server/func_button.qc @@ -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) { diff --git a/src/gs-entbase/server/multisource.qc b/src/gs-entbase/server/multisource.qc index 473b5d68..d7e680b4 100644 --- a/src/gs-entbase/server/multisource.qc +++ b/src/gs-entbase/server/multisource.qc @@ -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(); } diff --git a/src/gs-entbase/server/trigger_auto.qc b/src/gs-entbase/server/trigger_auto.qc index 2aa0ae20..68b92c5c 100644 --- a/src/gs-entbase/server/trigger_auto.qc +++ b/src/gs-entbase/server/trigger_auto.qc @@ -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; diff --git a/src/gs-entbase/server/trigger_changelevel.qc b/src/gs-entbase/server/trigger_changelevel.qc index 1af9ced3..707d8ea1 100644 --- a/src/gs-entbase/server/trigger_changelevel.qc +++ b/src/gs-entbase/server/trigger_changelevel.qc @@ -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) diff --git a/src/gs-entbase/shared/NSTrigger.h b/src/gs-entbase/shared/NSTrigger.h index 79658383..b557fb17 100644 --- a/src/gs-entbase/shared/NSTrigger.h +++ b/src/gs-entbase/shared/NSTrigger.h @@ -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; diff --git a/src/gs-entbase/shared/NSTrigger.qc b/src/gs-entbase/shared/NSTrigger.qc index c1e8b4bb..e924e51b 100644 --- a/src/gs-entbase/shared/NSTrigger.qc +++ b/src/gs-entbase/shared/NSTrigger.qc @@ -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); } diff --git a/src/server/entry.qc b/src/server/entry.qc index 401ac08a..f64023e4 100644 --- a/src/server/entry.qc +++ b/src/server/entry.qc @@ -503,6 +503,7 @@ initents(void) Plugin_InitEnts(); Mapcycle_Init(); Vote_Init(); + ChangeTarget_Activate(); g_ents_initialized = TRUE; }