diff --git a/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp b/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp index 317de7f16d..4c70d03f04 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp @@ -21,7 +21,10 @@ void CLuaTimerManager::DoPulse(CLuaMain* pLuaMain) // Use a separate queue to avoid trouble for (CFastList::const_iterator iter = m_TimerList.begin(); iter != m_TimerList.end(); iter++) - m_ProcessQueue.push_back(*iter); + { + if (!(*iter)->IsPaused()) + m_ProcessQueue.push_back(*iter); + } while (!m_ProcessQueue.empty()) { @@ -108,6 +111,16 @@ void CLuaTimerManager::RemoveAllTimers() m_pProcessingTimer = NULL; } +void CLuaTimerManager::SetTimerPaused(CLuaTimer* timer, bool paused) +{ + assert(timer); + + timer->SetPaused(paused); + if (paused) + ListRemove(m_ProcessQueue, timer); +} + + void CLuaTimerManager::ResetTimer(CLuaTimer* pLuaTimer) { assert(pLuaTimer); diff --git a/Client/mods/deathmatch/logic/lua/CLuaTimerManager.h b/Client/mods/deathmatch/logic/lua/CLuaTimerManager.h index 055b644fcb..c4f97d2626 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaTimerManager.h +++ b/Client/mods/deathmatch/logic/lua/CLuaTimerManager.h @@ -36,6 +36,7 @@ class CLuaTimerManager void RemoveAllTimers(); unsigned long GetTimerCount() const { return m_TimerList.size(); } + void SetTimerPaused(CLuaTimer* timer, bool paused); void ResetTimer(CLuaTimer* pLuaTimer); CFastList::const_iterator IterBegin() { return m_TimerList.begin(); } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp index 401abcfd96..e0c8a96ba0 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp @@ -10,12 +10,14 @@ *****************************************************************************/ #include "StdInc.h" +#include void CLuaTimerDefs::LoadFunctions() { constexpr static const std::pair functions[]{ - {"setTimer", SetTimer}, {"killTimer", KillTimer}, {"resetTimer", ResetTimer}, - {"getTimers", GetTimers}, {"isTimer", IsTimer}, {"getTimerDetails", GetTimerDetails}, + {"setTimer", SetTimer}, {"killTimer", KillTimer}, {"resetTimer", ResetTimer}, + {"setTimerPaused", ArgumentParser},{"isTimerPaused", ArgumentParser}, + {"getTimers", GetTimers}, {"isTimer", IsTimer}, {"getTimerDetails", GetTimerDetails}, }; // Add functions @@ -31,10 +33,10 @@ void CLuaTimerDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "destroy", "killTimer"); lua_classfunction(luaVM, "reset", "resetTimer"); lua_classfunction(luaVM, "isValid", "isTimer"); - lua_classfunction(luaVM, "getDetails", "getTimerDetails"); lua_classvariable(luaVM, "valid", NULL, "isTimer"); + lua_classvariable(luaVM, "paused", "setTimerPaused", "isTimerPaused"); lua_registerclass(luaVM, "Timer"); } @@ -111,6 +113,22 @@ int CLuaTimerDefs::KillTimer(lua_State* luaVM) return 1; } +bool CLuaTimerDefs::IsTimerPaused(CLuaTimer* timer) noexcept +{ + return timer->IsPaused(); +} + +bool CLuaTimerDefs::SetTimerPaused(lua_State* luaVM, CLuaTimer* timer, bool paused) +{ + // bool setTimerPaused ( timer theTimer, bool paused ) + CLuaMain* luaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (!luaMain) + return false; + + luaMain->GetTimerManager()->SetTimerPaused(timer, paused); + return true; +} + int CLuaTimerDefs::ResetTimer(lua_State* luaVM) { // bool resetTimer ( timer theTimer ) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h index 671a329b28..db6cac48a9 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h @@ -24,4 +24,6 @@ class CLuaTimerDefs : public CLuaDefs LUA_DECLARE(GetTimers); LUA_DECLARE(IsTimer); LUA_DECLARE(GetTimerDetails); + static bool IsTimerPaused(CLuaTimer* timer) noexcept; + static bool SetTimerPaused(lua_State* luaVM, CLuaTimer* timer, bool paused); }; diff --git a/Server/mods/deathmatch/logic/lua/CLuaTimerManager.cpp b/Server/mods/deathmatch/logic/lua/CLuaTimerManager.cpp index fbd86eccaf..0af771b289 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaTimerManager.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaTimerManager.cpp @@ -26,7 +26,10 @@ void CLuaTimerManager::DoPulse(CLuaMain* pLuaMain) // Use a separate queue to avoid trouble // What kind of problems are we trying to avoid? Doing a copy each frame isn't quite efficient for (CFastList::const_iterator iter = m_TimerList.begin(); iter != m_TimerList.end(); ++iter) - m_ProcessQueue.push_back(*iter); + { + if (!(*iter)->IsPaused()) + m_ProcessQueue.push_back(*iter); + } while (!m_ProcessQueue.empty()) { @@ -113,6 +116,15 @@ void CLuaTimerManager::RemoveAllTimers() m_pProcessingTimer = NULL; } +void CLuaTimerManager::SetTimerPaused(CLuaTimer* timer, bool paused) +{ + assert(timer); + + timer->SetPaused(paused); + if (paused) + ListRemove(m_ProcessQueue, timer); +} + void CLuaTimerManager::ResetTimer(CLuaTimer* pLuaTimer) { assert(pLuaTimer); diff --git a/Server/mods/deathmatch/logic/lua/CLuaTimerManager.h b/Server/mods/deathmatch/logic/lua/CLuaTimerManager.h index d9d2fc41f2..d63e659147 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaTimerManager.h +++ b/Server/mods/deathmatch/logic/lua/CLuaTimerManager.h @@ -36,6 +36,7 @@ class CLuaTimerManager void RemoveAllTimers(); unsigned long GetTimerCount() const { return m_TimerList.size(); } + void SetTimerPaused(CLuaTimer* timer, bool paused); void ResetTimer(CLuaTimer* pLuaTimer); CFastList::const_iterator IterBegin() { return m_TimerList.begin(); } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp index 49c83bd576..c3e0478c8b 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp @@ -16,8 +16,9 @@ void CLuaTimerDefs::LoadFunctions() { constexpr static const std::pair functions[]{ - {"setTimer", SetTimer}, {"killTimer", KillTimer}, {"resetTimer", ResetTimer}, - {"getTimers", GetTimers}, {"isTimer", IsTimer}, {"getTimerDetails", GetTimerDetails}, + {"setTimer", SetTimer}, {"killTimer", KillTimer}, {"resetTimer", ResetTimer}, + {"setTimerPaused", ArgumentParser},{"isTimerPaused", ArgumentParser}, + {"getTimers", GetTimers}, {"isTimer", IsTimer},{"getTimerDetails", GetTimerDetails}, }; // Add functions @@ -33,10 +34,10 @@ void CLuaTimerDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "destroy", "killTimer"); lua_classfunction(luaVM, "reset", "resetTimer"); lua_classfunction(luaVM, "isValid", "isTimer"); - lua_classfunction(luaVM, "getDetails", "getTimerDetails"); lua_classvariable(luaVM, "valid", NULL, "isTimer"); + lua_classvariable(luaVM, "paused", "setTimerPaused", "isTimerPaused"); lua_registerclass(luaVM, "Timer"); } @@ -114,6 +115,22 @@ int CLuaTimerDefs::KillTimer(lua_State* luaVM) return 1; } +bool CLuaTimerDefs::IsTimerPaused(CLuaTimer* timer) noexcept +{ + return timer->IsPaused(); +} + +bool CLuaTimerDefs::SetTimerPaused(lua_State* luaVM, CLuaTimer* timer, bool paused) +{ + // bool setTimerPaused ( timer theTimer, bool paused ) + CLuaMain* luaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (!luaMain) + return false; + + luaMain->GetTimerManager()->SetTimerPaused(timer, paused); + return true; +} + int CLuaTimerDefs::ResetTimer(lua_State* luaVM) { // bool resetTimer ( timer theTimer ) diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h index fd37e2aaa4..abf1b725d6 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h @@ -24,4 +24,6 @@ class CLuaTimerDefs : public CLuaDefs LUA_DECLARE(GetTimers); LUA_DECLARE(IsTimer); LUA_DECLARE(GetTimerDetails); -}; \ No newline at end of file + static bool IsTimerPaused(CLuaTimer* timer) noexcept; + static bool SetTimerPaused(lua_State* luaVM, CLuaTimer* timer, bool paused); +}; diff --git a/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp b/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp index f632a1a237..bd0383222b 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp +++ b/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp @@ -23,6 +23,7 @@ CLuaTimer::CLuaTimer(const CLuaFunctionRef& iLuaFunction, const CLuaArguments& A m_uiRepeats = 1; m_iLuaFunction = iLuaFunction; m_Arguments = Arguments; + m_paused = false; } CLuaTimer::~CLuaTimer() @@ -64,8 +65,30 @@ void CLuaTimer::ExecuteTimer(CLuaMain* pLuaMain) } } +void CLuaTimer::SetPaused(bool paused) +{ + if (paused == IsPaused()) + return; + + CTickCount llTimeRemaining = GetTimeLeft(); + if (paused) + { + m_pausedRemainingTime = llTimeRemaining.ToLongLong() == 0LL ? m_llDelay : llTimeRemaining; + } + else + { + CTickCount llCurrentTime = CTickCount::Now(); + CTickCount llNewStartTime = llCurrentTime - (m_llDelay - llTimeRemaining); + SetStartTime(llNewStartTime); + } + m_paused = paused; +} + CTickCount CLuaTimer::GetTimeLeft() { + if (IsPaused()) + return m_pausedRemainingTime; + CTickCount llCurrentTime = CTickCount::Now(); CTickCount llTimeLeft = m_llStartTime + m_llDelay - llCurrentTime; return llTimeLeft.ToLongLong() < 0LL ? CTickCount(0LL) : llTimeLeft; diff --git a/Shared/mods/deathmatch/logic/lua/CLuaTimer.h b/Shared/mods/deathmatch/logic/lua/CLuaTimer.h index 62bb3c97a5..9534c2c47f 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaTimer.h +++ b/Shared/mods/deathmatch/logic/lua/CLuaTimer.h @@ -17,7 +17,7 @@ class CLuaTimer; #include "lua/LuaCommon.h" #include "lua/CLuaArguments.h" -#define LUA_TIMER_MIN_INTERVAL 0 +#define LUA_TIMER_MIN_INTERVAL 0 class CLuaTimer { @@ -35,6 +35,8 @@ class CLuaTimer unsigned int GetRepeats() const { return m_uiRepeats; }; void SetRepeats(unsigned int uiRepeats) { m_uiRepeats = uiRepeats; } + bool IsPaused() const noexcept { return m_paused; }; + void SetPaused(bool paused); void ExecuteTimer(class CLuaMain* pLuaMain); @@ -45,10 +47,12 @@ class CLuaTimer void SetLuaDebugInfo(const SLuaDebugInfo& luaDebugInfo) { m_LuaDebugInfo = luaDebugInfo; } private: + bool m_paused; CLuaFunctionRef m_iLuaFunction; CLuaArguments m_Arguments; CTickCount m_llStartTime; CTickCount m_llDelay; + CTickCount m_pausedRemainingTime; unsigned int m_uiRepeats; uint m_uiScriptID; SLuaDebugInfo m_LuaDebugInfo;