- Added Thorim strategy (#1305)

This commit is contained in:
kadeshar
2025-05-17 15:03:17 +02:00
committed by GitHub
parent 9641092078
commit e2b5ab766d
7 changed files with 960 additions and 1 deletions

View File

@@ -45,7 +45,13 @@ public:
creators["freya nature resistance action"] = &RaidUlduarActionContext::freya_nature_resistance_action;
creators["freya mark dps target action"] = &RaidUlduarActionContext::freya_mark_dps_target_action;
creators["freya move to healing spore action"] = &RaidUlduarActionContext::freya_move_to_healing_spore_action;
creators["thorim frost resistance action"] = &RaidUlduarActionContext::thorim_frost_resistance_action;
creators["thorim nature resistance action"] = &RaidUlduarActionContext::thorim_nature_resistance_action;
creators["thorim unbalancing strike action"] = &RaidUlduarActionContext::thorim_unbalancing_strike_action;
creators["thorim mark dps target action"] = &RaidUlduarActionContext::thorim_mark_dps_target_action;
creators["thorim arena positioning action"] = &RaidUlduarActionContext::thorim_arena_positioning_action;
creators["thorim gauntlet positioning action"] = &RaidUlduarActionContext::thorim_gauntlet_positioning_action;
creators["thorim phase 2 positioning action"] = &RaidUlduarActionContext::thorim_phase2_positioning_action;
creators["mimiron fire resistance action"] = &RaidUlduarActionContext::mimiron_fire_resistance_action;
}
@@ -79,7 +85,13 @@ private:
static Action* freya_nature_resistance_action(PlayerbotAI* ai) { return new BossNatureResistanceAction(ai, "freya"); }
static Action* freya_mark_dps_target_action(PlayerbotAI* ai) { return new FreyaMarkDpsTargetAction(ai); }
static Action* freya_move_to_healing_spore_action(PlayerbotAI* ai) { return new FreyaMoveToHealingSporeAction(ai); }
static Action* thorim_frost_resistance_action(PlayerbotAI* ai) { return new BossFrostResistanceAction(ai, "thorim"); }
static Action* thorim_nature_resistance_action(PlayerbotAI* ai) { return new BossNatureResistanceAction(ai, "thorim"); }
static Action* thorim_unbalancing_strike_action(PlayerbotAI* ai) { return new ThorimUnbalancingStrikeAction(ai); }
static Action* thorim_mark_dps_target_action(PlayerbotAI* ai) { return new ThorimMarkDpsTargetAction(ai); }
static Action* thorim_arena_positioning_action(PlayerbotAI* ai) { return new ThorimArenaPositioningAction(ai); }
static Action* thorim_gauntlet_positioning_action(PlayerbotAI* ai) { return new ThorimGauntletPositioningAction(ai); }
static Action* thorim_phase2_positioning_action(PlayerbotAI* ai) { return new ThorimPhase2PositioningAction(ai); }
static Action* mimiron_fire_resistance_action(PlayerbotAI* ai) { return new BossFireResistanceAction(ai, "mimiron"); }
};

View File

