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:
ariel-
2017-03-28 01:52:49 -03:00
parent 97e54fe458
commit 2f99fa09c9
6 changed files with 70 additions and 60 deletions

View File

@@ -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())

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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);
}