mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
@@ -54,6 +54,14 @@ public:
|
||||
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;
|
||||
creators["mimiron shock blast action"] = &RaidUlduarActionContext::mimiron_shock_blast_action;
|
||||
creators["mimiron phase 1 positioning action"] = &RaidUlduarActionContext::mimiron_phase_1_positioning_action;
|
||||
creators["mimiron p3wx2 laser barrage action"] = &RaidUlduarActionContext::mimiron_p3wx2_laser_barrage_action;
|
||||
creators["mimiron rapid burst action"] = &RaidUlduarActionContext::mimiron_rapid_burst_action;
|
||||
creators["mimiron aerial command unit action"] = &RaidUlduarActionContext::mimiron_aerial_command_unit_action;
|
||||
creators["mimiron rocket strike action"] = &RaidUlduarActionContext::mimiron_rocket_strike_action;
|
||||
creators["mimiron phase 4 mark dps action"] = &RaidUlduarActionContext::mimiron_phase_4_mark_dps_action;
|
||||
creators["mimiron cheat action"] = &RaidUlduarActionContext::mimiron_cheat_action;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -95,6 +103,14 @@ private:
|
||||
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"); }
|
||||
static Action* mimiron_shock_blast_action(PlayerbotAI* ai) { return new MimironShockBlastAction(ai); }
|
||||
static Action* mimiron_phase_1_positioning_action(PlayerbotAI* ai) { return new MimironPhase1PositioningAction(ai); }
|
||||
static Action* mimiron_p3wx2_laser_barrage_action(PlayerbotAI* ai) { return new MimironP3Wx2LaserBarrageAction(ai); }
|
||||
static Action* mimiron_rapid_burst_action(PlayerbotAI* ai) { return new MimironRapidBurstAction(ai); }
|
||||
static Action* mimiron_aerial_command_unit_action(PlayerbotAI* ai) { return new MimironAerialCommandUnitAction(ai); }
|
||||
static Action* mimiron_rocket_strike_action(PlayerbotAI* ai) { return new MimironRocketStrikeAction(ai); }
|
||||
static Action* mimiron_phase_4_mark_dps_action(PlayerbotAI* ai) { return new MimironPhase4MarkDpsAction(ai); }
|
||||
static Action* mimiron_cheat_action(PlayerbotAI* ai) { return new MimironCheatAction(ai); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
#include "RaidUlduarActions.h"
|
||||
|
||||
#include <CombatStrategy.h>
|
||||
#include <FollowMasterStrategy.h>
|
||||
|
||||
#include <cmath>
|
||||
@@ -62,7 +63,7 @@ bool FlameLeviathanVehicleAction::Execute(Event event)
|
||||
continue;
|
||||
if (unit->GetEntry() == 33142) // Leviathan Defense Turret
|
||||
continue;
|
||||
if (unit->GetEntry() == 33113) // Flame Leviathan
|
||||
if (unit->GetEntry() == 33113) // Flame Leviathan
|
||||
{
|
||||
flame = unit;
|
||||
continue;
|
||||
@@ -1851,7 +1852,7 @@ bool ThorimMarkDpsTargetAction::Execute(Event event)
|
||||
(!currentSkullUnit || currentSkullUnit->GetEntry() != acolyte->GetEntry()))
|
||||
targetToMark = acolyte;
|
||||
else if (evoker && evoker->IsAlive() && bot->GetDistance(evoker) < 50.0f &&
|
||||
(!currentSkullUnit || currentSkullUnit->GetEntry() != evoker->GetEntry()))
|
||||
(!currentSkullUnit || currentSkullUnit->GetEntry() != evoker->GetEntry()))
|
||||
targetToMark = evoker;
|
||||
else
|
||||
return false;
|
||||
@@ -2095,8 +2096,8 @@ bool ThorimGauntletPositioningAction::Execute(Event event)
|
||||
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);
|
||||
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;
|
||||
@@ -2171,9 +2172,8 @@ bool ThorimPhase2PositioningAction::Execute(Event event)
|
||||
targetPosition = ULDUAR_THORIM_PHASE2_RANGE3_SPOT;
|
||||
}
|
||||
|
||||
MoveTo(bot->GetMapId(), targetPosition.GetPositionX(), targetPosition.GetPositionY(),
|
||||
targetPosition.GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT, true,
|
||||
backward);
|
||||
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;
|
||||
@@ -2186,3 +2186,464 @@ bool ThorimPhase2PositioningAction::isUseful()
|
||||
ThorimPhase2PositioningTrigger thorimPhase2PositioningTrigger(botAI);
|
||||
return thorimPhase2PositioningTrigger.IsActive();
|
||||
}
|
||||
|
||||
bool MimironShockBlastAction::Execute(Event event)
|
||||
{
|
||||
Unit* leviathanMkII = nullptr;
|
||||
Unit* vx001 = nullptr;
|
||||
Unit* aerialCommandUnit = nullptr;
|
||||
|
||||
float radius = 20.0f;
|
||||
|
||||
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;
|
||||
|
||||
if (target->GetEntry() == NPC_LEVIATHAN_MKII)
|
||||
{
|
||||
leviathanMkII = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_VX001)
|
||||
{
|
||||
vx001 = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_AERIAL_COMMAND_UNIT)
|
||||
{
|
||||
aerialCommandUnit = target;
|
||||
}
|
||||
}
|
||||
|
||||
if (!leviathanMkII)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vx001 && !aerialCommandUnit)
|
||||
{
|
||||
float currentDistance = bot->GetDistance2d(leviathanMkII);
|
||||
|
||||
MoveAway(leviathanMkII, radius - currentDistance);
|
||||
|
||||
if (botAI->IsMelee(bot))
|
||||
{
|
||||
botAI->SetNextCheckDelay(100);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
float init_angle = leviathanMkII->GetAngle(bot);
|
||||
float distance = radius - bot->GetDistance2d(leviathanMkII);
|
||||
for (float delta = 0; delta <= M_PI / 2; delta += M_PI / 8)
|
||||
{
|
||||
float angle = init_angle + delta;
|
||||
float dx = bot->GetPositionX() + cos(angle) * distance;
|
||||
float dy = bot->GetPositionY() + sin(angle) * distance;
|
||||
float dz = bot->GetPositionZ();
|
||||
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
|
||||
bot->GetPositionZ(), dx, dy, dz))
|
||||
{
|
||||
bot->TeleportTo(target->GetMapId(), dx, dy, dz, target->GetOrientation());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MimironShockBlastAction::isUseful()
|
||||
{
|
||||
MimironShockBlastTrigger mimironShockBlastTrigger(botAI);
|
||||
return mimironShockBlastTrigger.IsActive();
|
||||
}
|
||||
|
||||
bool MimironPhase1PositioningAction::Execute(Event event)
|
||||
{
|
||||
SET_AI_VALUE(float, "disperse distance", 6.0f);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MimironPhase1PositioningAction::isUseful()
|
||||
{
|
||||
MimironPhase1PositioningTrigger mimironPhase1PositioningTrigger(botAI);
|
||||
return mimironPhase1PositioningTrigger.IsActive();
|
||||
}
|
||||
|
||||
bool MimironP3Wx2LaserBarrageAction::Execute(Event event)
|
||||
{
|
||||
auto master = botAI->GetMaster();
|
||||
if (!master || !master->IsAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bot->GetDistance2d(master) > 15.0f)
|
||||
{
|
||||
return bot->TeleportTo(master->GetMapId(), master->GetPositionX(), master->GetPositionY(),
|
||||
master->GetPositionZ(), master->GetOrientation());
|
||||
}
|
||||
|
||||
return MoveTo(master->GetMapId(), master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), false,
|
||||
false, false, true, MovementPriority::MOVEMENT_COMBAT, true);
|
||||
}
|
||||
|
||||
bool MimironRapidBurstAction::isUseful()
|
||||
{
|
||||
MimironRapidBurstTrigger mimironRapidBurstTrigger(botAI);
|
||||
return mimironRapidBurstTrigger.IsActive();
|
||||
}
|
||||
|
||||
bool MimironRapidBurstAction::Execute(Event event)
|
||||
{
|
||||
Unit* leviathanMkII = nullptr;
|
||||
|
||||
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;
|
||||
|
||||
if (target->GetEntry() == NPC_LEVIATHAN_MKII)
|
||||
{
|
||||
leviathanMkII = target;
|
||||
}
|
||||
}
|
||||
|
||||
Position targetPosition;
|
||||
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 memberSpotNumber = 0;
|
||||
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||
{
|
||||
Player* member = gref->GetSource();
|
||||
if (!member)
|
||||
continue;
|
||||
|
||||
if (bot->GetGUID() == member->GetGUID())
|
||||
{
|
||||
if (botAI->IsRanged(bot))
|
||||
{
|
||||
switch (memberSpotNumber)
|
||||
{
|
||||
case 0:
|
||||
targetPosition = ULDUAR_MIMIRON_PHASE2_SIDE1RANGE_SPOT;
|
||||
break;
|
||||
case 1:
|
||||
targetPosition = ULDUAR_MIMIRON_PHASE2_SIDE2RANGE_SPOT;
|
||||
break;
|
||||
case 2:
|
||||
targetPosition = ULDUAR_MIMIRON_PHASE2_SIDE3RANGE_SPOT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (botAI->IsMainTank(bot) && leviathanMkII)
|
||||
{
|
||||
targetPosition = ULDUAR_MIMIRON_PHASE4_TANK_SPOT;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (memberSpotNumber)
|
||||
{
|
||||
case 0:
|
||||
targetPosition = ULDUAR_MIMIRON_PHASE2_SIDE1MELEE_SPOT;
|
||||
break;
|
||||
case 1:
|
||||
targetPosition = ULDUAR_MIMIRON_PHASE2_SIDE2MELEE_SPOT;
|
||||
break;
|
||||
case 2:
|
||||
targetPosition = ULDUAR_MIMIRON_PHASE2_SIDE3MELEE_SPOT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memberSpotNumber++;
|
||||
|
||||
if (memberSpotNumber == 3)
|
||||
{
|
||||
memberSpotNumber = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MoveTo(bot->GetMapId(), targetPosition.GetPositionX(), targetPosition.GetPositionY(), targetPosition.GetPositionZ(),
|
||||
false, false, false, true, MovementPriority::MOVEMENT_FORCED, true, false);
|
||||
|
||||
if (AI_VALUE(float, "disperse distance") != 0.0f)
|
||||
{
|
||||
SET_AI_VALUE(float, "disperse distance", 0.0f);
|
||||
}
|
||||
|
||||
TankFaceStrategy tankFaceStrategy(botAI);
|
||||
if (botAI->HasStrategy(tankFaceStrategy.getName(), BotState::BOT_STATE_COMBAT))
|
||||
{
|
||||
botAI->ChangeStrategy(REMOVE_STRATEGY_CHAR + tankFaceStrategy.getName(), BotState::BOT_STATE_COMBAT);
|
||||
}
|
||||
if (botAI->HasStrategy(tankFaceStrategy.getName(), BotState::BOT_STATE_NON_COMBAT))
|
||||
{
|
||||
botAI->ChangeStrategy(REMOVE_STRATEGY_CHAR + tankFaceStrategy.getName(), BotState::BOT_STATE_NON_COMBAT);
|
||||
}
|
||||
|
||||
if (bot->GetDistance(targetPosition) > 1.0f)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MimironAerialCommandUnitAction::Execute(Event event)
|
||||
{
|
||||
Unit* boss = nullptr;
|
||||
Unit* bombBot = nullptr;
|
||||
Unit* assaultBot = nullptr;
|
||||
|
||||
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;
|
||||
|
||||
if (target->GetEntry() == NPC_AERIAL_COMMAND_UNIT)
|
||||
{
|
||||
boss = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_BOMB_BOT)
|
||||
{
|
||||
bombBot = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_ASSAULT_BOT)
|
||||
{
|
||||
assaultBot = target;
|
||||
}
|
||||
}
|
||||
|
||||
if (botAI->IsMainTank(bot) || botAI->IsAssistTankOfIndex(bot, 0))
|
||||
{
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bombBot)
|
||||
{
|
||||
group->SetTargetIcon(crossIndex, bot->GetGUID(), bombBot->GetGUID());
|
||||
}
|
||||
else if (boss)
|
||||
{
|
||||
group->SetTargetIcon(crossIndex, bot->GetGUID(), boss->GetGUID());
|
||||
}
|
||||
|
||||
if (assaultBot)
|
||||
{
|
||||
ObjectGuid skullTarget = group->GetTargetIcon(skullIndex);
|
||||
Unit* skullUnit = botAI->GetUnit(skullTarget);
|
||||
if (!skullTarget || !skullUnit || !skullUnit->IsAlive())
|
||||
{
|
||||
group->SetTargetIcon(skullIndex, bot->GetGUID(), assaultBot->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (AI_VALUE(float, "disperse distance") != 5.0f)
|
||||
{
|
||||
SET_AI_VALUE(float, "disperse distance", 5.0f);
|
||||
}
|
||||
botAI->GetAiObjectContext()->GetValue<std::string>("rti")->Set("cross");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MimironRocketStrikeAction::isUseful()
|
||||
{
|
||||
MimironRocketStrikeTrigger mimironRocketStrikeTrigger(botAI);
|
||||
return mimironRocketStrikeTrigger.IsActive();
|
||||
}
|
||||
|
||||
bool MimironRocketStrikeAction::Execute(Event event)
|
||||
{
|
||||
Unit* leviathanMkII = nullptr;
|
||||
Unit* vx001 = nullptr;
|
||||
Unit* aerialCommandUnit = nullptr;
|
||||
|
||||
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;
|
||||
|
||||
if (target->GetEntry() == NPC_LEVIATHAN_MKII)
|
||||
{
|
||||
leviathanMkII = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_VX001)
|
||||
{
|
||||
vx001 = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_AERIAL_COMMAND_UNIT)
|
||||
{
|
||||
aerialCommandUnit = target;
|
||||
}
|
||||
}
|
||||
|
||||
Creature* rocketStrikeN = bot->FindNearestCreature(NPC_ROCKET_STRIKE_N, 100.0f);
|
||||
|
||||
if (!rocketStrikeN)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vx001 && !aerialCommandUnit)
|
||||
{
|
||||
MoveAway(rocketStrikeN, 10.0f);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
float init_angle = rocketStrikeN->GetAngle(bot);
|
||||
float distance = 10.0f - bot->GetDistance2d(rocketStrikeN);
|
||||
for (float delta = 0; delta <= M_PI / 2; delta += M_PI / 8)
|
||||
{
|
||||
float angle = init_angle + delta;
|
||||
float dx = bot->GetPositionX() + cos(angle) * distance;
|
||||
float dy = bot->GetPositionY() + sin(angle) * distance;
|
||||
float dz = bot->GetPositionZ();
|
||||
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
|
||||
bot->GetPositionZ(), dx, dy, dz))
|
||||
{
|
||||
bot->TeleportTo(target->GetMapId(), dx, dy, dz, target->GetOrientation());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MimironPhase4MarkDpsAction::Execute(Event event)
|
||||
{
|
||||
Unit* leviathanMkII = nullptr;
|
||||
Unit* vx001 = nullptr;
|
||||
Unit* aerialCommandUnit = nullptr;
|
||||
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (target->GetEntry() == NPC_LEVIATHAN_MKII)
|
||||
{
|
||||
leviathanMkII = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_VX001)
|
||||
{
|
||||
vx001 = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_AERIAL_COMMAND_UNIT)
|
||||
{
|
||||
aerialCommandUnit = target;
|
||||
}
|
||||
}
|
||||
|
||||
if (!leviathanMkII || !vx001 || !aerialCommandUnit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (botAI->IsMainTank(bot))
|
||||
{
|
||||
Unit* highestHealthUnit = nullptr;
|
||||
uint32 highestHealth = 0;
|
||||
if (leviathanMkII && leviathanMkII->GetHealth() > highestHealth)
|
||||
{
|
||||
highestHealth = leviathanMkII->GetHealth();
|
||||
highestHealthUnit = leviathanMkII;
|
||||
}
|
||||
if (vx001 && vx001->GetHealth() > highestHealth)
|
||||
{
|
||||
highestHealth = vx001->GetHealth();
|
||||
highestHealthUnit = vx001;
|
||||
}
|
||||
if (aerialCommandUnit && aerialCommandUnit->GetHealth() > highestHealth)
|
||||
{
|
||||
highestHealthUnit = aerialCommandUnit;
|
||||
}
|
||||
|
||||
group->SetTargetIcon(skullIndex, bot->GetGUID(), highestHealthUnit->GetGUID());
|
||||
if (highestHealthUnit == leviathanMkII)
|
||||
{
|
||||
if (AI_VALUE(std::string, "rti") == "skull")
|
||||
{
|
||||
botAI->GetAiObjectContext()->GetValue<std::string>("rti")->Set("skull");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
group->SetTargetIcon(crossIndex, bot->GetGUID(), leviathanMkII->GetGUID());
|
||||
if (AI_VALUE(std::string, "rti") != "cross")
|
||||
{
|
||||
botAI->GetAiObjectContext()->GetValue<std::string>("rti")->Set("cross");
|
||||
}
|
||||
}
|
||||
|
||||
botAI->DoSpecificAction("attack rti target");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*if (AI_VALUE(float, "disperse distance") != 0.0f)
|
||||
{
|
||||
SET_AI_VALUE(float, "disperse distance", 0.0f);
|
||||
}*/
|
||||
botAI->GetAiObjectContext()->GetValue<std::string>("rti")->Set("skull");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool MimironCheatAction::Execute(Event event)
|
||||
{
|
||||
GuidVector targets = AI_VALUE(GuidVector, "nearest npcs");
|
||||
for (const ObjectGuid& guid : targets)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(guid);
|
||||
if (!unit || !unit->IsAlive())
|
||||
continue;
|
||||
|
||||
if (unit->GetEntry() == NPC_PROXIMITY_MINE)
|
||||
{
|
||||
unit->Kill(bot, unit);
|
||||
}
|
||||
else if (unit->GetEntry() == NPC_BOMB_BOT)
|
||||
{
|
||||
unit->Kill(bot, unit);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -278,4 +278,80 @@ public:
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class MimironShockBlastAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
MimironShockBlastAction(PlayerbotAI* ai) : MovementAction(ai, "mimiron shock blast action") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class MimironPhase1PositioningAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
MimironPhase1PositioningAction(PlayerbotAI* ai) : MovementAction(ai, "mimiron phase 1 positioning action") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class MimironP3Wx2LaserBarrageAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
MimironP3Wx2LaserBarrageAction(PlayerbotAI* ai, float distance = 24.0f, float delta_angle = M_PI / 8)
|
||||
: MovementAction(ai, "mimiron p3wx2 laser barrage action")
|
||||
{
|
||||
this->distance = distance;
|
||||
this->delta_angle = delta_angle;
|
||||
}
|
||||
virtual bool Execute(Event event);
|
||||
|
||||
protected:
|
||||
float distance, delta_angle;
|
||||
};
|
||||
|
||||
class MimironRapidBurstAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
MimironRapidBurstAction(PlayerbotAI* ai) : MovementAction(ai, "mimiron rapid burst action") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class MimironAerialCommandUnitAction : public Action
|
||||
{
|
||||
public:
|
||||
MimironAerialCommandUnitAction(PlayerbotAI* ai) : Action(ai, "mimiron aerial command unit action") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class MimironRocketStrikeAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
MimironRocketStrikeAction(PlayerbotAI* ai) : MovementAction(ai, "mimiron rocket strike action") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class MimironPhase4MarkDpsAction : public Action
|
||||
{
|
||||
public:
|
||||
MimironPhase4MarkDpsAction(PlayerbotAI* ai) : Action(ai, "mimiron phase 4 mark dps action") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class MimironCheatAction : public Action
|
||||
{
|
||||
public:
|
||||
MimironCheatAction(PlayerbotAI* ai) : Action(ai, "mimiron cheat action") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -190,9 +190,41 @@ void RaidUlduarStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
//
|
||||
// Mimiron
|
||||
//
|
||||
triggers.push_back(new TriggerNode(
|
||||
"mimiron p3wx2 laser barrage trigger",
|
||||
NextAction::array(0, new NextAction("mimiron p3wx2 laser barrage action", ACTION_RAID + 2), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"mimiron shock blast trigger",
|
||||
NextAction::array(0, new NextAction("mimiron shock blast action", ACTION_RAID + 1), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"mimiron fire resistance trigger",
|
||||
NextAction::array(0, new NextAction("mimiron fire resistance action", ACTION_RAID), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"mimiron phase 1 positioning trigger",
|
||||
NextAction::array(0, new NextAction("mimiron phase 1 positioning action", ACTION_RAID), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"mimiron rapid burst trigger",
|
||||
NextAction::array(0, new NextAction("mimiron rapid burst action", ACTION_RAID), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"mimiron aerial command unit trigger",
|
||||
NextAction::array(0, new NextAction("mimiron aerial command unit action", ACTION_RAID), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"mimiron rocket strike trigger",
|
||||
NextAction::array(0, new NextAction("mimiron rocket strike action", ACTION_RAID), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"mimiron phase 4 mark dps trigger",
|
||||
NextAction::array(0, new NextAction("mimiron phase 4 mark dps action", ACTION_RAID), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"mimiron cheat trigger",
|
||||
NextAction::array(0, new NextAction("mimiron cheat action", ACTION_RAID), nullptr)));
|
||||
}
|
||||
|
||||
void RaidUlduarStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
||||
|
||||
@@ -56,6 +56,14 @@ public:
|
||||
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;
|
||||
creators["mimiron shock blast trigger"] = &RaidUlduarTriggerContext::mimiron_shock_blast_trigger;
|
||||
creators["mimiron phase 1 positioning trigger"] = &RaidUlduarTriggerContext::mimiron_phase_1_positioning_trigger;
|
||||
creators["mimiron p3wx2 laser barrage trigger"] = &RaidUlduarTriggerContext::mimiron_p3wx2_laser_barrage_trigger;
|
||||
creators["mimiron rapid burst trigger"] = &RaidUlduarTriggerContext::mimiron_rapid_burst_trigger;
|
||||
creators["mimiron aerial command unit trigger"] = &RaidUlduarTriggerContext::mimiron_aerial_command_unit_trigger;
|
||||
creators["mimiron rocket strike trigger"] = &RaidUlduarTriggerContext::mimiron_rocket_strike_trigger;
|
||||
creators["mimiron phase 4 mark dps trigger"] = &RaidUlduarTriggerContext::mimiron_phase_4_mark_dps_trigger;
|
||||
creators["mimiron cheat trigger"] = &RaidUlduarTriggerContext::mimiron_cheat_trigger;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -99,6 +107,14 @@ private:
|
||||
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"); }
|
||||
static Trigger* mimiron_shock_blast_trigger(PlayerbotAI* ai) { return new MimironShockBlastTrigger(ai); }
|
||||
static Trigger* mimiron_phase_1_positioning_trigger(PlayerbotAI* ai) { return new MimironPhase1PositioningTrigger(ai); }
|
||||
static Trigger* mimiron_p3wx2_laser_barrage_trigger(PlayerbotAI* ai) { return new MimironP3Wx2LaserBarrageTrigger(ai); }
|
||||
static Trigger* mimiron_rapid_burst_trigger(PlayerbotAI* ai) { return new MimironRapidBurstTrigger(ai); }
|
||||
static Trigger* mimiron_aerial_command_unit_trigger(PlayerbotAI* ai) { return new MimironAerialCommandUnitTrigger(ai); }
|
||||
static Trigger* mimiron_rocket_strike_trigger(PlayerbotAI* ai) { return new MimironRocketStrikeTrigger(ai); }
|
||||
static Trigger* mimiron_phase_4_mark_dps_trigger(PlayerbotAI* ai) { return new MimironPhase4MarkDpsTrigger(ai); }
|
||||
static Trigger* mimiron_cheat_trigger(PlayerbotAI* ai) { return new MimironCheatTrigger(ai); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "SharedDefines.h"
|
||||
#include "Trigger.h"
|
||||
#include "Vehicle.h"
|
||||
#include <MovementActions.h>
|
||||
|
||||
const std::vector<uint32> availableVehicles = {NPC_VEHICLE_CHOPPER, NPC_SALVAGED_DEMOLISHER,
|
||||
NPC_SALVAGED_DEMOLISHER_TURRET, NPC_SALVAGED_SIEGE_ENGINE,
|
||||
@@ -1108,3 +1109,451 @@ bool ThorimPhase2PositioningTrigger::IsActive()
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MimironShockBlastTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "leviathan mk ii");
|
||||
|
||||
// Check boss and it is alive
|
||||
if (!boss || !boss->IsAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!boss->HasUnitState(UNIT_STATE_CASTING) || !boss->FindCurrentSpellBySpellId(SPELL_SHOCK_BLAST))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (botAI->IsMelee(bot))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return bot->GetDistance2d(boss) < 15.0f;
|
||||
}
|
||||
}
|
||||
|
||||
bool MimironPhase1PositioningTrigger::IsActive()
|
||||
{
|
||||
if (!botAI->IsRanged(bot))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Unit* leviathanMkII = nullptr;
|
||||
Unit* vx001 = nullptr;
|
||||
Unit* aerialCommandUnit = nullptr;
|
||||
|
||||
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;
|
||||
|
||||
if (target->GetEntry() == NPC_LEVIATHAN_MKII)
|
||||
{
|
||||
leviathanMkII = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_VX001)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_AERIAL_COMMAND_UNIT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!leviathanMkII || !leviathanMkII->IsAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return AI_VALUE(float, "disperse distance") != 6.0f;
|
||||
}
|
||||
|
||||
bool MimironP3Wx2LaserBarrageTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "vx-001");
|
||||
|
||||
// Check boss and it is alive
|
||||
if (!boss || !boss->IsAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCasting = boss->HasUnitState(UNIT_STATE_CASTING);
|
||||
bool isP3WX2LaserBarrage = boss->FindCurrentSpellBySpellId(SPELL_SPINNING_UP) ||
|
||||
boss->FindCurrentSpellBySpellId(SPELL_P3WX2_LASER_BARRAGE_1) ||
|
||||
boss->FindCurrentSpellBySpellId(SPELL_P3WX2_LASER_BARRAGE_2) ||
|
||||
boss->FindCurrentSpellBySpellId(SPELL_P3WX2_LASER_BARRAGE_AURA_1) ||
|
||||
boss->FindCurrentSpellBySpellId(SPELL_P3WX2_LASER_BARRAGE_AURA_2) ||
|
||||
boss->FindCurrentSpellBySpellId(SPELL_P3WX2_LASER_BARRAGE_3);
|
||||
bool hasP3WX2LaserBarrageAura =
|
||||
boss->HasAura(SPELL_P3WX2_LASER_BARRAGE_AURA_1) || boss->HasAura(SPELL_P3WX2_LASER_BARRAGE_AURA_2);
|
||||
|
||||
if ((!isCasting && !hasP3WX2LaserBarrageAura) || !isP3WX2LaserBarrage)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MimironRapidBurstTrigger::IsActive()
|
||||
{
|
||||
Unit* leviathanMkII = nullptr;
|
||||
Unit* vx001 = nullptr;
|
||||
Unit* aerialCommandUnit = nullptr;
|
||||
|
||||
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;
|
||||
|
||||
if (target->GetEntry() == NPC_LEVIATHAN_MKII)
|
||||
{
|
||||
leviathanMkII = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_VX001)
|
||||
{
|
||||
vx001 = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_AERIAL_COMMAND_UNIT)
|
||||
{
|
||||
aerialCommandUnit = target;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vx001 || !vx001->IsAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (leviathanMkII && leviathanMkII->HasUnitState(UNIT_STATE_CASTING) &&
|
||||
leviathanMkII->FindCurrentSpellBySpellId(SPELL_SHOCK_BLAST))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (botAI->IsMainTank(bot) && leviathanMkII && leviathanMkII->IsAlive() && leviathanMkII->GetVictim() != bot)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (botAI->IsMelee(bot) && !botAI->IsMainTank(bot) && leviathanMkII && aerialCommandUnit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MimironP3Wx2LaserBarrageTrigger mimironP3Wx2LaserBarrageTrigger(botAI);
|
||||
if (mimironP3Wx2LaserBarrageTrigger.IsActive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 memberSpotNumber = 0;
|
||||
Position memberPosition;
|
||||
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||
{
|
||||
Player* member = gref->GetSource();
|
||||
if (!member)
|
||||
continue;
|
||||
|
||||
if (bot->GetGUID() == member->GetGUID())
|
||||
{
|
||||
if (botAI->IsRanged(bot))
|
||||
{
|
||||
switch (memberSpotNumber)
|
||||
{
|
||||
case 0:
|
||||
memberPosition = ULDUAR_MIMIRON_PHASE2_SIDE1RANGE_SPOT;
|
||||
break;
|
||||
case 1:
|
||||
memberPosition = ULDUAR_MIMIRON_PHASE2_SIDE2RANGE_SPOT;
|
||||
break;
|
||||
case 2:
|
||||
memberPosition = ULDUAR_MIMIRON_PHASE2_SIDE3RANGE_SPOT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (botAI->IsMainTank(bot) && leviathanMkII)
|
||||
{
|
||||
memberPosition = ULDUAR_MIMIRON_PHASE4_TANK_SPOT;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (memberSpotNumber)
|
||||
{
|
||||
case 0:
|
||||
memberPosition = ULDUAR_MIMIRON_PHASE2_SIDE1MELEE_SPOT;
|
||||
break;
|
||||
case 1:
|
||||
memberPosition = ULDUAR_MIMIRON_PHASE2_SIDE2MELEE_SPOT;
|
||||
break;
|
||||
case 2:
|
||||
memberPosition = ULDUAR_MIMIRON_PHASE2_SIDE3MELEE_SPOT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
memberSpotNumber++;
|
||||
|
||||
if (memberSpotNumber == 3)
|
||||
{
|
||||
memberSpotNumber = 0;
|
||||
}
|
||||
}
|
||||
|
||||
GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs");
|
||||
float nearestRocketStrikeDistance = std::numeric_limits<float>::max();
|
||||
bool rocketStrikeDetected = false;
|
||||
|
||||
for (const ObjectGuid& guid : npcs)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(guid);
|
||||
if (!unit)
|
||||
continue;
|
||||
|
||||
if (unit->GetEntry() == NPC_ROCKET_STRIKE_N)
|
||||
{
|
||||
rocketStrikeDetected = true;
|
||||
float distance = bot->GetDistance2d(memberPosition.GetPositionX(), memberPosition.GetPositionY());
|
||||
if (distance < nearestRocketStrikeDistance)
|
||||
{
|
||||
nearestRocketStrikeDistance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (bot->GetDistance(memberPosition) > 7.0f && !rocketStrikeDetected) ||
|
||||
bot->GetDistance(memberPosition) > 20.0f;
|
||||
}
|
||||
|
||||
bool MimironAerialCommandUnitTrigger::IsActive()
|
||||
{
|
||||
Unit* leviathanMkII = nullptr;
|
||||
Unit* vx001 = nullptr;
|
||||
Unit* aerialCommandUnit = nullptr;
|
||||
//Unit* bombBot = nullptr;
|
||||
Unit* assaultBot = nullptr;
|
||||
|
||||
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;
|
||||
|
||||
if (target->GetEntry() == NPC_LEVIATHAN_MKII)
|
||||
{
|
||||
leviathanMkII = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_VX001)
|
||||
{
|
||||
vx001 = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_AERIAL_COMMAND_UNIT)
|
||||
{
|
||||
aerialCommandUnit = target;
|
||||
}
|
||||
//else if (target->GetEntry() == NPC_BOMB_BOT)
|
||||
//{
|
||||
// bombBot = target;
|
||||
//}
|
||||
else if (target->GetEntry() == NPC_ASSAULT_BOT)
|
||||
{
|
||||
assaultBot = target;
|
||||
}
|
||||
}
|
||||
|
||||
if (!aerialCommandUnit || !aerialCommandUnit->IsAlive() || leviathanMkII || vx001)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!botAI->IsRanged(bot) && !botAI->IsMainTank(bot) && !botAI->IsAssistTankOfIndex(bot, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (botAI->IsMainTank(bot) || botAI->IsAssistTankOfIndex(bot, 0))
|
||||
{
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjectGuid skullTarget = group->GetTargetIcon(skullIndex);
|
||||
ObjectGuid crossTarget = group->GetTargetIcon(crossIndex);
|
||||
|
||||
//if (bombBot && bombBot->GetGUID() != crossTarget)
|
||||
//{
|
||||
// return true;
|
||||
//}
|
||||
if (!crossTarget || aerialCommandUnit->GetGUID() != crossTarget)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (assaultBot && (!skullTarget || assaultBot->GetGUID() != skullTarget))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string rtiMark = AI_VALUE(std::string, "rti");
|
||||
if (rtiMark != "cross")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MimironRocketStrikeTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "vx-001");
|
||||
|
||||
// Check boss and it is alive
|
||||
if (!boss || !boss->IsAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Creature* rocketStrikeN = bot->FindNearestCreature(NPC_ROCKET_STRIKE_N, 100.0f);
|
||||
|
||||
if (!rocketStrikeN)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return bot->GetDistance2d(rocketStrikeN->GetPositionX(), rocketStrikeN->GetPositionY()) <= 10.0f;
|
||||
}
|
||||
|
||||
bool MimironPhase4MarkDpsTrigger::IsActive()
|
||||
{
|
||||
Unit* leviathanMkII = nullptr;
|
||||
Unit* vx001 = nullptr;
|
||||
Unit* aerialCommandUnit = nullptr;
|
||||
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (target->GetEntry() == NPC_LEVIATHAN_MKII)
|
||||
{
|
||||
leviathanMkII = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_VX001)
|
||||
{
|
||||
vx001 = target;
|
||||
}
|
||||
else if (target->GetEntry() == NPC_AERIAL_COMMAND_UNIT)
|
||||
{
|
||||
aerialCommandUnit = target;
|
||||
}
|
||||
}
|
||||
|
||||
if (!leviathanMkII || !vx001 || !aerialCommandUnit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (botAI->IsMainTank(bot))
|
||||
{
|
||||
Unit* highestHealthUnit = nullptr;
|
||||
uint32 highestHealth = 0;
|
||||
|
||||
if (leviathanMkII && leviathanMkII->GetHealth() > highestHealth)
|
||||
{
|
||||
highestHealth = leviathanMkII->GetHealth();
|
||||
highestHealthUnit = leviathanMkII;
|
||||
}
|
||||
if (vx001 && vx001->GetHealth() > highestHealth)
|
||||
{
|
||||
highestHealth = vx001->GetHealth();
|
||||
highestHealthUnit = vx001;
|
||||
}
|
||||
if (aerialCommandUnit && aerialCommandUnit->GetHealth() > highestHealth)
|
||||
{
|
||||
highestHealthUnit = aerialCommandUnit;
|
||||
}
|
||||
|
||||
ObjectGuid skullTarget = group->GetTargetIcon(skullIndex);
|
||||
if (!skullTarget)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return highestHealthUnit->GetGUID() != skullTarget;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AI_VALUE(std::string, "rti") != "skull";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MimironCheatTrigger::IsActive()
|
||||
{
|
||||
if (!botAI->IsMainTank(bot))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
GuidVector targets = AI_VALUE(GuidVector, "nearest npcs");
|
||||
for (const ObjectGuid& guid : targets)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(guid);
|
||||
if (!unit || !unit->IsAlive())
|
||||
continue;
|
||||
|
||||
if (unit->GetEntry() == NPC_PROXIMITY_MINE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (unit->GetEntry() == NPC_BOMB_BOT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -61,6 +61,22 @@ enum UlduarIDs
|
||||
NPC_DARK_RUNE_ACOLYTE_G = 33110,
|
||||
NPC_IRON_HONOR_GUARD = 32875,
|
||||
SPELL_UNBALANCING_STRIKE = 62130,
|
||||
|
||||
//Mimiron
|
||||
NPC_LEVIATHAN_MKII = 33432,
|
||||
NPC_VX001 = 33651,
|
||||
NPC_AERIAL_COMMAND_UNIT = 33670,
|
||||
NPC_BOMB_BOT = 33836,
|
||||
NPC_ROCKET_STRIKE_N = 34047,
|
||||
NPC_ASSAULT_BOT = 34057,
|
||||
NPC_PROXIMITY_MINE = 34362,
|
||||
SPELL_P3WX2_LASER_BARRAGE_1 = 63293,
|
||||
SPELL_P3WX2_LASER_BARRAGE_2 = 63297,
|
||||
SPELL_SPINNING_UP = 63414,
|
||||
SPELL_SHOCK_BLAST = 63631,
|
||||
SPELL_P3WX2_LASER_BARRAGE_3 = 64042,
|
||||
SPELL_P3WX2_LASER_BARRAGE_AURA_1 = 63274,
|
||||
SPELL_P3WX2_LASER_BARRAGE_AURA_2 = 63300,
|
||||
|
||||
// Buffs
|
||||
SPELL_FROST_TRAP = 13809
|
||||
@@ -94,6 +110,13 @@ const Position ULDUAR_THORIM_PHASE2_TANK_SPOT = Position(2134.8572f, -287.0291f,
|
||||
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);
|
||||
const Position ULDUAR_MIMIRON_PHASE2_SIDE1RANGE_SPOT = Position(2753.708f, 2583.9617f, 364.31357f);
|
||||
const Position ULDUAR_MIMIRON_PHASE2_SIDE1MELEE_SPOT = Position(2746.9792f, 2573.6716f, 364.31357f);
|
||||
const Position ULDUAR_MIMIRON_PHASE2_SIDE2RANGE_SPOT = Position(2727.7224f, 2569.527f, 364.31357f);
|
||||
const Position ULDUAR_MIMIRON_PHASE2_SIDE2MELEE_SPOT = Position(2739.4746f, 2569.4106f, 364.31357f);
|
||||
const Position ULDUAR_MIMIRON_PHASE2_SIDE3RANGE_SPOT = Position(2754.1294f, 2553.9954f, 364.31357f);
|
||||
const Position ULDUAR_MIMIRON_PHASE2_SIDE3MELEE_SPOT = Position(2746.8513f, 2565.4263f, 364.31357f);
|
||||
const Position ULDUAR_MIMIRON_PHASE4_TANK_SPOT = Position(2744.5754f, 2570.8657f, 364.3138f);
|
||||
|
||||
//
|
||||
// Flame Levi
|
||||
@@ -336,4 +359,63 @@ public:
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
//
|
||||
// Mimiron
|
||||
//
|
||||
class MimironShockBlastTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
MimironShockBlastTrigger(PlayerbotAI* ai) : Trigger(ai, "mimiron shock blast trigger") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class MimironPhase1PositioningTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
MimironPhase1PositioningTrigger(PlayerbotAI* ai) : Trigger(ai, "mimiron phase 1 positioning trigger") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class MimironP3Wx2LaserBarrageTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
MimironP3Wx2LaserBarrageTrigger(PlayerbotAI* ai) : Trigger(ai, "mimiron p3wx2 laser barrage trigger") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class MimironRapidBurstTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
MimironRapidBurstTrigger(PlayerbotAI* ai) : Trigger(ai, "mimiron rapid burst trigger") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class MimironAerialCommandUnitTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
MimironAerialCommandUnitTrigger(PlayerbotAI* ai) : Trigger(ai, "mimiron aerial command unit trigger") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class MimironRocketStrikeTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
MimironRocketStrikeTrigger(PlayerbotAI* ai) : Trigger(ai, "mimiron rocket strike trigger") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class MimironPhase4MarkDpsTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
MimironPhase4MarkDpsTrigger(PlayerbotAI* ai) : Trigger(ai, "mimiron phase 4 mark dps trigger") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class MimironCheatTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
MimironCheatTrigger(PlayerbotAI* ai) : Trigger(ai, "mimiron cheat trigger") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,7 @@ void NearestNpcsValue::FindUnits(std::list<Unit*>& targets)
|
||||
Cell::VisitAllObjects(bot, searcher, range);
|
||||
}
|
||||
|
||||
bool NearestNpcsValue::AcceptUnit(Unit* unit) { return !unit->IsHostileTo(bot) && !unit->IsPlayer(); }
|
||||
bool NearestNpcsValue::AcceptUnit(Unit* unit) { return !unit->IsPlayer(); }
|
||||
|
||||
void NearestHostileNpcsValue::FindUnits(std::list<Unit*>& targets)
|
||||
{
|
||||
@@ -64,4 +64,4 @@ void NearestTotemsValue::FindUnits(std::list<Unit*>& targets)
|
||||
Cell::VisitAllObjects(bot, searcher, range);
|
||||
}
|
||||
|
||||
bool NearestTotemsValue::AcceptUnit(Unit* unit) { return unit->IsTotem(); }
|
||||
bool NearestTotemsValue::AcceptUnit(Unit* unit) { return unit->IsTotem(); }
|
||||
|
||||
Reference in New Issue
Block a user