@@ -1,6 +1,8 @@
#include "RaidUlduarActions.h"
#include <FollowMasterStrategy.h>
#include <cmath>
#include "AiObjectContext.h"
@@ -25,6 +27,9 @@
#include "Unit.h"
#include "Vehicle.h"
const std::string ADD_STRATEGY_CHAR = "+";
const std::string REMOVE_STRATEGY_CHAR = "-";
const std::vector<uint32> availableVehicles = {NPC_VEHICLE_CHOPPER, NPC_SALVAGED_DEMOLISHER,
NPC_SALVAGED_DEMOLISHER_TURRET, NPC_SALVAGED_SIEGE_ENGINE,
NPC_SALVAGED_SIEGE_ENGINE_TURRET};
@@ -35,6 +40,8 @@ const std::vector<Position> corners = {
const Position ULDUAR_KOLOGARN_RESTORE_POSITION = Position(1764.3749f, -24.02903f, 448.0f, 0.00087690353f);
const Position ULDUAR_KOLOGARN_EYEBEAM_LEFT_POSITION = Position(1781.2051f, 9.34402f, 449.0f, 0.00087690353f);
const Position ULDUAR_KOLOGARN_EYEBEAM_RIGHT_POSITION = Position(1763.2561f, -24.44305f, 449.0f, 0.00087690353f);
const Position ULDUAR_THORIM_JUMP_START_POINT = Position(2137.137f, -291.19025f, 438.24753f, 1.7059844f);
const Position ULDUAR_THORIM_JUMP_END_POINT = Position(2137.8818f, -278.18942f, 419.66653f);
bool FlameLeviathanVehicleAction::Execute(Event event)
{
@@ -1769,3 +1776,393 @@ bool FreyaMoveToHealingSporeAction::Execute(Event event)
return MoveTo(nearestSpore->GetMapId(), nearestSpore->GetPositionX(), nearestSpore->GetPositionY(),
nearestSpore->GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
}
bool ThorimUnbalancingStrikeAction::isUseful()
{
ThorimUnbalancingStrikeTrigger thorimUnbalancingStrikeTrigger(botAI);
return thorimUnbalancingStrikeTrigger.IsActive();
}
bool ThorimUnbalancingStrikeAction::Execute(Event event)
{
bot->RemoveAura(SPELL_UNBALANCING_STRIKE);
return true;
}
bool ThorimMarkDpsTargetAction::isUseful()
{
ThorimMarkDpsTargetTrigger thorimMarkDpsTargetTrigger(botAI);
return thorimMarkDpsTargetTrigger.IsActive();
}
bool ThorimMarkDpsTargetAction::Execute(Event event)
{
Unit* targetToMark = nullptr;
Group* group = bot->GetGroup();
if (!group)
return false;
ObjectGuid currentMoonTarget = group->GetTargetIcon(moonIndex);
Unit* currentMoonUnit = botAI->GetUnit(currentMoonTarget);
Unit* boss = AI_VALUE2(Unit*, "find target", "thorim");
if (!currentMoonUnit && boss && boss->IsAlive() && boss->GetPositionZ() > ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD)
{
group->SetTargetIcon(moonIndex, bot->GetGUID(), boss->GetGUID());
}
if (currentMoonUnit && boss && currentMoonUnit->GetEntry() == boss->GetEntry() &&
boss->GetPositionZ() < ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD)
{
group->SetTargetIcon(skullIndex, bot->GetGUID(), boss->GetGUID());
return true;
}
if (botAI->IsMainTank(bot))
{
ObjectGuid currentSkullTarget = group->GetTargetIcon(skullIndex);
Unit* currentSkullUnit = botAI->GetUnit(currentSkullTarget);
if (currentSkullUnit && !currentSkullUnit->IsAlive())
{
currentSkullUnit = nullptr;
}
Unit* acolyte = AI_VALUE2(Unit*, "find target", "dark rune acolyte");
Unit* evoker = AI_VALUE2(Unit*, "find target", "dark rune evoker");
if (acolyte && acolyte->IsAlive() && bot->GetDistance(acolyte) < 50.0f &&
(!currentSkullUnit || currentSkullUnit->GetEntry() != acolyte->GetEntry()))
targetToMark = acolyte;
else if (evoker && evoker->IsAlive() && bot->GetDistance(evoker) < 50.0f &&
(!currentSkullUnit || currentSkullUnit->GetEntry() != evoker->GetEntry()))
targetToMark = evoker;
else
return false;
}
else if (botAI->IsAssistTankOfIndex(bot, 0))
{
ObjectGuid currentCrossTarget = group->GetTargetIcon(crossIndex);
Unit* currentCrossUnit = botAI->GetUnit(currentCrossTarget);
if (currentCrossUnit && !currentCrossUnit->IsAlive())
{
currentCrossUnit = nullptr;
}
Unit* acolyte = AI_VALUE2(Unit*, "find target", "dark rune acolyte");
Unit* runicColossus = AI_VALUE2(Unit*, "find target", "runic colossus");
Unit* ancientRuneGiant = AI_VALUE2(Unit*, "find target", "ancient rune giant");
Unit* ironHonorGuard = AI_VALUE2(Unit*, "find target", "iron ring guard");
Unit* ironRingGuard = AI_VALUE2(Unit*, "find target", "iron honor guard");
if (acolyte && acolyte->IsAlive() && (!currentCrossUnit || currentCrossUnit->GetEntry() != acolyte->GetEntry()))
targetToMark = acolyte;
else if (runicColossus && runicColossus->IsAlive() &&
(!currentCrossUnit || currentCrossUnit->GetEntry() != runicColossus->GetEntry()))
targetToMark = runicColossus;
else if (ancientRuneGiant && ancientRuneGiant->IsAlive() &&
(!currentCrossUnit || currentCrossUnit->GetEntry() != ancientRuneGiant->GetEntry()))
targetToMark = ancientRuneGiant;
else if (ironHonorGuard && ironHonorGuard->IsAlive() &&
(!currentCrossUnit || currentCrossUnit->GetEntry() != ironHonorGuard->GetEntry()))
targetToMark = ironHonorGuard;
else if (ironRingGuard && ironRingGuard->IsAlive() &&
(!currentCrossUnit || currentCrossUnit->GetEntry() != ironRingGuard->GetEntry()))
targetToMark = ironRingGuard;
else
return false;
}
if (!targetToMark)
return false; // No target to mark
if (botAI->IsMainTank(bot))
{
group->SetTargetIcon(skullIndex, bot->GetGUID(), targetToMark->GetGUID());
return true;
}
if (botAI->IsAssistTankOfIndex(bot, 0))
{
group->SetTargetIcon(crossIndex, bot->GetGUID(), targetToMark->GetGUID());
return true;
}
return false;
}
bool ThorimArenaPositioningAction::isUseful()
{
ThorimArenaPositioningTrigger thorimArenaPositioningTrigger(botAI);
return thorimArenaPositioningTrigger.IsActive();
}
bool ThorimArenaPositioningAction::Execute(Event event)
{
FollowMasterStrategy followMasterStrategy(botAI);
MoveTo(bot->GetMapId(), ULDUAR_THORIM_NEAR_ARENA_CENTER.GetPositionX(),
ULDUAR_THORIM_NEAR_ARENA_CENTER.GetPositionY(), ULDUAR_THORIM_NEAR_ARENA_CENTER.GetPositionZ(), false, false,
false, true, MovementPriority::MOVEMENT_COMBAT, true);
if (botAI->HasStrategy(followMasterStrategy.getName(), BotState::BOT_STATE_NON_COMBAT))
{
botAI->ChangeStrategy(REMOVE_STRATEGY_CHAR + followMasterStrategy.getName(), BotState::BOT_STATE_NON_COMBAT);
}
return true;
}
bool ThorimGauntletPositioningAction::isUseful()
{
ThorimGauntletPositioningTrigger thorimGauntletPositioningTrigger(botAI);
return thorimGauntletPositioningTrigger.IsActive();
}
bool ThorimGauntletPositioningAction::Execute(Event event)
{
FollowMasterStrategy followMasterStrategy(botAI);
Unit* master = botAI->GetMaster();
std::string const rti = AI_VALUE(std::string, "rti");
if (rti != "cross")
{
botAI->GetAiObjectContext()->GetValue<std::string>("rti")->Set("cross");
}
if (master->GetDistance(ULDUAR_THORIM_NEAR_ENTRANCE_POSITION) < 10.0f && (bot->GetDistance2d(master) > 5.0f))
{
if (MoveTo(bot->GetMapId(), master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), false,
false, false, true, MovementPriority::MOVEMENT_NORMAL, true))
{
if (!botAI->HasStrategy(followMasterStrategy.getName(), BotState::BOT_STATE_NON_COMBAT))
{
botAI->ChangeStrategy(ADD_STRATEGY_CHAR + followMasterStrategy.getName(),
BotState::BOT_STATE_NON_COMBAT);
}
return true;
}
}
if (master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_1) < 6.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_2) < 6.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_5_YARDS_1) < 5.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_1) < 10.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_2) < 10.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_3) < 10.0f)
{
float distance1 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_1);
float distance2 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_2);
float distance3 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_5_YARDS_1);
float distance4 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_1);
float distance5 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_2);
float distance6 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_3);
float smallestDistance = std::min({distance1, distance2, distance3, distance4, distance5, distance6});
Position targetPosition;
if (smallestDistance == distance1)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_1.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_1.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_1.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_NORMAL, true);
}
else if (smallestDistance == distance2)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_2.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_2.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_2.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_COMBAT);
}
else if (smallestDistance == distance3)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_5_YARDS_1.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_5_YARDS_1.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_5_YARDS_1.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_NORMAL, true);
}
else if (smallestDistance == distance4)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_1.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_1.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_1.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_NORMAL, true);
}
else if (smallestDistance == distance5)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_2.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_2.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_2.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_NORMAL, true);
}
else if (smallestDistance == distance6)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_3.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_3.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_3.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_NORMAL, true);
}
else
return false;
}
if (master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_1) < 6.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_2) < 6.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_5_YARDS_1) < 5.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_1) < 10.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_2) < 10.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_3) < 10.0f)
{
float distance1 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_1);
float distance2 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_2);
float distance3 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_5_YARDS_1);
float distance4 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_1);
float distance5 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_2);
float distance6 = master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_3);
float smallestDistance = std::min({distance1, distance2, distance3, distance4, distance5, distance6});
Position targetPosition;
if (smallestDistance == distance1)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_1.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_1.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_1.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_NORMAL, true);
}
else if (smallestDistance == distance2)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_2.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_2.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_2.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_COMBAT);
}
else if (smallestDistance == distance3)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_5_YARDS_1.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_5_YARDS_1.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_5_YARDS_1.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_NORMAL, true);
}
else if (smallestDistance == distance4)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_1.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_1.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_1.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_NORMAL, true);
}
else if (smallestDistance == distance5)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_2.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_2.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_2.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_NORMAL, true);
}
else if (smallestDistance == distance6)
{
return MoveTo(bot->GetMapId(), ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_3.GetPositionX(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_3.GetPositionY(),
ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_3.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_NORMAL, true);
}
else
return false;
}
Unit* boss = AI_VALUE2(Unit*, "find target", "thorim");
if (boss && boss->IsAlive() && bot->GetPositionZ() > ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD &&
boss->GetPositionZ() < ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD)
{
MoveTo(bot->GetMapId(), ULDUAR_THORIM_JUMP_START_POINT.GetPositionX(),
ULDUAR_THORIM_JUMP_START_POINT.GetPositionY(), ULDUAR_THORIM_JUMP_START_POINT.GetPositionZ(), false,
false, false, true, MovementPriority::MOVEMENT_NORMAL, true);
if (bot->GetDistance(ULDUAR_THORIM_JUMP_START_POINT) > 0.5f)
return false;
JumpTo(bot->GetMapId(), ULDUAR_THORIM_JUMP_END_POINT.GetPositionX(),
ULDUAR_THORIM_JUMP_END_POINT.GetPositionY(), ULDUAR_THORIM_JUMP_END_POINT.GetPositionZ(),
MovementPriority::MOVEMENT_COMBAT);
}
return false;
}
bool ThorimFallFromFloorAction::Execute(Event event)
{
Player* master = botAI->GetMaster();
return bot->TeleportTo(bot->GetMapId(), master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(),
master->GetOrientation());
}
bool ThorimFallFromFloorAction::isUseful()
{
ThorimFallFromFloorTrigger thorimFallFromFloorTrigger(botAI);
return thorimFallFromFloorTrigger.IsActive();
}
bool ThorimPhase2PositioningAction::Execute(Event event)
{
Position targetPosition;
bool backward = false;
if (botAI->IsMainTank(bot))
{
targetPosition = ULDUAR_THORIM_PHASE2_TANK_SPOT;
backward = true;
}
else
{
Group* group = bot->GetGroup();
if (!group)
return false;
uint32 memberPositionNumber = 0;
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
{
Player* member = gref->GetSource();
if (!member)
continue;
if (botAI->IsRanged(member) || botAI->IsHeal(member))
{
if (bot->GetGUID() == member->GetGUID())
break;
memberPositionNumber++;
if (memberPositionNumber == 3)
memberPositionNumber = 0;
}
}
if (memberPositionNumber == 0)
targetPosition = ULDUAR_THORIM_PHASE2_RANGE1_SPOT;
if (memberPositionNumber == 1)
targetPosition = ULDUAR_THORIM_PHASE2_RANGE2_SPOT;
if (memberPositionNumber == 2)
targetPosition = ULDUAR_THORIM_PHASE2_RANGE3_SPOT;
}
MoveTo(bot->GetMapId(), targetPosition.GetPositionX(), targetPosition.GetPositionY(),
targetPosition.GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT, true,
backward);
if (bot->GetDistance(targetPosition) > 1.0f)
return false;
return true;
}
bool ThorimPhase2PositioningAction::isUseful()
{
ThorimPhase2PositioningTrigger thorimPhase2PositioningTrigger(botAI);
return thorimPhase2PositioningTrigger.IsActive();
}

