diff --git a/Client/mods/deathmatch/logic/CClientWater.cpp b/Client/mods/deathmatch/logic/CClientWater.cpp index 7cd75346fa..8be149dd44 100644 --- a/Client/mods/deathmatch/logic/CClientWater.cpp +++ b/Client/mods/deathmatch/logic/CClientWater.cpp @@ -68,6 +68,8 @@ bool CClientWater::Create() g_pCore->GetConsole()->Printf("CClientWater::Create %d", GetID()); #endif + m_iDefaultLevel = GetLevel(); + return true; } @@ -180,3 +182,18 @@ bool CClientWater::SetLevel(float fLevel, void* pChangeSource) } return true; } + +float CClientWater::GetLevel() const +{ + float fLevel = 0.0f; + for (int i = 0; i < GetNumVertices(); i++) + { + fLevel += m_Vertices[i].fZ; + } + return fLevel / static_cast(GetNumVertices()); +} + +void CClientWater::ResetLevel() +{ + SetLevel(m_iDefaultLevel); +} diff --git a/Client/mods/deathmatch/logic/CClientWater.h b/Client/mods/deathmatch/logic/CClientWater.h index 13277eef8f..8dcd9aaef9 100644 --- a/Client/mods/deathmatch/logic/CClientWater.h +++ b/Client/mods/deathmatch/logic/CClientWater.h @@ -31,10 +31,13 @@ class CClientWater final : public CClientEntity void SetPosition(const CVector& vecPosition); bool SetVertexPosition(int iVertexIndex, CVector& vecPosition, void* pChangeSource = nullptr); bool SetLevel(float fWaterLevel, void* pChangeSource = nullptr); + float GetLevel() const; + void ResetLevel(); void Unlink(); void SetDimension(unsigned short usDimension); void RelateDimension(unsigned short usWorldDimension); + private: CWaterPoly* m_pPoly; @@ -43,5 +46,7 @@ class CClientWater final : public CClientEntity bool m_bShallow; // Shallow water? std::vector m_Vertices; // List of vertices for this water + float m_iDefaultLevel{}; + friend class CClientWaterManager; }; diff --git a/Client/mods/deathmatch/logic/CClientWaterManager.cpp b/Client/mods/deathmatch/logic/CClientWaterManager.cpp index b25c110b9a..a7c30fe45b 100644 --- a/Client/mods/deathmatch/logic/CClientWaterManager.cpp +++ b/Client/mods/deathmatch/logic/CClientWaterManager.cpp @@ -104,6 +104,24 @@ bool CClientWaterManager::SetAllElementWaterLevel(float fLevel, void* pChangeSou return true; } +bool CClientWaterManager::ResetAllElementWaterLevel() +{ + for (CClientWater* pWater : m_List) + pWater->ResetLevel(); + return true; +} + +void CClientWaterManager::ResetElementWaterLevel(CClientWater* pWater) +{ + pWater->ResetLevel(); +} + +void CClientWaterManager::ResetElementWaterLevel(std::vector& vecWaterElements) +{ + for (CClientWater* pWater : vecWaterElements) + pWater->ResetLevel(); +} + void CClientWaterManager::ResetWorldWaterLevel() { g_pGame->GetWaterManager()->ResetWorldWaterLevel(); diff --git a/Client/mods/deathmatch/logic/CClientWaterManager.h b/Client/mods/deathmatch/logic/CClientWaterManager.h index e072b91732..8db1b9ea3b 100644 --- a/Client/mods/deathmatch/logic/CClientWaterManager.h +++ b/Client/mods/deathmatch/logic/CClientWaterManager.h @@ -31,6 +31,9 @@ class CClientWaterManager bool SetPositionWaterLevel(const CVector& vecPosition, float fLevel, void* pChangeSource); bool SetWorldWaterLevel(float fLevel, void* pChangeSource, bool bIncludeWorldNonSeaLevel, bool bIncludeWorldSeaLevel, bool bIncludeOutsideWorldLevel); bool SetAllElementWaterLevel(float fLevel, void* pChangeSource); + bool ResetAllElementWaterLevel(); + void ResetElementWaterLevel(CClientWater* pWater); + void ResetElementWaterLevel(std::vector& vecWaterElements); void ResetWorldWaterLevel(); float GetWaveLevel(); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp index f8a6890497..f1e6c8e4c9 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp @@ -10,6 +10,7 @@ *****************************************************************************/ #include "StdInc.h" +#include "lua/CLuaFunctionParser.h" void CLuaWaterDefs::LoadFunctions() { @@ -17,7 +18,7 @@ void CLuaWaterDefs::LoadFunctions() {"createWater", CreateWater}, {"testLineAgainstWater", TestLineAgainstWater}, {"resetWaterColor", ResetWaterColor}, - {"resetWaterLevel", ResetWaterLevel}, + {"resetWaterLevel", ArgumentParserWarn}, {"setWaterColor", SetWaterColor}, {"setWaterLevel", SetWaterLevel}, @@ -140,11 +141,42 @@ int CLuaWaterDefs::TestLineAgainstWater(lua_State* luaVM) return 1; } -int CLuaWaterDefs::ResetWaterLevel(lua_State* luaVM) +bool CLuaWaterDefs::ResetWaterLevel(std::variant, CClientWater*> resetElements) { - CStaticFunctionDefinitions::ResetWorldWaterLevel(); - lua_pushboolean(luaVM, true); - return 1; + CClientWaterManager* pWaterManager = g_pClientGame->GetManager()->GetWaterManager(); + + switch (resetElements.index()) + { + case 0: + CStaticFunctionDefinitions::ResetWorldWaterLevel(); + break; + + case 1: + { + if (std::get(resetElements) == true) + pWaterManager->ResetAllElementWaterLevel(); + else + CStaticFunctionDefinitions::ResetWorldWaterLevel(); + + break; + } + + case 2: + { + auto& vecWaterElements = std::get>(resetElements); + pWaterManager->ResetElementWaterLevel(vecWaterElements); + break; + } + + case 3: + { + auto pWaterElement = std::get(resetElements); + pWaterManager->ResetElementWaterLevel(pWaterElement); + break; + } + } + + return true; } int CLuaWaterDefs::ResetWaterColor(lua_State* luaVM) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h index a3615b109f..0d97e99a0f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h @@ -19,7 +19,6 @@ class CLuaWaterDefs : public CLuaDefs static void AddClass(lua_State* luaVM); LUA_DECLARE(CreateWater); - LUA_DECLARE(ResetWaterLevel); LUA_DECLARE(ResetWaterColor); LUA_DECLARE(TestLineAgainstWater); @@ -32,4 +31,6 @@ class CLuaWaterDefs : public CLuaDefs LUA_DECLARE(GetWaterLevel); LUA_DECLARE(IsWaterDrawnLast); LUA_DECLARE(GetWaterVertexPosition); + + static bool ResetWaterLevel(std::variant, CClientWater*> resetElements); }; diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index ad64816a6d..bb78e42d00 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -9448,6 +9448,8 @@ CWater* CStaticFunctionDefinitions::CreateWater(CResource* pResource, CVector* p return nullptr; } + pWater->SetDefaultLevel(pWater->GetLevel()); + if (pResource->IsClientSynced()) { CEntityAddPacket Packet; diff --git a/Server/mods/deathmatch/logic/CWater.cpp b/Server/mods/deathmatch/logic/CWater.cpp index 5e4696ac71..52973d4d76 100644 --- a/Server/mods/deathmatch/logic/CWater.cpp +++ b/Server/mods/deathmatch/logic/CWater.cpp @@ -14,6 +14,10 @@ #include "CWaterManager.h" #include "CLogger.h" +#include +#include "packets/CElementRPCPacket.h" +#include "CGame.h" + CWater::CWater(CWaterManager* pWaterManager, CElement* pParent, EWaterType waterType, bool bShallow) : CElement(pParent) { m_pWaterManager = pWaterManager; @@ -201,3 +205,12 @@ bool CWater::IsVertexWithinWorld(int index) { return m_Vertices[index].fX >= -3000.0f && m_Vertices[index].fX <= 3000.0f && m_Vertices[index].fY >= -3000.0f && m_Vertices[index].fY <= 3000.0f; } + +void CWater::ResetLevel() +{ + SetLevel(m_iDefaultLevel); + + CBitStream BitStream; + BitStream.pBitStream->Write(m_iDefaultLevel); + g_pGame->GetPlayerManager()->BroadcastOnlyJoined(CElementRPCPacket(this, SET_ELEMENT_WATER_LEVEL, *BitStream.pBitStream)); +} diff --git a/Server/mods/deathmatch/logic/CWater.h b/Server/mods/deathmatch/logic/CWater.h index f3422dca46..ac0a4ff0a7 100644 --- a/Server/mods/deathmatch/logic/CWater.h +++ b/Server/mods/deathmatch/logic/CWater.h @@ -33,6 +33,8 @@ class CWater final : public CElement void SetPosition(const CVector& vecPosition); float GetLevel() const; void SetLevel(float fLevel); + void SetDefaultLevel(float fLevel) { m_iDefaultLevel = fLevel; } + void ResetLevel(); void Unlink(); @@ -57,4 +59,6 @@ class CWater final : public CElement SFixedArray m_Vertices; EWaterType m_WaterType; bool m_bShallow; + + float m_iDefaultLevel{}; }; diff --git a/Server/mods/deathmatch/logic/CWaterManager.cpp b/Server/mods/deathmatch/logic/CWaterManager.cpp index 881fc48e8c..eb8f839952 100644 --- a/Server/mods/deathmatch/logic/CWaterManager.cpp +++ b/Server/mods/deathmatch/logic/CWaterManager.cpp @@ -69,6 +69,23 @@ void CWaterManager::SetAllElementWaterLevel(float fLevel) } } +void CWaterManager::ResetAllElementWaterLevel() +{ + for (CWater* pWater : m_List) + pWater->ResetLevel(); +} + +void CWaterManager::ResetElementWaterLevel(CWater* pWater) +{ + pWater->ResetLevel(); +} + +void CWaterManager::ResetElementWaterLevel(std::vector& vecWaterElements) +{ + for (CWater* pWater : vecWaterElements) + pWater->ResetLevel(); +} + void CWaterManager::SetWorldWaterLevel(float fLevel, bool bIncludeWorldNonSeaLevel, bool bIncludeWorldSeaLevel, bool bIncludeOutsideWorldLevel) { if (bIncludeWorldSeaLevel) diff --git a/Server/mods/deathmatch/logic/CWaterManager.h b/Server/mods/deathmatch/logic/CWaterManager.h index 4f8add14bb..8325ae95f1 100644 --- a/Server/mods/deathmatch/logic/CWaterManager.h +++ b/Server/mods/deathmatch/logic/CWaterManager.h @@ -37,6 +37,9 @@ class CWaterManager void ResetWorldWaterLevel(); void SetElementWaterLevel(CWater* pWater, float fLevel); void SetAllElementWaterLevel(float fLevel); + void ResetAllElementWaterLevel(); + void ResetElementWaterLevel(CWater* pWater); + void ResetElementWaterLevel(std::vector& vecWaterElements); std::list::const_iterator IterBegin() { return m_List.begin(); } std::list::const_iterator IterEnd() { return m_List.end(); } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp index dac1aff30f..17c45e7296 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.cpp @@ -12,15 +12,17 @@ #include "StdInc.h" #include "CLuaWaterDefs.h" #include "CWater.h" +#include "CWaterManager.h" #include "CStaticFunctionDefinitions.h" #include "CScriptArgReader.h" +#include "lua/CLuaFunctionParser.h" void CLuaWaterDefs::LoadFunctions() { constexpr static const std::pair functions[]{ {"createWater", CreateWater}, {"setWaterLevel", SetWaterLevel}, - {"resetWaterLevel", ResetWaterLevel}, + {"resetWaterLevel", ArgumentParserWarn}, {"getWaterVertexPosition", GetWaterVertexPosition}, {"setWaterVertexPosition", SetWaterVertexPosition}, {"getWaterColor", GetWaterColor}, @@ -167,11 +169,42 @@ int CLuaWaterDefs::SetWaterLevel(lua_State* luaVM) return 1; } -int CLuaWaterDefs::ResetWaterLevel(lua_State* luaVM) +bool CLuaWaterDefs::ResetWaterLevel(std::variant, CWater*> resetElements) { - CStaticFunctionDefinitions::ResetWorldWaterLevel(); - lua_pushboolean(luaVM, true); - return 1; + CWaterManager* pWaterManager = g_pGame->GetWaterManager(); + + switch (resetElements.index()) + { + case 0: + CStaticFunctionDefinitions::ResetWorldWaterLevel(); + break; + + case 1: + { + if (std::get(resetElements) == true) + pWaterManager->ResetAllElementWaterLevel(); + else + CStaticFunctionDefinitions::ResetWorldWaterLevel(); + + break; + } + + case 2: + { + auto& vecWaterElements = std::get>(resetElements); + pWaterManager->ResetElementWaterLevel(vecWaterElements); + break; + } + + case 3: + { + auto pWaterElement = std::get(resetElements); + pWaterManager->ResetElementWaterLevel(pWaterElement); + break; + } + } + + return true; } int CLuaWaterDefs::GetWaterVertexPosition(lua_State* luaVM) diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h index 31a55fcb9b..c892ca7812 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaWaterDefs.h @@ -20,10 +20,11 @@ class CLuaWaterDefs : public CLuaDefs LUA_DECLARE(CreateWater); LUA_DECLARE(SetWaterLevel); - LUA_DECLARE(ResetWaterLevel); LUA_DECLARE(GetWaterVertexPosition); LUA_DECLARE(SetWaterVertexPosition); LUA_DECLARE(GetWaterColor); LUA_DECLARE(SetWaterColor); LUA_DECLARE(ResetWaterColor); -}; \ No newline at end of file + + static bool ResetWaterLevel(std::variant, CWater*> resetElements); +};