diff --git a/Client/mods/deathmatch/logic/CClientPed.cpp b/Client/mods/deathmatch/logic/CClientPed.cpp index 87d90250d3a..aac04570792 100644 --- a/Client/mods/deathmatch/logic/CClientPed.cpp +++ b/Client/mods/deathmatch/logic/CClientPed.cpp @@ -4673,12 +4673,20 @@ float CClientPed::GetDistanceFromGround() return (vecPosition.fZ - fGroundLevel); } -bool CClientPed::IsOnGround() +bool CClientPed::IsOnGround(bool checkVehicles) { CVector vecPosition; GetPosition(vecPosition); float fGroundLevel = static_cast(g_pGame->GetWorld()->FindGroundZFor3DPosition(&vecPosition)); - return (vecPosition.fZ > fGroundLevel && (vecPosition.fZ - fGroundLevel) <= 1.0f); + + if (DefinitelyLessThan(vecPosition.fZ, fGroundLevel)) + return false; + + bool isOnGround = DefinitelyLessThan((vecPosition.fZ - fGroundLevel), 1.0f) || EssentiallyEqual((vecPosition.fZ - fGroundLevel), 1.0f); + if (!isOnGround && checkVehicles && m_pPlayerPed) + return m_pPlayerPed->IsStandingOnEntity(); + + return isOnGround; } bool CClientPed::IsClimbing() diff --git a/Client/mods/deathmatch/logic/CClientPed.h b/Client/mods/deathmatch/logic/CClientPed.h index 35df0fa09bd..489b1a0a501 100644 --- a/Client/mods/deathmatch/logic/CClientPed.h +++ b/Client/mods/deathmatch/logic/CClientPed.h @@ -380,7 +380,7 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule void SetInWater(bool bIsInWater) { m_bIsInWater = bIsInWater; }; bool IsInWater(); - bool IsOnGround(); + bool IsOnGround(bool checkVehicles = false); bool IsClimbing(); bool IsRadioOn() const noexcept { return m_bRadioOn; }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp index 9d1dab664de..de3ad74321e 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp @@ -914,13 +914,15 @@ int CLuaPedDefs::IsPedOnGround(lua_State* luaVM) { // Verify the argument CClientPed* pPed = NULL; + bool checkVehicles = false; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pPed); + argStream.ReadBool(checkVehicles, false); if (!argStream.HasErrors()) { // Find out whether he's on the ground or not and return it - bool bOnGround = pPed->IsOnGround(); + bool bOnGround = pPed->IsOnGround(checkVehicles); lua_pushboolean(luaVM, bOnGround); return 1; } diff --git a/Shared/sdk/SharedUtil.Math.h b/Shared/sdk/SharedUtil.Math.h index bd53f711106..f8d29401321 100644 --- a/Shared/sdk/SharedUtil.Math.h +++ b/Shared/sdk/SharedUtil.Math.h @@ -118,4 +118,25 @@ namespace SharedUtil { return std::fabs(a - b) <= epsilon; } + + inline bool ApproximatelyEqual(float a, float b, float epsilon = std::numeric_limits().epsilon()) noexcept + { + return std::fabs(a - b) <= std::max(std::fabs(a), std::fabs(b)) * epsilon; + } + + inline bool EssentiallyEqual(float a, float b, float epsilon = std::numeric_limits().epsilon()) noexcept + { + return std::fabs(a - b) <= std::min(std::fabs(a), std::fabs(b)) * epsilon; + } + + inline bool DefinitelyGreaterThan(float a, float b, float epsilon = std::numeric_limits().epsilon()) noexcept + { + return (a - b) > std::max(std::fabs(a), std::fabs(b)) * epsilon; + } + + inline bool DefinitelyLessThan(float a, float b, float epsilon = std::numeric_limits().epsilon()) noexcept + { + return (b - a) > std::max(std::fabs(a), std::fabs(b)) * epsilon; + } + } // namespace SharedUtil