mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 18:15:31 +01:00
Core/AI: AreaBoundary refactor
- Added an auxiliary function IsInBounds to base CreatureAI
- Changed container to vector. Set had no sense because we're storing new pointers, they have different addresses even if the boundary is the same
(cherry picked from commit 2f99fa09c9)
This commit is contained in:
@@ -368,13 +368,25 @@ bool CreatureAI::CheckBoundary(Position const* who) const
|
||||
who = me;
|
||||
|
||||
if (_boundary)
|
||||
for (AreaBoundary const* boundary : *_boundary)
|
||||
if (!boundary->IsWithinBoundary(who))
|
||||
for (AreaBoundary const* areaBoundary : *_boundary)
|
||||
if (!areaBoundary->IsWithinBoundary(who))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreatureAI::IsInBounds(CreatureBoundary const* boundary, Position const* pos)
|
||||
{
|
||||
if (!boundary)
|
||||
return true;
|
||||
|
||||
for (AreaBoundary const* areaBoundary : *boundary)
|
||||
if (!areaBoundary->IsWithinBoundary(pos))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CreatureAI::SetBoundary(CreatureBoundary const* boundary)
|
||||
{
|
||||
_boundary = boundary;
|
||||
|
||||
@@ -31,7 +31,7 @@ class PlayerAI;
|
||||
class WorldObject;
|
||||
struct Position;
|
||||
|
||||
typedef std::set<AreaBoundary const*> CreatureBoundary;
|
||||
typedef std::vector<AreaBoundary const*> CreatureBoundary;
|
||||
|
||||
#define TIME_INTERVAL_LOOK 5000
|
||||
#define VISIBILITY_RANGE 10000
|
||||
@@ -82,6 +82,8 @@ class TC_GAME_API CreatureAI : public UnitAI
|
||||
Creature* DoSummonFlyer(uint32 entry, WorldObject* obj, float flightZ, float radius = 5.0f, uint32 despawnTime = 30000, TempSummonType summonType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
|
||||
|
||||
bool CheckBoundary(Position const* who = nullptr) const;
|
||||
static bool IsInBounds(CreatureBoundary const* boundary, Position const* who);
|
||||
|
||||
void SetBoundary(CreatureBoundary const* boundary);
|
||||
public:
|
||||
enum EvadeReason
|
||||
|
||||
@@ -145,7 +145,7 @@ void InstanceScript::LoadBossBoundaries(const BossBoundaryData& data)
|
||||
{
|
||||
for (BossBoundaryEntry const& entry : data)
|
||||
if (entry.BossId < bosses.size())
|
||||
bosses[entry.BossId].boundary.insert(entry.Boundary);
|
||||
bosses[entry.BossId].boundary.push_back(entry.Boundary);
|
||||
}
|
||||
|
||||
void InstanceScript::LoadMinionData(const MinionData* data)
|
||||
|
||||
@@ -119,7 +119,7 @@ struct ObjectData
|
||||
uint32 type;
|
||||
};
|
||||
|
||||
typedef std::set<AreaBoundary const*> CreatureBoundary;
|
||||
typedef std::vector<AreaBoundary const*> CreatureBoundary;
|
||||
|
||||
struct BossInfo
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
// ---== RECTANGLE ==---
|
||||
RectangleBoundary::RectangleBoundary(float southX, float northX, float eastY, float westY, bool isInverted) :
|
||||
AreaBoundary(BoundaryType::BOUNDARY_RECTANGLE, isInverted), _minX(southX), _maxX(northX), _minY(eastY), _maxY(westY) { }
|
||||
AreaBoundary(isInverted), _minX(southX), _maxX(northX), _minY(eastY), _maxY(westY) { }
|
||||
bool RectangleBoundary::IsWithinBoundaryArea(Position const* pos) const
|
||||
{
|
||||
if (!pos)
|
||||
@@ -40,11 +40,11 @@ bool RectangleBoundary::IsWithinBoundaryArea(Position const* pos) const
|
||||
CircleBoundary::CircleBoundary(Position const& center, double radius, bool isInverted) :
|
||||
CircleBoundary(DoublePosition(center), radius, isInverted) { }
|
||||
CircleBoundary::CircleBoundary(DoublePosition const& center, double radius, bool isInverted) :
|
||||
AreaBoundary(BoundaryType::BOUNDARY_CIRCLE, isInverted), _center(center), _radiusSq(radius*radius) { }
|
||||
AreaBoundary(isInverted), _center(center), _radiusSq(radius*radius) { }
|
||||
CircleBoundary::CircleBoundary(Position const& center, Position const& pointOnCircle, bool isInverted) :
|
||||
CircleBoundary(DoublePosition(center), DoublePosition(pointOnCircle), isInverted) { }
|
||||
CircleBoundary::CircleBoundary(DoublePosition const& center, DoublePosition const& pointOnCircle, bool isInverted) :
|
||||
AreaBoundary(BoundaryType::BOUNDARY_CIRCLE, isInverted), _center(center), _radiusSq(center.GetDoubleExactDist2dSq(pointOnCircle)) { }
|
||||
AreaBoundary(isInverted), _center(center), _radiusSq(center.GetDoubleExactDist2dSq(pointOnCircle)) { }
|
||||
bool CircleBoundary::IsWithinBoundaryArea(Position const* pos) const
|
||||
{
|
||||
if (!pos)
|
||||
@@ -60,7 +60,7 @@ bool CircleBoundary::IsWithinBoundaryArea(Position const* pos) const
|
||||
EllipseBoundary::EllipseBoundary(Position const& center, double radiusX, double radiusY, bool isInverted) :
|
||||
EllipseBoundary(DoublePosition(center), radiusX, radiusY, isInverted) { }
|
||||
EllipseBoundary::EllipseBoundary(DoublePosition const& center, double radiusX, double radiusY, bool isInverted) :
|
||||
AreaBoundary(BoundaryType::BOUNDARY_ELLIPSE, isInverted), _center(center), _radiusYSq(radiusY*radiusY), _scaleXSq(_radiusYSq / (radiusX*radiusX)) { }
|
||||
AreaBoundary(isInverted), _center(center), _radiusYSq(radiusY*radiusY), _scaleXSq(_radiusYSq / (radiusX*radiusX)) { }
|
||||
bool EllipseBoundary::IsWithinBoundaryArea(Position const* pos) const
|
||||
{
|
||||
if (!pos)
|
||||
@@ -75,7 +75,7 @@ bool EllipseBoundary::IsWithinBoundaryArea(Position const* pos) const
|
||||
TriangleBoundary::TriangleBoundary(Position const& pointA, Position const& pointB, Position const& pointC, bool isInverted) :
|
||||
TriangleBoundary(DoublePosition(pointA), DoublePosition(pointB), DoublePosition(pointC), isInverted) { }
|
||||
TriangleBoundary::TriangleBoundary(DoublePosition const& pointA, DoublePosition const& pointB, DoublePosition const& pointC, bool isInverted) :
|
||||
AreaBoundary(BoundaryType::BOUNDARY_TRIANGLE, isInverted), _a(pointA), _b(pointB), _c(pointC), _abx(_b.GetDoublePositionX()-_a.GetDoublePositionX()), _bcx(_c.GetDoublePositionX()-_b.GetDoublePositionX()), _cax(_a.GetDoublePositionX() - _c.GetDoublePositionX()), _aby(_b.GetDoublePositionY()-_a.GetDoublePositionY()), _bcy(_c.GetDoublePositionY()-_b.GetDoublePositionY()), _cay(_a.GetDoublePositionY() - _c.GetDoublePositionY()) { }
|
||||
AreaBoundary(isInverted), _a(pointA), _b(pointB), _c(pointC), _abx(_b.GetDoublePositionX()-_a.GetDoublePositionX()), _bcx(_c.GetDoublePositionX()-_b.GetDoublePositionX()), _cax(_a.GetDoublePositionX() - _c.GetDoublePositionX()), _aby(_b.GetDoublePositionY()-_a.GetDoublePositionY()), _bcy(_c.GetDoublePositionY()-_b.GetDoublePositionY()), _cay(_a.GetDoublePositionY() - _c.GetDoublePositionY()) { }
|
||||
bool TriangleBoundary::IsWithinBoundaryArea(Position const* pos) const
|
||||
{
|
||||
if (!pos)
|
||||
@@ -95,7 +95,7 @@ bool TriangleBoundary::IsWithinBoundaryArea(Position const* pos) const
|
||||
ParallelogramBoundary::ParallelogramBoundary(Position const& cornerA, Position const& cornerB, Position const& cornerD, bool isInverted) :
|
||||
ParallelogramBoundary(DoublePosition(cornerA), DoublePosition(cornerB), DoublePosition(cornerD), isInverted) { }
|
||||
ParallelogramBoundary::ParallelogramBoundary(DoublePosition const& cornerA, DoublePosition const& cornerB, DoublePosition const& cornerD, bool isInverted) :
|
||||
AreaBoundary(BoundaryType::BOUNDARY_PARALLELOGRAM, isInverted), _a(cornerA), _b(cornerB), _d(cornerD), _c(DoublePosition(_d.GetDoublePositionX() + (_b.GetDoublePositionX() - _a.GetDoublePositionX()), _d.GetDoublePositionY() + (_b.GetDoublePositionY() - _a.GetDoublePositionY()))), _abx(_b.GetDoublePositionX() - _a.GetDoublePositionX()), _dax(_a.GetDoublePositionX() - _d.GetDoublePositionX()), _aby(_b.GetDoublePositionY() - _a.GetDoublePositionY()), _day(_a.GetDoublePositionY() - _d.GetDoublePositionY()) { }
|
||||
AreaBoundary(isInverted), _a(cornerA), _b(cornerB), _d(cornerD), _c(DoublePosition(_d.GetDoublePositionX() + (_b.GetDoublePositionX() - _a.GetDoublePositionX()), _d.GetDoublePositionY() + (_b.GetDoublePositionY() - _a.GetDoublePositionY()))), _abx(_b.GetDoublePositionX() - _a.GetDoublePositionX()), _dax(_a.GetDoublePositionX() - _d.GetDoublePositionX()), _aby(_b.GetDoublePositionY() - _a.GetDoublePositionY()), _day(_a.GetDoublePositionY() - _d.GetDoublePositionY()) { }
|
||||
bool ParallelogramBoundary::IsWithinBoundaryArea(Position const* pos) const
|
||||
{
|
||||
if (!pos)
|
||||
@@ -114,7 +114,7 @@ bool ParallelogramBoundary::IsWithinBoundaryArea(Position const* pos) const
|
||||
|
||||
// ---== Z RANGE ==---
|
||||
ZRangeBoundary::ZRangeBoundary(float minZ, float maxZ, bool isInverted) :
|
||||
AreaBoundary(BoundaryType::BOUNDARY_Z_RANGE, isInverted), _minZ(minZ), _maxZ(maxZ) { }
|
||||
AreaBoundary(isInverted), _minZ(minZ), _maxZ(maxZ) { }
|
||||
bool ZRangeBoundary::IsWithinBoundaryArea(Position const* pos) const
|
||||
{
|
||||
if (!pos)
|
||||
|
||||
@@ -23,48 +23,52 @@
|
||||
class TC_GAME_API AreaBoundary
|
||||
{
|
||||
public:
|
||||
enum BoundaryType
|
||||
{
|
||||
BOUNDARY_RECTANGLE, // Rectangle aligned with the coordinate axis
|
||||
BOUNDARY_CIRCLE,
|
||||
BOUNDARY_ELLIPSE,
|
||||
BOUNDARY_TRIANGLE,
|
||||
BOUNDARY_PARALLELOGRAM,
|
||||
BOUNDARY_Z_RANGE,
|
||||
};
|
||||
virtual ~AreaBoundary() { }
|
||||
BoundaryType GetBoundaryType() const { return m_boundaryType; }
|
||||
bool IsWithinBoundary(Position const* pos) const { return (IsWithinBoundaryArea(pos) != m_isInvertedBoundary); }
|
||||
bool IsWithinBoundary(Position const* pos) const { return (IsWithinBoundaryArea(pos) != _isInvertedBoundary); }
|
||||
bool IsWithinBoundary(Position const& pos) const { return IsWithinBoundary(&pos); }
|
||||
|
||||
virtual ~AreaBoundary() { }
|
||||
|
||||
protected:
|
||||
explicit AreaBoundary(bool isInverted) : _isInvertedBoundary(isInverted) { }
|
||||
|
||||
struct DoublePosition : Position
|
||||
{
|
||||
double d_positionX, d_positionY, d_positionZ;
|
||||
DoublePosition(double x = 0.0, double y = 0.0, double z = 0.0, float o = 0.0f)
|
||||
: Position(float(x), float(y), float(z), o), d_positionX(x), d_positionY(y), d_positionZ(z) { }
|
||||
DoublePosition(float x, float y = 0.0f, float z = 0.0f, float o = 0.0f)
|
||||
: Position(x, y, z, o), d_positionX(x), d_positionY(y), d_positionZ(z) { }
|
||||
DoublePosition(Position const & pos)
|
||||
: DoublePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()) { }
|
||||
: Position(float(x), float(y), float(z), o), DoublePosX(x), DoublePosY(y), DoublePosZ(z) { }
|
||||
|
||||
double GetDoublePositionX() const { return d_positionX; }
|
||||
double GetDoublePositionY() const { return d_positionY; }
|
||||
double GetDoublePositionZ() const { return d_positionZ; }
|
||||
DoublePosition(float x, float y = 0.0f, float z = 0.0f, float o = 0.0f)
|
||||
: Position(x, y, z, o), DoublePosX(x), DoublePosY(y), DoublePosZ(z) { }
|
||||
|
||||
DoublePosition(Position const & pos)
|
||||
: Position(pos), DoublePosX(pos.m_positionX), DoublePosY(pos.m_positionY), DoublePosZ(pos.m_positionZ) { }
|
||||
|
||||
double GetDoublePositionX() const { return DoublePosX; }
|
||||
double GetDoublePositionY() const { return DoublePosY; }
|
||||
double GetDoublePositionZ() const { return DoublePosZ; }
|
||||
|
||||
double GetDoubleExactDist2dSq(DoublePosition const& pos) const {
|
||||
double offX = GetDoublePositionX() - pos.GetDoublePositionX();
|
||||
double offY = GetDoublePositionY() - pos.GetDoublePositionY();
|
||||
return (offX*offX) + (offY*offY);
|
||||
double const offX = GetDoublePositionX() - pos.GetDoublePositionX();
|
||||
double const offY = GetDoublePositionY() - pos.GetDoublePositionY();
|
||||
return (offX * offX) + (offY * offY);
|
||||
}
|
||||
|
||||
Position* sync() { m_positionX = (float)d_positionX; m_positionY = (float)d_positionY; m_positionZ = (float)d_positionZ; return this; }
|
||||
Position* sync()
|
||||
{
|
||||
m_positionX = float(DoublePosX);
|
||||
m_positionY = float(DoublePosY);
|
||||
m_positionZ = float(DoublePosZ);
|
||||
return this;
|
||||
}
|
||||
|
||||
double DoublePosX;
|
||||
double DoublePosY;
|
||||
double DoublePosZ;
|
||||
};
|
||||
|
||||
protected:
|
||||
AreaBoundary(BoundaryType bType, bool isInverted) : m_boundaryType(bType), m_isInvertedBoundary(isInverted) { }
|
||||
virtual bool IsWithinBoundaryArea(Position const* pos) const = 0;
|
||||
const BoundaryType m_boundaryType;
|
||||
bool m_isInvertedBoundary;
|
||||
|
||||
private:
|
||||
bool _isInvertedBoundary;
|
||||
};
|
||||
|
||||
class TC_GAME_API RectangleBoundary : public AreaBoundary
|
||||
@@ -77,7 +81,7 @@ class TC_GAME_API RectangleBoundary : public AreaBoundary
|
||||
bool IsWithinBoundaryArea(Position const* pos) const override;
|
||||
|
||||
private:
|
||||
const float _minX, _maxX, _minY, _maxY;
|
||||
float const _minX, _maxX, _minY, _maxY;
|
||||
};
|
||||
|
||||
class TC_GAME_API CircleBoundary : public AreaBoundary
|
||||
@@ -92,8 +96,8 @@ class TC_GAME_API CircleBoundary : public AreaBoundary
|
||||
bool IsWithinBoundaryArea(Position const* pos) const override;
|
||||
|
||||
private:
|
||||
const DoublePosition _center;
|
||||
const double _radiusSq;
|
||||
DoublePosition const _center;
|
||||
double const _radiusSq;
|
||||
};
|
||||
|
||||
class TC_GAME_API EllipseBoundary : public AreaBoundary
|
||||
@@ -106,8 +110,8 @@ class TC_GAME_API EllipseBoundary : public AreaBoundary
|
||||
bool IsWithinBoundaryArea(Position const* pos) const override;
|
||||
|
||||
private:
|
||||
const DoublePosition _center;
|
||||
const double _radiusYSq, _scaleXSq;
|
||||
DoublePosition const _center;
|
||||
double const _radiusYSq, _scaleXSq;
|
||||
};
|
||||
|
||||
class TC_GAME_API TriangleBoundary : public AreaBoundary
|
||||
@@ -120,8 +124,8 @@ class TC_GAME_API TriangleBoundary : public AreaBoundary
|
||||
bool IsWithinBoundaryArea(Position const* pos) const override;
|
||||
|
||||
private:
|
||||
const DoublePosition _a, _b, _c;
|
||||
const double _abx, _bcx, _cax, _aby, _bcy, _cay;
|
||||
DoublePosition const _a, _b, _c;
|
||||
double const _abx, _bcx, _cax, _aby, _bcy, _cay;
|
||||
};
|
||||
|
||||
class TC_GAME_API ParallelogramBoundary : public AreaBoundary
|
||||
@@ -135,8 +139,8 @@ class TC_GAME_API ParallelogramBoundary : public AreaBoundary
|
||||
bool IsWithinBoundaryArea(Position const* pos) const override;
|
||||
|
||||
private:
|
||||
const DoublePosition _a, _b, _d, _c;
|
||||
const double _abx, _dax, _aby, _day;
|
||||
DoublePosition const _a, _b, _d, _c;
|
||||
double const _abx, _dax, _aby, _day;
|
||||
};
|
||||
|
||||
class TC_GAME_API ZRangeBoundary : public AreaBoundary
|
||||
@@ -148,7 +152,7 @@ class TC_GAME_API ZRangeBoundary : public AreaBoundary
|
||||
bool IsWithinBoundaryArea(Position const* pos) const override;
|
||||
|
||||
private:
|
||||
const float _minZ, _maxZ;
|
||||
float const _minZ, _maxZ;
|
||||
};
|
||||
|
||||
#endif //TRINITY_AREA_BOUNDARY_H
|
||||
|
||||
@@ -483,15 +483,6 @@ class npc_anubarak_anub_ar_assassin : public CreatureScript
|
||||
{
|
||||
npc_anubarak_anub_ar_assassinAI(Creature* creature) : npc_anubarak_pet_template(creature, false), _backstabTimer(6 * IN_MILLISECONDS) { }
|
||||
|
||||
bool IsInBounds(Position const& jumpTo, CreatureBoundary const* boundary)
|
||||
{
|
||||
if (!boundary)
|
||||
return true;
|
||||
for (AreaBoundary const* it : *boundary)
|
||||
if (!it->IsWithinBoundary(&jumpTo))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
Position GetRandomPositionAround(Creature* anubarak)
|
||||
{
|
||||
static float DISTANCE_MIN = 10.0f;
|
||||
@@ -508,7 +499,7 @@ class npc_anubarak_anub_ar_assassin : public CreatureScript
|
||||
Position jumpTo;
|
||||
do
|
||||
jumpTo = GetRandomPositionAround(anubarak);
|
||||
while (!IsInBounds(jumpTo, boundary));
|
||||
while (!CreatureAI::IsInBounds(boundary, &jumpTo));
|
||||
me->GetMotionMaster()->MoveJump(jumpTo, 40.0f, 40.0f);
|
||||
DoCastSelf(SPELL_ASSASSIN_VISUAL, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user