From bb34a09afe05d5e11888a7c06f41a0fc9dc93289 Mon Sep 17 00:00:00 2001 From: Fuzz Date: Tue, 20 Aug 2024 16:25:28 +1000 Subject: [PATCH 1/2] fixed bug I introduced in f87c87f5d4f5aefbf8db0a139d02b5989bf7b587 where bots wont dismount when they should --- src/strategy/actions/CheckMountStateAction.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/strategy/actions/CheckMountStateAction.cpp b/src/strategy/actions/CheckMountStateAction.cpp index 24684a6a1..249b065fe 100644 --- a/src/strategy/actions/CheckMountStateAction.cpp +++ b/src/strategy/actions/CheckMountStateAction.cpp @@ -132,11 +132,14 @@ bool CheckMountStateAction::isUseful() if (bot->HasUnitState(UNIT_STATE_IN_FLIGHT)) return false; - // checks both outdoors flag, and whether bot is clipping below floor slightly - // because that will cause bot to falsely indicate outdoors state and try - // mount indoors (seems to mostly be an issue in tunnels of WSG and AV) - if (!bot->IsOutdoors() || bot->GetPositionZ() < bot->GetMapWaterOrGroundLevel( - bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ())) + if (!bot->IsOutdoors()) + return false; + + // in addition to checking IsOutdoors, also check whether bot is clipping below floor slightly because that will + // cause bot to falsly indicate they are outdoors. This fixes bug where bot tries to mount indoors (which seems + // to mostly be an issue in tunnels of WSG and AV) + if (!bot->IsMounted() && bot->GetPositionZ() < bot->GetMapWaterOrGroundLevel( + bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ())) return false; if (bot->InArena()) From 87cbaa9527b40aa4d3cfd511ce30f6d6a951b23f Mon Sep 17 00:00:00 2001 From: Fuzz Date: Tue, 20 Aug 2024 16:32:08 +1000 Subject: [PATCH 2/2] bot will no longer mount to reach target within 21 units (as this is the distance at which the time taken to cast mount spell is more than the time saved by moving faster), warrior bot will now dismount with enough distance to perform charge (rather than right infront of target which real warrior wouldnt do) --- .../actions/CheckMountStateAction.cpp | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/strategy/actions/CheckMountStateAction.cpp b/src/strategy/actions/CheckMountStateAction.cpp index 249b065fe..ce223d16c 100644 --- a/src/strategy/actions/CheckMountStateAction.cpp +++ b/src/strategy/actions/CheckMountStateAction.cpp @@ -15,48 +15,49 @@ bool CheckMountStateAction::Execute(Event event) { - bool noattackers = - AI_VALUE2(bool, "combat", "self target") ? (AI_VALUE(uint8, "attacker count") > 0 ? false : true) : true; + bool noattackers = !AI_VALUE2(bool, "combat", "self target") || !AI_VALUE(uint8, "attacker count"); bool enemy = AI_VALUE(Unit*, "enemy player target"); bool dps = AI_VALUE(Unit*, "dps target"); bool shouldDismount = false; bool shouldMount = false; - // bool chasedistance = false; - float attack_distance; - float mount_distance; - if (PlayerbotAI::IsMelee(bot)) - { - attack_distance = sPlayerbotAIConfig->meleeDistance + 2.0f; - mount_distance = sPlayerbotAIConfig->meleeDistance + 10.0f; - } - else + + if (Unit* currentTarget = AI_VALUE(Unit*, "current target")) { - attack_distance = sPlayerbotAIConfig->spellDistance + 2.0f; - mount_distance = sPlayerbotAIConfig->spellDistance + 10.0f; - } + float dismount_distance; + float mount_distance; + if (PlayerbotAI::IsMelee(bot)) + { + dismount_distance = sPlayerbotAIConfig->meleeDistance + 2.0f; + mount_distance = sPlayerbotAIConfig->meleeDistance + 10.0f; + } + else + { + dismount_distance = sPlayerbotAIConfig->spellDistance + 2.0f; + mount_distance = sPlayerbotAIConfig->spellDistance + 10.0f; + } - Unit* currentTarget = AI_VALUE(Unit*, "current target"); + // warrior bots should dismount far enough to charge (because its important for generating some initial rage), + // a real player would be riding toward enemy mashing the charge key but the bots wont cast charge while mounted + if (CLASS_WARRIOR == bot->getClass()) + dismount_distance = std::max(18.0f, dismount_distance); - if (currentTarget) - { - float combatReach = bot->GetCombatReach() + currentTarget->GetCombatReach(); - attack_distance += combatReach; - float disToTarget = bot->GetExactDist(currentTarget); - shouldDismount = disToTarget <= attack_distance; - } - else - shouldDismount = false; + // mount_distance should be >= 21 regardless of class, because when travelling a distance < 21 it takes longer + // to cast mount-spell than the time saved from the speed increase. At a distance of 21 both approaches take 3 + // seconds: + // 21 / 7 = 21 / 14 + 1.5 = 3 (7 = dismounted speed 14 = epic-mount speed 1.5 = mount-spell cast time) + mount_distance = std::max(21.0f, mount_distance); - if (currentTarget) - { float combatReach = bot->GetCombatReach() + currentTarget->GetCombatReach(); - mount_distance += combatReach; float disToTarget = bot->GetExactDist(currentTarget); - shouldMount = disToTarget > mount_distance; + shouldDismount = disToTarget <= dismount_distance + combatReach; + shouldMount = disToTarget > mount_distance + combatReach; } else + { + shouldDismount = false; shouldMount = true; - + } + if (bot->IsMounted() && shouldDismount) { WorldPacket emptyPacket;