diff --git a/src/gs-entbase/server/basetrigger.cpp b/src/gs-entbase/server/basetrigger.cpp index 9051273f..1ddc8291 100644 --- a/src/gs-entbase/server/basetrigger.cpp +++ b/src/gs-entbase/server/basetrigger.cpp @@ -26,11 +26,14 @@ class CBaseTrigger : CBaseEntity string m_strTargetName; string m_strKillTarget; string m_strMessage; + string m_strMaster; int m_iUseType; + void() CBaseTrigger; virtual void() Trigger; virtual void() UseTargets; virtual int() GetValue; + virtual int() GetMaster; virtual void( float del ) UseTargets_Delay; virtual void() InitBrushTrigger; virtual void() InitPointTrigger; @@ -60,6 +63,25 @@ int CBaseTrigger :: GetValue ( void ) return TRUE; } +int CBaseTrigger :: GetMaster ( void ) +{ + CBaseTrigger t; + + /* default to success */ + if (!m_strMaster) { + return TRUE; + } + + t = (CBaseTrigger)find(world, CBaseTrigger::m_strTarget, m_strMaster); + + /* we couldn't find it, so let's not even bother going further */ + if (!t) { + return FALSE; + } + + return t.GetValue(); +} + void CBaseTrigger :: UseTargets_Delay ( float fDelay ) { static void Entities_UseTargets_Delay_Think( void ) { @@ -122,6 +144,9 @@ void CBaseTrigger :: CBaseTrigger ( void ) case "message": m_strMessage = argv( i + 1); break; + case "master": + m_strMaster = argv(i+1); + break; default: break; } diff --git a/src/gs-entbase/server/func_door_rotating.cpp b/src/gs-entbase/server/func_door_rotating.cpp index 63d234e3..1469ec21 100644 --- a/src/gs-entbase/server/func_door_rotating.cpp +++ b/src/gs-entbase/server/func_door_rotating.cpp @@ -183,6 +183,10 @@ void func_door_rotating::Away(void) void func_door_rotating::Trigger(void) { + if (GetMaster() == FALSE) { + return; + } + if (m_flNextAction > time) { return; } diff --git a/src/gs-entbase/server/func_guntarget.cpp b/src/gs-entbase/server/func_guntarget.cpp index 4f48bf59..d596d1b1 100644 --- a/src/gs-entbase/server/func_guntarget.cpp +++ b/src/gs-entbase/server/func_guntarget.cpp @@ -29,6 +29,7 @@ Gun targets brushes that trigger a target once they 'die'. class func_guntarget:CBaseTrigger { float m_flSpeed; + string m_strFire; void() func_guntarget; @@ -38,17 +39,27 @@ class func_guntarget:CBaseTrigger virtual void() Stop; virtual void() Trigger; virtual void(int) vDeath; + virtual int() GetValue; }; +int func_guntarget::GetValue(void) +{ + if (health <= 0) { + return TRUE; + } else { + return FALSE; + } +} + void func_guntarget::Move(void) { float flTravelTime; vector vel_to_pos; - entity f; + path_corner node; - f = find(world, CBaseTrigger::m_strTargetName, m_strTarget); + node = (path_corner)find(world, CBaseTrigger::m_strTargetName, m_strTarget); - if (!f) { + if (!node) { print("^1func_guntarget^7: Path node not found!\n"); return; } @@ -58,7 +69,7 @@ void func_guntarget::Move(void) vecWorldPos[1] = absmin[1] + (0.5 * (absmax[1] - absmin[1])); vecWorldPos[2] = absmin[2] + (0.5 * (absmax[2] - absmin[2])); - vel_to_pos = (f.origin - vecWorldPos); + vel_to_pos = (node.origin - vecWorldPos); flTravelTime = (vlen(vel_to_pos) / m_flSpeed); if (!flTravelTime) { @@ -73,18 +84,18 @@ void func_guntarget::Move(void) void func_guntarget::NextPath(void) { - CBaseTrigger current_target; + path_corner node; print(sprintf("^2func_guntarget^7: Talking to current target %s... ", m_strTarget)); - current_target = (CBaseTrigger)find(world, CBaseTrigger::m_strTargetName, m_strTarget); + node = (path_corner)find(world, path_corner::m_strTargetName, m_strTarget); - if (!current_target) { + if (!node) { print("^1FAILED.\n"); } else { print("^2SUCCESS.\n"); } - m_strTarget = current_target.m_strTarget; + m_strTarget = node.m_strTarget; velocity = [0,0,0]; if (m_strTarget) { @@ -94,7 +105,17 @@ void func_guntarget::NextPath(void) void func_guntarget::vDeath(int iHitBody) { + entity a; Stop(); + + if (!m_strFire) { + return; + } + + for (a = world; (a = find(a, CBaseTrigger::m_strTargetName, m_strFire));) { + CBaseTrigger trigger = (CBaseTrigger)a; + trigger.Trigger(); + } } void func_guntarget::Stop(void) @@ -122,13 +143,12 @@ void func_guntarget::Respawn(void) { solid = SOLID_BSP; movetype = MOVETYPE_PUSH; - setmodel(this, m_oldModel); setorigin(this, m_oldOrigin); if (spawnflags & SF_GUNTARGET_ON) { think = Trigger; - nextthink = time + 0.1f; + nextthink = ltime + 0.25f; } } @@ -142,6 +162,9 @@ void func_guntarget::func_guntarget(void) case "speed": m_flSpeed = stof(argv(i+1)); break; + case "message": + m_strFire = argv(i+1); + break; default: break; } diff --git a/src/gs-entbase/server/multi_manager.cpp b/src/gs-entbase/server/multi_manager.cpp index f53ea2fe..c55e84f9 100644 --- a/src/gs-entbase/server/multi_manager.cpp +++ b/src/gs-entbase/server/multi_manager.cpp @@ -27,21 +27,39 @@ again before it has finished triggering it's previous list of entities. #define MM_MULTITHREADED 1 +class multi_manager_sub:CBaseTrigger +{ + int m_iValue; + virtual int() GetValue; +}; + +int multi_manager_sub::GetValue(void) +{ + return m_iValue; +} + class multi_manager : CBaseTrigger { - CBaseTrigger m_eTriggers[16]; + multi_manager_sub m_eTriggers[16]; string m_strBuffer; int m_iBusy; + int m_iValue; + virtual void() Trigger; + virtual int() GetValue; }; +int multi_manager :: GetValue (void) +{ + return m_iValue; +} + void multi_manager :: Trigger (void) { static void mm_enttrigger (void) { - CBaseTrigger wow = (CBaseTrigger) self; - wow.m_strTarget = wow.netname; + multi_manager_sub wow = (multi_manager_sub)self; - entity eFind = find(world, CBaseTrigger::m_strTargetName, self.netname); + entity eFind = find(world, CBaseTrigger::m_strTargetName, wow.m_strTarget); #ifdef GS_DEVELOPER print(sprintf("multi_manager: %s (%s)\n", wow.m_strTarget, eFind.classname)); @@ -49,7 +67,9 @@ void multi_manager :: Trigger (void) CBaseTrigger::UseTargets(); } - + + m_iValue = TRUE; + /* If not multi-threaded, we have to watch out 'til all triggers are done. */ if (!(spawnflags & MM_MULTITHREADED)) { for (int i = 0; i < 16; i++) { @@ -59,6 +79,7 @@ void multi_manager :: Trigger (void) } } + /* time to trigger our sub triggers */ int iFields = tokenizebyseparator(m_strBuffer, " "); int b = 0; for (int i = 0; i < iFields; i+=2) { @@ -69,15 +90,24 @@ void multi_manager :: Trigger (void) // HACK: Avoid infinite loops if (m_strTargetName != argv(i)) { - entity eTemp = m_eTriggers[b]; - eTemp.netname = argv(i); - eTemp.think = mm_enttrigger; - eTemp.nextthink = time + stof(argv(i + 1)); + m_eTriggers[b].think = mm_enttrigger; + m_eTriggers[b].nextthink = time + stof(argv(i + 1)); + m_eTriggers[b].m_iValue = TRUE; b++; } } } +void multi_manager::Respawn(void) +{ + m_iValue = FALSE; + + /* Mark them inactive */ + for (int b = 0; b < 16; b++) { + m_eTriggers[b].m_iValue = FALSE; + } +} + void multi_manager :: multi_manager (void) { m_strBuffer = ""; @@ -103,9 +133,24 @@ void multi_manager :: multi_manager (void) } } } - + for (int b = 0; b < 16; b++) { - m_eTriggers[b] = spawn(CBaseTrigger); + m_eTriggers[b] = spawn(multi_manager_sub); + } + + /* set up our triggers */ + iFields = tokenizebyseparator(m_strBuffer, " "); + int b = 0; + for (int i = 0; i < iFields; i+=2) { + if (b >= 16) { + break; + } + + // HACK: Avoid infinite loops + if (m_strTargetName != argv(i)) { + m_eTriggers[b].m_strTarget = argv(i); + b++; + } } CBaseTrigger::CBaseTrigger(); diff --git a/src/gs-entbase/server/multisource.cpp b/src/gs-entbase/server/multisource.cpp index 63289b28..09ea8516 100644 --- a/src/gs-entbase/server/multisource.cpp +++ b/src/gs-entbase/server/multisource.cpp @@ -29,32 +29,49 @@ class multisource : CBaseTrigger virtual void() Trigger; }; -int multisource :: GetValue ( void ) +int +multisource::GetValue(void) { - int iWillTrigger = TRUE; - - for ( entity eTemp = world; ( eTemp = find( eTemp, CBaseTrigger::m_strTarget, m_strTargetName ) ); ) { - CBaseTrigger tTemp = (CBaseTrigger) eTemp; - if ( tTemp.GetValue() == FALSE ) { - iWillTrigger = FALSE; - break; + entity a; + int out = TRUE; + + /* normal triggers */ + for (a = world; (a = find(a, CBaseTrigger::m_strTarget, m_strTargetName));) { + CBaseTrigger tTemp = (CBaseTrigger) a; +#ifdef GS_DEVELOPER + print("[^1MULTISOURCE^7] "); + print(tTemp.classname); + if (tTemp.GetValue() == FALSE) { + print(" is ^1OFF^7, name: "); + out = FALSE; + } else { + print(" is ^2ON^7, name: "); } + print(tTemp.m_strTargetName); + print("\n"); +#else + /* exit out immediately as there's no point unless in-dev */ + if (tTemp.GetValue() == FALSE) { + return FALSE; + } +#endif } - - return iWillTrigger; + + return out; } -void multisource :: Trigger ( void ) +void +multisource::Trigger(void) { - if ( GetValue() == FALSE ) { + if (GetValue() == FALSE) { return; } - - //dprint( sprintf( "multisource: Trigger of %s\n", m_strTarget ) ); + CBaseTrigger::UseTargets(); } -void multisource :: multisource ( void ) +void +multisource::multisource(void) { CBaseTrigger::CBaseTrigger(); } diff --git a/src/gs-entbase/server/path_corner.cpp b/src/gs-entbase/server/path_corner.cpp index 27cd1ed0..eba0783f 100644 --- a/src/gs-entbase/server/path_corner.cpp +++ b/src/gs-entbase/server/path_corner.cpp @@ -52,7 +52,8 @@ class path_corner:CBaseTrigger virtual void() Respawn; }; -void path_corner::Trigger(void) +void +path_corner::Trigger(void) { entity a; @@ -67,12 +68,14 @@ void path_corner::Trigger(void) } } -void path_corner::Respawn(void) +void +path_corner::Respawn(void) { m_iFired = FALSE; } -void path_corner::path_corner(void) +void +path_corner::path_corner(void) { CBaseTrigger::CBaseTrigger();