diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index eae1a60c..1a080470 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -2570,7 +2570,7 @@ void Creature::OnLand() glm::vec3 point; bool ok = false; for (int i = 0; i < 10; ++i) { - ok = room->map_instance->FindNearestPoint(center, 1.0f + 10 * i, point); + ok = room->map_instance->FindConnectableNearestPoint(center, 1.0f + 10 * i, point); if (ok) { break; } diff --git a/server/gameserver/mapinstance.cc b/server/gameserver/mapinstance.cc index 21fe9e29..a12faaa8 100644 --- a/server/gameserver/mapinstance.cc +++ b/server/gameserver/mapinstance.cc @@ -72,6 +72,20 @@ static void TraverseMapColliderNode(mc::ColliderNode* node, std::functionIsConnectablePoly(ref); + } + +}; + void MapInstance::Init() { map_meta_ = mt::Map::GetById(map_id); @@ -435,6 +449,34 @@ bool MapInstance::FindNearestPoint(const glm::vec3& center, float radius, glm::v return true; } +bool MapInstance::FindConnectableNearestPoint(const glm::vec3& center, float radius, glm::vec3& nearest_pt) +{ + dtPolyRef startRef = INVALID_NAVMESH_POLYREF; + + ConnectableQueryFilter filter; + filter.map_instance = this; + filter.setIncludeFlags(0xffff); + filter.setExcludeFlags(0); + + const float extents[3] = {radius, 10.0f, radius}; + float nearestPt[3]; + + float pos[3]; + pos[0] = center.x; + pos[1] = center.y; + pos[2] = center.z; + + navmesh_query_->findNearestPoly(pos, extents, &filter, &startRef, nearestPt); + if (!startRef) { + return false; + } + + nearest_pt.x = nearestPt[0]; + nearest_pt.y = nearestPt[1]; + nearest_pt.z = nearestPt[2]; + return true; +} + bool MapInstance::GetPosHeight(const Position& pos, float& out_height) { dtPolyRef startRef = INVALID_NAVMESH_POLYREF; @@ -1122,7 +1164,8 @@ void MapInstance::AdjustOnLandPoint(glm::vec3& point) const float extents[3] = {4.0f/10.0f, 100.0f, 4.0f/10.0f}; - dtQueryFilter filter; + ConnectableQueryFilter filter; + filter.map_instance = this; filter.setIncludeFlags(0xffff); filter.setExcludeFlags(0); @@ -1247,3 +1290,8 @@ void MapInstance::MarkConnectablePolys() } } } + +bool MapInstance::IsConnectablePoly(dtPolyRef poly_ref) +{ + return connectable_polys_.find(poly_ref) != connectable_polys_.end(); +} diff --git a/server/gameserver/mapinstance.h b/server/gameserver/mapinstance.h index 8188e0ef..02ec160f 100644 --- a/server/gameserver/mapinstance.h +++ b/server/gameserver/mapinstance.h @@ -48,6 +48,7 @@ class MapInstance : public std::enable_shared_from_this int& same_polys_flags, std::vector& spec_polys, unsigned short exclude_flags); bool FindNearestPoint(const glm::vec3& center, float radius, glm::vec3& nearestPt); + bool FindConnectableNearestPoint(const glm::vec3& center, float radius, glm::vec3& nearestPt); bool GetPosHeight(const Position& pos, float& out_height); dtPoly* GetPoly(glm::vec3 pos, int& poly_idx); void Scale(glm::vec3& v); @@ -60,6 +61,7 @@ class MapInstance : public std::enable_shared_from_this glm::vec3& hit_pos, float& ray_length); bool GetNearestGrass(const glm::vec3& center, glm::vec3& out_pt); void AdjustOnLandPoint(glm::vec3& point); + bool IsConnectablePoly(dtPolyRef poly_ref); private: void LoadHouse();