From b0c0002206c0d7f4f1c5c94799215d6db104924e Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Sat, 3 Aug 2024 11:52:02 +0800 Subject: [PATCH] Make better move point for follow and reach combat --- src/strategy/actions/MovementActions.cpp | 17 +++++- src/strategy/values/Arrow.cpp | 3 +- src/strategy/values/Formations.cpp | 76 +++++++++++++----------- 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 670735e4..de4cc750 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -789,15 +789,28 @@ bool MovementAction::ReachCombatTo(Unit* target, float distance) float dx = cos(angle) * needToGo + bx; float dy = sin(angle) * needToGo + by; - float dz; // = std::max(bz, tz); // calc accurate z position to avoid stuck - if (distanceToTarget > CONTACT_DISTANCE) + float dz; // = std::max(bz, tz); // calc accurate z position to avoid stuck + + if (target->HasUnitMovementFlag(MOVEMENTFLAG_FORWARD)) // target is moving forward, predict the position { + float timeToGo = MoveDelay(abs(needToGo)); + float targetMoveDist = timeToGo * target->GetSpeed(MOVE_RUN); + targetMoveDist = std::min(5.0f, targetMoveDist); + dx += targetMoveDist * cos(target->GetOrientation()); + dy += targetMoveDist * sin(target->GetOrientation()); + } + + if (distanceToTarget > CONTACT_DISTANCE) { dz = bz + (tz - bz) * (needToGo / distanceToTarget); } else { dz = tz; } + + if (!bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), dx, dy, dz)) + return false; + return MoveTo(target->GetMapId(), dx, dy, dz); } diff --git a/src/strategy/values/Arrow.cpp b/src/strategy/values/Arrow.cpp index adcfcde4..ff52c81d 100644 --- a/src/strategy/values/Arrow.cpp +++ b/src/strategy/values/Arrow.cpp @@ -48,8 +48,7 @@ WorldLocation ArrowFormation::GetLocationInternal() float y = master->GetPositionY() - masterUnit->GetY() + botUnit->GetY(); float z = master->GetPositionZ(); - float ground = master->GetMapHeight(x, y, z + 30.0f); - if (ground <= INVALID_HEIGHT) + if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), x, y, z)) return Formation::NullLocation; // master->UpdateGroundPositionZ(x, y, z); return WorldLocation(master->GetMapId(), x, y, z); diff --git a/src/strategy/values/Formations.cpp b/src/strategy/values/Formations.cpp index 7036609f..be1d53c7 100644 --- a/src/strategy/values/Formations.cpp +++ b/src/strategy/values/Formations.cpp @@ -83,19 +83,15 @@ public: if (!master) return WorldLocation(); - float range = sPlayerbotAIConfig->followDistance; - float angle = GetFollowAngle(); - float x = master->GetPositionX() + cos(angle) * range; - float y = master->GetPositionY() + sin(angle) * range; - float z = master->GetPositionZ(); - - float ground = master->GetMapHeight(x, y, z + 30.0f); - if (ground <= INVALID_HEIGHT) - return Formation::NullLocation; - - // z += CONTACT_DISTANCE; - // bot->UpdateAllowedPositionZ(x, y, z); - return WorldLocation(master->GetMapId(), x, y, z); + float range = sPlayerbotAIConfig->followDistance; + float angle = GetFollowAngle(); + float x = master->GetPositionX() + cos(angle) * range; + float y = master->GetPositionY() + sin(angle) * range; + float z = master->GetPositionZ(); + + if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), x, y, z)) + return Formation::NullLocation; + return WorldLocation(master->GetMapId(), x, y, z); } float GetMaxDistance() override { return sPlayerbotAIConfig->followDistance; } @@ -118,21 +114,36 @@ public: time_t now = time(nullptr); if (!lastChangeTime || now - lastChangeTime >= 3) { - lastChangeTime = now; - dx = (urand(0, 10) / 10.0 - 0.5) * sPlayerbotAIConfig->tooCloseDistance; - dy = (urand(0, 10) / 10.0 - 0.5) * sPlayerbotAIConfig->tooCloseDistance; - dr = sqrt(dx * dx + dy * dy); + Player* master = botAI->GetGroupMaster(); + if (!master) + return WorldLocation(); + + float range = sPlayerbotAIConfig->followDistance; + float angle = GetFollowAngle(); + + time_t now = time(nullptr); + if (!lastChangeTime || now - lastChangeTime >= 3) + { + lastChangeTime = now; + dx = (urand(0, 10) / 10.0 - 0.5) * sPlayerbotAIConfig->tooCloseDistance; + dy = (urand(0, 10) / 10.0 - 0.5) * sPlayerbotAIConfig->tooCloseDistance; + dr = sqrt(dx*dx + dy*dy); + } + + float x = master->GetPositionX() + cos(angle) * range + dx; + float y = master->GetPositionY() + sin(angle) * range + dy; + float z = master->GetPositionZ(); + if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), x, y, z)) + return Formation::NullLocation; + // bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), x, y, z); + return WorldLocation(master->GetMapId(), x, y, z); } float x = master->GetPositionX() + cos(angle) * range + dx; float y = master->GetPositionY() + sin(angle) * range + dy; float z = master->GetPositionZ(); - float ground = master->GetMapHeight(x, y, z + 30.0f); - if (ground <= INVALID_HEIGHT) + if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), x, y, z)) return Formation::NullLocation; - - z += CONTACT_DISTANCE; - bot->UpdateAllowedPositionZ(x, y, z); return WorldLocation(master->GetMapId(), x, y, z); } @@ -184,13 +195,9 @@ public: float x = target->GetPositionX() + cos(angle) * range; float y = target->GetPositionY() + sin(angle) * range; float z = target->GetPositionZ(); - float ground = target->GetMapHeight(x, y, z + 30.0f); - if (ground <= INVALID_HEIGHT) + if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), x, y, z)) return Formation::NullLocation; - z += CONTACT_DISTANCE; - bot->UpdateAllowedPositionZ(x, y, z); - return WorldLocation(bot->GetMapId(), x, y, z); } }; @@ -350,16 +357,16 @@ public: if (minDist) { - z += CONTACT_DISTANCE; - bot->UpdateAllowedPositionZ(minX, minY, z); + if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), x, y, z)) + return Formation::NullLocation; return WorldLocation(bot->GetMapId(), minX, minY, z); } return Formation::NullLocation; } - z += CONTACT_DISTANCE; - bot->UpdateAllowedPositionZ(x, y, z); + if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), x, y, z)) + return Formation::NullLocation; return WorldLocation(bot->GetMapId(), x, y, z); } }; @@ -618,12 +625,11 @@ WorldLocation MoveFormation::MoveSingleLine(std::vector line, float dif float lx = x + cos(angle) * radius; float ly = y + sin(angle) * radius; float lz = cz; - float ground = bot->GetMapHeight(lx, ly, lz + 30.0f); - if (ground <= INVALID_HEIGHT) + + Player* master = botAI->GetMaster(); + if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), lx, ly, lz)) return Formation::NullLocation; - lz += CONTACT_DISTANCE; - bot->UpdateAllowedPositionZ(lx, ly, lz); return WorldLocation(bot->GetMapId(), lx, ly, lz); }