Refined assignment cooldowns and logic for bot tanks

This commit is contained in:
avirar 2024-12-22 19:46:59 +11:00 committed by GitHub
parent 900a922d34
commit c265a5e018
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -9,7 +9,11 @@
#include "Playerbots.h" #include "Playerbots.h"
#include "World.h" #include "World.h"
// Prevent harpoon spam
std::unordered_map<ObjectGuid, time_t> RazorscaleBossHelper::_harpoonCooldowns; std::unordered_map<ObjectGuid, time_t> RazorscaleBossHelper::_harpoonCooldowns;
// Prevent role assignment spam
std::unordered_map<ObjectGuid, std::time_t> RazorscaleBossHelper::_lastRoleSwapTime;
const std::time_t RazorscaleBossHelper::_roleSwapCooldown;
bool RazorscaleBossHelper::UpdateBossAI() bool RazorscaleBossHelper::UpdateBossAI()
{ {
@ -118,14 +122,15 @@ bool RazorscaleBossHelper::AreRolesAssigned() const
if (!group) if (!group)
return false; return false;
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) // Retrieve the group member slot list (GUID + flags + other info)
Group::MemberSlotList const& slots = group->GetMemberSlots();
for (auto const& slot : slots)
{ {
Player* member = ref->GetSource(); // Check if this member has the MAINTANK flag
if (!member) if (slot.flags & MEMBER_FLAG_MAINTANK)
continue; {
if (botAI->IsMainTank(member))
return true; return true;
}
} }
return false; return false;
@ -133,12 +138,30 @@ bool RazorscaleBossHelper::AreRolesAssigned() const
bool RazorscaleBossHelper::CanSwapRoles() const bool RazorscaleBossHelper::CanSwapRoles() const
{ {
// Identify the GUID of the current bot
ObjectGuid botGuid = bot->GetGUID();
if (!botGuid)
return false;
// If no entry exists yet for this bot, initialize it to 0
auto it = _lastRoleSwapTime.find(botGuid);
if (it == _lastRoleSwapTime.end())
{
_lastRoleSwapTime[botGuid] = 0;
it = _lastRoleSwapTime.find(botGuid);
}
// Compare the current time against the stored time
std::time_t currentTime = std::time(nullptr); std::time_t currentTime = std::time(nullptr);
return (currentTime - _lastRoleSwapTime) >= _roleSwapCooldown; std::time_t lastSwapTime = it->second;
return (currentTime - lastSwapTime) >= _roleSwapCooldown;
} }
void RazorscaleBossHelper::AssignRolesBasedOnHealth() void RazorscaleBossHelper::AssignRolesBasedOnHealth()
{ {
// Check if enough time has passed since last swap
if (!CanSwapRoles()) if (!CanSwapRoles())
return; return;
@ -146,7 +169,7 @@ void RazorscaleBossHelper::AssignRolesBasedOnHealth()
if (!group) if (!group)
return; return;
// Gather all tank-capable players (bots and real players) in the group, excluding those with Fuse Armor // Gather all tank-capable players (bots + real players), excluding those with too many Fuse Armor stacks
std::vector<Player*> tankCandidates; std::vector<Player*> tankCandidates;
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
{ {
@ -161,10 +184,11 @@ void RazorscaleBossHelper::AssignRolesBasedOnHealth()
tankCandidates.push_back(member); tankCandidates.push_back(member);
} }
// If there are no viable tanks, do nothing
if (tankCandidates.empty()) if (tankCandidates.empty())
return; return;
// Sort tanks by max health descending // Sort by highest max health first
std::sort(tankCandidates.begin(), tankCandidates.end(), std::sort(tankCandidates.begin(), tankCandidates.end(),
[](Player* a, Player* b) [](Player* a, Player* b)
{ {
@ -172,11 +196,12 @@ void RazorscaleBossHelper::AssignRolesBasedOnHealth()
} }
); );
// Pick the top candidate
Player* newMainTank = tankCandidates[0]; Player* newMainTank = tankCandidates[0];
if (!newMainTank) // Safety check if (!newMainTank) // Safety check
return; return;
// Remove all MAINTANK flags // Unflag everyone from main tank
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
{ {
Player* member = ref->GetSource(); Player* member = ref->GetSource();
@ -187,27 +212,15 @@ void RazorscaleBossHelper::AssignRolesBasedOnHealth()
// Assign the single main tank // Assign the single main tank
group->SetGroupMemberFlag(newMainTank->GetGUID(), true, MEMBER_FLAG_MAINTANK); group->SetGroupMemberFlag(newMainTank->GetGUID(), true, MEMBER_FLAG_MAINTANK);
// Notify if the new main tank is a real player // Yell a message regardless of whether the new main tank is a bot or a real player
// If newMainTank is a real player, GET_PLAYERBOT_AI(...) should be null
PlayerbotAI* newMainTankAI = GET_PLAYERBOT_AI(newMainTank);
// If this is a normal bot, newMainTankAI won't be nullptr, but it won't be a real player either
bool isRealPlayer = (newMainTankAI == nullptr);
if (!isRealPlayer)
{
return;
}
// Otherwise, we have a real player
const std::string playerName = newMainTank->GetName(); const std::string playerName = newMainTank->GetName();
const std::string text = playerName + " please taunt Razorscale now!"; const std::string text = playerName + " set as main tank!";
bot->Yell(text, LANG_UNIVERSAL); bot->Yell(text, LANG_UNIVERSAL);
ObjectGuid botGuid = bot->GetGUID(); ObjectGuid botGuid = bot->GetGUID();
if (!botGuid) if (!botGuid)
return; return;
// Set current time in the cooldown map for this bot to start cooldown
_lastRoleSwapTime[botGuid] = std::time(nullptr); _lastRoleSwapTime[botGuid] = std::time(nullptr);
} }