From d3e7026e2ef04af115c6da054be59a5adb16cee0 Mon Sep 17 00:00:00 2001 From: ratkosrb Date: Thu, 16 Nov 2023 17:45:59 +0200 Subject: [PATCH] Use center of gameobject model as collision height. --- src/game/Objects/GameObject.cpp | 8 ++++++++ src/game/Objects/GameObject.h | 1 + src/game/Objects/Object.cpp | 6 +++--- src/game/Objects/Object.h | 1 + src/game/Objects/Unit.h | 2 +- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/game/Objects/GameObject.cpp b/src/game/Objects/GameObject.cpp index 685796817ff..b8b0249e33b 100644 --- a/src/game/Objects/GameObject.cpp +++ b/src/game/Objects/GameObject.cpp @@ -2541,6 +2541,14 @@ void GameObject::GetClosestChairSlotPosition(float userX, float userY, float& ou outY = GetPositionY(); } +float GameObject::GetCollisionHeight() const +{ + // use the center of the model + if (GameObjectDisplayInfoAddon const* displayInfo = sGameObjectDisplayInfoAddonStorage.LookupEntry(GetDisplayId())) + return (displayInfo->max_z + displayInfo->min_z) * 0.5f * GetObjectScale(); + return 1.0f; +} + bool GameObject::IsAtInteractDistance(Position const& pos, float radius) const { if (GameObjectDisplayInfoAddon const* displayInfo = sGameObjectDisplayInfoAddonStorage.LookupEntry(GetDisplayId())) diff --git a/src/game/Objects/GameObject.h b/src/game/Objects/GameObject.h index dfb3355de46..b1f82c80b56 100644 --- a/src/game/Objects/GameObject.h +++ b/src/game/Objects/GameObject.h @@ -250,6 +250,7 @@ class GameObject : public SpellCaster uint32 GetFactionTemplateId() const final { return GetGOInfo()->faction; } uint32 GetLevel() const final ; + float GetCollisionHeight() const final; bool IsAtInteractDistance(Position const& pos, float radius) const; bool IsAtInteractDistance(Player const* player, uint32 maxRange = 0) const; diff --git a/src/game/Objects/Object.cpp b/src/game/Objects/Object.cpp index 2b8188864e5..e3f632cd3b3 100644 --- a/src/game/Objects/Object.cpp +++ b/src/game/Objects/Object.cpp @@ -1617,7 +1617,7 @@ bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, bool checkDynLos) con return true; float ox, oy, oz; obj->GetPosition(ox, oy, oz); - float targetHeight = obj->IsUnit() ? obj->ToUnit()->GetCollisionHeight() : 2.f; + float targetHeight = obj->GetCollisionHeight(); return (IsWithinLOS(ox, oy, oz, checkDynLos, targetHeight)); } @@ -1625,7 +1625,7 @@ bool WorldObject::IsWithinLOSAtPosition(float ownX, float ownY, float ownZ, floa { if (IsInWorld()) { - float height = IsUnit() ? ToUnit()->GetCollisionHeight() : 2.f; + float height = GetCollisionHeight(); return GetMap()->isInLineOfSight(ownX, ownY, ownZ + height, targetX, targetY, targetZ + targetHeight, checkDynLos); } @@ -2005,7 +2005,7 @@ void WorldObject::MovePositionToFirstCollision(Position& pos, float dist, float GenericTransport* transport = GetTransport(); - float halfHeight = IsUnit() ? static_cast(this)->GetCollisionHeight() : 0.0f; + float halfHeight = GetCollisionHeight(); if (IsUnit()) { PathFinder path(static_cast(this)); diff --git a/src/game/Objects/Object.h b/src/game/Objects/Object.h index e7a19574a8c..f2a7c64bba1 100644 --- a/src/game/Objects/Object.h +++ b/src/game/Objects/Object.h @@ -723,6 +723,7 @@ class WorldObject : public Object // angle to face `obj` to `this` using distance includes size of `obj` GetNearPoint(obj, x, y, z, obj->GetObjectBoundingRadius(), distance2d, GetAngle(obj)); } + virtual float GetCollisionHeight() const { return 1.0f; } virtual float GetObjectBoundingRadius() const { return DEFAULT_WORLD_OBJECT_SIZE; } virtual float GetCombatReach() const { return 0.f; } diff --git a/src/game/Objects/Unit.h b/src/game/Objects/Unit.h index 8bf08a49031..6ee9300075c 100644 --- a/src/game/Objects/Unit.h +++ b/src/game/Objects/Unit.h @@ -553,7 +553,7 @@ class Unit : public SpellCaster void ResetTransformScale(); float GetNativeScale() const; void SetNativeScale(float scale); - float GetCollisionHeight() const { return m_modelCollisionHeight * m_nativeScaleOverride; } + float GetCollisionHeight() const final { return m_modelCollisionHeight * m_nativeScaleOverride; } float GetMinSwimDepth() const { return GetCollisionHeight() * 0.75f; } // client switches to swim animation at this depth static float GetScaleForDisplayId(uint32 displayId); void UpdateModelData(); // at any changes to scale and/or displayId