mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 08:28:32 +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
This commit is contained in:
@@ -358,13 +358,25 @@ bool CreatureAI::CheckBoundary(Position const* who) const
|
||||
who = me;
|
||||
|
||||
if (_boundary)
|
||||
for (CreatureBoundary::const_iterator it = _boundary->begin(); it != _boundary->end(); ++it)
|
||||
if (!(*it)->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;
|
||||
}
|
||||
|
||||
bool CreatureAI::CheckInRoom()
|
||||
{
|
||||
if (CheckBoundary())
|
||||
|
||||
@@ -65,7 +65,7 @@ enum SCEquip
|
||||
EQUIP_UNEQUIP = 0
|
||||
};
|
||||
|
||||
typedef std::set<AreaBoundary const*> CreatureBoundary;
|
||||
typedef std::vector<AreaBoundary const*> CreatureBoundary;
|
||||
class TC_GAME_API CreatureAI : public UnitAI
|
||||
{
|
||||
protected:
|
||||
@@ -81,6 +81,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) { _boundary = boundary; me->DoImmediateBoundaryCheck(); }
|
||||
public:
|
||||
enum EvadeReason
|
||||
|
||||
@@ -120,7 +120,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)
|
||||
|
||||
@@ -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,53 @@
|
||||
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) { }
|
||||
: Position(float(x), float(y), float(z), o), DoublePosX(x), DoublePosY(y), DoublePosZ(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(x, y, 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(Position const& pos)
|
||||
: Position(pos), DoublePosX(pos.m_positionX), DoublePosY(pos.m_positionY), DoublePosZ(pos.m_positionZ) { }
|
||||
|
||||
double GetDoubleExactDist2dSq(DoublePosition const& pos) const {
|
||||
double offX = GetDoublePositionX() - pos.GetDoublePositionX();
|
||||
double offY = GetDoublePositionY() - pos.GetDoublePositionY();
|
||||
return (offX*offX) + (offY*offY);
|
||||
double GetDoublePositionX() const { return DoublePosX; }
|
||||
double GetDoublePositionY() const { return DoublePosY; }
|
||||
double GetDoublePositionZ() const { return DoublePosZ; }
|
||||
|
||||
double GetDoubleExactDist2dSq(DoublePosition const& pos) const
|
||||
{
|
||||
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 +82,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 +97,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 +111,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 +125,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 +140,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 +153,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
|
||||
|
||||
@@ -476,15 +476,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 (CreatureBoundary::const_iterator it = boundary->cbegin(); it != boundary->cend(); ++it)
|
||||
if (!(*it)->IsWithinBoundary(&jumpTo))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
Position GetRandomPositionAround(Creature* anubarak)
|
||||
{
|
||||
static float DISTANCE_MIN = 10.0f;
|
||||
@@ -501,7 +492,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