View File

@@ -217,4 +217,57 @@ public:
bool isUseful() override;
};
class ThorimUnbalancingStrikeAction : public Action
{
public:
ThorimUnbalancingStrikeAction(PlayerbotAI* ai) : Action(ai, "thorim unbalancing strike action") {}
bool Execute(Event event) override;
bool isUseful() override;
};
class ThorimMarkDpsTargetAction : public Action
{
public:
ThorimMarkDpsTargetAction(PlayerbotAI* ai) : Action(ai, "thorim mark dps target action") {}
bool Execute(Event event) override;
bool isUseful() override;
};
class ThorimArenaPositioningAction : public MovementAction
{
public:
ThorimArenaPositioningAction(PlayerbotAI* ai) : MovementAction(ai, "thorim arena positioning action") {}
bool Execute(Event event) override;
bool isUseful() override;
};
class ThorimGauntletPositioningAction : public MovementAction
{
public:
ThorimGauntletPositioningAction(PlayerbotAI* ai) : MovementAction(ai, "thorim gauntlet positioning action") {}
bool Execute(Event event) override;
bool isUseful() override;
};
class ThorimFallFromFloorAction : public Action
{
public:
ThorimFallFromFloorAction(PlayerbotAI* botAI) : Action(botAI, "thorim fall from floor action") {}
bool Execute(Event event) override;
bool isUseful() override;
};
class ThorimPhase2PositioningAction : public MovementAction
{
public:
ThorimPhase2PositioningAction(PlayerbotAI* ai) : MovementAction(ai, "thorim phase 2 positioning action") {}
bool Execute(Event event) override;
bool isUseful() override;
};
#endif

