improved path selection for non-WSG BG's (improvements to pathing in AB and AV especially)

This commit is contained in:
Fuzz
2024-07-10 22:25:59 +10:00
parent 500de1de10
commit 06379b1ad0

View File

@@ -4162,99 +4162,84 @@ bool BGTactics::selectObjectiveWp(std::vector<BattleBotPath*> const& vPaths)
if (bgType == BATTLEGROUND_WS /* && (bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) || bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG))*/) if (bgType == BATTLEGROUND_WS /* && (bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) || bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG))*/)
return wsgPaths(); return wsgPaths();
BattleBotPath* pClosestPath = nullptr; float chosenPathScore = FLT_MAX;//lower score is better
uint32 closestPoint = 0; BattleBotPath* chosenPath = nullptr;
float closestDistanceToTarget = FLT_MAX; uint32 chosenPathPoint = 0;
bool reverse = false; bool chosenPathReverse = false;
float maxDistanceToPoint = 50.0f;
if (bgType == BATTLEGROUND_IC)
maxDistanceToPoint = 80.0f;
for (auto const& pPath : vPaths) float botDistanceLimit = 50.0f; // limit for how far path can be from bot
float botDistanceScoreSubtract = 8.0f; // path score modifier - lower = less likely to chose a further path (it's basically the distance from bot that's ignored)
float botDistanceScoreMultiply = 3.0f; // path score modifier - higher = less likely to chose a further path (it's basically a multiplier on distance from bot - makes distance from bot more signifcant than distance from destination)
if (bgType == BATTLEGROUND_IC)
botDistanceLimit = 80.0f;
else if (bgType == BATTLEGROUND_AB)
{
botDistanceScoreSubtract = 2.0f;
botDistanceScoreMultiply = 4.0f;
}
for (auto const& path : vPaths)
{ {
// skip mine paths of own faction // skip mine paths of own faction
if (bot->GetTeamId() == TEAM_ALLIANCE && std::find(vPaths_AllyMine.begin(), vPaths_AllyMine.end(), pPath) != vPaths_AllyMine.end()) if (bot->GetTeamId() == TEAM_ALLIANCE && std::find(vPaths_AllyMine.begin(), vPaths_AllyMine.end(), path) != vPaths_AllyMine.end())
continue; continue;
if (bot->GetTeamId() == TEAM_HORDE && std::find(vPaths_HordeMine.begin(), vPaths_HordeMine.end(), pPath) != vPaths_HordeMine.end()) if (bot->GetTeamId() == TEAM_HORDE && std::find(vPaths_HordeMine.begin(), vPaths_HordeMine.end(), path) != vPaths_HordeMine.end())
continue; continue;
BattleBotWaypoint& lastPoint = ((*pPath)[pPath->size() - 1]); BattleBotWaypoint& startPoint = ((*path)[0]);
float const distanceFromPathEndToTarget = sqrt(Position(pos.x, pos.y, pos.z, 0.f).GetExactDist(lastPoint.x, lastPoint.y, lastPoint.z)); float const startPointDistToDestination = sqrt(Position(pos.x, pos.y, pos.z, 0.f).GetExactDist(startPoint.x, startPoint.y, startPoint.z));
if (closestDistanceToTarget > distanceFromPathEndToTarget) BattleBotWaypoint& endPoint = ((*path)[path->size() - 1]);
float const endPointDistToDestination = sqrt(Position(pos.x, pos.y, pos.z, 0.f).GetExactDist(endPoint.x, endPoint.y, endPoint.z));
bool reverse = startPointDistToDestination < endPointDistToDestination;
// dont travel reverse if it's a reverse paths
if (reverse && std::find(vPaths_NoReverseAllowed.begin(), vPaths_NoReverseAllowed.end(), path) != vPaths_NoReverseAllowed.end())
continue;
int closestPointIndex = -1;
float closestPointDistToBot = FLT_MAX;
for (uint32 i = 0; i < path->size(); i++)
{ {
float closestDistanceFromMeToPoint = FLT_MAX; BattleBotWaypoint& waypoint = ((*path)[i]);
float const distToBot = sqrt(bot->GetDistance(waypoint.x, waypoint.y, waypoint.z));
for (uint32 i = 0; i < pPath->size(); i++) if (closestPointDistToBot > distToBot)
{ {
BattleBotWaypoint& waypoint = ((*pPath)[i]); closestPointDistToBot = distToBot;
float const distanceFromMeToPoint = sqrt(bot->GetDistance(waypoint.x, waypoint.y, waypoint.z)); closestPointIndex = i;
if (distanceFromMeToPoint < maxDistanceToPoint && closestDistanceFromMeToPoint > distanceFromMeToPoint)
{
reverse = false;
pClosestPath = pPath;
closestPoint = i;
closestDistanceToTarget = distanceFromPathEndToTarget;
closestDistanceFromMeToPoint = distanceFromMeToPoint;
}
} }
} }
// skip no reverse paths // don't pick path where bot is already closest to the paths closest point to target (it means path cant lead it anywhere)
if (std::find(vPaths_NoReverseAllowed.begin(), vPaths_NoReverseAllowed.end(), pPath) != vPaths_NoReverseAllowed.end()) // don't pick path where closest point is too far away
if (closestPointIndex == (reverse ? 0 : path->size() - 1) || closestPointDistToBot > botDistanceLimit)
continue; continue;
// skip mine paths of own faction
if (bot->GetTeamId() == TEAM_ALLIANCE && std::find(vPaths_AllyMine.begin(), vPaths_AllyMine.end(), pPath) != vPaths_AllyMine.end())
continue;
if (bot->GetTeamId() == TEAM_HORDE && std::find(vPaths_HordeMine.begin(), vPaths_HordeMine.end(), pPath) != vPaths_HordeMine.end()) // creates a score based on dist-to-bot and dist-to-destination, where lower is better, and dist-to-bot is more important (when its beyond a certain distance)
continue; // dist-to-bot is more important because otherwise they cant reach it at all (or will fly through air with MM::MovePoint()), also bot may need to use multiple
// paths (one after another) anyway
float distToDestination = reverse ? startPointDistToDestination : endPointDistToDestination;
float pathScore = (closestPointDistToBot < botDistanceScoreSubtract ? 0.0f : ((closestPointDistToBot - botDistanceScoreSubtract) * botDistanceScoreMultiply)) + distToDestination;
{ //LOG_INFO("playerbots", "bot={}\t{:6.1f}\t{:4.1f}\t{:4.1f}\t{}", bot->GetName(), pathScore, closestPointDistToBot, distToDestination, vPaths_AB_name[pathNum]);
BattleBotWaypoint& firstPoint = ((*pPath)[0]);
float const distanceFromPathBeginToTarget = sqrt(Position(pos.x, pos.y, pos.z, 0).GetExactDist(firstPoint.x, firstPoint.y, firstPoint.z));
if (closestDistanceToTarget > distanceFromPathBeginToTarget)
{
float closestDistanceFromMeToPoint = FLT_MAX;
for (uint32 i = 0; i < pPath->size(); i++) if (chosenPathScore > pathScore) {
{ chosenPathScore = pathScore;
BattleBotWaypoint& waypoint = ((*pPath)[i]); chosenPath = path;
float const distanceFromMeToPoint = sqrt(bot->GetDistance(waypoint.x, waypoint.y, waypoint.z)); chosenPathPoint = closestPointIndex;
if (distanceFromMeToPoint < maxDistanceToPoint && closestDistanceFromMeToPoint > distanceFromMeToPoint) chosenPathReverse = reverse;
{
reverse = true;
pClosestPath = pPath;
closestPoint = i;
closestDistanceToTarget = distanceFromPathBeginToTarget;
closestDistanceFromMeToPoint = distanceFromMeToPoint;
}
}
}
} }
} }
if (!pClosestPath) if (!chosenPath)
return false; return false;
// Prevent picking last point of path. //LOG_INFO("playerbots", "bot={} {}", bot->GetName(), vPaths_AB_name[chosenPathNum]);
// It means we are already there.
if (reverse)
{
if (closestPoint == 0)
return false;
}
else
{
if (closestPoint == pClosestPath->size() - 1)
return false;
}
BattleBotPath* currentPath = pClosestPath; return moveToObjectiveWp(chosenPath, chosenPathPoint, chosenPathReverse);
uint32 currentPoint = reverse ? closestPoint + 1 : closestPoint - 1;
return moveToObjectiveWp(currentPath, currentPoint, reverse);
return false; return false;
} }