Better waypoints for combat reach

This commit is contained in:
Yunfan Li
2024-08-05 12:08:14 +08:00
parent 1a92743dfd
commit f706fa2ba6
3 changed files with 36 additions and 28 deletions

View File

@@ -29,7 +29,7 @@ bool FollowAction::Execute(Event event)
if (Formation::IsNullLocation(loc) || loc.GetMapId() == -1) if (Formation::IsNullLocation(loc) || loc.GetMapId() == -1)
return false; return false;
moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ()); moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), false, false, false, true);
} }
if (Pet* pet = bot->GetPet()) if (Pet* pet = bot->GetPet())

View File

@@ -12,6 +12,7 @@
#include "Event.h" #include "Event.h"
#include "FleeManager.h" #include "FleeManager.h"
#include "G3D/Vector3.h"
#include "GameObject.h" #include "GameObject.h"
#include "Geometry.h" #include "Geometry.h"
#include "LastMovementValue.h" #include "LastMovementValue.h"
@@ -160,7 +161,7 @@ bool MovementAction::MoveToLOS(WorldObject* target, bool ranged)
return false; return false;
} }
bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bool react, bool normal_only) bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bool react, bool normal_only, bool exact_waypoint)
{ {
UpdateMovementState(); UpdateMovementState();
if (!IsMovingAllowed(mapId, x, y, z)) if (!IsMovingAllowed(mapId, x, y, z))
@@ -190,7 +191,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
bool generatePath = !bot->IsFlying() && !bot->isSwimming(); bool generatePath = !bot->IsFlying() && !bot->isSwimming();
bool disableMoveSplinePath = sPlayerbotAIConfig->disableMoveSplinePath >= 2 || bool disableMoveSplinePath = sPlayerbotAIConfig->disableMoveSplinePath >= 2 ||
(sPlayerbotAIConfig->disableMoveSplinePath == 1 && bot->InBattleground()); (sPlayerbotAIConfig->disableMoveSplinePath == 1 && bot->InBattleground());
if (disableMoveSplinePath || !generatePath) if (exact_waypoint || disableMoveSplinePath || !generatePath)
{ {
float distance = bot->GetExactDist(x, y, z); float distance = bot->GetExactDist(x, y, z);
if (distance > sPlayerbotAIConfig->contactDistance) if (distance > sPlayerbotAIConfig->contactDistance)
@@ -785,28 +786,34 @@ bool MovementAction::ReachCombatTo(Unit* target, float distance)
float ty = target->GetPositionY(); float ty = target->GetPositionY();
float tz = target->GetPositionZ(); float tz = target->GetPositionZ();
float combatDistance = bot->GetCombatReach() + target->GetCombatReach(); float combatDistance = bot->GetCombatReach() + target->GetCombatReach();
float distanceToTarget = bot->GetExactDist(target) - combatDistance; distance += combatDistance;
float angle = bot->GetAngle(target);
float needToGo = distanceToTarget - distance;
float maxDistance = sPlayerbotAIConfig->spellDistance; if (target->HasUnitMovementFlag(MOVEMENTFLAG_FORWARD)) // target is moving forward, predict the position
if (needToGo > 0 && needToGo > maxDistance) {
needToGo = maxDistance; float needToGo = bot->GetExactDist(target) - distance;
else if (needToGo < 0 && needToGo < -maxDistance) float timeToGo = MoveDelay(abs(needToGo)) + sPlayerbotAIConfig->reactDelay;
needToGo = -maxDistance; float targetMoveDist = timeToGo * target->GetSpeed(MOVE_RUN);
targetMoveDist = std::min(5.0f, targetMoveDist);
tx += targetMoveDist * cos(target->GetOrientation());
ty += targetMoveDist * sin(target->GetOrientation());
if (!target->GetMap()->CheckCollisionAndGetValidCoords(target, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),
tx, ty, tz))
{
// disable prediction if position is invalid
tx = target->GetPositionX();
ty = target->GetPositionY();
tz = target->GetPositionZ();
}
}
float dx = cos(angle) * needToGo + bx; PathGenerator path(bot);
float dy = sin(angle) * needToGo + by; path.CalculatePath(tx, ty, tz, false);
float dz; // = std::max(bz, tz); // calc accurate z position to avoid stuck PathType type = path.GetPathType();
if (distanceToTarget > CONTACT_DISTANCE) if (type != PATHFIND_NORMAL && type != PATHFIND_INCOMPLETE)
{ return false;
dz = bz + (tz - bz) * (needToGo / distanceToTarget); path.ShortenPathUntilDist(G3D::Vector3(tx, ty, tz), distance);
} G3D::Vector3 endPos = path.GetPath().back();
else return MoveTo(target->GetMapId(), endPos.x, endPos.y, endPos.z);
{
dz = tz;
}
return MoveTo(target->GetMapId(), dx, dy, dz);
} }
float MovementAction::GetFollowAngle() float MovementAction::GetFollowAngle()
@@ -1560,13 +1567,14 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
gen.CalculatePath(x, y, tempZ); gen.CalculatePath(x, y, tempZ);
Movement::PointsArray result = gen.GetPath(); Movement::PointsArray result = gen.GetPath();
float min_length = gen.getPathLength(); float min_length = gen.getPathLength();
if ((gen.GetPathType() & PATHFIND_NORMAL) && abs(tempZ - z) < 0.5f) int typeOk = PATHFIND_NORMAL | PATHFIND_INCOMPLETE;
if ((gen.GetPathType() & typeOk) && abs(tempZ - z) < 0.5f)
{ {
modified_z = tempZ; modified_z = tempZ;
return result; return result;
} }
// Start searching // Start searching
if (gen.GetPathType() & PATHFIND_NORMAL) if (gen.GetPathType() & typeOk)
{ {
modified_z = tempZ; modified_z = tempZ;
found = true; found = true;
@@ -1581,7 +1589,7 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
} }
PathGenerator gen(bot); PathGenerator gen(bot);
gen.CalculatePath(x, y, tempZ); gen.CalculatePath(x, y, tempZ);
if ((gen.GetPathType() & PATHFIND_NORMAL) && gen.getPathLength() < min_length) if ((gen.GetPathType() & typeOk) && gen.getPathLength() < min_length)
{ {
found = true; found = true;
min_length = gen.getPathLength(); min_length = gen.getPathLength();
@@ -1598,7 +1606,7 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
} }
PathGenerator gen(bot); PathGenerator gen(bot);
gen.CalculatePath(x, y, tempZ); gen.CalculatePath(x, y, tempZ);
if ((gen.GetPathType() & PATHFIND_NORMAL) && gen.getPathLength() < min_length) if ((gen.GetPathType() & typeOk) && gen.getPathLength() < min_length)
{ {
found = true; found = true;
min_length = gen.getPathLength(); min_length = gen.getPathLength();

View File

@@ -27,7 +27,7 @@ protected:
bool MoveNear(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->contactDistance); bool MoveNear(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->contactDistance);
bool MoveToLOS(WorldObject* target, bool ranged = false); bool MoveToLOS(WorldObject* target, bool ranged = false);
bool MoveTo(uint32 mapId, float x, float y, float z, bool idle = false, bool react = false, bool MoveTo(uint32 mapId, float x, float y, float z, bool idle = false, bool react = false,
bool normal_only = false); bool normal_only = false, bool exact_waypoint = false);
bool MoveTo(Unit* target, float distance = 0.0f); bool MoveTo(Unit* target, float distance = 0.0f);
bool MoveNear(WorldObject* target, float distance = sPlayerbotAIConfig->contactDistance); bool MoveNear(WorldObject* target, float distance = sPlayerbotAIConfig->contactDistance);
float GetFollowAngle(); float GetFollowAngle();