mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
- Added Thorim strategy (#1305)
This commit is contained in:
@@ -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"); }
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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"); }
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user