View File

@@ -152,6 +152,34 @@ void RaidUlduarStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
"thorim nature resistance trigger",
NextAction::array(0, new NextAction("thorim nature resistance action", ACTION_RAID), nullptr)));
triggers.push_back(new TriggerNode(
"thorim frost resistance trigger",
NextAction::array(0, new NextAction("thorim frost resistance action", ACTION_RAID), nullptr)));
triggers.push_back(new TriggerNode(
"thorim unbalancing strike trigger",
NextAction::array(0, new NextAction("thorim unbalancing strike action", ACTION_RAID), nullptr)));
triggers.push_back(new TriggerNode(
"thorim mark dps target trigger",
NextAction::array(0, new NextAction("thorim mark dps target action", ACTION_RAID), nullptr)));
triggers.push_back(new TriggerNode(
"thorim gauntlet positioning trigger",
NextAction::array(0, new NextAction("thorim gauntlet positioning action", ACTION_RAID), nullptr)));
triggers.push_back(new TriggerNode(
"thorim arena positioning trigger",
NextAction::array(0, new NextAction("thorim arena positioning action", ACTION_RAID), nullptr)));
triggers.push_back(new TriggerNode(
"thorim fall from floor trigger",
NextAction::array(0, new NextAction("thorim fall from floor action", ACTION_RAID + 1), nullptr)));
triggers.push_back(new TriggerNode(
"thorim phase 2 positioning trigger",
NextAction::array(0, new NextAction("thorim phase 2 positioning action", ACTION_RAID), nullptr)));
//
// Mimiron
//

