diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index dcb73b17389..7c65ef82c79 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -406,7 +406,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. @@ -1026,7 +1026,7 @@ void CClientGame::DoPulsePostFrame() } auto taskManager = pLocalPlayer->GetTaskManager(); - auto task = taskManager->GetActiveTask(); + auto task = taskManager->GetActiveTask(); auto pVehicle = pLocalPlayer->GetOccupiedVehicle(); bool useZoneName = true; @@ -1080,7 +1080,7 @@ void CClientGame::DoPulsePostFrame() discordState = taskState.strState; useZoneName = taskState.bUseZone; - } + } if (useZoneName) { @@ -6928,6 +6928,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 2d9c268dc36..d6e2e7d36ad 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp @@ -29,6 +29,8 @@ void CLuaCameraDefs::LoadFunctions() {"getCameraGoggleEffect", ArgumentParserWarn}, {"getCameraFieldOfView", GetCameraFieldOfView}, {"getCameraDrunkLevel", ArgumentParserWarn}, + {"getCameraUnderwaterEffect", ArgumentParser}, + {"getCameraUnderwaterDarkness", ArgumentParser}, // Cam set funcs {"setCameraMatrix", SetCameraMatrix}, @@ -42,8 +44,15 @@ void CLuaCameraDefs::LoadFunctions() {"setCameraGoggleEffect", SetCameraGoggleEffect}, {"setCameraDrunkLevel", ArgumentParserWarn}, + {"setCameraUnderwaterEffectEnabled", ArgumentParser}, + {"setCameraUnderwaterEffectSpeed", ArgumentParser}, + {"setCameraUnderwaterDarkness", ArgumentParser}, + {"resetCameraUnderwaterEffect", ArgumentParser}, + {"resetCameraUnderwaterDarkness", ArgumentParser}, + {"shakeCamera", ArgumentParser}, {"resetShakeCamera", ArgumentParser}, + }; // Add functions @@ -71,6 +80,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); @@ -83,6 +94,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"); @@ -165,6 +181,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; @@ -467,6 +499,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) @@ -567,4 +634,4 @@ bool CLuaCameraDefs::ResetShakeCamera() noexcept { m_pManager->GetCamera()->ResetShakeCamera(); return true; -} \ No newline at end of file +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.h index b233d4e39c8..946b7209f63 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 0dd642cb4b4..23739358bfb 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -255,6 +255,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 79491f3ad9a..05381c05677 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 33e349ea71a..c66e1470390 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -462,4 +462,12 @@ class CMultiplayer virtual unsigned int EntryInfoNodePool_NoOfUsedSpaces() const noexcept = 0; virtual unsigned int PtrNodeSingleLinkPool_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; };