diff --git a/Client/mods/deathmatch/logic/CClientPed.cpp b/Client/mods/deathmatch/logic/CClientPed.cpp index 959a462021..7774a38b4e 100644 --- a/Client/mods/deathmatch/logic/CClientPed.cpp +++ b/Client/mods/deathmatch/logic/CClientPed.cpp @@ -4666,12 +4666,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 17a519f50a..b897b53915 100644 --- a/Client/mods/deathmatch/logic/CClientPed.h +++ b/Client/mods/deathmatch/logic/CClientPed.h @@ -379,7 +379,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 9d1dab664d..de3ad74321 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/mods/deathmatch/logic/Utils.cpp b/Shared/mods/deathmatch/logic/Utils.cpp index e3107c77a6..9152faef05 100644 --- a/Shared/mods/deathmatch/logic/Utils.cpp +++ b/Shared/mods/deathmatch/logic/Utils.cpp @@ -1102,3 +1102,23 @@ CVector ConvertEulerRotationOrder(const CVector& a_vRotation, eEulerRotationOrde return a_vRotation; } } + +bool approximatelyEqual(float a, float b, float epsilon) +{ + return std::fabs(a - b) <= std::max(std::fabs(a), std::fabs(b)) * epsilon; +} + +bool essentiallyEqual(float a, float b, float epsilon) +{ + return std::fabs(a - b) <= std::min(std::fabs(a), std::fabs(b)) * epsilon; +} + +bool definitelyGreaterThan(float a, float b, float epsilon) +{ + return (a - b) > std::max(std::fabs(a), std::fabs(b)) * epsilon; +} + +bool definitelyLessThan(float a, float b, float epsilon) +{ + return (b - a) > std::max(std::fabs(a), std::fabs(b)) * epsilon; +} diff --git a/Shared/mods/deathmatch/logic/Utils.h b/Shared/mods/deathmatch/logic/Utils.h index 8afade98c8..5019268c1a 100644 --- a/Shared/mods/deathmatch/logic/Utils.h +++ b/Shared/mods/deathmatch/logic/Utils.h @@ -336,3 +336,9 @@ void DeletePointersAndClearList(T& elementList) delete *iter; } } + +// Comparing floating point numbers +bool approximatelyEqual(float a, float b, float epsilon = FLOAT_EPSILON); +bool essentiallyEqual(float a, float b, float epsilon = FLOAT_EPSILON); +bool definitelyGreaterThan(float a, float b, float epsilon = FLOAT_EPSILON); +bool definitelyLessThan(float a, float b, float epsilon = FLOAT_EPSILON);