diff --git a/src/Ai/Base/Actions/ChangeStrategyAction.cpp b/src/Ai/Base/Actions/ChangeStrategyAction.cpp index b4fe5faaf..e81096b2a 100644 --- a/src/Ai/Base/Actions/ChangeStrategyAction.cpp +++ b/src/Ai/Base/Actions/ChangeStrategyAction.cpp @@ -9,28 +9,36 @@ #include "PlayerbotRepository.h" #include "Playerbots.h" +// Helper function for prefixes used by combat and non-combat strategy commands. +static void HandleStrategyCommon(PlayerbotAI* botAI, std::string const& text, BotState state) +{ + std::vector splitted = split(text, ','); + for (std::vector::iterator i = splitted.begin(); i != splitted.end(); i++) + { + const char* name = i->c_str(); + switch (name[0]) + { + case '+': + case '-': + case '~': + PlayerbotRepository::instance().Save(botAI); + break; + case '!': + botAI->SelectiveResetStrategies(state); + PlayerbotRepository::instance().Save(botAI); + break; + case '?': + break; + } + } +} + bool ChangeCombatStrategyAction::Execute(Event event) { std::string const text = event.getParam(); botAI->ChangeStrategy(text.empty() ? getName() : text, BOT_STATE_COMBAT); if (event.GetSource() == "co") - { - std::vector splitted = split(text, ','); - for (std::vector::iterator i = splitted.begin(); i != splitted.end(); i++) - { - const char* name = i->c_str(); - switch (name[0]) - { - case '+': - case '-': - case '~': - PlayerbotRepository::instance().Save(botAI); - break; - case '?': - break; - } - } - } + HandleStrategyCommon(botAI, text, BOT_STATE_COMBAT); return true; } @@ -52,23 +60,7 @@ bool ChangeNonCombatStrategyAction::Execute(Event event) botAI->ChangeStrategy(text, BOT_STATE_NON_COMBAT); if (event.GetSource() == "nc") - { - std::vector splitted = split(text, ','); - for (std::vector::iterator i = splitted.begin(); i != splitted.end(); i++) - { - const char* name = i->c_str(); - switch (name[0]) - { - case '+': - case '-': - case '~': - PlayerbotRepository::instance().Save(botAI); - break; - case '?': - break; - } - } - } + HandleStrategyCommon(botAI, text, BOT_STATE_NON_COMBAT); return true; } diff --git a/src/Bot/PlayerbotAI.cpp b/src/Bot/PlayerbotAI.cpp index 8b20b2e88..5937f0ef6 100644 --- a/src/Bot/PlayerbotAI.cpp +++ b/src/Bot/PlayerbotAI.cpp @@ -1585,6 +1585,27 @@ void PlayerbotAI::ClearStrategies(BotState type) e->removeAllStrategies(); } +// Resets only the combat or non-combat engine: wipe strategies, repopulate with class/spec defaults, +// re-apply current map's instance strategy (if any), and call Init() to rebuild trigger/action lists. +void PlayerbotAI::SelectiveResetStrategies(BotState type) +{ + Engine* e = engines[type]; + if (!e) + return; + + e->removeAllStrategies(); + + if (type == BOT_STATE_COMBAT) + AiFactory::AddDefaultCombatStrategies(bot, this, e); + else if (type == BOT_STATE_NON_COMBAT) + AiFactory::AddDefaultNonCombatStrategies(bot, this, e); + + if (sPlayerbotAIConfig.applyInstanceStrategies) + ApplyInstanceStrategies(bot->GetMapId()); + + e->Init(); +} + std::vector PlayerbotAI::GetStrategies(BotState type) { Engine* e = engines[type]; diff --git a/src/Bot/PlayerbotAI.h b/src/Bot/PlayerbotAI.h index dc7770ed8..01924c46f 100644 --- a/src/Bot/PlayerbotAI.h +++ b/src/Bot/PlayerbotAI.h @@ -404,6 +404,7 @@ public: std::string const qualifier = ""); void ChangeStrategy(std::string const name, BotState type); void ClearStrategies(BotState type); + void SelectiveResetStrategies(BotState type); std::vector GetStrategies(BotState type); Strategy* GetStrategy(std::string const name, BotState type); void ApplyInstanceStrategies(uint32 mapId, bool tellMaster = false);