Magtheridon timer keys fix (#1936)

Same deal as Karazhan--changing map id to instance id for timer keys to
prevent conflicts from multiple groups (plus other tweaks with respect
to the timers). This strategy could use a broader refactor, but that's
for another day--this PR is just to address the timer logic.
This commit is contained in:
Crow
2025-12-23 02:04:36 -06:00
committed by GitHub
parent 467b63b840
commit 895df9b197
4 changed files with 45 additions and 53 deletions

View File

@@ -401,14 +401,20 @@ std::unordered_map<ObjectGuid, bool> MagtheridonSpreadRangedAction::hasReachedIn
bool MagtheridonSpreadRangedAction::Execute(Event event)
{
Unit* magtheridon = AI_VALUE2(Unit*, "find target", "magtheridon");
if (!magtheridon)
return false;
Group* group = bot->GetGroup();
if (!group)
return false;
const uint32 instanceId = magtheridon->GetMap()->GetInstanceId();
// Wait for 6 seconds after Magtheridon activates to spread
const uint8 spreadWaitSeconds = 6;
auto it = magtheridonSpreadWaitTimer.find(bot->GetMapId());
if (it == magtheridonSpreadWaitTimer.end() ||
auto it = spreadWaitTimer.find(instanceId);
if (it == spreadWaitTimer.end() ||
(time(nullptr) - it->second) < spreadWaitSeconds)
return false;
@@ -416,8 +422,8 @@ bool MagtheridonSpreadRangedAction::Execute(Event event)
if (cubeIt != botToCubeAssignment.end())
{
time_t now = time(nullptr);
auto timerIt = magtheridonBlastNovaTimer.find(bot->GetMapId());
if (timerIt != magtheridonBlastNovaTimer.end())
auto timerIt = blastNovaTimer.find(instanceId);
if (timerIt != blastNovaTimer.end())
{
time_t lastBlastNova = timerIt->second;
if (now - lastBlastNova >= 49)
@@ -559,8 +565,8 @@ bool MagtheridonUseManticronCubeAction::HandleCubeRelease(Unit* magtheridon, Gam
bool MagtheridonUseManticronCubeAction::ShouldActivateCubeLogic(Unit* magtheridon)
{
auto timerIt = magtheridonBlastNovaTimer.find(bot->GetMapId());
if (timerIt == magtheridonBlastNovaTimer.end())
auto timerIt = blastNovaTimer.find(magtheridon->GetMap()->GetInstanceId());
if (timerIt == blastNovaTimer.end())
return false;
time_t now = time(nullptr);
@@ -650,52 +656,38 @@ bool MagtheridonManageTimersAndAssignmentsAction::Execute(Event event)
if (!magtheridon)
return false;
uint32 mapId = magtheridon->GetMapId();
const uint32 instanceId = magtheridon->GetMap()->GetInstanceId();
const time_t now = time(nullptr);
bool blastNovaActive = magtheridon->HasUnitState(UNIT_STATE_CASTING) &&
magtheridon->FindCurrentSpellBySpellId(SPELL_BLAST_NOVA);
bool lastBlastNova = lastBlastNovaState[mapId];
bool lastBlastNova = lastBlastNovaState[instanceId];
if (lastBlastNova && !blastNovaActive && IsMapIDTimerManager(botAI, bot))
magtheridonBlastNovaTimer[mapId] = time(nullptr);
lastBlastNovaState[mapId] = blastNovaActive;
if (lastBlastNova && !blastNovaActive && IsInstanceTimerManager(botAI, bot))
blastNovaTimer[instanceId] = now;
lastBlastNovaState[instanceId] = blastNovaActive;
if (IsMapIDTimerManager(botAI, bot))
{
if (!magtheridon->HasAura(SPELL_SHADOW_CAGE))
{
if (magtheridonSpreadWaitTimer.find(mapId) == magtheridonSpreadWaitTimer.end())
magtheridonSpreadWaitTimer[mapId] = time(nullptr);
if (magtheridonBlastNovaTimer.find(mapId) == magtheridonBlastNovaTimer.end())
magtheridonBlastNovaTimer[mapId] = time(nullptr);
if (magtheridonAggroWaitTimer.find(mapId) == magtheridonAggroWaitTimer.end())
magtheridonAggroWaitTimer[mapId] = time(nullptr);
}
}
if (magtheridon->HasAura(SPELL_SHADOW_CAGE))
if (IsInstanceTimerManager(botAI, bot))
{
spreadWaitTimer.try_emplace(instanceId, now);
blastNovaTimer.try_emplace(instanceId, now);
dpsWaitTimer.try_emplace(instanceId, now);
}
}
else
{
if (!MagtheridonSpreadRangedAction::initialPositions.empty())
MagtheridonSpreadRangedAction::initialPositions.clear();
if (!MagtheridonSpreadRangedAction::hasReachedInitialPosition.empty())
MagtheridonSpreadRangedAction::hasReachedInitialPosition.clear();
if (!botToCubeAssignment.empty())
botToCubeAssignment.clear();
if (IsMapIDTimerManager(botAI, bot))
if (IsInstanceTimerManager(botAI, bot))
{
if (magtheridonSpreadWaitTimer.find(mapId) != magtheridonSpreadWaitTimer.end())
magtheridonSpreadWaitTimer.erase(mapId);
if (magtheridonBlastNovaTimer.find(mapId) != magtheridonBlastNovaTimer.end())
magtheridonBlastNovaTimer.erase(mapId);
if (magtheridonAggroWaitTimer.find(mapId) != magtheridonAggroWaitTimer.end())
magtheridonAggroWaitTimer.erase(mapId);
spreadWaitTimer.erase(instanceId);
blastNovaTimer.erase(instanceId);
dpsWaitTimer.erase(instanceId);
}
}

View File

@@ -170,9 +170,9 @@ namespace MagtheridonHelpers
}
std::unordered_map<uint32, bool> lastBlastNovaState;
std::unordered_map<uint32, time_t> magtheridonBlastNovaTimer;
std::unordered_map<uint32, time_t> magtheridonSpreadWaitTimer;
std::unordered_map<uint32, time_t> magtheridonAggroWaitTimer;
std::unordered_map<uint32, time_t> blastNovaTimer;
std::unordered_map<uint32, time_t> spreadWaitTimer;
std::unordered_map<uint32, time_t> dpsWaitTimer;
bool IsSafeFromMagtheridonHazards(PlayerbotAI* botAI, Player* bot, float x, float y, float z)
{
@@ -209,14 +209,14 @@ namespace MagtheridonHelpers
return true;
}
bool IsMapIDTimerManager(PlayerbotAI* botAI, Player* bot)
bool IsInstanceTimerManager(PlayerbotAI* botAI, Player* bot)
{
if (Group* group = bot->GetGroup())
{
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
{
Player* member = ref->GetSource();
if (member && member->IsAlive() && !botAI->IsMainTank(member) && GET_PLAYERBOT_AI(member))
if (member && member->IsAlive() && botAI->IsDps(member) && GET_PLAYERBOT_AI(member))
return member == bot;
}
}

View File

@@ -54,7 +54,7 @@ namespace MagtheridonHelpers
void MarkTargetWithCross(Player* bot, Unit* target);
void SetRtiTarget(PlayerbotAI* botAI, const std::string& rtiName, Unit* target);
bool IsSafeFromMagtheridonHazards(PlayerbotAI* botAI, Player* bot, float x, float y, float z);
bool IsMapIDTimerManager(PlayerbotAI* botAI, Player* bot);
bool IsInstanceTimerManager(PlayerbotAI* botAI, Player* bot);
struct Location
{
@@ -82,9 +82,9 @@ namespace MagtheridonHelpers
std::vector<CubeInfo> GetAllCubeInfosByDbGuids(Map* map, const std::vector<uint32>& cubeDbGuids);
void AssignBotsToCubesByGuidAndCoords(Group* group, const std::vector<CubeInfo>& cubes, PlayerbotAI* botAI);
extern std::unordered_map<uint32, bool> lastBlastNovaState;
extern std::unordered_map<uint32, time_t> magtheridonBlastNovaTimer;
extern std::unordered_map<uint32, time_t> magtheridonSpreadWaitTimer;
extern std::unordered_map<uint32, time_t> magtheridonAggroWaitTimer;
extern std::unordered_map<uint32, time_t> blastNovaTimer;
extern std::unordered_map<uint32, time_t> spreadWaitTimer;
extern std::unordered_map<uint32, time_t> dpsWaitTimer;
}
#endif

View File

@@ -41,10 +41,10 @@ float MagtheridonWaitToAttackMultiplier::GetValue(Action* action)
if (!magtheridon || magtheridon->HasAura(SPELL_SHADOW_CAGE))
return 1.0f;
const uint8 aggroWaitSeconds = 6;
auto it = magtheridonAggroWaitTimer.find(bot->GetMapId());
if (it == magtheridonAggroWaitTimer.end() ||
(time(nullptr) - it->second) < aggroWaitSeconds)
const uint8 dpsWaitSeconds = 6;
auto it = dpsWaitTimer.find(magtheridon->GetMap()->GetInstanceId());
if (it == dpsWaitTimer.end() ||
(time(nullptr) - it->second) < dpsWaitSeconds)
{
if (!botAI->IsMainTank(bot) && (dynamic_cast<AttackAction*>(action) ||
(!botAI->IsHeal(bot) && dynamic_cast<CastSpellAction*>(action))))