Fix Assistant Assignment Functions (#1930)

IsHealAssistantOfIndex() and IsRangedDpsAssistantOfIndex() are supposed
to iterate through the group and first return members with the
applicable role that have the assistant flag, and then iterate through
non-assistants only if there are not enough assistants for the
designated index. They are not written properly and actually completely
ignore the assistant flag.

I rely on these functions for significant roles in SSC and TK (which I
have decided I'll PR in the same way as SSC, as a long-term draft). I
have them fixed on my own fork, but it is problematic for testers if
these functions do not work.

So I've done three things here:
1. Fixed the functions to prefer members with the assistant flag.
2. Added a third parameter for ignoreDeadPlayers, like
IsAssistTankOfIndex() has. Note that the parameter is by default false
for IsAssistTankOfIndex(), meaning dead players are _not_ ignored. This
is not my preferred design choice--I think the default should be to
ignore dead players, but I have not changed the default and have made
the default the same for IsAssistHealOfIndex() and
IsAssistRangedDpsOfIndex(), since I don't know the intent of the
pre-existing boss strats that use the functions.
3. Changed the names to IsAssistHealOfIndex() and
IsAssistRangedDpsOfIndex() so they parallel IsAssistTankOfIndex(), and
made corresponding changes in the few boss strats that use the
functions.

Also, note that the functions _do _not_ exclude real players. I think
there are arguments for and against excluding real players. A fourth
parameter for this could be useful, but I've not made any change in that
regard.
This commit is contained in:
Crow
2026-01-24 14:26:49 -06:00
committed by GitHub
parent 3d467ce3bb
commit 378254af3f
3 changed files with 58 additions and 44 deletions

View File

@@ -78,19 +78,19 @@ bool SartharionMeleePositioningTrigger::IsActive()
bool TwilightPortalEnterTrigger::IsActive() bool TwilightPortalEnterTrigger::IsActive()
{ {
if (botAI->IsMainTank(bot) || botAI->IsHealAssistantOfIndex(bot, 0)) { return false; } if (botAI->IsMainTank(bot) || botAI->IsAssistHealOfIndex(bot, 0)) { return false; }
// In 25-man, take two healers in. Otherwise just take one // In 25-man, take two healers in. Otherwise just take one
// if (bot->GetRaidDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) // if (bot->GetRaidDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
// { // {
// if (botAI->IsHealAssistantOfIndex(bot, 0) || botAI->IsHealAssistantOfIndex(bot, 1)) // if (botAI->IsAssistHealOfIndex(bot, 0) || botAI->IsAssistHealOfIndex(bot, 1))
// { // {
// return false; // return false;
// } // }
// } // }
// else // else
// { // {
// if (botAI->IsHealAssistantOfIndex(bot, 0)) // if (botAI->IsAssistHealOfIndex(bot, 0))
// { // {
// return false; // return false;
// } // }

View File

@@ -1796,35 +1796,46 @@ bool PlayerbotAI::IsCombo(Player* player)
bool PlayerbotAI::IsRangedDps(Player* player, bool bySpec) { return IsRanged(player, bySpec) && IsDps(player, bySpec); } bool PlayerbotAI::IsRangedDps(Player* player, bool bySpec) { return IsRanged(player, bySpec) && IsDps(player, bySpec); }
bool PlayerbotAI::IsHealAssistantOfIndex(Player* player, int index) bool PlayerbotAI::IsAssistHealOfIndex(Player* player, int index, bool ignoreDeadPlayers)
{ {
Group* group = player->GetGroup(); Group* group = player->GetGroup();
if (!group) if (!group)
{
return false; return false;
}
int counter = 0; int counter = 0;
// First, assistants
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();
if (!member) if (!member)
{
continue; continue;
}
if (IsHeal(member)) // Check if the member is a healer if (ignoreDeadPlayers && !member->IsAlive())
continue;
if (group->IsAssistant(member->GetGUID()) && IsHeal(member))
{ {
bool isAssistant = group->IsAssistant(member->GetGUID()); if (index == counter)
// Check if the index matches for both assistant and non-assistant healers
if ((isAssistant && index == counter) || (!isAssistant && index == counter))
{
return player == member; return player == member;
} counter++;
}
}
// If not enough assistants, get non-assistants
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
{
Player* member = ref->GetSource();
if (!member)
continue;
if (ignoreDeadPlayers && !member->IsAlive())
continue;
if (!group->IsAssistant(member->GetGUID()) && IsHeal(member))
{
if (index == counter)
return player == member;
counter++; counter++;
} }
} }
@@ -1832,35 +1843,46 @@ bool PlayerbotAI::IsHealAssistantOfIndex(Player* player, int index)
return false; return false;
} }
bool PlayerbotAI::IsRangedDpsAssistantOfIndex(Player* player, int index) bool PlayerbotAI::IsAssistRangedDpsOfIndex(Player* player, int index, bool ignoreDeadPlayers)
{ {
Group* group = player->GetGroup(); Group* group = player->GetGroup();
if (!group) if (!group)
{
return false; return false;
}
int counter = 0; int counter = 0;
// First, assistants
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();
if (!member) if (!member)
{
continue; continue;
}
if (IsRangedDps(member)) // Check if the member is a ranged DPS if (ignoreDeadPlayers && !member->IsAlive())
continue;
if (group->IsAssistant(member->GetGUID()) && IsRangedDps(member))
{ {
bool isAssistant = group->IsAssistant(member->GetGUID()); if (index == counter)
// Check the index for both assistant and non-assistant ranges
if ((isAssistant && index == counter) || (!isAssistant && index == counter))
{
return player == member; return player == member;
} counter++;
}
}
// If not enough assistants, get non-assistants
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
{
Player* member = ref->GetSource();
if (!member)
continue;
if (ignoreDeadPlayers && !member->IsAlive())
continue;
if (!group->IsAssistant(member->GetGUID()) && IsRangedDps(member))
{
if (index == counter)
return player == member;
counter++; counter++;
} }
} }
@@ -2335,18 +2357,16 @@ bool PlayerbotAI::IsAssistTankOfIndex(Player* player, int index, bool ignoreDead
{ {
Group* group = player->GetGroup(); Group* group = player->GetGroup();
if (!group) if (!group)
{
return false; return false;
}
int counter = 0; int counter = 0;
// First, assistants
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();
if (!member) if (!member)
{
continue; continue;
}
if (ignoreDeadPlayers && !member->IsAlive()) if (ignoreDeadPlayers && !member->IsAlive())
continue; continue;
@@ -2354,21 +2374,17 @@ bool PlayerbotAI::IsAssistTankOfIndex(Player* player, int index, bool ignoreDead
if (group->IsAssistant(member->GetGUID()) && IsAssistTank(member)) if (group->IsAssistant(member->GetGUID()) && IsAssistTank(member))
{ {
if (index == counter) if (index == counter)
{
return player == member; return player == member;
}
counter++; counter++;
} }
} }
// not enough
// If not enough assistants, get non-assistants
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();
if (!member) if (!member)
{
continue; continue;
}
if (ignoreDeadPlayers && !member->IsAlive()) if (ignoreDeadPlayers && !member->IsAlive())
continue; continue;
@@ -2376,9 +2392,7 @@ bool PlayerbotAI::IsAssistTankOfIndex(Player* player, int index, bool ignoreDead
if (!group->IsAssistant(member->GetGUID()) && IsAssistTank(member)) if (!group->IsAssistant(member->GetGUID()) && IsAssistTank(member))
{ {
if (index == counter) if (index == counter)
{
return player == member; return player == member;
}
counter++; counter++;
} }
} }

View File

@@ -429,8 +429,8 @@ public:
static uint32 GetGroupTankNum(Player* player); static uint32 GetGroupTankNum(Player* player);
static bool IsAssistTank(Player* player); static bool IsAssistTank(Player* player);
static bool IsAssistTankOfIndex(Player* player, int index, bool ignoreDeadPlayers = false); static bool IsAssistTankOfIndex(Player* player, int index, bool ignoreDeadPlayers = false);
static bool IsHealAssistantOfIndex(Player* player, int index); static bool IsAssistHealOfIndex(Player* player, int index, bool ignoreDeadPlayers = false);
static bool IsRangedDpsAssistantOfIndex(Player* player, int index); static bool IsAssistRangedDpsOfIndex(Player* player, int index, bool ignoreDeadPlayers = false);
bool HasAggro(Unit* unit); bool HasAggro(Unit* unit);
static int32 GetAssistTankIndex(Player* player); static int32 GetAssistTankIndex(Player* player);
int32 GetGroupSlotIndex(Player* player); int32 GetGroupSlotIndex(Player* player);