diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index 3492697244..5455f2829d 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -4387,6 +4387,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 0d057bf424..cbd68a3b8c 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -6998,6 +6998,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 d86e4c1f90..38a6c06f57 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -2667,6 +2667,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 a13aca8be3..bc2af81b99 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp @@ -149,7 +149,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) @@ -1818,6 +1823,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 5668ca6dd4..1535e41dff 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h @@ -90,6 +90,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 38a15493fa..573a05d3ec 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 5c5c4514f1..59026c2fd7 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 da8153d04a..293eafe003 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA.cpp @@ -16,6 +16,7 @@ #include #include #include +#include class CEventDamageSAInterface; @@ -594,6 +595,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() @@ -2064,6 +2067,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 2d209976b3..d6672c43c1 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -21,6 +21,11 @@ class CRemoteDataSA; #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 @@ void InitHooks(); 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 @@ void InitHooks(); 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 e5e591ad5d..2e56406737 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 5807a7f3ed..91c7d71d16 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 connecti 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 07c4f227e6..3b1c3da2f0 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 d62ad044f4..99d871bcaf 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,8 @@ void CMapManager::OnPlayerJoin(CPlayer& Player) fJetpackMaxHeight, 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)); + fFogDistance, fAircraftMaxHeight, 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 810820a820..cabfb51e27 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -10710,6 +10710,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(); @@ -10894,6 +10905,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); @@ -10986,6 +11008,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 388f38b443..05f4903006 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -605,6 +605,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); @@ -644,6 +645,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); @@ -653,6 +655,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 181798114c..6011337cf6 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp @@ -93,7 +93,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) @@ -797,6 +802,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); @@ -983,6 +1001,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()) @@ -1060,6 +1083,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 49032579b3..80b9b33f2b 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h @@ -96,4 +96,8 @@ class CLuaWorldDefs : public CLuaDefs LUA_DECLARE(resetMoonSize); 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 aceac1b129..444ddaa532 100644 --- a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp @@ -27,8 +27,9 @@ CMapInfoPacket::CMapInfoPacket(unsigned char ucWeather, unsigned char ucWeatherB bool bOverrideRainLevel, float fRainLevel, bool bOverrideSunSize, float fSunSize, bool bOverrideSunColor, 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 fWindVelZ, bool bOverrideFarClipDistance, float fFarClip, bool bOverrideFogDistance, float fFogDistance, 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 f4583cc3c2..37d33d8477 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 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 84c7518bc4..620c92b053 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 };