refactor to remove the while loop

This commit is contained in:
Grimdhex
2024-09-25 18:47:17 +02:00
parent 93a5a5570d
commit 0d1ded2ea0
7 changed files with 30 additions and 46 deletions

View File

@@ -2739,6 +2739,34 @@ Position WorldObject::GetRandomNearPosition(float radius)
return pos;
}
Position WorldObject::GetRandomNearPositionWithCollisionCheck(Unit* caster, float radius)
{
Position pos = GetRandomNearPosition(radius);
for (float angle = float(M_PI) / 8; angle < float(M_PI) * 2; angle += float(M_PI) / 8)
{
Position endPos = pos;
endPos.RelocatePolarOffset(angle, radius);
G3D::Vector3 hitResult;
if (GetMap()->GetObjectHitPos(caster->GetPhaseMask(), pos.m_positionX, pos.m_positionY, pos.m_positionZ,
endPos.m_positionX, endPos.m_positionY, endPos.m_positionZ,
hitResult.x, hitResult.y, hitResult.z, 0.0f))
{
G3D::Vector3 newPos;
newPos.x = 2 * pos.GetPositionX() - endPos.GetPositionX();
newPos.y = 2 * pos.GetPositionY() - endPos.GetPositionY();
newPos.z = 2 * pos.GetPositionZ() - endPos.GetPositionZ();
pos.Relocate(newPos.x, newPos.y, newPos.z);
break;
}
}
return pos;
}
void WorldObject::GetContactPoint(WorldObject const* obj, float& x, float& y, float& z, float distance2d) const
{
// angle to face `obj` to `this` using distance includes size of `obj`

View File

@@ -427,6 +427,7 @@ public:
Position GetFirstCollisionPosition(float destX, float destY, float destZ);
Position GetFirstCollisionPosition(float dist, float angle);
Position GetRandomNearPosition(float radius);
Position GetRandomNearPositionWithCollisionCheck(Unit* caster, float radius);
void GetContactPoint(WorldObject const* obj, float& x, float& y, float& z, float distance2d = CONTACT_DISTANCE) const;
void GetChargeContactPoint(WorldObject const* obj, float& x, float& y, float& z, float distance2d = CONTACT_DISTANCE) const;

View File

@@ -177,17 +177,6 @@ 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,7 +153,6 @@ 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,25 +2751,6 @@ 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
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,8 +480,6 @@ 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

@@ -212,19 +212,7 @@ class spell_mother_shahraz_fatal_attraction : public SpellScript
void SetDest(SpellDestination& dest)
{
// Initialize a first destination
Position teleportDest = GetCaster()->GetRandomNearPosition(50.0f);
// 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.IsRadiusPositionValid(GetCaster(), teleportDest, 25.0f))
{
// If the conditions are not met, find a new destination.
teleportDest = GetCaster()->GetRandomNearPosition(50.0f);
}
// When a valid destination is found, relocate it.
dest.Relocate(teleportDest);
dest.Relocate(GetCaster()->GetRandomNearPositionWithCollisionCheck(GetCaster(), 50.0f));
}
void HandleTeleportUnits(SpellEffIndex /*effIndex*/)