diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index fe73aeaba80..d26586b03eb 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -4395,6 +4395,9 @@ void CSettings::SaveData() if (CGUIListItem* pQualitySelected = m_pComboFxQuality->GetSelectedItem()) { gameSettings->SetFXQuality((int)pQualitySelected->GetData()); + + // Update grass draw distance to reflect new FX quality setting + g_pCore->GetMultiplayer()->RefreshGrassDrawDistance(); } // Aspect ratio diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 47d7461cdd0..f3a3a32ae6a 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -7006,6 +7006,7 @@ void CClientGame::ResetWorldProperties(const ResetWorldPropsInfo& resetPropsInfo g_pMultiplayer->ResetSunSize(); g_pMultiplayer->RestoreWindVelocity(); g_pMultiplayer->ResetColorFilter(); + g_pMultiplayer->ResetGrassDrawDistance(); g_pGame->GetWeather()->ResetAmountOfRain(); } diff --git a/Client/mods/deathmatch/logic/CPacketHandler.cpp b/Client/mods/deathmatch/logic/CPacketHandler.cpp index fc10ed05cd8..f989f8d5644 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -2671,6 +2671,19 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) bitStream.ReadBit(bOcclusionsEnabled); g_pGame->GetWorld()->SetOcclusionsEnabled(bOcclusionsEnabled); + + // Grass draw distance + bool overrideGrassDrawDistance = false; + float grassCloseDistance, grassFarDistance; + if (!bitStream.ReadBit(overrideGrassDrawDistance)) + return; + if (overrideGrassDrawDistance) + { + if (!bitStream.Read(grassCloseDistance) || !bitStream.Read(grassFarDistance)) + return; + + g_pMultiplayer->SetGrassDrawDistance(grassCloseDistance, grassFarDistance); + } } void CPacketHandler::Packet_PartialPacketInfo(NetBitStreamInterface& bitStream) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp index f9c1e69bdcc..0788bd6052d 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp @@ -140,6 +140,28 @@ void CLuaWorldDefs::LoadFunctions() {"resetWorldProperties", ArgumentParser}, {"resetDynamicPedShadows", ArgumentParser}, + // World reset funcs + {"resetColorFilter", ArgumentParser}, + {"resetCoronaReflectionsEnabled", ArgumentParser}, + {"resetSkyGradient", ResetSkyGradient}, + {"resetHeatHaze", ResetHeatHaze}, + {"resetWindVelocity", ResetWindVelocity}, + {"resetRainLevel", ResetRainLevel}, + {"resetFarClipDistance", ResetFarClipDistance}, + {"resetNearClipDistance", ResetNearClipDistance}, + {"resetVehiclesLODDistance", ResetVehiclesLODDistance}, + {"resetPedsLODDistance", ResetPedsLODDistance}, + {"resetFogDistance", ResetFogDistance}, + {"resetSunColor", ResetSunColor}, + {"resetSunSize", ResetSunSize}, + {"resetMoonSize", ResetMoonSize}, + {"resetBlurLevel", ResetBlurLevel}, + {"resetWorldProperty", ArgumentParserWarn}, + {"resetTimeFrozen", ArgumentParser}, + {"resetVolumetricShadows", ArgumentParser}, + {"resetWorldProperties", ArgumentParser}, + {"resetDynamicPedShadows", ArgumentParser}, + // World check funcs {"areTrafficLightsLocked", AreTrafficLightsLocked}, {"isPedTargetingMarkerEnabled", IsPedTargetingMarkerEnabled}, @@ -149,7 +171,12 @@ void CLuaWorldDefs::LoadFunctions() {"isTimeFrozen", ArgumentParser}, {"isVolumetricShadowsEnabled", ArgumentParser}, {"isDynamicPedShadowsEnabled", ArgumentParser}, - {"testSphereAgainstWorld", ArgumentParser}}; + {"testSphereAgainstWorld", ArgumentParser}, + + // Grass draw distance functions + {"getGrassDrawDistance", ArgumentParser}, + {"setGrassDrawDistance", ArgumentParser}, + {"resetGrassDrawDistance", ArgumentParser}}; // Add functions for (const auto& [name, func] : functions) @@ -1830,6 +1857,23 @@ int CLuaWorldDefs::ResetFogDistance(lua_State* luaVM) return 1; } +CLuaMultiReturn CLuaWorldDefs::GetGrassDrawDistance() +{ + float closeDistance, farDistance; + g_pMultiplayer->GetGrassDrawDistance(closeDistance, farDistance); + return {closeDistance, farDistance}; +} + +void CLuaWorldDefs::SetGrassDrawDistance(float closeDistance, float farDistance) +{ + g_pMultiplayer->SetGrassDrawDistance(closeDistance, farDistance); +} + +void CLuaWorldDefs::ResetGrassDrawDistance() +{ + g_pMultiplayer->ResetGrassDrawDistance(); +} + int CLuaWorldDefs::GetSunColor(lua_State* luaVM) { unsigned char ucCoreRed, ucCoreGreen, ucCoreBlue, ucCoronaRed, ucCoronaGreen, ucCoronaBlue; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h index 5ad83bdeae0..fbf8f0cf75d 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h @@ -91,6 +91,9 @@ class CLuaWorldDefs : public CLuaDefs LUA_DECLARE(GetFogDistance); LUA_DECLARE(SetFogDistance); LUA_DECLARE(ResetFogDistance); + static CLuaMultiReturn GetGrassDrawDistance(); + static void SetGrassDrawDistance(float closeDistance, float farDistance); + static void ResetGrassDrawDistance(); LUA_DECLARE(GetSunColor); LUA_DECLARE(SetSunColor); LUA_DECLARE(ResetSunColor); diff --git a/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp index 38a15493fad..573a05d3ec6 100644 --- a/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp @@ -73,6 +73,9 @@ void CWorldRPCs::LoadFunctions() AddHandler(SET_WORLD_SPECIAL_PROPERTY, SetWorldSpecialPropertyEnabled, "SetWorldSpecialPropertyEnabled"); AddHandler(RESET_WORLD_PROPERTIES, ResetWorldProperties, "ResetWorldProperties"); + + AddHandler(SET_GRASS_DRAW_DISTANCE, SetGrassDrawDistance, "SetGrassDrawDistance"); + AddHandler(RESET_GRASS_DRAW_DISTANCE, ResetGrassDrawDistance, "ResetGrassDrawDistance"); } void CWorldRPCs::SetTime(NetBitStreamInterface& bitStream) @@ -354,6 +357,16 @@ void CWorldRPCs::SetFogDistance(NetBitStreamInterface& bitStream) } } +void CWorldRPCs::SetGrassDrawDistance(NetBitStreamInterface& bitStream) +{ + float closeDistance, farDistance; + + if (bitStream.Read(closeDistance) && bitStream.Read(farDistance)) + { + g_pMultiplayer->SetGrassDrawDistance(closeDistance, farDistance); + } +} + void CWorldRPCs::SetAircraftMaxHeight(NetBitStreamInterface& bitStream) { float fMaxHeight; @@ -414,6 +427,11 @@ void CWorldRPCs::ResetFogDistance(NetBitStreamInterface& bitStream) g_pMultiplayer->RestoreFogDistance(); } +void CWorldRPCs::ResetGrassDrawDistance(NetBitStreamInterface& bitStream) +{ + g_pMultiplayer->ResetGrassDrawDistance(); +} + void CWorldRPCs::SetWeaponProperty(NetBitStreamInterface& bitStream) { unsigned char ucWeapon = 0; diff --git a/Client/mods/deathmatch/logic/rpc/CWorldRPCs.h b/Client/mods/deathmatch/logic/rpc/CWorldRPCs.h index 5c5c4514f1d..59026c2fd7a 100644 --- a/Client/mods/deathmatch/logic/rpc/CWorldRPCs.h +++ b/Client/mods/deathmatch/logic/rpc/CWorldRPCs.h @@ -66,4 +66,6 @@ class CWorldRPCs : public CRPCFunctions DECLARE_RPC(SetSyncIntervals); DECLARE_RPC(SetWorldSpecialPropertyEnabled); DECLARE_RPC(ResetWorldProperties); + DECLARE_RPC(SetGrassDrawDistance); + DECLARE_RPC(ResetGrassDrawDistance); }; diff --git a/Client/multiplayer_sa/CMultiplayerSA.cpp b/Client/multiplayer_sa/CMultiplayerSA.cpp index f4b9573d05d..3e048667eba 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA.cpp @@ -16,6 +16,7 @@ #include #include #include +#include class CEventDamageSAInterface; @@ -596,6 +597,8 @@ CMultiplayerSA::CMultiplayerSA() m_fMaddDoggPoolLevel = 1082.73f; m_dwLastStaticAnimGroupID = eAnimGroup::ANIM_GROUP_DEFAULT; m_dwLastStaticAnimID = eAnimID::ANIM_ID_WALK; + m_grassCloseDistance = DEFAULT_GRASS_CLOSE_DISTANCE; + m_grassFarDistance = DEFAULT_GRASS_FAR_DISTANCE; } CMultiplayerSA::~CMultiplayerSA() @@ -2067,6 +2070,54 @@ void CMultiplayerSA::RestoreFogDistance() } } +void CMultiplayerSA::SetGrassDrawDistance(float closeDistance, float farDistance) +{ + // Store unscaled values + m_grassCloseDistance = closeDistance; + m_grassFarDistance = farDistance; + + // Apply FX quality scaling + CGameSettings* pSettings = pGameInterface ? pGameInterface->GetSettings() : nullptr; + const unsigned int fxQuality = pSettings ? pSettings->GetFXQuality() : 2; + + if (fxQuality) + farDistance /= 2.0f; + + MemPutFast(VAR_CGrassCloseDist, closeDistance); + MemPutFast(VAR_CGrassFarDist, farDistance); +} + +void CMultiplayerSA::GetGrassDrawDistance(float& closeDistance, float& farDistance) const +{ + closeDistance = *(float*)VAR_CGrassCloseDist; + farDistance = *(float*)VAR_CGrassFarDist; +} + +void CMultiplayerSA::ResetGrassDrawDistance() +{ + // Store unscaled default values + m_grassCloseDistance = DEFAULT_GRASS_CLOSE_DISTANCE; + m_grassFarDistance = DEFAULT_GRASS_FAR_DISTANCE; + + // Apply FX quality scaling + CGameSettings* pSettings = pGameInterface ? pGameInterface->GetSettings() : nullptr; + const unsigned int fxQuality = pSettings ? pSettings->GetFXQuality() : 2; + + float farDistance = DEFAULT_GRASS_FAR_DISTANCE; + + if (fxQuality) + farDistance /= 2.0f; + + MemPutFast(VAR_CGrassCloseDist, DEFAULT_GRASS_CLOSE_DISTANCE); + MemPutFast(VAR_CGrassFarDist, farDistance); +} + +void CMultiplayerSA::RefreshGrassDrawDistance() +{ + // Re-apply stored grass distances with current FX quality + SetGrassDrawDistance(m_grassCloseDistance, m_grassFarDistance); +} + void CMultiplayerSA::GetSunColor(unsigned char& ucCoreRed, unsigned char& ucCoreGreen, unsigned char& ucCoreBlue, unsigned char& ucCoronaRed, unsigned char& ucCoronaGreen, unsigned char& ucCoronaBlue) { diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index 77e95b4191a..af1743bf2e3 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -19,8 +19,13 @@ #include "CRemoteDataSA.h" class CRemoteDataSA; -#define DEFAULT_NEAR_CLIP_DISTANCE (0.3f) -#define DEFAULT_SHADOWS_OFFSET (0.013f) // GTA default = 0.06f +#define DEFAULT_NEAR_CLIP_DISTANCE (0.3f) +#define DEFAULT_SHADOWS_OFFSET (0.013f) // GTA default = 0.06f +#define DEFAULT_GRASS_CLOSE_DISTANCE (3.0f) +#define DEFAULT_GRASS_FAR_DISTANCE (60.0f) + +#define VAR_CGrassCloseDist 0xC02DBC +#define VAR_CGrassFarDist 0x8D132C enum eRadioStationID { @@ -192,6 +197,10 @@ class CMultiplayerSA : public CMultiplayer float GetFogDistance(); void SetFogDistance(float fDistance); void RestoreFogDistance(); + void SetGrassDrawDistance(float closeDistance, float farDistance) override; + void GetGrassDrawDistance(float& closeDistance, float& farDistance) const override; + void ResetGrassDrawDistance() override; + void RefreshGrassDrawDistance() override; void GetSunColor(unsigned char& ucCoreRed, unsigned char& ucCoreGreen, unsigned char& ucCoreBlue, unsigned char& ucCoronaRed, unsigned char& ucCoronaGreen, unsigned char& ucCoronaBlue); void SetSunColor(unsigned char ucCoreRed, unsigned char ucCoreGreen, unsigned char ucCoreBlue, unsigned char ucCoronaRed, unsigned char ucCoronaGreen, @@ -391,6 +400,8 @@ class CMultiplayerSA : public CMultiplayer eAnimID m_dwLastStaticAnimID; DWORD m_dwLastAnimArrayAddress; float m_fShadowsOffset; + float m_grassCloseDistance; + float m_grassFarDistance; bool m_isRapidVehicleStopFixEnabled{false}; diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index 5926e578a89..183886c0827 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -299,6 +299,10 @@ class CMultiplayer virtual void SetFogDistance(float fDistance) = 0; virtual float GetFogDistance() = 0; virtual void RestoreFogDistance() = 0; + virtual void SetGrassDrawDistance(float closeDistance, float farDistance) = 0; + virtual void GetGrassDrawDistance(float& closeDistance, float& farDistance) const = 0; + virtual void ResetGrassDrawDistance() = 0; + virtual void RefreshGrassDrawDistance() = 0; virtual void GetSunColor(unsigned char& ucCoreRed, unsigned char& ucCoreGreen, unsigned char& ucCoreBlue, unsigned char& ucCoronaRed, unsigned char& ucCoronaGreen, unsigned char& ucCoronaBlue) = 0; virtual void SetSunColor(unsigned char ucCoreRed, unsigned char ucCoreGreen, unsigned char ucCoreBlue, unsigned char ucCoronaRed, diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 0ed84294df7..89afd19911b 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -219,6 +219,9 @@ CGame::CGame() : m_FloodProtect(4, 30000, 30000) // Max of 4 connections per 30 m_bOverrideWindVelocity = false; m_bOverrideFarClip = false; m_bOverrideFogDistance = false; + m_overrideGrassDrawDistance = false; + m_grassCloseDistance = 3.0f; + m_grassFarDistance = 60.0f; m_bOverrideMoonSize = false; m_pASE = NULL; diff --git a/Server/mods/deathmatch/logic/CGame.h b/Server/mods/deathmatch/logic/CGame.h index 9d0ace7b1aa..03155a8127d 100644 --- a/Server/mods/deathmatch/logic/CGame.h +++ b/Server/mods/deathmatch/logic/CGame.h @@ -404,6 +404,20 @@ class CGame float GetFogDistance() { return m_fFogDistance; } void SetFogDistance(float& fFogDistance) { m_fFogDistance = fFogDistance; } + bool HasGrassDrawDistance() const noexcept { return m_overrideGrassDrawDistance; } + void SetHasGrassDrawDistance(bool overrideGrassDrawDistance) noexcept { m_overrideGrassDrawDistance = overrideGrassDrawDistance; } + + void GetGrassDrawDistance(float& closeDistance, float& farDistance) const noexcept + { + closeDistance = m_grassCloseDistance; + farDistance = m_grassFarDistance; + } + void SetGrassDrawDistance(float closeDistance, float farDistance) noexcept + { + m_grassCloseDistance = closeDistance; + m_grassFarDistance = farDistance; + } + float GetAircraftMaxHeight() { return m_fAircraftMaxHeight; } void SetAircraftMaxHeight(float fMaxHeight) { m_fAircraftMaxHeight = fMaxHeight; } @@ -640,6 +654,10 @@ class CGame bool m_bOverrideFogDistance; float m_fFogDistance; + bool m_overrideGrassDrawDistance; + float m_grassCloseDistance; + float m_grassFarDistance; + SGarageStates m_bGarageStates; // FPS statistics diff --git a/Server/mods/deathmatch/logic/CMapManager.cpp b/Server/mods/deathmatch/logic/CMapManager.cpp index 29b9c7eb2e4..ff761c630c1 100644 --- a/Server/mods/deathmatch/logic/CMapManager.cpp +++ b/Server/mods/deathmatch/logic/CMapManager.cpp @@ -519,6 +519,11 @@ void CMapManager::OnPlayerJoin(CPlayer& Player) bool bOverrideFogDistance = g_pGame->HasFogDistance(); float fFogDistance = g_pGame->GetFogDistance(); + // Grass draw distance + bool overrideGrassDrawDistance = g_pGame->HasGrassDrawDistance(); + float grassCloseDistance, grassFarDistance; + g_pGame->GetGrassDrawDistance(grassCloseDistance, grassFarDistance); + marker.Set("FirstBit"); // Send the packet to the given player @@ -528,7 +533,7 @@ void CMapManager::OnPlayerJoin(CPlayer& Player) bOverrideWaterColor, ucWaterRed, ucWaterGreen, ucWaterBlue, ucWaterAlpha, bInteriorSoundsEnabled, bOverrideRainLevel, fRainLevel, bOverrideSunSize, fSunSize, bOverrideSunColor, ucCoreR, ucCoreG, ucCoreB, ucCoronaR, ucCoronaG, ucCoronaB, bOverrideWindVelocity, fWindVelX, fWindVelY, fWindVelZ, bOverrideFarClipDistance, fFarClip, bOverrideFogDistance, fFogDistance, fAircraftMaxHeight, - fAircraftMaxVelocity, bOverrideMoonSize, iMoonSize)); + fAircraftMaxVelocity, bOverrideMoonSize, iMoonSize, overrideGrassDrawDistance, grassCloseDistance, grassFarDistance)); marker.Set("SendMapInfoPacket"); diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 2e1065bd897..92a9eab4c36 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -10714,6 +10714,17 @@ bool CStaticFunctionDefinitions::GetFogDistance(float& fFogDist) return false; } +bool CStaticFunctionDefinitions::GetGrassDrawDistance(float& closeDistance, float& farDistance) +{ + if (g_pGame->HasGrassDrawDistance()) + { + g_pGame->GetGrassDrawDistance(closeDistance, farDistance); + return true; + } + + return false; +} + bool CStaticFunctionDefinitions::GetAircraftMaxHeight(float& fMaxHeight) { fMaxHeight = g_pGame->GetAircraftMaxHeight(); @@ -10898,6 +10909,17 @@ bool CStaticFunctionDefinitions::SetFogDistance(float fFogDist) return true; } +void CStaticFunctionDefinitions::SetGrassDrawDistance(float closeDistance, float farDistance) +{ + g_pGame->SetGrassDrawDistance(closeDistance, farDistance); + g_pGame->SetHasGrassDrawDistance(true); + + CBitStream BitStream; + BitStream.pBitStream->Write(closeDistance); + BitStream.pBitStream->Write(farDistance); + m_pPlayerManager->BroadcastOnlyJoined(CLuaPacket(SET_GRASS_DRAW_DISTANCE, *BitStream.pBitStream)); +} + bool CStaticFunctionDefinitions::SetAircraftMaxHeight(float fMaxHeight) { g_pGame->SetAircraftMaxHeight(fMaxHeight); @@ -10990,6 +11012,14 @@ bool CStaticFunctionDefinitions::ResetFogDistance() return true; } +void CStaticFunctionDefinitions::ResetGrassDrawDistance() +{ + g_pGame->SetHasGrassDrawDistance(false); + + CBitStream BitStream; + m_pPlayerManager->BroadcastOnlyJoined(CLuaPacket(RESET_GRASS_DRAW_DISTANCE, *BitStream.pBitStream)); +} + bool CStaticFunctionDefinitions::RemoveWorldModel(unsigned short usModel, float fRadius, const CVector& vecPosition, char cInterior) { g_pGame->GetBuildingRemovalManager()->CreateBuildingRemoval(usModel, fRadius, vecPosition, cInterior); diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 0b642a1714d..a27f650b6fe 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -607,6 +607,7 @@ class CStaticFunctionDefinitions static bool GetWindVelocity(float& fVelX, float& fVelY, float& fVelZ); static bool GetFarClipDistance(float& fFarClip); static bool GetFogDistance(float& fFogDist); + static bool GetGrassDrawDistance(float& closeDistance, float& farDistance); static bool GetAircraftMaxHeight(float& fMaxHeight); static bool GetOcclusionsEnabled(bool& bEnabled); static bool GetMoonSize(int& iSize); @@ -646,6 +647,7 @@ class CStaticFunctionDefinitions static bool SetWindVelocity(float fVelX, float fVelY, float fVelZ); static bool SetFarClipDistance(float fFarClip); static bool SetFogDistance(float fFogDist); + static void SetGrassDrawDistance(float closeDistance, float farDistance); static bool SetAircraftMaxHeight(float fMaxHeight); static bool SetAircraftMaxVelocity(float fVelocity); static bool SetOcclusionsEnabled(bool bEnabled); @@ -655,6 +657,7 @@ class CStaticFunctionDefinitions static bool ResetWindVelocity(); static bool ResetFarClipDistance(); static bool ResetFogDistance(); + static void ResetGrassDrawDistance(); static bool RemoveWorldModel(unsigned short usModel, float fRadius, const CVector& vecPosition, char cInterior); static bool RestoreWorldModel(unsigned short usModel, float fRadius, const CVector& vecPosition, char cInterior); static bool RestoreAllWorldModels(); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp index 0e7f7dc212c..7364fa09b3e 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp @@ -94,7 +94,12 @@ void CLuaWorldDefs::LoadFunctions() {"isGarageOpen", isGarageOpen}, {"isGlitchEnabled", isGlitchEnabled}, {"isWorldSpecialPropertyEnabled", ArgumentParserWarn}, - {"areTrafficLightsLocked", areTrafficLightsLocked}}; + {"areTrafficLightsLocked", areTrafficLightsLocked}, + + // Grass draw distance functions + {"getGrassDrawDistance", ArgumentParser}, + {"setGrassDrawDistance", ArgumentParser}, + {"resetGrassDrawDistance", ArgumentParser}}; // Add functions for (const auto& [name, func] : functions) @@ -798,6 +803,19 @@ int CLuaWorldDefs::getFogDistance(lua_State* luaVM) return 1; } +std::variant> CLuaWorldDefs::GetGrassDrawDistance() +{ + float closeDistance, farDistance; + bool bSuccess = CStaticFunctionDefinitions::GetGrassDrawDistance(closeDistance, farDistance); + + if (bSuccess) + { + return CLuaMultiReturn(closeDistance, farDistance); + } + + return false; +} + int CLuaWorldDefs::setInteriorSoundsEnabled(lua_State* luaVM) { CScriptArgReader argStream(luaVM); @@ -984,6 +1002,11 @@ int CLuaWorldDefs::setFogDistance(lua_State* luaVM) return 1; } +void CLuaWorldDefs::SetGrassDrawDistance(float closeDistance, float farDistance) +{ + CStaticFunctionDefinitions::SetGrassDrawDistance(closeDistance, farDistance); +} + int CLuaWorldDefs::resetRainLevel(lua_State* luaVM) { if (CStaticFunctionDefinitions::ResetRainLevel()) @@ -1061,6 +1084,11 @@ int CLuaWorldDefs::resetFogDistance(lua_State* luaVM) return 1; } +void CLuaWorldDefs::ResetGrassDrawDistance() +{ + CStaticFunctionDefinitions::ResetGrassDrawDistance(); +} + int CLuaWorldDefs::RemoveWorldModel(lua_State* luaVM) { CScriptArgReader argStream(luaVM); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h index be9a0d9dce8..79720d82617 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h @@ -98,4 +98,8 @@ class CLuaWorldDefs : public CLuaDefs static void ResetWorldProperties(std::optional resetSpecialWorldProperties, std::optional resetWorldProperties, std::optional resetWeatherProperties, std::optional resetLODs, std::optional resetSounds, std::optional resetGlitches, std::optional resetJetpackWeapons) noexcept; + + static void SetGrassDrawDistance(float closeDistance, float farDistance); + static std::variant> GetGrassDrawDistance(); + static void ResetGrassDrawDistance(); }; diff --git a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp index aceac1b129f..f5166e52857 100644 --- a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp @@ -28,7 +28,8 @@ CMapInfoPacket::CMapInfoPacket(unsigned char ucWeather, unsigned char ucWeatherB unsigned char ucSunCoreR, unsigned char ucSunCoreG, unsigned char ucSunCoreB, unsigned char ucSunCoronaR, unsigned char ucSunCoronaG, unsigned char ucSunCoronaB, bool bOverrideWindVelocity, float fWindVelX, float fWindVelY, float fWindVelZ, bool bOverrideFarClipDistance, float fFarClip, bool bOverrideFogDistance, float fFogDistance, - float fAircraftMaxHeight, float fAircraftMaxVelocity, bool bOverrideMoonSize, int iMoonSize) + float fAircraftMaxHeight, float fAircraftMaxVelocity, bool bOverrideMoonSize, int iMoonSize, bool overrideGrassDrawDistance, + float grassCloseDistance, float grassFarDistance) { m_ucWeather = ucWeather; m_ucWeatherBlendingTo = ucWeatherBlendingTo; @@ -80,6 +81,9 @@ CMapInfoPacket::CMapInfoPacket(unsigned char ucWeather, unsigned char ucWeatherB m_fFarClip = fFarClip; m_bOverrideFogDistance = bOverrideFogDistance; m_fFogDistance = fFogDistance; + m_overrideGrassDrawDistance = overrideGrassDrawDistance; + m_grassCloseDistance = grassCloseDistance; + m_grassFarDistance = grassFarDistance; m_fAircraftMaxHeight = fAircraftMaxHeight; m_fAircraftMaxVelocity = fAircraftMaxVelocity; m_bOverrideMoonSize = bOverrideMoonSize; @@ -357,5 +361,13 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const bool bOcclusionsEnabled = g_pGame->GetOcclusionsEnabled(); BitStream.WriteBit(bOcclusionsEnabled); + // Grass draw distance + BitStream.WriteBit(m_overrideGrassDrawDistance); + if (m_overrideGrassDrawDistance) + { + BitStream.Write(m_grassCloseDistance); + BitStream.Write(m_grassFarDistance); + } + return true; } diff --git a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.h b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.h index 9425a0687e6..bd7751b2029 100644 --- a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.h +++ b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.h @@ -39,7 +39,8 @@ class CMapInfoPacket final : public CPacket unsigned char ucSunCoreG = 0, unsigned char ucSunCoreB = 0, unsigned char ucSunCoronaR = 0, unsigned char ucSunCoronaG = 0, unsigned char ucSunCoronaB = 0, bool bOverrideWindVelocity = false, float fWindVelX = 0, float fWindVelY = 0, float fWindVelZ = 0, bool bOverrideFarClipDistance = false, float fFarClip = 0, bool bOverrideFogDistance = false, float fFogDistance = 0, - float fAircraftMaxHeight = 800, float fAircraftMaxVelocity = 1.5f, bool bOverrideMoonSize = false, int iMoonSize = 3); + float fAircraftMaxHeight = 800, float fAircraftMaxVelocity = 1.5f, bool bOverrideMoonSize = false, int iMoonSize = 3, + bool overrideGrassDrawDistance = false, float grassCloseDistance = 3.0f, float grassFarDistance = 60.0f); ePacketID GetPacketID() const { return PACKET_ID_MAP_INFO; }; unsigned long GetFlags() const { return PACKET_HIGH_PRIORITY | PACKET_RELIABLE | PACKET_SEQUENCED; }; @@ -93,6 +94,9 @@ class CMapInfoPacket final : public CPacket float m_fFarClip; bool m_bOverrideFogDistance; float m_fFogDistance; + bool m_overrideGrassDrawDistance; + float m_grassCloseDistance; + float m_grassFarDistance; float m_fAircraftMaxHeight; float m_fAircraftMaxVelocity; bool m_bOverrideMoonSize; diff --git a/Shared/sdk/net/rpc_enums.h b/Shared/sdk/net/rpc_enums.h index 81ec05b0444..fc438626892 100644 --- a/Shared/sdk/net/rpc_enums.h +++ b/Shared/sdk/net/rpc_enums.h @@ -293,5 +293,8 @@ enum eElementRPCFunctions SET_ELEMENT_ON_FIRE, + SET_GRASS_DRAW_DISTANCE, + RESET_GRASS_DRAW_DISTANCE, + NUM_RPC_FUNCS // Add above this line };