From f26c4e99f6530441b703300af952d9fee9781924 Mon Sep 17 00:00:00 2001 From: Gonzalo Date: Thu, 25 Sep 2025 18:26:28 -0300 Subject: [PATCH 1/8] Fix: Prevent bots from eating and drinking while mounted This change modifies the `DrinkAction::Execute()` and `EatAction::Execute()` functions in `src/strategy/actions/NonCombatActions.cpp`. Previously, playerbots could attempt to eat food or drink water while mounted, which is not possible in the game and creates unrealistic behavior. This fix adds mount state checks to both actions: 1. `DrinkAction::Execute()` now checks `bot->IsMounted()` and returns false if mounted 2. `EatAction::Execute()` now checks `bot->IsMounted()` and returns false if mounted This prevents bots from attempting to consume food or drinks while mounted, improving bot behavior realism and preventing unnecessary action attempts that would fail anyway. --- src/strategy/actions/NonCombatActions.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/strategy/actions/NonCombatActions.cpp b/src/strategy/actions/NonCombatActions.cpp index d3c49dec..b696a27b 100644 --- a/src/strategy/actions/NonCombatActions.cpp +++ b/src/strategy/actions/NonCombatActions.cpp @@ -13,6 +13,10 @@ bool DrinkAction::Execute(Event event) if (bot->IsInCombat()) return false; + // Don't drink while mounted + if (bot->IsMounted()) + return false; + bool hasMana = AI_VALUE2(bool, "has mana", "self target"); if (!hasMana) return false; @@ -66,6 +70,10 @@ bool EatAction::Execute(Event event) if (bot->IsInCombat()) return false; + // Don't eat while mounted + if (bot->IsMounted()) + return false; + if (botAI->HasCheat(BotCheatMask::food)) { // if (bot->IsNonMeleeSpellCast(true)) From e042e3b12b922c1f9f0ecf80b35d36d7e2a9fc4b Mon Sep 17 00:00:00 2001 From: bash <31279994+hermensbas@users.noreply.github.com> Date: Sat, 27 Sep 2025 22:55:52 +0200 Subject: [PATCH 2/8] Added shapeshift --- src/strategy/actions/NonCombatActions.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/strategy/actions/NonCombatActions.cpp b/src/strategy/actions/NonCombatActions.cpp index 98956f56..f7b5a26a 100644 --- a/src/strategy/actions/NonCombatActions.cpp +++ b/src/strategy/actions/NonCombatActions.cpp @@ -13,10 +13,12 @@ bool DrinkAction::Execute(Event event) if (bot->IsInCombat()) return false; - // Don't drink while mounted if (bot->IsMounted()) return false; + if (botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form","flight form", "swift flight form", nullptr)) + return false; + if (botAI->HasCheat(BotCheatMask::food)) { // if (bot->IsNonMeleeSpellCast(true)) @@ -73,10 +75,12 @@ bool EatAction::Execute(Event event) if (bot->IsInCombat()) return false; - // Don't eat while mounted if (bot->IsMounted()) return false; + if (botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form","flight form", "swift flight form", nullptr)) + return false; + if (botAI->HasCheat(BotCheatMask::food)) { // if (bot->IsNonMeleeSpellCast(true)) From d9b57fcfd4decd0efe66183c9e718683d3cb59ef Mon Sep 17 00:00:00 2001 From: bash <31279994+hermensbas@users.noreply.github.com> Date: Sat, 27 Sep 2025 23:26:29 +0200 Subject: [PATCH 3/8] Updated the locations of the checks, also added the checks as additional gatekeeper of the execute. --- src/strategy/actions/NonCombatActions.cpp | 38 ++++++++++------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/strategy/actions/NonCombatActions.cpp b/src/strategy/actions/NonCombatActions.cpp index f7b5a26a..6037948a 100644 --- a/src/strategy/actions/NonCombatActions.cpp +++ b/src/strategy/actions/NonCombatActions.cpp @@ -10,13 +10,8 @@ bool DrinkAction::Execute(Event event) { - if (bot->IsInCombat()) - return false; - - if (bot->IsMounted()) - return false; - - if (botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form","flight form", "swift flight form", nullptr)) + // gatekeeper + if (!isPossible()) return false; if (botAI->HasCheat(BotCheatMask::food)) @@ -58,27 +53,22 @@ bool DrinkAction::Execute(Event event) bool DrinkAction::isUseful() { - // check class uses mana - if (!AI_VALUE2(bool, "has mana", "self target")) - return false; - return UseItemAction::isUseful() && AI_VALUE2(uint8, "mana", "self target") < 100; } bool DrinkAction::isPossible() { - return !bot->IsInCombat() && (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); + return !bot->IsInCombat() && + AI_VALUE2(bool, "has mana", "self target") && + !bot->IsMounted() && + !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form","flight form", "swift flight form", nullptr) && + (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); } bool EatAction::Execute(Event event) { - if (bot->IsInCombat()) - return false; - - if (bot->IsMounted()) - return false; - - if (botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form","flight form", "swift flight form", nullptr)) + // gatekeeper + if (!isPossible()) return false; if (botAI->HasCheat(BotCheatMask::food)) @@ -118,9 +108,15 @@ bool EatAction::Execute(Event event) return UseItemAction::Execute(event); } -bool EatAction::isUseful() { return UseItemAction::isUseful() && AI_VALUE2(uint8, "health", "self target") < 85; } +bool EatAction::isUseful() +{ + return UseItemAction::isUseful() && AI_VALUE2(uint8, "health", "self target") < 100; +} bool EatAction::isPossible() { - return !bot->IsInCombat() && (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); + return !bot->IsInCombat() && + !bot->IsMounted() && + !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form","flight form", "swift flight form", nullptr) && + (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); } From 62e2ca247ae523934572702b1f4241e76c299c70 Mon Sep 17 00:00:00 2001 From: bash <31279994+hermensbas@users.noreply.github.com> Date: Sat, 27 Sep 2025 23:28:48 +0200 Subject: [PATCH 4/8] formatting --- src/strategy/actions/NonCombatActions.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/strategy/actions/NonCombatActions.cpp b/src/strategy/actions/NonCombatActions.cpp index 6037948a..d6747c23 100644 --- a/src/strategy/actions/NonCombatActions.cpp +++ b/src/strategy/actions/NonCombatActions.cpp @@ -61,7 +61,8 @@ bool DrinkAction::isPossible() return !bot->IsInCombat() && AI_VALUE2(bool, "has mana", "self target") && !bot->IsMounted() && - !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form","flight form", "swift flight form", nullptr) && + !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", + "aquatic form","flight form", "swift flight form", nullptr) && (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); } @@ -117,6 +118,7 @@ bool EatAction::isPossible() { return !bot->IsInCombat() && !bot->IsMounted() && - !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form","flight form", "swift flight form", nullptr) && + !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", + "aquatic form","flight form", "swift flight form", nullptr) && (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); } From ec4ab34f947c4f5f6950ff4b9a4b14fd8b785e9b Mon Sep 17 00:00:00 2001 From: bash <31279994+hermensbas@users.noreply.github.com> Date: Sat, 27 Sep 2025 23:31:16 +0200 Subject: [PATCH 5/8] Update NonCombatActions.cpp Expensive checks last. --- src/strategy/actions/NonCombatActions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strategy/actions/NonCombatActions.cpp b/src/strategy/actions/NonCombatActions.cpp index d6747c23..c17829aa 100644 --- a/src/strategy/actions/NonCombatActions.cpp +++ b/src/strategy/actions/NonCombatActions.cpp @@ -59,8 +59,8 @@ bool DrinkAction::isUseful() bool DrinkAction::isPossible() { return !bot->IsInCombat() && - AI_VALUE2(bool, "has mana", "self target") && !bot->IsMounted() && + AI_VALUE2(bool, "has mana", "self target") && !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form","flight form", "swift flight form", nullptr) && (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); From df77668b4bcc46cfbbeecc8135c1515147e9b592 Mon Sep 17 00:00:00 2001 From: bash <31279994+hermensbas@users.noreply.github.com> Date: Sun, 28 Sep 2025 20:37:01 +0200 Subject: [PATCH 6/8] Review --- src/strategy/actions/NonCombatActions.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/strategy/actions/NonCombatActions.cpp b/src/strategy/actions/NonCombatActions.cpp index c17829aa..30842135 100644 --- a/src/strategy/actions/NonCombatActions.cpp +++ b/src/strategy/actions/NonCombatActions.cpp @@ -10,10 +10,6 @@ bool DrinkAction::Execute(Event event) { - // gatekeeper - if (!isPossible()) - return false; - if (botAI->HasCheat(BotCheatMask::food)) { // if (bot->IsNonMeleeSpellCast(true)) @@ -53,14 +49,15 @@ bool DrinkAction::Execute(Event event) bool DrinkAction::isUseful() { - return UseItemAction::isUseful() && AI_VALUE2(uint8, "mana", "self target") < 100; + return UseItemAction::isUseful() && + AI_VALUE2(bool, "has mana", "self target") && + AI_VALUE2(uint8, "mana", "self target") < 100; } bool DrinkAction::isPossible() { return !bot->IsInCombat() && !bot->IsMounted() && - AI_VALUE2(bool, "has mana", "self target") && !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form","flight form", "swift flight form", nullptr) && (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); @@ -68,10 +65,6 @@ bool DrinkAction::isPossible() bool EatAction::Execute(Event event) { - // gatekeeper - if (!isPossible()) - return false; - if (botAI->HasCheat(BotCheatMask::food)) { // if (bot->IsNonMeleeSpellCast(true)) @@ -111,7 +104,8 @@ bool EatAction::Execute(Event event) bool EatAction::isUseful() { - return UseItemAction::isUseful() && AI_VALUE2(uint8, "health", "self target") < 100; + return UseItemAction::isUseful() && + AI_VALUE2(uint8, "health", "self target") < 100; } bool EatAction::isPossible() From aaa9e1a42cb5c01a16cb40d75cb369eb28a0a707 Mon Sep 17 00:00:00 2001 From: bash <31279994+hermensbas@users.noreply.github.com> Date: Mon, 29 Sep 2025 00:06:56 +0200 Subject: [PATCH 7/8] Placed cheap checks in isPossible() more expensive in isUseful() combat en mounted are both HasUnitFlag checks, which are cheap calls to make. --- src/strategy/actions/NonCombatActions.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/strategy/actions/NonCombatActions.cpp b/src/strategy/actions/NonCombatActions.cpp index 30842135..25c1fc47 100644 --- a/src/strategy/actions/NonCombatActions.cpp +++ b/src/strategy/actions/NonCombatActions.cpp @@ -51,15 +51,15 @@ bool DrinkAction::isUseful() { return UseItemAction::isUseful() && AI_VALUE2(bool, "has mana", "self target") && - AI_VALUE2(uint8, "mana", "self target") < 100; + AI_VALUE2(uint8, "mana", "self target") < 100 && + !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", + "aquatic form","flight form", "swift flight form", nullptr) && } bool DrinkAction::isPossible() { return !bot->IsInCombat() && !bot->IsMounted() && - !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", - "aquatic form","flight form", "swift flight form", nullptr) && (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); } @@ -105,14 +105,14 @@ bool EatAction::Execute(Event event) bool EatAction::isUseful() { return UseItemAction::isUseful() && - AI_VALUE2(uint8, "health", "self target") < 100; + AI_VALUE2(uint8, "health", "self target") < 100 && + !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", + "aquatic form","flight form", "swift flight form", nullptr) && } bool EatAction::isPossible() { return !bot->IsInCombat() && !bot->IsMounted() && - !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", - "aquatic form","flight form", "swift flight form", nullptr) && (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); } From 972e2604ce0cc4d02fe690faf126a9b6de71bd92 Mon Sep 17 00:00:00 2001 From: bash <31279994+hermensbas@users.noreply.github.com> Date: Mon, 29 Sep 2025 00:14:28 +0200 Subject: [PATCH 8/8] Update NonCombatActions.cpp This is better, even though aura check is tiny more expensive then most. Placing them into isUseful() is kinda confusing. --- src/strategy/actions/NonCombatActions.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/strategy/actions/NonCombatActions.cpp b/src/strategy/actions/NonCombatActions.cpp index 25c1fc47..60628bc7 100644 --- a/src/strategy/actions/NonCombatActions.cpp +++ b/src/strategy/actions/NonCombatActions.cpp @@ -51,15 +51,15 @@ bool DrinkAction::isUseful() { return UseItemAction::isUseful() && AI_VALUE2(bool, "has mana", "self target") && - AI_VALUE2(uint8, "mana", "self target") < 100 && - !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", - "aquatic form","flight form", "swift flight form", nullptr) && + AI_VALUE2(uint8, "mana", "self target") < 100; } bool DrinkAction::isPossible() { return !bot->IsInCombat() && !bot->IsMounted() && + !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", + "aquatic form","flight form", "swift flight form", nullptr) && (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); } @@ -105,14 +105,14 @@ bool EatAction::Execute(Event event) bool EatAction::isUseful() { return UseItemAction::isUseful() && - AI_VALUE2(uint8, "health", "self target") < 100 && - !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", - "aquatic form","flight form", "swift flight form", nullptr) && + AI_VALUE2(uint8, "health", "self target") < 100; } bool EatAction::isPossible() { return !bot->IsInCombat() && !bot->IsMounted() && + !botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", + "aquatic form","flight form", "swift flight form", nullptr) && (botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible()); }