From f2884d94e6c9ea38cfc3083cf6fc07b1e8ca3b0b Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Thu, 11 Apr 2024 19:17:42 +0800 Subject: [PATCH] Movement overhead --- src/strategy/actions/MovementActions.cpp | 89 +++++++++++++++++++++--- src/strategy/actions/MovementActions.h | 1 + 2 files changed, 82 insertions(+), 8 deletions(-) diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 926dcb3f..92a7cf3c 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -3,7 +3,9 @@ */ #include "MovementActions.h" +#include "Map.h" #include "MotionMaster.h" +#include "MoveSplineInitArgs.h" #include "MovementGenerator.h" #include "ObjectDefines.h" #include "ObjectGuid.h" @@ -151,13 +153,8 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, // } bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->IsFlying() && !bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater(); - float modifiedZ = SearchBestGroundZForPath(x, y, z, generatePath, 20.0f, normal_only, 8.0f); - if (modifiedZ == INVALID_HEIGHT) { - return false; - } - float distance = bot->GetExactDist(x, y, modifiedZ); - if (distance > sPlayerbotAIConfig->contactDistance) - { + if (!generatePath) { + float distance = bot->GetExactDist(x, y, z); WaitForReach(distance); if (bot->IsSitState()) @@ -171,9 +168,36 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, MotionMaster &mm = *bot->GetMotionMaster(); mm.Clear(); - mm.MovePoint(mapId, x, y, modifiedZ, generatePath); + mm.MovePoint(mapId, x, y, z, generatePath); AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation()); return true; + } else { + float modifiedZ; + Movement::PointsArray path = SearchForBestPath(x, y, z, modifiedZ); + if (modifiedZ == INVALID_HEIGHT) { + return false; + } + float distance = bot->GetExactDist(x, y, modifiedZ); + if (distance > sPlayerbotAIConfig->contactDistance) + { + WaitForReach(distance); + + if (bot->IsSitState()) + bot->SetStandState(UNIT_STAND_STATE_STAND); + + if (bot->IsNonMeleeSpellCast(true)) + { + bot->CastStop(); + botAI->InterruptSpell(); + } + MotionMaster &mm = *bot->GetMotionMaster(); + + mm.Clear(); + mm.MoveSplinePath(&path); + AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation()); + return true; + } + } return false; @@ -1378,6 +1402,55 @@ float MovementAction::SearchBestGroundZForPath(float x, float y, float z, bool g return current_z; } +const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y, float z, float &modified_z, int maxSearchCount, bool normal_only, float step) +{ + bool found = false; + modified_z = INVALID_HEIGHT; + float tempZ = bot->GetMapWaterOrGroundLevel(x, y, z); + PathGenerator gen(bot); + gen.CalculatePath(x, y, tempZ); + Movement::PointsArray result = gen.GetPath(); + float min_length = gen.getPathLength(); + if (gen.GetPathType() == PATHFIND_NORMAL && abs(tempZ - z) < 0.5f) { + modified_z = tempZ; + return result; + } + // Start searching + if (gen.GetPathType() == PATHFIND_NORMAL) { + found = true; + modified_z = tempZ; + } + int count = 1; + for (float delta = step; count < maxSearchCount / 2 + 1; count++, delta += step) { + tempZ = bot->GetMapWaterOrGroundLevel(x, y, z + delta); + PathGenerator gen(bot); + gen.CalculatePath(x, y, tempZ); + if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) { + found = true; + min_length = gen.getPathLength(); + result = gen.GetPath(); + modified_z = tempZ; + } + } + for (float delta = -step; count < maxSearchCount; count++, delta -= step) { + tempZ = bot->GetMapWaterOrGroundLevel(x, y, z + delta); + PathGenerator gen(bot); + gen.CalculatePath(x, y, tempZ); + if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) { + found = true; + min_length = gen.getPathLength(); + result = gen.GetPath(); + modified_z = tempZ; + } + } + if (!found && normal_only) { + return Movement::PointsArray{}; + } + if (!found && !normal_only) { + return result; + } + return result; +} bool FleeAction::Execute(Event event) { diff --git a/src/strategy/actions/MovementActions.h b/src/strategy/actions/MovementActions.h index bff7ff3a..93fc242b 100644 --- a/src/strategy/actions/MovementActions.h +++ b/src/strategy/actions/MovementActions.h @@ -43,6 +43,7 @@ class MovementAction : public Action void CreateWp(Player* wpOwner, float x, float y, float z, float o, uint32 entry, bool important = false); private: float SearchBestGroundZForPath(float x, float y, float z, bool generatePath, float range = 20.0f, bool normal_only = false, float step = 8.0f); + const Movement::PointsArray SearchForBestPath(float x, float y, float z, float &modified_z, int maxSearchCount = 5, bool normal_only = false, float step = 8.0f); }; class FleeAction : public MovementAction