raycast around the new position for check a valid dest

This commit is contained in:
Grimdhex
2024-09-22 10:06:29 +02:00
parent c57d97ac9f
commit 70f67db190
5 changed files with 34 additions and 2 deletions

View File

@@ -177,6 +177,17 @@ bool Position::IsPositionValid() const
return Acore::IsValidMapCoord(m_positionX, m_positionY, m_positionZ, m_orientation);
}
bool Position::IsRadiusPositionValid(Unit* caster, Position startPos, float distance) const
{
if (!IsPositionValid())
return false;
if (caster->GetMap()->CheckForObjectsAround(startPos, distance, caster->GetPhaseMask()))
return false;
return true;
}
ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer)
{
float x, y, z, o;

View File

@@ -153,6 +153,7 @@ struct Position
}
[[nodiscard]] bool IsPositionValid() const;
[[nodiscard]] bool IsRadiusPositionValid(Unit* caster, Position startPos, float distance) const;
[[nodiscard]] float GetExactDist2dSq(const float x, const float y) const
{

View File

@@ -2751,6 +2751,25 @@ uint32 Map::GetPlayersCountExceptGMs() const
return count;
}
bool Map::CheckForObjectsAround(Position startPos, float distance, uint32 phasemask) const
{
for (float angle = float(M_PI) / 8; angle < float(M_PI) * 2; angle += float(M_PI) / 8)
{
Position endPos = startPos;
endPos.RelocatePolarOffset(angle, distance);
G3D::Vector3 startVec(startPos.m_positionX, startPos.m_positionY, startPos.m_positionZ);
G3D::Vector3 endVec(endPos.m_positionX, endPos.m_positionY, endPos.m_positionZ);
G3D::Vector3 resultHit;
if (_dynamicTree.GetObjectHitPos(phasemask, startVec, endVec, resultHit, 0.0f))
return true;
}
// No object found in the 16 directions
return false;
}
void Map::SendToPlayers(WorldPacket const* data) const
{
for (MapRefMgr::const_iterator itr = m_mapRefMgr.begin(); itr != m_mapRefMgr.end(); ++itr)

View File

@@ -480,6 +480,8 @@ public:
void AddWorldObject(WorldObject* obj) { i_worldObjects.insert(obj); }
void RemoveWorldObject(WorldObject* obj) { i_worldObjects.erase(obj); }
[[nodiscard]] bool CheckForObjectsAround(Position startPos, float distance, uint32 phasemask) const;
void SendToPlayers(WorldPacket const* data) const;
typedef MapRefMgr PlayerList;

View File

@@ -223,8 +223,7 @@ class spell_mother_shahraz_fatal_attraction : public SpellScript
// Ensure that the destination is not too close to the caster.
// Add a check for LOS, to ensure to not be teleported under the map
while (teleportDest.GetExactDist(GetCaster()) < minDist ||
!GetCaster()->IsWithinLOS(teleportDest.GetPositionX(), teleportDest.GetPositionY(), teleportDest.GetPositionZ()))
while (!teleportDest.IsRadiusPositionValid(GetCaster(), teleportDest, 25.0f))
{
// If the conditions are not met, find a new destination.
teleportDest = GetCaster()->GetRandomNearPosition(teleportDist);