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:
ariel-
2017-03-28 01:52:49 -03:00
committed by funjoker
parent 124b014f40
commit 3f79c9f696
7 changed files with 70 additions and 61 deletions

View File

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

View File

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

View File

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

View File

@@ -119,7 +119,7 @@ struct ObjectData
uint32 type;
};
typedef std::set<AreaBoundary const*> CreatureBoundary;
typedef std::vector<AreaBoundary const*> CreatureBoundary;
struct BossInfo
{

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

View File

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