View File

@@ -46,7 +46,14 @@ public:
creators["freya nature resistance trigger"] = &RaidUlduarTriggerContext::freya_nature_resistance_trigger;
creators["freya mark dps target trigger"] = &RaidUlduarTriggerContext::freya_mark_dps_target_trigger;
creators["freya move to healing spore trigger"] = &RaidUlduarTriggerContext::freya_move_to_healing_spore_trigger;
creators["thorim frost resistance trigger"] = &RaidUlduarTriggerContext::thorim_frost_resistance_trigger;
creators["thorim nature resistance trigger"] = &RaidUlduarTriggerContext::thorim_nature_resistance_trigger;
creators["thorim unbalancing strike trigger"] = &RaidUlduarTriggerContext::thorim_unbalancing_strike_trigger;
creators["thorim mark dps target trigger"] = &RaidUlduarTriggerContext::thorim_mark_dps_target_trigger;
creators["thorim arena positioning trigger"] = &RaidUlduarTriggerContext::thorim_arena_positioning_trigger;
creators["thorim gauntlet positioning trigger"] = &RaidUlduarTriggerContext::thorim_gauntlet_positioning_trigger;
creators["thorim fall from floor trigger"] = &RaidUlduarTriggerContext::thorim_fall_from_floor_trigger;
creators["thorim phase 2 positioning trigger"] = &RaidUlduarTriggerContext::thorim_phase2_positioning_trigger;
creators["mimiron fire resistance trigger"] = &RaidUlduarTriggerContext::mimiron_fire_resistance_trigger;
}
@@ -81,7 +88,14 @@ private:
static Trigger* freya_nature_resistance_trigger(PlayerbotAI* ai) { return new BossNatureResistanceTrigger(ai, "freya"); }
static Trigger* freya_mark_dps_target_trigger(PlayerbotAI* ai) { return new FreyaMarkDpsTargetTrigger(ai); }
static Trigger* freya_move_to_healing_spore_trigger(PlayerbotAI* ai) { return new FreyaMoveToHealingSporeTrigger(ai); }
static Trigger* thorim_frost_resistance_trigger(PlayerbotAI* ai) { return new BossFrostResistanceTrigger(ai, "thorim"); }
static Trigger* thorim_nature_resistance_trigger(PlayerbotAI* ai) { return new BossNatureResistanceTrigger(ai, "thorim"); }
static Trigger* thorim_unbalancing_strike_trigger(PlayerbotAI* ai) { return new ThorimUnbalancingStrikeTrigger(ai); }
static Trigger* thorim_mark_dps_target_trigger(PlayerbotAI* ai) { return new ThorimMarkDpsTargetTrigger(ai); }
static Trigger* thorim_arena_positioning_trigger(PlayerbotAI* ai) { return new ThorimArenaPositioningTrigger(ai); }
static Trigger* thorim_gauntlet_positioning_trigger(PlayerbotAI* ai) { return new ThorimGauntletPositioningTrigger(ai); }
static Trigger* thorim_fall_from_floor_trigger(PlayerbotAI* ai) { return new ThorimFallFromFloorTrigger(ai); }
static Trigger* thorim_phase2_positioning_trigger(PlayerbotAI* ai) { return new ThorimPhase2PositioningTrigger(ai); }
static Trigger* mimiron_fire_resistance_trigger(PlayerbotAI* ai) { return new BossFireResistanceTrigger(ai, "mimiron"); }
};

View File

