diff --git a/src/strategy/raids/karazhan/RaidKarazhanActions.cpp b/src/strategy/raids/karazhan/RaidKarazhanActions.cpp index e452cf45..2e5d7abc 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanActions.cpp +++ b/src/strategy/raids/karazhan/RaidKarazhanActions.cpp @@ -44,7 +44,7 @@ bool AttumenTheHuntsmanMarkTargetAction::Execute(Event event) Unit* attumenMounted = GetFirstAliveUnitByEntry(botAI, NPC_ATTUMEN_THE_HUNTSMAN_MOUNTED); if (attumenMounted) { - if (IsMapIDTimerManager(botAI, bot)) + if (IsInstanceTimerManager(botAI, bot)) MarkTargetWithStar(bot, attumenMounted); SetRtiTarget(botAI, "star", attumenMounted); @@ -57,7 +57,7 @@ bool AttumenTheHuntsmanMarkTargetAction::Execute(Event event) } else if (Unit* midnight = AI_VALUE2(Unit*, "find target", "midnight")) { - if (IsMapIDTimerManager(botAI, bot)) + if (IsInstanceTimerManager(botAI, bot)) MarkTargetWithStar(bot, midnight); if (!botAI->IsAssistTankOfIndex(bot, 0)) @@ -131,8 +131,10 @@ bool AttumenTheHuntsmanManageDpsTimerAction::Execute(Event event) if (!midnight) return false; + const uint32 instanceId = midnight->GetMap()->GetInstanceId(); + if (midnight && midnight->GetHealth() == midnight->GetMaxHealth()) - attumenDpsWaitTimer.erase(KARAZHAN_MAP_ID); + attumenDpsWaitTimer.erase(instanceId); // Midnight is still present as a separate (invisible) unit after Attumen mounts // So this block can be reached @@ -143,7 +145,7 @@ bool AttumenTheHuntsmanManageDpsTimerAction::Execute(Event event) const time_t now = std::time(nullptr); if (attumenMounted) - attumenDpsWaitTimer.try_emplace(KARAZHAN_MAP_ID, now); + attumenDpsWaitTimer.try_emplace(instanceId, now); return false; } @@ -178,7 +180,7 @@ bool MoroesMarkTargetAction::Execute(Event event) if (target) { - if (IsMapIDTimerManager(botAI, bot)) + if (IsInstanceTimerManager(botAI, bot)) MarkTargetWithSkull(bot, target); SetRtiTarget(botAI, "skull", target); @@ -297,19 +299,18 @@ bool BigBadWolfPositionBossAction::Execute(Event event) if (wolf->GetVictim() == bot) { const Position& position = BIG_BAD_WOLF_BOSS_POSITION; - const float maxStep = 2.0f; - float dist = wolf->GetExactDist2d(position); + float distanceToPosition = wolf->GetExactDist2d(position); - if (dist > 0.0f && dist > maxStep) + if (distanceToPosition > 2.0f) { float dX = position.GetPositionX() - wolf->GetPositionX(); float dY = position.GetPositionY() - wolf->GetPositionY(); - float moveDist = std::min(maxStep, dist); - float moveX = wolf->GetPositionX() + (dX / dist) * moveDist; - float moveY = wolf->GetPositionY() + (dY / dist) * moveDist; + float moveDist = std::min(5.0f, distanceToPosition); + float moveX = wolf->GetPositionX() + (dX / distanceToPosition) * moveDist; + float moveY = wolf->GetPositionY() + (dY / distanceToPosition) * moveDist; return MoveTo(KARAZHAN_MAP_ID, moveX, moveY, position.GetPositionZ(), false, false, false, false, - MovementPriority::MOVEMENT_COMBAT, true, false); + MovementPriority::MOVEMENT_COMBAT, true, true); } } @@ -404,7 +405,7 @@ bool TheCuratorMarkAstralFlareAction::Execute(Event event) if (!flare) return false; - if (IsMapIDTimerManager(botAI, bot)) + if (IsInstanceTimerManager(botAI, bot)) MarkTargetWithSkull(bot, flare); SetRtiTarget(botAI, "skull", flare); @@ -429,17 +430,17 @@ bool TheCuratorPositionBossAction::Execute(Event event) if (curator->GetVictim() == bot) { const Position& position = THE_CURATOR_BOSS_POSITION; - const float maxDistance = 3.0f; - float distanceToBossPosition = curator->GetExactDist2d(position); + float distanceToPosition = curator->GetExactDist2d(position); - if (distanceToBossPosition > maxDistance) + if (distanceToPosition > 2.0f) { float dX = position.GetPositionX() - curator->GetPositionX(); float dY = position.GetPositionY() - curator->GetPositionY(); - float mX = position.GetPositionX() + (dX / distanceToBossPosition) * maxDistance; - float mY = position.GetPositionY() + (dY / distanceToBossPosition) * maxDistance; + float moveDist = std::min(10.0f, distanceToPosition); + float moveX = position.GetPositionX() + (dX / distanceToPosition) * moveDist; + float moveY = position.GetPositionY() + (dY / distanceToPosition) * moveDist; - return MoveTo(KARAZHAN_MAP_ID, mX, mY, position.GetPositionZ(), false, false, false, false, + return MoveTo(KARAZHAN_MAP_ID, moveX, moveY, position.GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT, true, false); } } @@ -997,6 +998,7 @@ bool NetherspiteManageTimersAndTrackersAction::Execute(Event event) if (!netherspite) return false; + const uint32 instanceId = netherspite->GetMap()->GetInstanceId(); const ObjectGuid botGuid = bot->GetGUID(); const time_t now = std::time(nullptr); @@ -1005,8 +1007,8 @@ bool NetherspiteManageTimersAndTrackersAction::Execute(Event event) if (netherspite->GetHealth() == netherspite->GetMaxHealth() && !netherspite->HasAura(SPELL_GREEN_BEAM_HEAL)) { - if (IsMapIDTimerManager(botAI, bot)) - netherspiteDpsWaitTimer.insert_or_assign(KARAZHAN_MAP_ID, now); + if (IsInstanceTimerManager(botAI, bot)) + netherspiteDpsWaitTimer.insert_or_assign(instanceId, now); if (botAI->IsTank(bot) && !bot->HasAura(SPELL_RED_BEAM_DEBUFF)) { @@ -1016,8 +1018,8 @@ bool NetherspiteManageTimersAndTrackersAction::Execute(Event event) } else if (netherspite->HasAura(SPELL_NETHERSPITE_BANISHED)) { - if (IsMapIDTimerManager(botAI, bot)) - netherspiteDpsWaitTimer.erase(KARAZHAN_MAP_ID); + if (IsInstanceTimerManager(botAI, bot)) + netherspiteDpsWaitTimer.erase(instanceId); if (botAI->IsTank(bot)) { @@ -1027,8 +1029,8 @@ bool NetherspiteManageTimersAndTrackersAction::Execute(Event event) } else if (!netherspite->HasAura(SPELL_NETHERSPITE_BANISHED)) { - if (IsMapIDTimerManager(botAI, bot)) - netherspiteDpsWaitTimer.try_emplace(KARAZHAN_MAP_ID, now); + if (IsInstanceTimerManager(botAI, bot)) + netherspiteDpsWaitTimer.try_emplace(instanceId, now); if (botAI->IsTank(bot) && bot->HasAura(SPELL_RED_BEAM_DEBUFF)) { @@ -1443,6 +1445,7 @@ bool NightbaneManageTimersAndTrackersAction::Execute(Event event) if (!nightbane) return false; + const uint32 instanceId = nightbane->GetMap()->GetInstanceId(); const ObjectGuid botGuid = bot->GetGUID(); const time_t now = std::time(nullptr); @@ -1455,18 +1458,18 @@ bool NightbaneManageTimersAndTrackersAction::Execute(Event event) if (botAI->IsRanged(bot)) nightbaneRangedStep.erase(botGuid); - if (IsMapIDTimerManager(botAI, bot)) - nightbaneDpsWaitTimer.erase(KARAZHAN_MAP_ID); + if (IsInstanceTimerManager(botAI, bot)) + nightbaneDpsWaitTimer.erase(instanceId); } // Erase flight phase timer and Rain of Bones tracker on ground phase and start DPS wait timer else if (nightbane->GetPositionZ() <= NIGHTBANE_FLIGHT_Z) { nightbaneRainOfBonesHit.erase(botGuid); - if (IsMapIDTimerManager(botAI, bot)) + if (IsInstanceTimerManager(botAI, bot)) { - nightbaneFlightPhaseStartTimer.erase(KARAZHAN_MAP_ID); - nightbaneDpsWaitTimer.try_emplace(KARAZHAN_MAP_ID, now); + nightbaneFlightPhaseStartTimer.erase(instanceId); + nightbaneDpsWaitTimer.try_emplace(instanceId, now); } } // Erase DPS wait timer and tank and ranged position tracking and start flight phase timer @@ -1479,10 +1482,10 @@ bool NightbaneManageTimersAndTrackersAction::Execute(Event event) if (botAI->IsRanged(bot)) nightbaneRangedStep.erase(botGuid); - if (IsMapIDTimerManager(botAI, bot)) + if (IsInstanceTimerManager(botAI, bot)) { - nightbaneDpsWaitTimer.erase(KARAZHAN_MAP_ID); - nightbaneFlightPhaseStartTimer.try_emplace(KARAZHAN_MAP_ID, now); + nightbaneDpsWaitTimer.erase(instanceId); + nightbaneFlightPhaseStartTimer.try_emplace(instanceId, now); } } diff --git a/src/strategy/raids/karazhan/RaidKarazhanHelpers.cpp b/src/strategy/raids/karazhan/RaidKarazhanHelpers.cpp index 9ca9f7b3..821cc670 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanHelpers.cpp +++ b/src/strategy/raids/karazhan/RaidKarazhanHelpers.cpp @@ -105,8 +105,8 @@ namespace KarazhanHelpers } } - // Only one bot is needed to set/reset mapwide timers - bool IsMapIDTimerManager(PlayerbotAI* botAI, Player* bot) + // Only one bot is needed to set/reset instance-wide timers + bool IsInstanceTimerManager(PlayerbotAI* botAI, Player* bot) { if (Group* group = bot->GetGroup()) { diff --git a/src/strategy/raids/karazhan/RaidKarazhanHelpers.h b/src/strategy/raids/karazhan/RaidKarazhanHelpers.h index fb08333a..394693b2 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanHelpers.h +++ b/src/strategy/raids/karazhan/RaidKarazhanHelpers.h @@ -112,7 +112,7 @@ namespace KarazhanHelpers void MarkTargetWithCircle(Player* bot, Unit* target); void MarkTargetWithMoon(Player* bot, Unit* target); void SetRtiTarget(PlayerbotAI* botAI, const std::string& rtiName, Unit* target); - bool IsMapIDTimerManager(PlayerbotAI* botAI, Player* bot); + bool IsInstanceTimerManager(PlayerbotAI* botAI, Player* bot); Unit* GetFirstAliveUnit(const std::vector& units); Unit* GetFirstAliveUnitByEntry(PlayerbotAI* botAI, uint32 entry); Unit* GetNearestPlayerInRadius(Player* bot, float radius); diff --git a/src/strategy/raids/karazhan/RaidKarazhanMultipliers.cpp b/src/strategy/raids/karazhan/RaidKarazhanMultipliers.cpp index cd64ea98..117a17f3 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanMultipliers.cpp +++ b/src/strategy/raids/karazhan/RaidKarazhanMultipliers.cpp @@ -61,10 +61,11 @@ float AttumenTheHuntsmanWaitForDpsMultiplier::GetValue(Action* action) if (!attumenMounted) return 1.0f; + const uint32 instanceId = attumenMounted->GetMap()->GetInstanceId(); const time_t now = std::time(nullptr); const uint8 dpsWaitSeconds = 8; - auto it = attumenDpsWaitTimer.find(KARAZHAN_MAP_ID); + auto it = attumenDpsWaitTimer.find(instanceId); if (it == attumenDpsWaitTimer.end() || (now - it->second) < dpsWaitSeconds) { if (!botAI->IsMainTank(bot)) @@ -201,10 +202,11 @@ float NetherspiteWaitForDpsMultiplier::GetValue(Action* action) if (!netherspite || netherspite->HasAura(SPELL_NETHERSPITE_BANISHED)) return 1.0f; + const uint32 instanceId = netherspite->GetMap()->GetInstanceId(); const time_t now = std::time(nullptr); const uint8 dpsWaitSeconds = 5; - auto it = netherspiteDpsWaitTimer.find(KARAZHAN_MAP_ID); + auto it = netherspiteDpsWaitTimer.find(instanceId); if (it == netherspiteDpsWaitTimer.end() || (now - it->second) < dpsWaitSeconds) { if (!botAI->IsTank(bot)) @@ -299,10 +301,11 @@ float NightbaneWaitForDpsMultiplier::GetValue(Action* action) if (!nightbane || nightbane->GetPositionZ() > NIGHTBANE_FLIGHT_Z) return 1.0f; + const uint32 instanceId = nightbane->GetMap()->GetInstanceId(); const time_t now = std::time(nullptr); const uint8 dpsWaitSeconds = 8; - auto it = nightbaneDpsWaitTimer.find(KARAZHAN_MAP_ID); + auto it = nightbaneDpsWaitTimer.find(instanceId); if (it == nightbaneDpsWaitTimer.end() || (now - it->second) < dpsWaitSeconds) { if (!botAI->IsMainTank(bot)) diff --git a/src/strategy/raids/karazhan/RaidKarazhanTriggers.cpp b/src/strategy/raids/karazhan/RaidKarazhanTriggers.cpp index e39006f7..2fb7d5af 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanTriggers.cpp +++ b/src/strategy/raids/karazhan/RaidKarazhanTriggers.cpp @@ -40,7 +40,7 @@ bool AttumenTheHuntsmanAttumenIsMountedTrigger::IsActive() bool AttumenTheHuntsmanBossWipesAggroWhenMountingTrigger::IsActive() { - if (!IsMapIDTimerManager(botAI, bot)) + if (!IsInstanceTimerManager(botAI, bot)) return false; Unit* midnight = AI_VALUE2(Unit*, "find target", "midnight"); @@ -110,7 +110,7 @@ bool BigBadWolfBossIsChasingLittleRedRidingHoodTrigger::IsActive() bool RomuloAndJulianneBothBossesRevivedTrigger::IsActive() { - if (!IsMapIDTimerManager(botAI, bot)) + if (!IsInstanceTimerManager(botAI, bot)) return false; Unit* romulo = AI_VALUE2(Unit*, "find target", "romulo"); @@ -126,7 +126,7 @@ bool RomuloAndJulianneBothBossesRevivedTrigger::IsActive() bool WizardOfOzNeedTargetPriorityTrigger::IsActive() { - if (!IsMapIDTimerManager(botAI, bot)) + if (!IsInstanceTimerManager(botAI, bot)) return false; Unit* dorothee = AI_VALUE2(Unit*, "find target", "dorothee"); @@ -178,7 +178,7 @@ bool TheCuratorBossAstralFlaresCastArcingSearTrigger::IsActive() bool TerestianIllhoofNeedTargetPriorityTrigger::IsActive() { - if (!IsMapIDTimerManager(botAI, bot)) + if (!IsInstanceTimerManager(botAI, bot)) return false; Unit* illhoof = AI_VALUE2(Unit*, "find target", "terestian illhoof"); @@ -202,7 +202,7 @@ bool ShadeOfAranFlameWreathIsActiveTrigger::IsActive() // Exclusion of Banish is so the player may Banish elementals if they wish bool ShadeOfAranConjuredElementalsSummonedTrigger::IsActive() { - if (!IsMapIDTimerManager(botAI, bot)) + if (!IsInstanceTimerManager(botAI, bot)) return false; Unit* elemental = AI_VALUE2(Unit*, "find target", "conjured elemental"); @@ -279,7 +279,7 @@ bool NetherspiteBossIsBanishedTrigger::IsActive() bool NetherspiteNeedToManageTimersAndTrackersTrigger::IsActive() { - if (!botAI->IsTank(bot) && !IsMapIDTimerManager(botAI, bot)) + if (!botAI->IsTank(bot) && !IsInstanceTimerManager(botAI, bot)) return false; Unit* netherspite = AI_VALUE2(Unit*, "find target", "netherspite"); @@ -370,11 +370,12 @@ bool NightbaneBossIsFlyingTrigger::IsActive() if (!nightbane || nightbane->GetPositionZ() <= NIGHTBANE_FLIGHT_Z) return false; + const uint32 instanceId = nightbane->GetMap()->GetInstanceId(); const time_t now = std::time(nullptr); const uint8 flightPhaseDurationSeconds = 35; - return nightbaneFlightPhaseStartTimer.find(KARAZHAN_MAP_ID) != nightbaneFlightPhaseStartTimer.end() && - (now - nightbaneFlightPhaseStartTimer[KARAZHAN_MAP_ID] < flightPhaseDurationSeconds); + return nightbaneFlightPhaseStartTimer.find(instanceId) != nightbaneFlightPhaseStartTimer.end() && + (now - nightbaneFlightPhaseStartTimer[instanceId] < flightPhaseDurationSeconds); } bool NightbaneNeedToManageTimersAndTrackersTrigger::IsActive()