diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 49343f0c9e..65b9015bac 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -409,7 +409,7 @@ CClientGame::~CClientGame() m_bBeingDeleted = true; // Remove active projectile references to local player if (auto pLocalPlayer = g_pClientGame->GetLocalPlayer()) - g_pGame->GetProjectileInfo()->RemoveEntityReferences(pLocalPlayer->GetGameEntity()); + g_pGame->GetProjectileInfo()->RemoveEntityReferences(pLocalPlayer->GetGameEntity()); // Stop all explosions. Unfortunately this doesn't fix the crash // if a vehicle is destroyed while it explodes. @@ -1024,7 +1024,7 @@ void CClientGame::DoPulsePostFrame() } auto taskManager = pLocalPlayer->GetTaskManager(); - auto task = taskManager->GetActiveTask(); + auto task = taskManager->GetActiveTask(); auto pVehicle = pLocalPlayer->GetOccupiedVehicle(); bool useZoneName = true; @@ -1078,7 +1078,7 @@ void CClientGame::DoPulsePostFrame() discordState = taskState.strState; useZoneName = taskState.bUseZone; - } + } if (useZoneName) { @@ -6952,6 +6952,10 @@ void CClientGame::ResetWorldProperties(const ResetWorldPropsInfo& resetPropsInfo GetManager()->GetWaterManager()->ResetWorldWaterLevel(); GetManager()->GetWaterManager()->SetWaveLevel(0.0f); + // Underwater effects + g_pMultiplayer->ResetUnderwaterDarkness(); + g_pMultiplayer->ResetUnderwaterEffect(); + // Reset volumetric shadows g_pGame->GetSettings()->ResetVolumetricShadows(); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp index 9c8cb6cd83..a0fb57a6a7 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp @@ -30,6 +30,8 @@ void CLuaCameraDefs::LoadFunctions() {"getCameraGoggleEffect", ArgumentParserWarn}, {"getCameraFieldOfView", GetCameraFieldOfView}, {"getCameraDrunkLevel", ArgumentParserWarn}, + {"getCameraUnderwaterEffect", ArgumentParser}, + {"getCameraUnderwaterDarkness", ArgumentParser}, // Cam set funcs {"setCameraMatrix", SetCameraMatrix}, @@ -43,8 +45,15 @@ void CLuaCameraDefs::LoadFunctions() {"setCameraGoggleEffect", SetCameraGoggleEffect}, {"setCameraDrunkLevel", ArgumentParserWarn}, + {"setCameraUnderwaterEffectEnabled", ArgumentParser}, + {"setCameraUnderwaterEffectSpeed", ArgumentParser}, + {"setCameraUnderwaterDarkness", ArgumentParser}, + {"resetCameraUnderwaterEffect", ArgumentParser}, + {"resetCameraUnderwaterDarkness", ArgumentParser}, + {"shakeCamera", ArgumentParser}, {"resetShakeCamera", ArgumentParser}, + }; // Add functions @@ -72,6 +81,8 @@ void CLuaCameraDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getFarClipDistance", "getFarClipDistance"); lua_classfunction(luaVM, "getNearClipDistance", "getNearClipDistance"); lua_classfunction(luaVM, "getType", ArgumentParser); + lua_classfunction(luaVM, "getUnderwaterEffect", ArgumentParser); + lua_classfunction(luaVM, "getUnderwaterDarkness", ArgumentParser); lua_classfunction(luaVM, "setPosition", OOP_SetCameraPosition); lua_classfunction(luaVM, "setRotation", OOP_SetCameraRotation); @@ -84,6 +95,11 @@ void CLuaCameraDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setClip", "setCameraClip"); lua_classfunction(luaVM, "setFarClipDistance", "setFarClipDistance"); lua_classfunction(luaVM, "setNearClipDistance", "setNearClipDistance"); + lua_classfunction(luaVM, "setUnderwaterEffectEnabled", ArgumentParser); + lua_classfunction(luaVM, "setUnderwaterEffectSpeed", ArgumentParser); + lua_classfunction(luaVM, "setUnderwaterDarkness", ArgumentParser); + lua_classfunction(luaVM, "resetUnderwaterEffect", ArgumentParser); + lua_classfunction(luaVM, "resetUnderwaterDarkness", ArgumentParser); lua_classvariable(luaVM, "interior", "setCameraInterior", "getCameraInterior"); lua_classvariable(luaVM, "target", "setCameraTarget", "getCameraTarget"); @@ -166,6 +182,22 @@ unsigned char CLuaCameraDefs::GetCameraDrunkLevel() return g_pGame->GetPlayerInfo()->GetCamDrunkLevel(); } +CLuaMultiReturn CLuaCameraDefs::GetCameraUnderwaterEffect() noexcept +{ + bool isEnabled; + float speed, frequency; + g_pMultiplayer->GetUnderwaterEffect(isEnabled, speed, frequency); + return {isEnabled, speed, frequency}; +} + +CLuaMultiReturn CLuaCameraDefs::GetCameraUnderwaterDarkness() noexcept +{ + bool isEnabled; + float fullDarknessDepth; + g_pMultiplayer->GetUnderwaterDarkness(isEnabled, fullDarknessDepth); + return {isEnabled, fullDarknessDepth}; +} + int CLuaCameraDefs::SetCameraMatrix(lua_State* luaVM) { CVector vecPosition; @@ -475,6 +507,41 @@ int CLuaCameraDefs::SetCameraGoggleEffect(lua_State* luaVM) return 1; } +bool CLuaCameraDefs::SetCameraUnderwaterEffectEnabled(bool bEnabled) noexcept +{ + g_pMultiplayer->SetUnderwaterEffectEnabled(bEnabled); + + return true; +} + +bool CLuaCameraDefs::SetCameraUnderwaterEffectSpeed(float fSpeed, std::optional fFrequency) +{ + g_pMultiplayer->SetUnderwaterEffectSpeed(fSpeed, fFrequency.value_or(0.04f)); + + return true; +} + +bool CLuaCameraDefs::SetCameraUnderwaterDarkness(bool bEnabled, std::optional fFullDarknessDepth) +{ + g_pMultiplayer->SetUnderwaterDarkness(bEnabled, fFullDarknessDepth.value_or(90.0f)); + + return true; +} + +bool CLuaCameraDefs::ResetCameraUnderwaterEffect() noexcept +{ + g_pMultiplayer->ResetUnderwaterEffect(); + + return true; +} + +bool CLuaCameraDefs::ResetCameraUnderwaterDarkness() noexcept +{ + g_pMultiplayer->ResetUnderwaterDarkness(); + + return true; +} + bool CLuaCameraDefs::SetCameraDrunkLevel(short drunkLevel) { if (drunkLevel < 0 || drunkLevel > 255) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.h index b233d4e39c..946b7209f6 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.h @@ -31,6 +31,8 @@ class CLuaCameraDefs : public CLuaDefs static std::string GetCameraGoggleEffect(); LUA_DECLARE(GetCameraFieldOfView); static unsigned char GetCameraDrunkLevel(); + static CLuaMultiReturn GetCameraUnderwaterEffect() noexcept; + static CLuaMultiReturn GetCameraUnderwaterDarkness() noexcept; // Cam set funcs LUA_DECLARE(SetCameraMatrix); @@ -43,10 +45,17 @@ class CLuaCameraDefs : public CLuaDefs LUA_DECLARE(SetCameraGoggleEffect); static bool SetCameraDrunkLevel(short drunkLevel); + static bool SetCameraUnderwaterEffectEnabled(bool isEnabled) noexcept; + static bool SetCameraUnderwaterEffectSpeed(float speed, float frequency); + static bool SetCameraUnderwaterDarkness(bool isEnabled, std::optional fullDarknessDepth); + static bool ResetCameraUnderwaterEffect() noexcept; + static bool ResetCameraUnderwaterDarkness() noexcept; + // Cam do funcs static bool ShakeCamera(float radius, std::optional x, std::optional y, std::optional z) noexcept; static bool ResetShakeCamera() noexcept; + // For OOP only LUA_DECLARE(OOP_GetCameraPosition); LUA_DECLARE(OOP_SetCameraPosition); diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index 75206d8211..c73349c198 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -257,6 +257,14 @@ class CMultiplayerSA : public CMultiplayer bool IsNightVisionEnabled(); bool IsThermalVisionEnabled(); + void GetUnderwaterEffect(bool& isEnabled, float& speed, float& frequency) const noexcept; + void GetUnderwaterDarkness(bool& isEnabled, float& fullDarknessDepth) const noexcept; + void SetUnderwaterEffectEnabled(bool isEnabled) const noexcept override; + void SetUnderwaterEffectSpeed(float speed, float frequency) const noexcept override; + void SetUnderwaterDarkness(bool isEnabled, float fullDarknessDepth) override; + void ResetUnderwaterEffect() noexcept override; + void ResetUnderwaterDarkness() noexcept override; + void AllowWindowsCursorShowing(bool bAllow); CShotSyncData* GetLocalShotSyncData(); diff --git a/Client/multiplayer_sa/CMultiplayerSA_Postprocess.cpp b/Client/multiplayer_sa/CMultiplayerSA_Postprocess.cpp index cf1214437a..fcaecbd444 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Postprocess.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Postprocess.cpp @@ -15,6 +15,18 @@ #define HOOKPOS_GrainEffect_RainModifier 0x705078 #define HOOKPOS_GrainEffect_OverlayModifier 0x705091 +#define VAR_CPostEffects_WaterEnable 0xC402D3 +#define VAR_CPostEffects_WaterSpeed 0x8D5138 +#define VAR_CPostEffects_WaterFreq 0x8D513C +#define VAR_CPostEffects_WaterDepthDarkessEnabled 0x8D5144 +#define VAR_CPostEffects_WaterFullDarknessDepth 0x8D5148 +#define VAR_CPostEffects_WaterFxStartUnderWaterness 0x8D514C +#define VAR_CWeather_UnderWaterness 0xC8132C + +#define DEFAULT_UNDERWATER_EFFECT_SPEED ( 0.0015f ) +#define DEFAULT_UNDERWATER_EFFECT_FREQUENCY ( 0.04f ) +#define DEFAULT_UNDERWATER_FULL_DARKNESS_DEPTH ( 90.0f ) + namespace GrainEffect { @@ -119,7 +131,7 @@ void CMultiplayerSA::SetGrainLevel(BYTE ucLevel) GrainEffect::dwGrainStrength = static_cast(ucLevel); if (bEnable == bOverridden) - return; + return; if (bEnable) { @@ -154,6 +166,35 @@ void CMultiplayerSA::SetNightVisionEnabled(bool bEnabled, bool bNoiseEnabled) } } +void CMultiplayerSA::SetUnderwaterEffectEnabled(bool isEnabled) const noexcept +{ + MemPutFast(VAR_CPostEffects_WaterEnable, isEnabled ? 1 : 0); +} + +void CMultiplayerSA::SetUnderwaterEffectSpeed(float speed, float frequency) const noexcept +{ + MemPutFast(VAR_CPostEffects_WaterSpeed, speed); + MemPutFast(VAR_CPostEffects_WaterFreq, frequency); +} + +void CMultiplayerSA::SetUnderwaterDarkness(bool isEnabled, float fullDarknessDepth) +{ + MemPutFast(VAR_CPostEffects_WaterDepthDarkessEnabled, isEnabled ? 1 : 0); + + MemPutFast(VAR_CPostEffects_WaterFullDarknessDepth, fullDarknessDepth); +} + +void CMultiplayerSA::ResetUnderwaterEffect() noexcept +{ + this->SetUnderwaterEffectEnabled(false); + this->SetUnderwaterEffectSpeed(DEFAULT_UNDERWATER_EFFECT_SPEED, DEFAULT_UNDERWATER_EFFECT_FREQUENCY); +} + +void CMultiplayerSA::ResetUnderwaterDarkness() noexcept +{ + this->SetUnderwaterDarkness(false, DEFAULT_UNDERWATER_FULL_DARKNESS_DEPTH); +} + void CMultiplayerSA::SetThermalVisionEnabled(bool bEnabled, bool bNoiseEnabled) { if (bEnabled) @@ -184,6 +225,19 @@ bool CMultiplayerSA::IsThermalVisionEnabled() return (*(BYTE*)0xC402B9 == 1); } +void CMultiplayerSA::GetUnderwaterEffect(bool& isEnabled, float& speed, float& frequency) const noexcept +{ + isEnabled = (*(uint8_t*)VAR_CPostEffects_WaterEnable == 1) || (*(float*)VAR_CWeather_UnderWaterness) >= (*(float*)VAR_CPostEffects_WaterFxStartUnderWaterness); + speed = (*(float*)VAR_CPostEffects_WaterSpeed); + frequency = (*(float*)VAR_CPostEffects_WaterFreq); +} + +void CMultiplayerSA::GetUnderwaterDarkness(bool& isEnabled, float& fullDarknessDepth) const noexcept +{ + isEnabled = (*(std::uint8_t*)VAR_CPostEffects_WaterDepthDarkessEnabled); + fullDarknessDepth = (*(float*)VAR_CPostEffects_WaterFullDarknessDepth); +} + void CMultiplayerSA::InitHooks_Postprocess() { HookInstallCall(HOOKPOS_GrainEffect_NightModifier, (DWORD)GrainEffect::NightModifier::ApplyEffect); diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index e5e591ad5d..415046e4ce 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -467,4 +467,12 @@ class CMultiplayer virtual unsigned int EntryInfoNodePool_NoOfUsedSpaces() const noexcept = 0; virtual unsigned int PtrNodeDoubleLinkPool_NoOfUsedSpaces() const noexcept = 0; + + virtual void GetUnderwaterEffect(bool& isEnabled, float& speed, float& frequency) = 0; + virtual void GetUnderwaterDarkness(bool& isEnabled, float& fullDarknessDepth) = 0; + virtual void SetUnderwaterEffectEnabled(bool isEnabled) = 0; + virtual void SetUnderwaterEffectSpeed(float speed, float frequency) = 0; + virtual void SetUnderwaterDarkness(bool isEnabled, float fullDarknessDepth) = 0; + virtual void ResetUnderwaterEffect() = 0; + virtual void ResetUnderwaterDarkness() = 0; };