@@ -724,3 +724,373 @@ bool FreyaMoveToHealingSporeTrigger::IsActive()
// If the nearest spore is farther than 6 yards, a move is required
return nearestDistance > 6.0f;
}
bool ThorimUnbalancingStrikeTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "thorim");
// Check boss and it is alive
if (!boss || !boss->IsAlive())
return false;
return bot->HasAura(SPELL_UNBALANCING_STRIKE);
}
bool ThorimMarkDpsTargetTrigger::IsActive()
{
if (bot->GetDistance(ULDUAR_THORIM_NEAR_ARENA_CENTER) > 110.0f)
return false;
Group* group = bot->GetGroup();
if (!group)
return false;
if (botAI->IsMainTank(bot))
{
ObjectGuid currentSkullTarget = group->GetTargetIcon(skullIndex);
Unit* currentSkullUnit = botAI->GetUnit(currentSkullTarget);
if (currentSkullUnit && !currentSkullUnit->IsAlive())
{
currentSkullUnit = nullptr;
}
Unit* acolyte = AI_VALUE2(Unit*, "find target", "dark rune acolyte");
Unit* evoker = AI_VALUE2(Unit*, "find target", "dark rune evoker");
if (acolyte && acolyte->IsAlive() && bot->GetDistance(acolyte) < 50.0f &&
(!currentSkullUnit || currentSkullUnit->GetEntry() != acolyte->GetEntry()))
return true;
if (evoker && evoker->IsAlive() && bot->GetDistance(evoker) < 50.0f &&
(!currentSkullUnit || currentSkullUnit->GetEntry() != evoker->GetEntry()))
return true;
Unit* boss = AI_VALUE2(Unit*, "find target", "thorim");
// Check boss and it is alive
if (!boss || !boss->IsAlive())
return false;
if (boss->GetPositionZ() < ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD && (!currentSkullUnit || !currentSkullUnit->IsAlive()))
{
group->SetTargetIcon(skullIndex, bot->GetGUID(), boss->GetGUID());
return true;
}
return false;
}
else if (botAI->IsAssistTankOfIndex(bot, 0))
{
Player* mainTank = nullptr;
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
{
Player* member = gref->GetSource();
if (member && botAI->IsMainTank(member))
{
mainTank = member;
break;
}
}
if (mainTank && bot->GetDistance(mainTank) < 30.0f)
return false;
ObjectGuid currentCrossTarget = group->GetTargetIcon(crossIndex);
Unit* currentCrossUnit = botAI->GetUnit(currentCrossTarget);
if (currentCrossUnit && !currentCrossUnit->IsAlive())
{
currentCrossUnit = nullptr;
}
Unit* acolyte = AI_VALUE2(Unit*, "find target", "dark rune acolyte");
if (currentCrossUnit && currentCrossUnit->GetEntry() == NPC_DARK_RUNE_ACOLYTE_I)
return false;
Unit* runicColossus = AI_VALUE2(Unit*, "find target", "runic colossus");
Unit* ancientRuneGiant = AI_VALUE2(Unit*, "find target", "ancient rune giant");
Unit* ironHonorGuard = AI_VALUE2(Unit*, "find target", "iron ring guard");
Unit* ironRingGuard = AI_VALUE2(Unit*, "find target", "iron honor guard");
if (acolyte && acolyte->IsAlive() && (!currentCrossUnit || currentCrossUnit->GetEntry() != acolyte->GetEntry()))
return true;
if (currentCrossUnit && currentCrossUnit->GetEntry() == NPC_RUNIC_COLOSSUS)
return false;
if (runicColossus && runicColossus->IsAlive() &&
(!currentCrossUnit || currentCrossUnit->GetEntry() != runicColossus->GetEntry()))
return true;
if (currentCrossUnit && currentCrossUnit->GetEntry() == NPC_ANCIENT_RUNE_GIANT)
return false;
if (ancientRuneGiant && ancientRuneGiant->IsAlive() &&
(!currentCrossUnit || currentCrossUnit->GetEntry() != ancientRuneGiant->GetEntry()))
return true;
return false;
}
return false;
}
bool ThorimGauntletPositioningTrigger::IsActive()
{
if (bot->GetDistance(ULDUAR_THORIM_NEAR_ARENA_CENTER) > 110.0f)
return false;
Difficulty raidDifficulty = bot->GetRaidDifficulty();
Group* group = bot->GetGroup();
if (!group)
return false;
uint32 requiredAssistTankQuantity = 1;
uint32 requiredHealerQuantity = 0;
uint32 requiredDpsQuantity = 0;
if (raidDifficulty == Difficulty::RAID_DIFFICULTY_10MAN_NORMAL)
{
requiredDpsQuantity = 3;
requiredHealerQuantity = 1;
}
else if (raidDifficulty == Difficulty::RAID_DIFFICULTY_25MAN_NORMAL)
{
requiredDpsQuantity = 7;
requiredHealerQuantity = 2;
}
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
{
Player* member = gref->GetSource();
if (!member)
continue;
if (requiredDpsQuantity > 0 && botAI->IsDps(member))
{
requiredDpsQuantity--;
if (bot->GetGUID() == member->GetGUID())
break;
}
if (requiredAssistTankQuantity > 0 && botAI->IsAssistTankOfIndex(member, 0))
{
requiredAssistTankQuantity--;
if (bot->GetGUID() == member->GetGUID())
break;
}
if (requiredHealerQuantity > 0 && botAI->IsHeal(member))
{
requiredHealerQuantity--;
if (bot->GetGUID() == member->GetGUID())
break;
}
if (requiredDpsQuantity == 0 && requiredAssistTankQuantity == 0 && requiredHealerQuantity == 0)
return false;
}
Unit* master = botAI->GetMaster();
if (master->GetDistance(ULDUAR_THORIM_NEAR_ENTRANCE_POSITION) < 10.0f && (bot->GetDistance2d(master) > 5.0f))
{
return true;
}
if ((master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_1) < 6.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_2) < 6.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_5_YARDS_1) < 5.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_1) < 10.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_2) < 10.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_3) < 10.0f) &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_1) > 6.0f &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_2) > 6.0f &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_5_YARDS_1) > 5.0f &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_1) > 10.0f &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_2) > 10.0f &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_3) > 10.0f)
{
if (bot->GetPositionZ() > ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD)
return false;
return true;
}
if ((master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_1) < 6.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_2) < 6.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_5_YARDS_1) < 5.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_1) < 10.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_2) < 10.0f ||
master->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_3) < 10.0f) &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_1) > 6.0f &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_2) > 6.0f &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_5_YARDS_1) > 5.0f &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_1) > 10.0f &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_2) > 10.0f &&
bot->GetDistance(ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_3) > 10.0f)
{
if (bot->GetPositionZ() > ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD)
return false;
return true;
}
Unit* boss = AI_VALUE2(Unit*, "find target", "thorim");
if (boss && boss->IsAlive() && bot->GetPositionZ() > ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD &&
boss->GetPositionZ() < ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD)
{
return true;
}
return false;
}
bool ThorimArenaPositioningTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "thorim");
// Check boss and it is alive
if (!boss || !boss->IsAlive())
return false;
if (boss->GetPositionZ() < ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD)
return false;
Difficulty raidDifficulty = bot->GetRaidDifficulty();
Group* group = bot->GetGroup();
if (!group)
return false;
uint32 requiredAssistTankQuantity = 1;
uint32 requiredHealerQuantity = 0;
uint32 requiredDpsQuantity = 0;
if (raidDifficulty == Difficulty::RAID_DIFFICULTY_10MAN_NORMAL)
{
requiredDpsQuantity = 3;
requiredHealerQuantity = 1;
}
else if (raidDifficulty == Difficulty::RAID_DIFFICULTY_25MAN_NORMAL)
{
requiredDpsQuantity = 7;
requiredHealerQuantity = 2;
}
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
{
Player* member = gref->GetSource();
if (!member)
continue;
if (requiredDpsQuantity > 0 && botAI->IsDps(member))
{
requiredDpsQuantity--;
if (bot->GetGUID() == member->GetGUID())
return false;
}
if (requiredAssistTankQuantity > 0 && botAI->IsAssistTankOfIndex(member, 0))
{
requiredAssistTankQuantity--;
if (bot->GetGUID() == member->GetGUID())
return false;
}
if (requiredHealerQuantity > 0 && botAI->IsHeal(member))
{
requiredHealerQuantity--;
if (bot->GetGUID() == member->GetGUID())
return false;
}
if (requiredDpsQuantity == 0 && requiredAssistTankQuantity == 0 && requiredHealerQuantity == 0)
break;
}
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
Unit* target = nullptr;
for (auto i = targets.begin(); i != targets.end(); ++i)
{
target = botAI->GetUnit(*i);
if (!target || !target->IsAlive())
continue;
uint32 entry = target->GetEntry();
if (entry == NPC_DARK_RUNE_ACOLYTE_I || entry == NPC_CAPTURED_MERCENARY_SOLDIER_ALLY ||
entry == NPC_CAPTURED_MERCENARY_SOLDIER_HORDE || entry == NPC_CAPTURED_MERCENARY_CAPTAIN_ALLY ||
entry == NPC_CAPTURED_MERCENARY_CAPTAIN_HORDE || entry == NPC_JORMUNGAR_BEHEMOT ||
entry == NPC_DARK_RUNE_WARBRINGER || entry == NPC_DARK_RUNE_EVOKER || entry == NPC_DARK_RUNE_CHAMPION ||
entry == NPC_DARK_RUNE_COMMONER)
return false;
}
if (bot && bot->GetDistance(ULDUAR_THORIM_NEAR_ARENA_CENTER) > 5.0f)
return true;
return false;
}
bool ThorimFallFromFloorTrigger::IsActive()
{
if (bot->GetDistance(ULDUAR_THORIM_NEAR_ARENA_CENTER) > 110.0f)
return false;
// Check if bot is on the floor
return bot->GetPositionZ() < ULDUAR_THORIM_AXIS_Z_PATHING_ISSUE_DETECT;
}
bool ThorimPhase2PositioningTrigger::IsActive()
{
if (!botAI->IsRanged(bot) && !botAI->IsMainTank(bot))
return false;
Unit* boss = AI_VALUE2(Unit*, "find target", "thorim");
// Check boss and it is alive
if (!boss || !boss->IsAlive())
return false;
if (boss->GetPositionZ() > ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD)
return false;
if (botAI->IsMainTank(bot))
{
if (bot->GetDistance(ULDUAR_THORIM_PHASE2_TANK_SPOT) > 1.0f && boss->GetVictim() == bot)
return true;
return false;
}
Group* group = bot->GetGroup();
if (!group)
return false;
uint32 memberPositionNumber = 0;
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
{
Player* member = gref->GetSource();
if (!member)
continue;
if (botAI->IsRanged(member))
{
if (bot->GetGUID() == member->GetGUID())
break;
memberPositionNumber++;
if (memberPositionNumber == 3)
memberPositionNumber = 0;
}
}
if (memberPositionNumber == 0 && bot->GetDistance(ULDUAR_THORIM_PHASE2_RANGE1_SPOT) > 1.0f)
return true;
if (memberPositionNumber == 1 && bot->GetDistance(ULDUAR_THORIM_PHASE2_RANGE2_SPOT) > 1.0f)
return true;
if (memberPositionNumber == 2 && bot->GetDistance(ULDUAR_THORIM_PHASE2_RANGE3_SPOT) > 1.0f)
return true;
return false;
}

