mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-21 20:46:22 +00:00
- Changed Eye of Eternity healers selection (#1102)
- Added Iron Assembly strategies for normal mode - Improved Hodir Biting Cold strategy
This commit is contained in:
@@ -24,7 +24,10 @@ public:
|
||||
creators["razorscale grounded"] = &RaidUlduarActionContext::razorscale_grounded;
|
||||
creators["razorscale harpoon action"] = &RaidUlduarActionContext::razorscale_harpoon_action;
|
||||
creators["razorscale fuse armor action"] = &RaidUlduarActionContext::razorscale_fuse_armor_action;
|
||||
creators["iron assembly lightning tendrils action"] = &RaidUlduarActionContext::iron_assembly_lightning_tendrils_action;
|
||||
creators["iron assembly overload action"] = &RaidUlduarActionContext::iron_assembly_overload_action;
|
||||
creators["hodir move snowpacked icicle"] = &RaidUlduarActionContext::hodir_move_snowpacked_icicle;
|
||||
creators["hodir biting cold jump"] = &RaidUlduarActionContext::hodir_biting_cold_jump;
|
||||
creators["freya move away nature bomb"] = &RaidUlduarActionContext::freya_move_away_nature_bomb;
|
||||
creators["freya mark eonars gift"] = &RaidUlduarActionContext::freya_mark_eonars_gift;
|
||||
}
|
||||
@@ -39,7 +42,10 @@ private:
|
||||
static Action* razorscale_grounded(PlayerbotAI* ai) { return new RazorscaleGroundedAction(ai); }
|
||||
static Action* razorscale_harpoon_action(PlayerbotAI* ai) { return new RazorscaleHarpoonAction(ai); }
|
||||
static Action* razorscale_fuse_armor_action(PlayerbotAI* ai) { return new RazorscaleFuseArmorAction(ai); }
|
||||
static Action* iron_assembly_lightning_tendrils_action(PlayerbotAI* ai) { return new IronAssemblyLightningTendrilsAction(ai); }
|
||||
static Action* iron_assembly_overload_action(PlayerbotAI* ai) { return new IronAssemblyOverloadAction(ai); }
|
||||
static Action* hodir_move_snowpacked_icicle(PlayerbotAI* ai) { return new HodirMoveSnowpackedIcicleAction(ai); }
|
||||
static Action* hodir_biting_cold_jump(PlayerbotAI* ai) { return new HodirBitingColdJumpAction(ai); }
|
||||
static Action* freya_move_away_nature_bomb(PlayerbotAI* ai) { return new FreyaMoveAwayNatureBombAction(ai); }
|
||||
static Action* freya_mark_eonars_gift(PlayerbotAI* ai) { return new FreyaMarkEonarsGiftAction(ai); }
|
||||
};
|
||||
|
||||
@@ -1166,6 +1166,54 @@ bool RazorscaleFuseArmorAction::Execute(Event event)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IronAssemblyLightningTendrilsAction::isUseful()
|
||||
{
|
||||
IronAssemblyLightningTendrilsTrigger ironAssemblyLightningTendrilsTrigger(botAI);
|
||||
return ironAssemblyLightningTendrilsTrigger.IsActive();
|
||||
}
|
||||
|
||||
bool IronAssemblyLightningTendrilsAction::Execute(Event event)
|
||||
{
|
||||
const float radius = 18.0f + 10.0f; // 18 yards + 10 yards for safety
|
||||
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "stormcaller brundir");
|
||||
if (!boss)
|
||||
return false;
|
||||
|
||||
float currentDistance = bot->GetDistance2d(boss);
|
||||
|
||||
if (currentDistance < radius)
|
||||
{
|
||||
return MoveAway(boss, radius - currentDistance);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IronAssemblyOverloadAction::isUseful()
|
||||
{
|
||||
IronAssemblyOverloadTrigger ironAssemblyOverloadTrigger(botAI);
|
||||
return ironAssemblyOverloadTrigger.IsActive();
|
||||
}
|
||||
|
||||
bool IronAssemblyOverloadAction::Execute(Event event)
|
||||
{
|
||||
const float radius = 20.0f + 5.0f; // 20 yards + 5 yards for safety
|
||||
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "stormcaller brundir");
|
||||
if (!boss)
|
||||
return false;
|
||||
|
||||
float currentDistance = bot->GetDistance2d(boss);
|
||||
|
||||
if (currentDistance < radius)
|
||||
{
|
||||
return MoveAway(boss, radius - currentDistance);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HodirMoveSnowpackedIcicleAction::isUseful()
|
||||
{
|
||||
// Check boss and it is alive
|
||||
@@ -1175,13 +1223,19 @@ bool HodirMoveSnowpackedIcicleAction::isUseful()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if boss is casting Flash Freeze
|
||||
if (!boss->HasUnitState(UNIT_STATE_CASTING) || !boss->FindCurrentSpellBySpellId(SPELL_FLASH_FREEZE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the nearest Snowpacked Icicle Target
|
||||
Creature* target = bot->FindNearestCreature(33174, 100.0f);
|
||||
Creature* target = bot->FindNearestCreature(NPC_SNOWPACKED_ICICLE, 100.0f);
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
// Check that boss is stacked on Snowpacked Icicle
|
||||
if (bot->GetDistance2d(target->GetPositionX(), target->GetPositionY()) <= 3.0f)
|
||||
// Check that bot is stacked on Snowpacked Icicle
|
||||
if (bot->GetDistance2d(target->GetPositionX(), target->GetPositionY()) <= 5.0f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1191,12 +1245,42 @@ bool HodirMoveSnowpackedIcicleAction::isUseful()
|
||||
|
||||
bool HodirMoveSnowpackedIcicleAction::Execute(Event event)
|
||||
{
|
||||
Creature* target = bot->FindNearestCreature(33174, 100.0f);
|
||||
Creature* target = bot->FindNearestCreature(NPC_SNOWPACKED_ICICLE, 100.0f);
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
return MoveTo(target->GetMapId(), target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false,
|
||||
false, false, true, MovementPriority::MOVEMENT_NORMAL);
|
||||
false, false, true, MovementPriority::MOVEMENT_NORMAL, true);
|
||||
}
|
||||
|
||||
bool HodirBitingColdJumpAction::Execute(Event event)
|
||||
{
|
||||
// This needs improving but maybe it should be done in the playerbot core.
|
||||
|
||||
int mapId = bot->GetMap()->GetId();
|
||||
int x = bot->GetPositionX();
|
||||
int y = bot->GetPositionY();
|
||||
int z = bot->GetPositionZ() + 3.98f;
|
||||
float speed = 7.96f;
|
||||
|
||||
UpdateMovementState();
|
||||
if (!IsMovingAllowed(mapId, x, y, z))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
MovementPriority priority;
|
||||
if (IsWaitingForLastMove(priority))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MotionMaster& mm = *bot->GetMotionMaster();
|
||||
mm.Clear();
|
||||
mm.MoveJump(x, y, z, speed, speed, 1, AI_VALUE(Unit*, "current target"));
|
||||
mm.MoveFall(0, true);
|
||||
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), 1000, priority);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FreyaMoveAwayNatureBombAction::isUseful()
|
||||
|
||||
@@ -114,6 +114,29 @@ public:
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class IronAssemblyLightningTendrilsAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
IronAssemblyLightningTendrilsAction(PlayerbotAI* botAI) : MovementAction(botAI, "iron assembly lightning tendrils action") {}
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class IronAssemblyOverloadAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
IronAssemblyOverloadAction(PlayerbotAI* botAI) : MovementAction(botAI, "iron assembly overload action") {}
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class HodirBitingColdJumpAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
HodirBitingColdJumpAction(PlayerbotAI* ai) : MovementAction(ai, "hodir biting cold jump") {}
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class FreyaMoveAwayNatureBombAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -46,25 +46,38 @@ void RaidUlduarStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
"razorscale fuse armor trigger",
|
||||
NextAction::array(0, new NextAction("razorscale fuse armor action", ACTION_RAID + 2), nullptr)));
|
||||
|
||||
//
|
||||
// Iron Assembly
|
||||
//
|
||||
triggers.push_back(new TriggerNode(
|
||||
"iron assembly lightning tendrils trigger",
|
||||
NextAction::array(0, new NextAction("iron assembly lightning tendrils action", ACTION_RAID), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"iron assembly overload trigger",
|
||||
NextAction::array(0, new NextAction("iron assembly overload action", ACTION_RAID), nullptr)));
|
||||
|
||||
//
|
||||
// Hodir
|
||||
//
|
||||
triggers.push_back(new TriggerNode(
|
||||
"hodir near snowpacked icicle",
|
||||
NextAction::array(0, new NextAction("hodir move snowpacked icicle", ACTION_RAID + 5), nullptr)));
|
||||
NextAction::array(0, new NextAction("hodir move snowpacked icicle", ACTION_RAID + 1), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"hodir biting cold", NextAction::array(0, new NextAction("intense cold jump", ACTION_RAID + 4), nullptr)));
|
||||
"hodir biting cold",
|
||||
NextAction::array(0, new NextAction("hodir biting cold jump", ACTION_RAID), nullptr)));
|
||||
|
||||
//
|
||||
// Freya
|
||||
//
|
||||
triggers.push_back(
|
||||
new TriggerNode("freya tank near eonars gift",
|
||||
NextAction::array(0, new NextAction("freya mark eonars gift", ACTION_RAID + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"freya tank near eonars gift",
|
||||
NextAction::array(0, new NextAction("freya mark eonars gift", ACTION_RAID + 1), nullptr)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("freya near nature bomb",
|
||||
NextAction::array(0, new NextAction("freya move away nature bomb", ACTION_RAID), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"freya near nature bomb",
|
||||
NextAction::array(0, new NextAction("freya move away nature bomb", ACTION_RAID), nullptr)));
|
||||
}
|
||||
|
||||
void RaidUlduarStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
||||
|
||||
@@ -24,6 +24,8 @@ public:
|
||||
creators["razorscale grounded"] = &RaidUlduarTriggerContext::razorscale_grounded;
|
||||
creators["razorscale harpoon trigger"] = &RaidUlduarTriggerContext::razorscale_harpoon_trigger;
|
||||
creators["razorscale fuse armor trigger"] = &RaidUlduarTriggerContext::razorscale_fuse_armor_trigger;
|
||||
creators["iron assembly lightning tendrils trigger"] = &RaidUlduarTriggerContext::iron_assembly_lightning_tendrils_trigger;
|
||||
creators["iron assembly overload trigger"] = &RaidUlduarTriggerContext::iron_assembly_overload_trigger;
|
||||
creators["hodir biting cold"] = &RaidUlduarTriggerContext::hodir_biting_cold;
|
||||
creators["hodir near snowpacked icicle"] = &RaidUlduarTriggerContext::hodir_near_snowpacked_icicle;
|
||||
creators["freya near nature bomb"] = &RaidUlduarTriggerContext::freya_near_nature_bomb;
|
||||
@@ -40,6 +42,8 @@ private:
|
||||
static Trigger* razorscale_grounded(PlayerbotAI* ai) { return new RazorscaleGroundedTrigger(ai); }
|
||||
static Trigger* razorscale_harpoon_trigger(PlayerbotAI* ai) { return new RazorscaleHarpoonAvailableTrigger(ai); }
|
||||
static Trigger* razorscale_fuse_armor_trigger(PlayerbotAI* ai) { return new RazorscaleFuseArmorTrigger(ai); }
|
||||
static Trigger* iron_assembly_lightning_tendrils_trigger(PlayerbotAI* ai) { return new IronAssemblyLightningTendrilsTrigger(ai); }
|
||||
static Trigger* iron_assembly_overload_trigger(PlayerbotAI* ai) { return new IronAssemblyOverloadTrigger(ai); }
|
||||
static Trigger* hodir_biting_cold(PlayerbotAI* ai) { return new HodirBitingColdTrigger(ai); }
|
||||
static Trigger* hodir_near_snowpacked_icicle(PlayerbotAI* ai) { return new HodirNearSnowpackedIcicleTrigger(ai); }
|
||||
static Trigger* freya_near_nature_bomb(PlayerbotAI* ai) { return new FreyaNearNatureBombTrigger(ai); }
|
||||
|
||||
@@ -242,10 +242,58 @@ bool RazorscaleFuseArmorTrigger::IsActive()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IronAssemblyLightningTendrilsTrigger::IsActive()
|
||||
{
|
||||
// Check boss and it is alive
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "stormcaller brundir");
|
||||
if (!boss || !boss->IsAlive())
|
||||
return false;
|
||||
|
||||
// Check if bot is within 35 yards of the boss
|
||||
if (boss->GetDistance(bot) > 35.0f)
|
||||
return false;
|
||||
|
||||
// Check if the boss has the Lightning Tendrils aura
|
||||
return boss->HasAura(SPELL_LIGHTNING_TENDRILS_10_MAN) || boss->HasAura(SPELL_LIGHTNING_TENDRILS_25_MAN);
|
||||
}
|
||||
|
||||
bool IronAssemblyOverloadTrigger::IsActive()
|
||||
{
|
||||
// Check if bot is tank
|
||||
if (botAI->IsTank(bot))
|
||||
return false;
|
||||
|
||||
// Check boss and it is alive
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "stormcaller brundir");
|
||||
if (!boss || !boss->IsAlive())
|
||||
return false;
|
||||
|
||||
// Check if bot is within 35 yards of the boss
|
||||
if (boss->GetDistance(bot) > 35.0f)
|
||||
return false;
|
||||
|
||||
// Check if the boss has the Overload aura
|
||||
return boss->HasAura(SPELL_OVERLOAD_10_MAN) || boss->HasAura(SPELL_OVERLOAD_25_MAN) ||
|
||||
boss->HasAura(SPELL_OVERLOAD_10_MAN_2) || boss->HasAura(SPELL_OVERLOAD_25_MAN_2);
|
||||
}
|
||||
|
||||
bool HodirBitingColdTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "hodir");
|
||||
return boss && botAI->GetAura("biting cold", bot, false, false);
|
||||
|
||||
// Check boss and it is alive
|
||||
if (!boss || !boss->IsAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Override if boss is casting Flash Freeze
|
||||
if (!boss->HasUnitState(UNIT_STATE_CASTING) || !boss->FindCurrentSpellBySpellId(SPELL_FLASH_FREEZE))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return boss && botAI->GetAura("biting cold", bot, false, false, 2);
|
||||
}
|
||||
|
||||
//Snowpacked Icicle Target
|
||||
@@ -258,9 +306,24 @@ bool HodirNearSnowpackedIcicleTrigger::IsActive()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if boss is casting Flash Freeze
|
||||
if (!boss->HasUnitState(UNIT_STATE_CASTING) || !boss->FindCurrentSpellBySpellId(SPELL_FLASH_FREEZE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the nearest Snowpacked Icicle Target
|
||||
Creature* target = bot->FindNearestCreature(33174, 100.0f);
|
||||
return target != nullptr;
|
||||
Creature* target = bot->FindNearestCreature(NPC_SNOWPACKED_ICICLE, 100.0f);
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
// Check that bot is stacked on Snowpacked Icicle
|
||||
if (bot->GetDistance2d(target->GetPositionX(), target->GetPositionY()) <= 5.0f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FreyaNearNatureBombTrigger::IsActive()
|
||||
|
||||
@@ -9,9 +9,21 @@
|
||||
|
||||
enum UlduarIDs
|
||||
{
|
||||
// Iron Assembly
|
||||
SPELL_LIGHTNING_TENDRILS_10_MAN = 61887,
|
||||
SPELL_LIGHTNING_TENDRILS_25_MAN = 63486,
|
||||
SPELL_OVERLOAD_10_MAN = 61869,
|
||||
SPELL_OVERLOAD_25_MAN = 63481,
|
||||
SPELL_OVERLOAD_10_MAN_2 = 63485,
|
||||
SPELL_OVERLOAD_25_MAN_2 = 61886,
|
||||
|
||||
// Hodir
|
||||
NPC_SNOWPACKED_ICICLE = 33174,
|
||||
NPC_TOASTY_FIRE = 33342,
|
||||
SPELL_FLASH_FREEZE = 61968,
|
||||
|
||||
// Freya
|
||||
NPC_EONARS_GIFT = 33228,
|
||||
|
||||
GOBJECT_NATURE_BOMB = 194902,
|
||||
};
|
||||
|
||||
@@ -84,6 +96,26 @@ public:
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
//
|
||||
// Iron Assembly
|
||||
//
|
||||
class IronAssemblyLightningTendrilsTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
IronAssemblyLightningTendrilsTrigger(PlayerbotAI* ai) : Trigger(ai, "iron assembly lightning tendrils trigger") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class IronAssemblyOverloadTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
IronAssemblyOverloadTrigger(PlayerbotAI* ai) : Trigger(ai, "iron assembly overload trigger") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
//
|
||||
// Hodir
|
||||
//
|
||||
class HodirBitingColdTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
@@ -98,6 +130,9 @@ public:
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
//
|
||||
// Freya
|
||||
//
|
||||
class FreyaNearNatureBombTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user