Added logic for bots to offtank

Bot tanks will mark targets and establish themselves as main tank when necessary, announcing when ever re-assignment occurs
This commit is contained in:
avirar
2024-12-22 19:45:51 +11:00
committed by GitHub
parent b897593d76
commit 900a922d34

View File

@@ -440,6 +440,12 @@ bool RazorscaleAvoidDevouringFlameAction::Execute(Event event)
} }
} }
// Off tanks are following the main tank during grounded and should prioritise stacking
if (razorscaleHelper.IsGroundPhase() && (botAI->IsTank(bot) && !botAI->IsMainTank(bot)))
{
return false;
}
// Handle movement from flames // Handle movement from flames
if (closestDistance < safeDistance) if (closestDistance < safeDistance)
{ {
@@ -477,11 +483,6 @@ bool RazorscaleAvoidSentinelAction::Execute(Event event)
{ {
bool isTank = botAI->IsTank(bot); bool isTank = botAI->IsTank(bot);
bool isMainTank = botAI->IsMainTank(bot); bool isMainTank = botAI->IsMainTank(bot);
if (isTank && !isMainTank)
{
return false;
}
bool isRanged = botAI->IsRanged(bot); bool isRanged = botAI->IsRanged(bot);
const float radius = 8.0f; const float radius = 8.0f;
@@ -512,38 +513,76 @@ bool RazorscaleAvoidSentinelAction::Execute(Event event)
} }
} }
// Mark the lowest-health sentinel with Skull if main tank // Check if the main tank is a human player
if (isMainTank && lowestHealthSentinel) Unit* mainTankUnit = AI_VALUE(Unit*, "main tank");
Player* mainTank = mainTankUnit ? mainTankUnit->ToPlayer() : nullptr;
if (mainTank && !GET_PLAYERBOT_AI(mainTank)) // Main tank is a real player
{
// Iterate through the first 3 bot tanks to assign the Skull marker
for (int i = 0; i < 3; ++i)
{
if (botAI->IsAssistTankOfIndex(bot, i) && GET_PLAYERBOT_AI(bot)) // Bot is a valid tank
{
Group* group = bot->GetGroup();
if (group && lowestHealthSentinel)
{
int8 skullIndex = 7; // Skull
ObjectGuid currentSkullTarget = group->GetTargetIcon(skullIndex);
// If there's no skull set yet, or the skull is on a different target, set the sentinel
if (!currentSkullTarget || (lowestHealthSentinel->GetGUID() != currentSkullTarget))
{
group->SetTargetIcon(skullIndex, bot->GetGUID(), lowestHealthSentinel->GetGUID());
}
}
break; // Stop after finding the first valid bot tank
}
}
}
else if (isMainTank && lowestHealthSentinel) // Bot is the main tank
{ {
Group* group = bot->GetGroup(); Group* group = bot->GetGroup();
if (group) if (group)
{ {
int8 skullIndex = 7; // Skull int8 skullIndex = 7; // Skull
ObjectGuid currentSkullTarget = group->GetTargetIcon(skullIndex); ObjectGuid currentSkullTarget = group->GetTargetIcon(skullIndex);
if (currentSkullTarget && lowestHealthSentinel->GetGUID() != currentSkullTarget)
// If there's no skull set yet, or the skull is on a different target, set the sentinel
if (!currentSkullTarget || (lowestHealthSentinel->GetGUID() != currentSkullTarget))
{ {
group->SetTargetIcon(skullIndex, bot->GetGUID(), lowestHealthSentinel->GetGUID()); group->SetTargetIcon(skullIndex, bot->GetGUID(), lowestHealthSentinel->GetGUID());
} }
} }
} }
return movedAway; // Return true if moved return movedAway; // Return true if moved
} }
bool RazorscaleAvoidSentinelAction::isUseful() bool RazorscaleAvoidSentinelAction::isUseful()
{ {
bool isTank = botAI->IsTank(bot);
bool isMainTank = botAI->IsMainTank(bot); bool isMainTank = botAI->IsMainTank(bot);
if (isTank && !isMainTank) Unit* mainTankUnit = AI_VALUE(Unit*, "main tank");
{ Player* mainTank = mainTankUnit ? mainTankUnit->ToPlayer() : nullptr;
return false;
} // If this bot is the main tank, it should always try to mark
// Main tank always tries to mark sentinel
if (isMainTank) if (isMainTank)
{ {
return true; return true;
} }
// If the main tank is a human, check if this bot is one of the first three valid bot tanks
if (mainTank && !GET_PLAYERBOT_AI(mainTank)) // Main tank is a human player
{
for (int i = 0; i < 3; ++i)
{
if (botAI->IsAssistTankOfIndex(bot, i) && GET_PLAYERBOT_AI(bot)) // Bot is a valid tank
{
return true; // This bot should assist with marking
}
}
}
bool isRanged = botAI->IsRanged(bot); bool isRanged = botAI->IsRanged(bot);
const float radius = 8.0f; const float radius = 8.0f;
@@ -621,30 +660,62 @@ bool RazorscaleIgnoreBossAction::isUseful()
Unit* boss = AI_VALUE2(Unit*, "find target", "razorscale"); Unit* boss = AI_VALUE2(Unit*, "find target", "razorscale");
if (!boss) if (!boss)
{ {
return false; return false;
} }
// Check if the boss is flying // Check if the boss is flying
if (boss->GetPositionZ() >= RazorscaleBossHelper::RAZORSCALE_FLYING_Z_THRESHOLD) if (boss->GetPositionZ() >= RazorscaleBossHelper::RAZORSCALE_FLYING_Z_THRESHOLD)
{ {
bool isMainTank = botAI->IsMainTank(bot);
// Check if the bot is outside the designated area // Check if the bot is outside the designated area
if (bot->GetDistance2d(RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y) > RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS + 25.0f) if (bot->GetDistance2d(
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X,
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y) > RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS + 25.0f)
{
return true; // Movement to the center is the top priority for all bots
}
if (!botAI->IsTank(bot))
{
return false;
}
Group* group = bot->GetGroup();
if (!group)
{
return false;
}
// Check if the boss is already set as the moon marker
int8 moonIndex = 4; // Moon marker index
ObjectGuid currentMoonTarget = group->GetTargetIcon(moonIndex);
if (currentMoonTarget == boss->GetGUID())
{
return false; // Moon marker is already correctly set, no further action needed
}
// Proceed to tank-specific logic
Unit* mainTankUnit = AI_VALUE(Unit*, "main tank");
Player* mainTank = mainTankUnit ? mainTankUnit->ToPlayer() : nullptr;
// If this bot is the main tank, it needs to set the moon marker
if (mainTankUnit == bot)
{ {
return true; return true;
} }
// Check moon mark if main tank
if (isMainTank) // If the main tank is a human, check if this bot is the lowest-indexed bot tank
if (mainTank && !GET_PLAYERBOT_AI(mainTank)) // Main tank is a human player
{ {
Group* group = bot->GetGroup(); for (int i = 0; i < 3; ++i) // Only iterate through the first 3 indexes
if (group)
{ {
int8 moonIndex = 4; if (botAI->IsAssistTankOfIndex(bot, i) && GET_PLAYERBOT_AI(bot)) // Valid bot tank
ObjectGuid currentMoonTarget = group->GetTargetIcon(moonIndex); {
return currentMoonTarget != boss->GetGUID(); return true; // This bot should assign the marker
}
} }
} }
} }
return false; return false;
} }
@@ -653,13 +724,20 @@ bool RazorscaleIgnoreBossAction::Execute(Event event)
Unit* boss = AI_VALUE2(Unit*, "find target", "razorscale"); Unit* boss = AI_VALUE2(Unit*, "find target", "razorscale");
if (!boss) if (!boss)
{ {
return false; return false;
} }
bool isMainTank = botAI->IsMainTank(bot); Group* group = bot->GetGroup();
if (!isMainTank) if (!group)
{
return false;
}
// Check if the bot is outside the designated area and move inside first
if (bot->GetDistance2d(
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X,
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y) > RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS + 25.0f)
{ {
// Move non-tanks inside
return MoveInside( return MoveInside(
ULDUAR_MAP_ID, ULDUAR_MAP_ID,
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X,
@@ -670,22 +748,43 @@ bool RazorscaleIgnoreBossAction::Execute(Event event)
); );
} }
Group* group = bot->GetGroup(); if (!botAI->IsTank(bot))
if (!group)
{ {
return false; return false;
} }
// Assign moon rti to boss // Check if the boss is already set as the moon marker
int8 moonIndex = 4; int8 moonIndex = 4;
ObjectGuid currentMoonTarget = group->GetTargetIcon(moonIndex); ObjectGuid currentMoonTarget = group->GetTargetIcon(moonIndex);
if (currentMoonTarget != boss->GetGUID()) if (currentMoonTarget == boss->GetGUID())
{
return false; // Moon marker is already correctly set
}
// Get the main tank and determine role
Unit* mainTankUnit = AI_VALUE(Unit*, "main tank");
Player* mainTank = mainTankUnit ? mainTankUnit->ToPlayer() : nullptr;
// If the main tank is a human, assign the moon marker using the lowest-indexed bot tank
if (mainTank && !GET_PLAYERBOT_AI(mainTank)) // Main tank is a real player
{
for (int i = 0; i < 3; ++i) // Only iterate through the first 3 indexes
{
if (botAI->IsAssistTankOfIndex(bot, i) && GET_PLAYERBOT_AI(bot)) // Bot is a valid tank
{
group->SetTargetIcon(moonIndex, bot->GetGUID(), boss->GetGUID());
SetNextMovementDelay(1000);
break; // Assign the moon marker and stop
}
}
}
else if (mainTankUnit == bot) // If this bot is the main tank
{ {
group->SetTargetIcon(moonIndex, bot->GetGUID(), boss->GetGUID()); group->SetTargetIcon(moonIndex, bot->GetGUID(), boss->GetGUID());
SetNextMovementDelay(1000); SetNextMovementDelay(1000);
} }
// Move main tank inside // Tanks move inside the arena
return MoveInside( return MoveInside(
ULDUAR_MAP_ID, ULDUAR_MAP_ID,
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X,
@@ -792,10 +891,35 @@ bool RazorscaleGroundedAction::Execute(Event event)
if (!group) if (!group)
return false; return false;
if (botAI->IsMainTank(bot)) Unit* mainTankUnit = AI_VALUE(Unit*, "main tank");
Player* mainTank = mainTankUnit ? mainTankUnit->ToPlayer() : nullptr;
if (mainTank && !GET_PLAYERBOT_AI(mainTank)) // Main tank is a human player
{
// Iterate through the first 3 bot tanks to handle the moon marker
for (int i = 0; i < 3; ++i)
{
if (botAI->IsAssistTankOfIndex(bot, i) && GET_PLAYERBOT_AI(bot)) // Bot is a valid tank
{
int8 moonIndex = 4;
ObjectGuid currentMoonTarget = group->GetTargetIcon(moonIndex);
// If the moon marker is set to the boss, reset it
if (currentMoonTarget == boss->GetGUID())
{
group->SetTargetIcon(moonIndex, bot->GetGUID(), ObjectGuid::Empty);
SetNextMovementDelay(1000);
return true;
}
}
}
}
else if (botAI->IsMainTank(bot)) // Bot is the main tank
{ {
int8 moonIndex = 4; int8 moonIndex = 4;
ObjectGuid currentMoonTarget = group->GetTargetIcon(moonIndex); ObjectGuid currentMoonTarget = group->GetTargetIcon(moonIndex);
// If the moon marker is set to the boss, reset it
if (currentMoonTarget == boss->GetGUID()) if (currentMoonTarget == boss->GetGUID())
{ {
group->SetTargetIcon(moonIndex, bot->GetGUID(), ObjectGuid::Empty); group->SetTargetIcon(moonIndex, bot->GetGUID(), ObjectGuid::Empty);
@@ -804,24 +928,12 @@ bool RazorscaleGroundedAction::Execute(Event event)
} }
} }
if (botAI->IsTank(bot))
{
Player* mainTank = nullptr;
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
{
Player* member = ref->GetSource();
if (member && botAI->IsMainTank(member))
{
mainTank = member;
break;
}
}
if (mainTank) if (mainTank && (botAI->IsTank(bot) && !botAI->IsMainTank(bot)))
{ {
constexpr float followDistance = 2.0f; constexpr float followDistance = 2.0f;
return MoveNear(mainTank, followDistance, MovementPriority::MOVEMENT_COMBAT); return MoveNear(mainTank, followDistance, MovementPriority::MOVEMENT_COMBAT);
}
} }
if (botAI->IsRanged(bot)) if (botAI->IsRanged(bot))