View File

@@ -44,6 +44,24 @@ enum UlduarIDs
NPC_EONARS_GIFT = 33228,
GOBJECT_NATURE_BOMB = 194902,
//Thorim
NPC_DARK_RUNE_ACOLYTE_I = 32886,
NPC_CAPTURED_MERCENARY_SOLDIER_ALLY = 32885,
NPC_CAPTURED_MERCENARY_SOLDIER_HORDE = 32883,
NPC_CAPTURED_MERCENARY_CAPTAIN_ALLY = 32908,
NPC_CAPTURED_MERCENARY_CAPTAIN_HORDE = 32907,
NPC_JORMUNGAR_BEHEMOT = 32882,
NPC_DARK_RUNE_WARBRINGER = 32877,
NPC_DARK_RUNE_EVOKER = 32878,
NPC_DARK_RUNE_CHAMPION = 32876,
NPC_DARK_RUNE_COMMONER = 32904,
NPC_IRON_RING_GUARD = 32874,
NPC_RUNIC_COLOSSUS = 32872,
NPC_ANCIENT_RUNE_GIANT = 32873,
NPC_DARK_RUNE_ACOLYTE_G = 33110,
NPC_IRON_HONOR_GUARD = 32875,
SPELL_UNBALANCING_STRIKE = 62130,
// Buffs
SPELL_FROST_TRAP = 13809
};
@@ -54,6 +72,28 @@ const int8 moonIndex = 4; // Moon
const float ULDUAR_KOLOGARN_AXIS_Z_PATHING_ISSUE_DETECT = 420.0f;
const float ULDUAR_KOLOGARN_EYEBEAM_RADIUS = 3.0f;
const float ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD = 429.6094f;
const float ULDUAR_THORIM_AXIS_Z_PATHING_ISSUE_DETECT = 410.0f;
const Position ULDUAR_THORIM_NEAR_ARENA_CENTER = Position(2134.9854f, -263.11853f, 419.8465f);
const Position ULDUAR_THORIM_NEAR_ENTRANCE_POSITION = Position(2172.4355f, -258.27957f, 418.47162f);
const Position ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_1 = Position(2237.6187f, -265.08844f, 412.17548f);
const Position ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_6_YARDS_2 = Position(2237.2498f, -275.81122f, 412.17548f);
const Position ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_5_YARDS_1 = Position(2236.895f, -294.62448f, 412.1348f);
const Position ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_1 = Position(2242.1162f, -310.15308f, 412.1348f);
const Position ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_2 = Position(2242.018f, -318.66003f, 412.1348f);
const Position ULDUAR_THORIM_GAUNTLET_LEFT_SIDE_10_YARDS_3 = Position(2242.1904f, -329.0533f, 412.1348f);
const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_1 = Position(2219.5417f, -264.77167f, 412.17548f);
const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_6_YARDS_2 = Position(2217.446f, -275.85248f, 412.17548f);
const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_5_YARDS_1 = Position(2217.8877f, -295.01193f, 412.13434f);
const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_1 = Position(2212.193f, -307.44992f, 412.1348f);
const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_2 = Position(2212.1353f, -318.20795f, 412.1348f);
const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_3 = Position(2212.1956f, -328.0144f, 412.1348f);
const Position ULDUAR_THORIM_PHASE2_TANK_SPOT = Position(2134.8572f, -287.0291f, 419.4935f);
const Position ULDUAR_THORIM_PHASE2_RANGE1_SPOT = Position(2112.8752f, -267.69305f, 419.52814f);
const Position ULDUAR_THORIM_PHASE2_RANGE2_SPOT = Position(2129.09f, -277.142f, 419.67462f);
const Position ULDUAR_THORIM_PHASE2_RANGE3_SPOT = Position(2156.798f, -267.57434f, 419.52722f);
//
// Flame Levi
@@ -241,4 +281,49 @@ public:
bool IsActive() override;
};
//
// Thorim
//
class ThorimUnbalancingStrikeTrigger : public Trigger
{
public:
ThorimUnbalancingStrikeTrigger(PlayerbotAI* ai) : Trigger(ai, "thorim unbalancing strike trigger") {}
bool IsActive() override;
};
class ThorimMarkDpsTargetTrigger : public Trigger
{
public:
ThorimMarkDpsTargetTrigger(PlayerbotAI* ai) : Trigger(ai, "thorim mark dps target trigger") {}
bool IsActive() override;
};
class ThorimGauntletPositioningTrigger : public Trigger
{
public:
ThorimGauntletPositioningTrigger(PlayerbotAI* ai) : Trigger(ai, "thorim gauntlet positioning trigger") {}
bool IsActive() override;
};
class ThorimArenaPositioningTrigger : public Trigger
{
public:
ThorimArenaPositioningTrigger(PlayerbotAI* ai) : Trigger(ai, "thorim arena positioning trigger") {}
bool IsActive() override;
};
class ThorimFallFromFloorTrigger : public Trigger
{
public:
ThorimFallFromFloorTrigger(PlayerbotAI* ai) : Trigger(ai, "thorim fall from floor trigger") {}
bool IsActive() override;
};
class ThorimPhase2PositioningTrigger : public Trigger
{
public:
ThorimPhase2PositioningTrigger(PlayerbotAI* ai) : Trigger(ai, "thorim phase 2 positioning trigger") {}
bool IsActive() override;
};
#endif