raycast around the new position for check a valid dest
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user