From 5e39f3c73275614ba9f71bab6ed0baae3cc1dcff Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 9 Feb 2024 20:31:34 +0800 Subject: [PATCH] Fix melee reach target --- conf/playerbots.conf.dist | 2 +- src/strategy/actions/MovementActions.cpp | 38 +++++++++++++++++++-- src/strategy/actions/MovementActions.h | 1 + src/strategy/actions/ReachTargetActions.cpp | 7 ++-- src/strategy/druid/FeralDruidStrategy.cpp | 2 +- src/strategy/triggers/RangeTriggers.cpp | 4 ++- 6 files changed, 46 insertions(+), 8 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 59123fb3..48babb9a 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -275,7 +275,7 @@ AiPlayerbot.HealDistance = 38.5 AiPlayerbot.LootDistance = 15.0 AiPlayerbot.FleeDistance = 5.0 AiPlayerbot.TooCloseDistance = 5.0 -AiPlayerbot.MeleeDistance = 0.01 +AiPlayerbot.MeleeDistance = 0.75 AiPlayerbot.FollowDistance = 1.5 AiPlayerbot.WhisperDistance = 6000.0 AiPlayerbot.ContactDistance = 0.45 diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 1b6218bd..9437f3c1 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -149,7 +149,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, // if (bot->Unit::IsFalling()) { // bot->Say("I'm falling", LANG_UNIVERSAL); // } - float distance = bot->GetDistance(x, y, z); + float distance = bot->GetExactDist(x, y, z); if (distance > sPlayerbotAIConfig->contactDistance) { WaitForReach(distance); @@ -671,7 +671,41 @@ bool MovementAction::MoveTo(Unit* target, float distance) float ty = target->GetPositionY(); float tz = target->GetPositionZ(); - float distanceToTarget = bot->GetDistance2d(target); + float distanceToTarget = bot->GetDistance(target); + float angle = bot->GetAngle(target); + float needToGo = distanceToTarget - distance; + + float maxDistance = sPlayerbotAIConfig->spellDistance; + if (needToGo > 0 && needToGo > maxDistance) + needToGo = maxDistance; + else if (needToGo < 0 && needToGo < -maxDistance) + needToGo = -maxDistance; + + 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) { + dz = bz + (tz - bz) * (needToGo / distanceToTarget); + } else { + dz = tz; + } + return MoveTo(target->GetMapId(), dx, dy, dz); +} + +bool MovementAction::ReachCombatTo(Unit* target, float distance) +{ + if (!IsMovingAllowed(target)) + return false; + + float bx = bot->GetPositionX(); + float by = bot->GetPositionY(); + float bz = bot->GetPositionZ(); + + float tx = target->GetPositionX(); + float ty = target->GetPositionY(); + float tz = target->GetPositionZ(); + float combatDistance = bot->GetCombatReach() + target->GetCombatReach(); + float distanceToTarget = bot->GetExactDist(target) - combatDistance; float angle = bot->GetAngle(target); float needToGo = distanceToTarget - distance; diff --git a/src/strategy/actions/MovementActions.h b/src/strategy/actions/MovementActions.h index fb7b4245..722a941c 100644 --- a/src/strategy/actions/MovementActions.h +++ b/src/strategy/actions/MovementActions.h @@ -29,6 +29,7 @@ class MovementAction : public Action bool Follow(Unit* target, float distance = sPlayerbotAIConfig->followDistance); bool Follow(Unit* target, float distance, float angle); bool ChaseTo(WorldObject* obj, float distance = 0.0f, float angle = 0.0f); + bool ReachCombatTo(Unit* target, float distance = 0.0f); float MoveDelay(float distance); void WaitForReach(float distance); bool IsMovingAllowed(Unit* target); diff --git a/src/strategy/actions/ReachTargetActions.cpp b/src/strategy/actions/ReachTargetActions.cpp index 919cbff8..df26d21f 100644 --- a/src/strategy/actions/ReachTargetActions.cpp +++ b/src/strategy/actions/ReachTargetActions.cpp @@ -10,7 +10,7 @@ bool ReachTargetAction::Execute(Event event) { - return MoveTo(AI_VALUE(Unit*, GetTargetName()), distance); + return ReachCombatTo(AI_VALUE(Unit*, GetTargetName()), distance); } bool ReachTargetAction::isUseful() @@ -19,8 +19,9 @@ bool ReachTargetAction::isUseful() if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL) != nullptr) { return false; } - - return AI_VALUE2(float, "distance", GetTargetName()) > (distance + sPlayerbotAIConfig->contactDistance); + Unit* target = GetTarget(); + // float dis = distance + CONTACT_DISTANCE; + return target && !bot->IsWithinCombatRange(target, distance); // sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", GetTargetName()), distance); } std::string const ReachTargetAction::GetTargetName() diff --git a/src/strategy/druid/FeralDruidStrategy.cpp b/src/strategy/druid/FeralDruidStrategy.cpp index 2b506152..a3779405 100644 --- a/src/strategy/druid/FeralDruidStrategy.cpp +++ b/src/strategy/druid/FeralDruidStrategy.cpp @@ -98,7 +98,7 @@ void FeralDruidStrategy::InitTriggers(std::vector& triggers) // triggers.push_back(new TriggerNode("not facing target", NextAction::array(0, new NextAction("set facing", ACTION_NORMAL + 7), nullptr))); triggers.push_back(new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("reach melee", ACTION_NORMAL + 8), nullptr))); - triggers.push_back(new TriggerNode("enemy too close for melee", NextAction::array(0, new NextAction("move out of enemy contact", ACTION_NORMAL + 8), nullptr))); + // triggers.push_back(new TriggerNode("enemy too close for melee", NextAction::array(0, new NextAction("move out of enemy contact", ACTION_NORMAL + 8), nullptr))); triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("survival instincts", ACTION_EMERGENCY + 1), nullptr))); triggers.push_back(new TriggerNode("omen of clarity", NextAction::array(0, new NextAction("omen of clarity", ACTION_HIGH + 9), nullptr))); triggers.push_back(new TriggerNode("player has flag", NextAction::array(0, new NextAction("dash", ACTION_EMERGENCY + 2), nullptr))); diff --git a/src/strategy/triggers/RangeTriggers.cpp b/src/strategy/triggers/RangeTriggers.cpp index 2d02ee5f..55b095dd 100644 --- a/src/strategy/triggers/RangeTriggers.cpp +++ b/src/strategy/triggers/RangeTriggers.cpp @@ -131,7 +131,9 @@ bool EnemyIsCloseTrigger::IsActive() bool OutOfRangeTrigger::IsActive() { Unit* target = AI_VALUE(Unit*, GetTargetName()); - return target && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", GetTargetName()), distance); + // increase contact distance to prevent calculation error + float dis = distance + CONTACT_DISTANCE; + return target && !bot->IsWithinCombatRange(target, dis); // sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", GetTargetName()), distance); } EnemyOutOfSpellRangeTrigger::EnemyOutOfSpellRangeTrigger(PlayerbotAI* botAI) : OutOfRangeTrigger(botAI, "enemy out of spell range", botAI->GetRange("spell"))