mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Generalise dragon flanking action
This commit is contained in:
@@ -94,6 +94,7 @@ public:
|
||||
creators["avoid aoe"] = &ActionContext::avoid_aoe;
|
||||
creators["combat formation move"] = &ActionContext::combat_formation_move;
|
||||
creators["tank face"] = &ActionContext::tank_face;
|
||||
creators["rear flank"] = &ActionContext::rear_flank;
|
||||
creators["disperse set"] = &ActionContext::disperse_set;
|
||||
creators["gift of the naaru"] = &ActionContext::gift_of_the_naaru;
|
||||
creators["shoot"] = &ActionContext::shoot;
|
||||
@@ -278,6 +279,7 @@ private:
|
||||
static Action* avoid_aoe(PlayerbotAI* botAI) { return new AvoidAoeAction(botAI); }
|
||||
static Action* combat_formation_move(PlayerbotAI* botAI) { return new CombatFormationMoveAction(botAI); }
|
||||
static Action* tank_face(PlayerbotAI* botAI) { return new TankFaceAction(botAI); }
|
||||
static Action* rear_flank(PlayerbotAI* botAI) { return new RearFlankAction(botAI); }
|
||||
static Action* disperse_set(PlayerbotAI* botAI) { return new DisperseSetAction(botAI); }
|
||||
static Action* gift_of_the_naaru(PlayerbotAI* botAI) { return new CastGiftOfTheNaaruAction(botAI); }
|
||||
static Action* lifeblood(PlayerbotAI* botAI) { return new CastLifeBloodAction(botAI); }
|
||||
|
||||
@@ -2372,6 +2372,46 @@ bool TankFaceAction::Execute(Event event)
|
||||
return MoveTo(bot->GetMapId(), nearest.GetPositionX(), nearest.GetPositionY(), nearest.GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
|
||||
bool RearFlankAction::isUseful()
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target) { return false; }
|
||||
|
||||
// Need to double the front angle check to account for mirrored angle.
|
||||
bool inFront = target->HasInArc(2.f * minAngle, bot);
|
||||
// Rear check does not need to double this angle as the logic is inverted
|
||||
// and we are subtracting from 2pi.
|
||||
bool inRear = !target->HasInArc((2.f * M_PI) - maxAngle, bot);
|
||||
|
||||
return inFront || inRear;
|
||||
}
|
||||
|
||||
bool RearFlankAction::Execute(Event event)
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target) { return false; }
|
||||
|
||||
float angle = frand(minAngle, maxAngle);
|
||||
float baseDistance = bot->GetMeleeRange(target) * 0.5f;
|
||||
Position leftFlank = target->GetPosition();
|
||||
Position rightFlank = target->GetPosition();
|
||||
Position* destination = nullptr;
|
||||
leftFlank.RelocatePolarOffset(angle, baseDistance + distance);
|
||||
rightFlank.RelocatePolarOffset(-angle, baseDistance + distance);
|
||||
|
||||
if (bot->GetExactDist2d(leftFlank) < bot->GetExactDist2d(rightFlank))
|
||||
{
|
||||
destination = &leftFlank;
|
||||
}
|
||||
else
|
||||
{
|
||||
destination = &rightFlank;
|
||||
}
|
||||
|
||||
return MoveTo(bot->GetMapId(), destination->GetPositionX(), destination->GetPositionY(), destination->GetPositionZ(),
|
||||
false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
|
||||
bool DisperseSetAction::Execute(Event event)
|
||||
{
|
||||
std::string const text = event.getParam();
|
||||
|
||||
@@ -18,6 +18,9 @@ class Unit;
|
||||
class WorldObject;
|
||||
class Position;
|
||||
|
||||
#define ANGLE_45_DEG (static_cast<float>(M_PI) / 4.f)
|
||||
#define ANGLE_90_DEG M_PI_2
|
||||
#define ANGLE_120_DEG (2.f * static_cast<float>(M_PI) / 3.f)
|
||||
|
||||
class MovementAction : public Action
|
||||
{
|
||||
@@ -144,6 +147,27 @@ public:
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class RearFlankAction : public MovementAction
|
||||
{
|
||||
// 90 degree minimum angle prevents any frontal cleaves/breaths and avoids parry-hasting the boss.
|
||||
// 120 degree maximum angle leaves a 120 degree symmetrical cone at the tail end which is usually enough to avoid tail swipes.
|
||||
// Some dragons or mobs may have different danger zone angles, override if needed.
|
||||
public:
|
||||
RearFlankAction(PlayerbotAI* botAI, float distance = 0.0f, float minAngle = ANGLE_90_DEG, float maxAngle = ANGLE_120_DEG)
|
||||
: MovementAction(botAI, "rear flank")
|
||||
{
|
||||
this->distance = distance;
|
||||
this->minAngle = minAngle;
|
||||
this->maxAngle = maxAngle;
|
||||
}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
|
||||
protected:
|
||||
float distance, minAngle, maxAngle;
|
||||
};
|
||||
|
||||
class DisperseSetAction : public Action
|
||||
{
|
||||
public:
|
||||
@@ -268,4 +292,5 @@ public:
|
||||
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user