diff --git a/src/Ai/Raid/MC/MCActionContext.h b/src/Ai/Raid/MC/MCActionContext.h index 3cc95257a..111e63922 100644 --- a/src/Ai/Raid/MC/MCActionContext.h +++ b/src/Ai/Raid/MC/MCActionContext.h @@ -26,6 +26,7 @@ public: creators["mc golemagg assist tank attack core rager"] = &RaidMcActionContext::golemagg_assist_tank_attack_core_rager; creators["mc majordomo shadow resistance"] = &RaidMcActionContext::majordomo_shadow_resistance; creators["mc ragnaros fire resistance"] = &RaidMcActionContext::ragnaros_fire_resistance; + creators["mc core hound mark"] = &RaidMcActionContext::core_hound_mark; } private: @@ -44,6 +45,7 @@ private: static Action* golemagg_assist_tank_attack_core_rager(PlayerbotAI* botAI) { return new McGolemaggAssistTankAttackCoreRagerAction(botAI); } static Action* majordomo_shadow_resistance(PlayerbotAI* botAI) { return new BossShadowResistanceAction(botAI, "majordomo executus"); } static Action* ragnaros_fire_resistance(PlayerbotAI* botAI) { return new BossFireResistanceAction(botAI, "ragnaros"); } + static Action* core_hound_mark(PlayerbotAI* botAI) { return new McCoreHoundMarkAction(botAI); } }; #endif diff --git a/src/Ai/Raid/MC/MCActions.cpp b/src/Ai/Raid/MC/MCActions.cpp index 96050ac43..f4868613d 100644 --- a/src/Ai/Raid/MC/MCActions.cpp +++ b/src/Ai/Raid/MC/MCActions.cpp @@ -212,3 +212,45 @@ bool McGolemaggAssistTankAttackCoreRagerAction::Execute(Event event) return false; } + +Unit* McCoreHoundMarkAction::GetTarget() +{ + Unit* highestHealthHound = nullptr; + for (auto const& [guid, ref] : bot->GetThreatMgr().GetThreatenedByMeList()) + { + Unit* unit = ref->GetOwner(); + if (unit && unit->IsAlive() && unit->GetEntry() == NPC_CORE_HOUND) + { + if (!highestHealthHound || unit->GetHealth() > highestHealthHound->GetHealth()) + highestHealthHound = unit; + } + } + + if (!highestHealthHound) + return nullptr; + + Group* group = bot->GetGroup(); + ObjectGuid currentSkullGuid = group ? group->GetTargetIcon(RtiTargetValue::skullIndex) : ObjectGuid::Empty; + if (!currentSkullGuid.IsEmpty() && currentSkullGuid != highestHealthHound->GetGUID()) + { + // Only switch skull if the new target has meaningfully more health (10% buffer) to prevent rapid re-marking + if (Unit* currentSkullUnit = botAI->GetUnit(currentSkullGuid)) + if (currentSkullUnit->IsAlive() && highestHealthHound->GetHealth() <= currentSkullUnit->GetHealth() * 1.10f) + return nullptr; + } + + if (currentSkullGuid.IsEmpty() || currentSkullGuid != highestHealthHound->GetGUID()) + return highestHealthHound; + + return nullptr; +} + +bool McCoreHoundMarkAction::Execute(Event /*event*/) +{ + Unit* target = GetTarget(); + if (!target) + return false; + + bot->GetGroup()->SetTargetIcon(RtiTargetValue::skullIndex, bot->GetGUID(), target->GetGUID()); + return true; +} diff --git a/src/Ai/Raid/MC/MCActions.h b/src/Ai/Raid/MC/MCActions.h index 680b311d3..ad4d47a91 100644 --- a/src/Ai/Raid/MC/MCActions.h +++ b/src/Ai/Raid/MC/MCActions.h @@ -64,4 +64,13 @@ public: bool Execute(Event event) override; }; +class McCoreHoundMarkAction : public Action +{ +public: + McCoreHoundMarkAction(PlayerbotAI* botAI, std::string const name = "mc core hound mark") + : Action(botAI, name) {}; + Unit* GetTarget() override; + bool Execute(Event event) override; +}; + #endif diff --git a/src/Ai/Raid/MC/MCHelpers.h b/src/Ai/Raid/MC/MCHelpers.h index 5dc821246..139cde423 100644 --- a/src/Ai/Raid/MC/MCHelpers.h +++ b/src/Ai/Raid/MC/MCHelpers.h @@ -7,6 +7,9 @@ enum MoltenCoreNPCs { // Golemagg NPC_CORE_RAGER = 11672, + + // Core Hound (trash) + NPC_CORE_HOUND = 11671, }; enum MoltenCoreSpells { diff --git a/src/Ai/Raid/MC/MCStrategy.cpp b/src/Ai/Raid/MC/MCStrategy.cpp index fc63c66b9..0b2eddd23 100644 --- a/src/Ai/Raid/MC/MCStrategy.cpp +++ b/src/Ai/Raid/MC/MCStrategy.cpp @@ -71,6 +71,11 @@ void RaidMcStrategy::InitTriggers(std::vector& triggers) triggers.push_back( new TriggerNode("mc ragnaros fire resistance", { NextAction("mc ragnaros fire resistance", ACTION_RAID) })); + + // Trash + triggers.push_back( + new TriggerNode("mc core hound mark", + { NextAction("mc core hound mark", ACTION_RAID) })); } void RaidMcStrategy::InitMultipliers(std::vector& multipliers) diff --git a/src/Ai/Raid/MC/MCTriggerContext.h b/src/Ai/Raid/MC/MCTriggerContext.h index 7efa95298..67d8b3935 100644 --- a/src/Ai/Raid/MC/MCTriggerContext.h +++ b/src/Ai/Raid/MC/MCTriggerContext.h @@ -25,6 +25,7 @@ public: creators["mc golemagg is assist tank"] = &RaidMcTriggerContext::golemagg_is_assist_tank; creators["mc majordomo shadow resistance"] = &RaidMcTriggerContext::majordomo_shadow_resistance; creators["mc ragnaros fire resistance"] = &RaidMcTriggerContext::ragnaros_fire_resistance; + creators["mc core hound mark"] = &RaidMcTriggerContext::core_hound_mark; } private: @@ -43,6 +44,7 @@ private: static Trigger* golemagg_is_assist_tank(PlayerbotAI* botAI) { return new McGolemaggIsAssistTankTrigger(botAI); } static Trigger* majordomo_shadow_resistance(PlayerbotAI* botAI) { return new BossShadowResistanceTrigger(botAI, "majordomo executus"); } static Trigger* ragnaros_fire_resistance(PlayerbotAI* botAI) { return new BossFireResistanceTrigger(botAI, "ragnaros"); } + static Trigger* core_hound_mark(PlayerbotAI* botAI) { return new McCoreHoundMarkTrigger(botAI); } }; #endif diff --git a/src/Ai/Raid/MC/MCTriggers.cpp b/src/Ai/Raid/MC/MCTriggers.cpp index b9b2aa1b7..d0571b1d2 100644 --- a/src/Ai/Raid/MC/MCTriggers.cpp +++ b/src/Ai/Raid/MC/MCTriggers.cpp @@ -38,3 +38,8 @@ bool McGolemaggIsAssistTankTrigger::IsActive() { return AI_VALUE2(Unit*, "find target", "golemagg the incinerator") && PlayerbotAI::IsAssistTank(bot); } + +bool McCoreHoundMarkTrigger::IsActive() +{ + return PlayerbotAI::IsMainTank(bot) && AI_VALUE2(Unit*, "find target", "core hound"); +} diff --git a/src/Ai/Raid/MC/MCTriggers.h b/src/Ai/Raid/MC/MCTriggers.h index 4cd84a2df..7d91bb1e7 100644 --- a/src/Ai/Raid/MC/MCTriggers.h +++ b/src/Ai/Raid/MC/MCTriggers.h @@ -47,4 +47,11 @@ public: bool IsActive() override; }; +class McCoreHoundMarkTrigger : public Trigger +{ +public: + McCoreHoundMarkTrigger(PlayerbotAI* botAI) : Trigger(botAI, "mc core hound mark") {} + bool IsActive() override; +}; + #endif