Druid Flight Form Bug Fix

Hello everyone,

This is a fix for issue #1233

I have added a clause in the CanCastSpell check that checks if the bot is in flight form/swift flight form & not in combat. It will no longer attempt to shift into a caster form  and repetitively try and heal/buff party members while flying. Tested on my PC with the changes and druid now successfully flies as fast as the player with no stopping.

This was causing the issue:

static ActionNode* thorns([[maybe_unused]] PlayerbotAI* botAI)
{
    return new ActionNode("thorns",
                          /*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
                          /*A*/ nullptr,
                          /*C*/ nullptr);
}

static ActionNode* thorns_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
    return new ActionNode("thorns on party",
                          /*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
                          /*A*/ nullptr,
                          /*C*/ nullptr);
}

static ActionNode* mark_of_the_wild([[maybe_unused]] PlayerbotAI* botAI)
{
    return new ActionNode("mark of the wild",
                          /*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
                          /*A*/ nullptr,
                          /*C*/ nullptr);
}

static ActionNode* mark_of_the_wild_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
    return new ActionNode("mark of the wild on party",
                          /*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
                          /*A*/ nullptr,
                          /*C*/ nullptr);
}
static ActionNode* regrowth_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
    return new ActionNode("regrowth on party",
                          /*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
                          /*A*/ NULL,
                          /*C*/ NULL);
}
static ActionNode* rejuvenation_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
    return new ActionNode("rejuvenation on party",
                          /*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
                          /*A*/ NULL,
                          /*C*/ NULL);
}
static ActionNode* remove_curse_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
    return new ActionNode("remove curse on party",
                          /*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
                          /*A*/ NULL,
                          /*C*/ NULL);
}
static ActionNode* abolish_poison_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
    return new ActionNode("abolish poison on party",
                          /*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
                          /*A*/ NULL,
                          /*C*/ NULL);
}
static ActionNode* revive([[maybe_unused]] PlayerbotAI* botAI)
{
    return new ActionNode("revive",
                          /*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
                          /*A*/ NULL,
                          /*C*/ NULL);
}

The *P* stands for prior, aka before this action is taken, do this other action "caster form". This is the Caster Form action:

class CastCasterFormAction : public CastBuffSpellAction
{
public:
    CastCasterFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "caster form") {}

    bool isUseful() override;
    bool isPossible() override { return true; }
    bool Execute(Event event) override;
};

And this:

bool CastCasterFormAction::isUseful()
{
    return botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form",
                               "flight form", "swift flight form", "moonkin form", nullptr) &&
           AI_VALUE2(uint8, "mana", "self target") > sPlayerbotAIConfig->mediumHealth;
}

bool CastCasterFormAction::Execute(Event event)
{
    botAI->RemoveShapeshift();
    return true;
}

So basically, the druid was triggering to heal/buff the party, and before it could do that, it had to switch into "caster form" which executed RemoveShapeshift(). After it did that, mounting back up into flight form/swift flight form had the highest priority, so it would loop the triggers/actions.
This commit is contained in:
ThePenguinMan96
2025-07-27 01:10:31 -07:00
parent 66c88d4815
commit de9f8fbbea

View File

@@ -2935,6 +2935,18 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell,
return false;
}
if ((bot->GetShapeshiftForm() == FORM_FLIGHT || bot->GetShapeshiftForm() == FORM_FLIGHT_EPIC) && !bot->IsInCombat())
{
if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster()))
{
LOG_DEBUG(
"playerbots",
"Can cast spell failed. In flight form (not in combat). - target name: {}, spellid: {}, bot name: {}",
target->GetName(), spellid, bot->GetName());
}
return false;
}
uint32 CastingTime = !spellInfo->IsChanneled() ? spellInfo->CalcCastTime(bot) : spellInfo->GetDuration();
// bool interruptOnMove = spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT;
if ((CastingTime || spellInfo->IsAutoRepeatRangedSpell()) && bot->isMoving())