From e5f1b862dd8d273abffd61f43187cb303628c1e1 Mon Sep 17 00:00:00 2001 From: kadeshar Date: Sun, 22 Dec 2024 12:46:11 +0100 Subject: [PATCH 1/2] [Bugfix] (#809) - reverted changes in need world buff trigger --- src/strategy/triggers/CureTriggers.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/strategy/triggers/CureTriggers.cpp b/src/strategy/triggers/CureTriggers.cpp index 60aa29f6..abd23022 100644 --- a/src/strategy/triggers/CureTriggers.cpp +++ b/src/strategy/triggers/CureTriggers.cpp @@ -25,8 +25,4 @@ bool PartyMemberNeedCureTrigger::IsActive() return target && target->IsInWorld(); } -bool NeedWorldBuffTrigger::IsActive() -{ - std::any_of(WorldBuffAction::NeedWorldBuffs(bot).begin(), WorldBuffAction::NeedWorldBuffs(bot).end(), - [](const auto& wb) { return true; }); -} +bool NeedWorldBuffTrigger::IsActive() { return !WorldBuffAction::NeedWorldBuffs(bot).empty(); } From d9f9d980cff7b08864bf7c0bf4386d5aa2341971 Mon Sep 17 00:00:00 2001 From: SaW Date: Sun, 22 Dec 2024 23:08:47 +0100 Subject: [PATCH 2/2] Fix various formations - Issue #749 (#807) * Fix various formations * Refactor Formation::GetFollowAngle() * Update Formations.cpp * Refactored Formation::GetFollowAngle() Final refactor of Formation::GetFollowAngle() - By combining the group member iteration, unnecessary loops are avoided. - Clearer Structure: The code is more readable, with fewer redundant operations. - Better Maintainability: Comments and logical grouping make it easier to modify or extend the function in the future. * Logic order improvement --- src/strategy/values/Formations.cpp | 120 +++++++++++++++-------------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/src/strategy/values/Formations.cpp b/src/strategy/values/Formations.cpp index 77dc2264..a6f92ac5 100644 --- a/src/strategy/values/Formations.cpp +++ b/src/strategy/values/Formations.cpp @@ -413,79 +413,83 @@ float Formation::GetFollowAngle() Group* group = bot->GetGroup(); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); + // If there's no master and no group + if (!master && !group) + return 0.0f; + uint32 index = 1; uint32 total = 1; - PlayerbotMgr* masterBotMgr = nullptr; - if (master) - masterBotMgr = GET_PLAYERBOT_MGR(master); - if (!group && master && !GET_PLAYERBOT_AI(master) && masterBotMgr) - { - for (PlayerBotMap::const_iterator i = masterBotMgr->GetPlayerBotsBegin(); i != masterBotMgr->GetPlayerBotsEnd(); - ++i) - { - if (i->second == bot) - index = total; + std::vector roster; - ++total; + if (group) + { + bool left = true; // Used for alternating tanks' positions + + for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) + { + Player* member = ref->GetSource(); + + // Skip invalid, dead, or out-of-map members + if (!member || !member->IsAlive() || bot->GetMapId() != member->GetMapId()) + continue; + + // Skip the master + if (member == master) + continue; + + // Put DPS in the middle + if (!botAI->IsTank(member) && !botAI->IsHeal(member)) + { + roster.insert(roster.begin() + roster.size() / 2, member); + } + + // Put Healers in the middle + else if (botAI->IsHeal(member)) + { + roster.insert(roster.begin() + roster.size() / 2, member); + } + + // Handle tanks (alternate between front and back) + else if (botAI->IsTank(member)) + { + if (left) + roster.push_back(member); // Place tank at the back + else + roster.insert(roster.begin(), member); // Place tank at the front + + left = !left; // Alternate for the next tank + } + + total++; } } - else if (group) + else if (master) { - std::vector roster; - for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) + // If the bot is following a master, look up the bot's position in the master's list + PlayerbotMgr* masterBotMgr = GET_PLAYERBOT_MGR(master); + if (masterBotMgr && !GET_PLAYERBOT_AI(master)) { - if (Player* member = ref->GetSource()) + for (auto it = masterBotMgr->GetPlayerBotsBegin(); it != masterBotMgr->GetPlayerBotsEnd(); ++it) { - if (!member || member == bot || !member->IsAlive() || bot->GetMapId() != member->GetMapId()) continue; - if (member != master && !botAI->IsTank(member) && !botAI->IsHeal(member)) + if (it->second == bot) { - roster.insert(roster.begin() + roster.size() / 2, member); + index = total; // Found bot in master's list, set the index + break; } + ++total; } } - - for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) - { - if (Player* member = ref->GetSource()) - { - if (!member || member == bot || !member->IsAlive() || bot->GetMapId() != member->GetMapId()) continue; - if (member != master && botAI->IsHeal(member)) - { - roster.insert(roster.begin() + roster.size() / 2, member); - } - } - } - - bool left = true; - for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) - { - if (Player* member = ref->GetSource()) - { - if (!member || member == bot || !member->IsAlive() || bot->GetMapId() != member->GetMapId()) continue; - if (member != master && botAI->IsTank(member)) - { - if (left) - roster.push_back(member); - else - roster.insert(roster.begin(), member); - - left = !left; - } - } - } - - for (Player* playerRoster : roster) - { - if (playerRoster == bot) - break; - - ++index; - } - - total = roster.size() + 1; } + // Find the bot's position in the roster + auto it = std::find(roster.begin(), roster.end(), bot); + if (it != roster.end()) + { + index = std::distance(roster.begin(), it) + 1; // Find bot's index in the roster + } + + // Return float start = (master ? master->GetOrientation() : 0.0f); return start + (0.125f + 1.75f * index / total + (total == 2 ? 0.125f : 0.0f)) * M_PI; }