diff options
-rw-r--r-- | src/common/Collision/DynamicTree.cpp | 22 | ||||
-rw-r--r-- | src/common/Collision/Models/GameObjectModel.cpp | 8 | ||||
-rw-r--r-- | src/common/Collision/Models/GameObjectModel.h | 15 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 12 |
4 files changed, 42 insertions, 15 deletions
diff --git a/src/common/Collision/DynamicTree.cpp b/src/common/Collision/DynamicTree.cpp index c2d84e06864..dc21ebc44d8 100644 --- a/src/common/Collision/DynamicTree.cpp +++ b/src/common/Collision/DynamicTree.cpp @@ -143,7 +143,25 @@ struct DynamicTreeIntersectionCallback bool operator()(G3D::Ray const& r, GameObjectModel const& obj, float& distance) { - _didHit = obj.intersectRay(r, distance, true, _phaseShift, VMAP::ModelIgnoreFlags::Nothing); + _didHit = obj.IntersectRay(r, distance, true, _phaseShift, VMAP::ModelIgnoreFlags::Nothing); + return _didHit; + } + + bool didHit() const { return _didHit; } + +private: + bool _didHit; + PhaseShift const& _phaseShift; +}; + +struct DynamicTreeLosCallback +{ + DynamicTreeLosCallback(PhaseShift const& phaseShift) : _didHit(false), _phaseShift(phaseShift) { } + + bool operator()(G3D::Ray const& r, GameObjectModel const& obj, float& distance) + { + if (!obj.IsLosBlockingDisabled()) + _didHit = obj.IntersectRay(r, distance, true, _phaseShift, VMAP::ModelIgnoreFlags::Nothing); return _didHit; } @@ -229,7 +247,7 @@ bool DynamicMapTree::isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 return true; G3D::Ray r(startPos, (endPos - startPos) / maxDist); - DynamicTreeIntersectionCallback callback(phaseShift); + DynamicTreeLosCallback callback(phaseShift); impl->intersectRay(r, callback, maxDist, endPos); return !callback.didHit(); diff --git a/src/common/Collision/Models/GameObjectModel.cpp b/src/common/Collision/Models/GameObjectModel.cpp index 24e9489326e..b32a5bdd44f 100644 --- a/src/common/Collision/Models/GameObjectModel.cpp +++ b/src/common/Collision/Models/GameObjectModel.cpp @@ -152,14 +152,14 @@ GameObjectModel* GameObjectModel::Create(std::unique_ptr<GameObjectModelOwnerBas return mdl; } -bool GameObjectModel::isMapObject() const +bool GameObjectModel::IsMapObject() const { return !iModel->IsM2(); } -bool GameObjectModel::intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift, VMAP::ModelIgnoreFlags ignoreFlags) const +bool GameObjectModel::IntersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift, VMAP::ModelIgnoreFlags ignoreFlags) const { - if (!isCollisionEnabled() || !owner->IsSpawned()) + if (!IsCollisionEnabled() || !owner->IsSpawned()) return false; if (!owner->IsInPhase(phaseShift)) @@ -184,7 +184,7 @@ bool GameObjectModel::intersectRay(G3D::Ray const& ray, float& maxDist, bool sto bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, PhaseShift const& phaseShift) const { - if (!isCollisionEnabled() || !owner->IsSpawned() || !isMapObject()) + if (!IsCollisionEnabled() || !owner->IsSpawned() || !IsMapObject()) return false; if (!owner->IsInPhase(phaseShift)) diff --git a/src/common/Collision/Models/GameObjectModel.h b/src/common/Collision/Models/GameObjectModel.h index 1cfe27a050e..8a315e8b7d5 100644 --- a/src/common/Collision/Models/GameObjectModel.h +++ b/src/common/Collision/Models/GameObjectModel.h @@ -59,7 +59,7 @@ public: class TC_COMMON_API GameObjectModel /*, public Intersectable*/ { - GameObjectModel() : _collisionEnabled(false), iInvScale(0), iScale(0), iModel(nullptr) { } + GameObjectModel() : iCollisionEnabled(false), iInvScale(0), iScale(0), iModel(nullptr) { } public: const G3D::AABox& getBounds() const { return iBound; } @@ -68,12 +68,14 @@ public: const G3D::Vector3& getPosition() const { return iPos;} /* Enables/disables collision */ - void enableCollision(bool enable) { _collisionEnabled = enable; } - bool isCollisionEnabled() const { return _collisionEnabled; } - bool isMapObject() const; + void EnableCollision(bool enable) { iCollisionEnabled = enable; } + bool IsCollisionEnabled() const { return iCollisionEnabled; } + void DisableLosBlocking(bool enable) { iLosBlockingDisabled = enable; } + bool IsLosBlockingDisabled() const { return iLosBlockingDisabled; } + bool IsMapObject() const; uint8 GetNameSetId() const { return owner->GetNameSetId(); } - bool intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift, VMAP::ModelIgnoreFlags ignoreFlags) const; + bool IntersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift, VMAP::ModelIgnoreFlags ignoreFlags) const; bool GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, PhaseShift const& phaseShift) const; bool GetLiquidLevel(G3D::Vector3 const& point, VMAP::LocationInfo& info, float& liqHeight) const; @@ -84,7 +86,8 @@ public: private: bool initialize(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath); - bool _collisionEnabled; + bool iCollisionEnabled; ///< Is model ignored in all checks + bool iLosBlockingDisabled; ///< Is model ignored during line of sight checks (but is always included in location/height checks) G3D::AABox iBound; G3D::Matrix3 iInvRot; G3D::Vector3 iPos; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 4528293fdfa..a8903ee3c9f 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -3935,7 +3935,7 @@ void GameObject::EnableCollision(bool enable) /*if (enable && !GetMap()->ContainsGameObjectModel(*m_model)) GetMap()->InsertGameObjectModel(*m_model);*/ - m_model->enableCollision(enable); + m_model->EnableCollision(enable); } void GameObject::UpdateModel() @@ -4480,8 +4480,14 @@ void GameObject::HandleCustomTypeCommand(GameObjectTypeBase::CustomCommand const void GameObject::CreateModel() { m_model = GameObjectModel::Create(std::make_unique<GameObjectModelOwnerImpl>(this), sWorld->GetDataPath()); - if (m_model && m_model->isMapObject()) - SetFlag(GO_FLAG_MAP_OBJECT); + if (m_model) + { + if (m_model->IsMapObject()) + SetFlag(GO_FLAG_MAP_OBJECT); + + if (GetGoType() == GAMEOBJECT_TYPE_DOOR) + m_model->DisableLosBlocking(GetGOInfo()->door.NotLOSBlocking); + } } std::string GameObject::GetDebugInfo() const |