Files
mod-playerbots/src/AiFactory.cpp
Crow b16789fa54 Remove "potion" strategy from arenas + code cleanups (#1922)
Lines 481 through 484 are the only substantive changes. Bots were having
the potion strategy added in arenas, and since potions are not allowed
in arenas, this caused them to lock up and attempt to repeatedly drink
potions when under the applicable health or mana trigger thresholds. Now
they won't have the potion strategy in arenas.

Otherwise, I noticed a bunch of magic numbers for spec tabs and so went
ahead and did some refactoring:
1. All references to spec tab numbers now use the appropriate constant
name.
2. A bunch of extra braces were deleted.
3. DEATHKNIGHT_TAB was changed to DEATH_KNIGHT_TAB, and
HUNTER_TAB_BEASTMASTERY was changed to HUNTER_TAB_BEAST_MASTERY, to
reflect the correct names of the class and spec.
4. Deleted some comments that were clearly unneeded. There's much more
that can be cleaned up, and probably the entire logic sequence for
adding/removing strategies in AiFactory.cpp can be redone, but that's
above my pay grade.
2025-12-30 21:17:14 +01:00

740 lines
27 KiB
C++

/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include "AiFactory.h"
#include "BattlegroundMgr.h"
#include "DKAiObjectContext.h"
#include "DruidAiObjectContext.h"
#include "Engine.h"
#include "Group.h"
#include "HunterAiObjectContext.h"
#include "Item.h"
#include "MageAiObjectContext.h"
#include "PaladinAiObjectContext.h"
#include "PlayerbotAI.h"
#include "PlayerbotAIConfig.h"
#include "Playerbots.h"
#include "PriestAiObjectContext.h"
#include "RogueAiObjectContext.h"
#include "ShamanAiObjectContext.h"
#include "SharedDefines.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
#include "WarlockAiObjectContext.h"
#include "WarriorAiObjectContext.h"
AiObjectContext* AiFactory::createAiObjectContext(Player* player, PlayerbotAI* botAI)
{
switch (player->getClass())
{
case CLASS_PRIEST:
return new PriestAiObjectContext(botAI);
case CLASS_MAGE:
return new MageAiObjectContext(botAI);
case CLASS_WARLOCK:
return new WarlockAiObjectContext(botAI);
case CLASS_WARRIOR:
return new WarriorAiObjectContext(botAI);
case CLASS_SHAMAN:
return new ShamanAiObjectContext(botAI);
case CLASS_PALADIN:
return new PaladinAiObjectContext(botAI);
case CLASS_DRUID:
return new DruidAiObjectContext(botAI);
case CLASS_HUNTER:
return new HunterAiObjectContext(botAI);
case CLASS_ROGUE:
return new RogueAiObjectContext(botAI);
case CLASS_DEATH_KNIGHT:
return new DKAiObjectContext(botAI);
}
return new AiObjectContext(botAI);
}
uint8 AiFactory::GetPlayerSpecTab(Player* bot)
{
std::map<uint8, uint32> tabs = GetPlayerSpecTabs(bot);
if (bot->GetLevel() >= 10 && ((tabs[0] + tabs[1] + tabs[2]) > 0))
{
int8 tab = -1;
uint32 max = 0;
for (uint32 i = 0; i < uint32(3); i++)
{
if (tab == -1 || max < tabs[i])
{
tab = i;
max = tabs[i];
}
}
return tab;
}
else
{
uint8 tab = 0;
switch (bot->getClass())
{
case CLASS_MAGE:
tab = MAGE_TAB_FROST;
break;
case CLASS_PALADIN:
tab = PALADIN_TAB_RETRIBUTION;
break;
case CLASS_PRIEST:
tab = PRIEST_TAB_HOLY;
break;
case CLASS_WARLOCK:
tab = WARLOCK_TAB_DEMONOLOGY;
break;
case CLASS_SHAMAN:
tab = SHAMAN_TAB_ELEMENTAL;
break;
}
return tab;
}
}
std::map<uint8, uint32> AiFactory::GetPlayerSpecTabs(Player* bot)
{
std::map<uint8, uint32> tabs = {{0, 0}, {0, 0}, {0, 0}};
const PlayerTalentMap& talentMap = bot->GetTalentMap();
for (PlayerTalentMap::const_iterator i = talentMap.begin(); i != talentMap.end(); ++i)
{
uint32 spellId = i->first;
if ((bot->GetActiveSpecMask() & i->second->specMask) == 0)
{
continue;
}
TalentSpellPos const* talentPos = GetTalentSpellPos(spellId);
if (!talentPos)
continue;
TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id);
if (!talentInfo)
continue;
uint32 const* talentTabIds = GetTalentTabPages(bot->getClass());
const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
int rank = spellInfo ? spellInfo->GetRank() : 1;
if (talentInfo->TalentTab == talentTabIds[0])
tabs[0] += rank;
if (talentInfo->TalentTab == talentTabIds[1])
tabs[1] += rank;
if (talentInfo->TalentTab == talentTabIds[2])
tabs[2] += rank;
}
return tabs;
}
BotRoles AiFactory::GetPlayerRoles(Player* player)
{
BotRoles role = BOT_ROLE_NONE;
uint8 tab = GetPlayerSpecTab(player);
switch (player->getClass())
{
case CLASS_PRIEST:
if (tab == PRIEST_TAB_SHADOW)
role = BOT_ROLE_DPS;
else
role = BOT_ROLE_HEALER;
break;
case CLASS_SHAMAN:
if (tab == SHAMAN_TAB_RESTORATION)
role = BOT_ROLE_HEALER;
else
role = BOT_ROLE_DPS;
break;
case CLASS_WARRIOR:
if (tab == WARRIOR_TAB_PROTECTION)
role = BOT_ROLE_TANK;
else
role = BOT_ROLE_DPS;
break;
case CLASS_PALADIN:
if (tab == PALADIN_TAB_HOLY)
role = BOT_ROLE_HEALER;
else if (tab == PALADIN_TAB_PROTECTION)
role = BOT_ROLE_TANK;
else if (tab == PALADIN_TAB_RETRIBUTION)
role = BOT_ROLE_DPS;
break;
case CLASS_DRUID:
if (tab == DRUID_TAB_BALANCE)
role = BOT_ROLE_DPS;
else if (tab == DRUID_TAB_FERAL)
role = (BotRoles)(BOT_ROLE_TANK | BOT_ROLE_DPS);
else if (tab == DRUID_TAB_RESTORATION)
role = BOT_ROLE_HEALER;
break;
default:
role = BOT_ROLE_DPS;
break;
}
return role;
}
std::string AiFactory::GetPlayerSpecName(Player* player)
{
std::string specName;
int tab = GetPlayerSpecTab(player);
switch (player->getClass())
{
case CLASS_PRIEST:
if (tab == PRIEST_TAB_SHADOW)
specName = "shadow";
else if (tab == PRIEST_TAB_HOLY)
specName = "holy";
else
specName = "disc";
break;
case CLASS_SHAMAN:
if (tab == SHAMAN_TAB_RESTORATION)
specName = "resto";
else if (tab == SHAMAN_TAB_ENHANCEMENT)
specName = "enhance";
else
specName = "elem";
break;
case CLASS_WARRIOR:
if (tab == WARRIOR_TAB_PROTECTION)
specName = "prot";
else if (tab == WARRIOR_TAB_FURY)
specName = "fury";
else
specName = "arms";
break;
case CLASS_PALADIN:
if (tab == PALADIN_TAB_HOLY)
specName = "holy";
else if (tab == PALADIN_TAB_PROTECTION)
specName = "prot";
else if (tab == PALADIN_TAB_RETRIBUTION)
specName = "retrib";
break;
case CLASS_DRUID:
if (tab == DRUID_TAB_BALANCE)
specName = "balance";
else if (tab == DRUID_TAB_FERAL)
specName = "feraldps";
else if (tab == DRUID_TAB_RESTORATION)
specName = "resto";
break;
case CLASS_ROGUE:
if (tab == ROGUE_TAB_ASSASSINATION)
specName = "assas";
else if (tab == ROGUE_TAB_COMBAT)
specName = "combat";
else if (tab == ROGUE_TAB_SUBTLETY)
specName = "subtle";
break;
case CLASS_HUNTER:
if (tab == HUNTER_TAB_BEAST_MASTERY)
specName = "beast";
else if (tab == HUNTER_TAB_MARKSMANSHIP)
specName = "marks";
else if (tab == HUNTER_TAB_SURVIVAL)
specName = "surv";
break;
case CLASS_DEATH_KNIGHT:
if (tab == DEATH_KNIGHT_TAB_BLOOD)
specName = "blooddps";
else if (tab == DEATH_KNIGHT_TAB_FROST)
specName = "frostdps";
else if (tab == DEATH_KNIGHT_TAB_UNHOLY)
specName = "unholydps";
break;
case CLASS_MAGE:
if (tab == MAGE_TAB_ARCANE)
specName = "arcane";
else if (tab == MAGE_TAB_FIRE)
specName = "fire";
else if (tab == MAGE_TAB_FROST)
specName = "frost";
break;
case CLASS_WARLOCK:
if (tab == WARLOCK_TAB_AFFLICTION)
specName = "afflic";
else if (tab == WARLOCK_TAB_DEMONOLOGY)
specName = "demo";
else if (tab == WARLOCK_TAB_DESTRUCTION)
specName = "destro";
break;
default:
break;
}
return specName;
}
void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const facade, Engine* engine)
{
uint8 tab = GetPlayerSpecTab(player);
if (!player->InBattleground())
engine->addStrategiesNoInit("racials", "chat", "default", "cast time", "potions", "duel", "boost", nullptr);
if (sPlayerbotAIConfig->autoAvoidAoe && facade->HasRealPlayerMaster())
engine->addStrategy("avoid aoe", false);
engine->addStrategy("formation", false);
switch (player->getClass())
{
case CLASS_PRIEST:
if (tab == PRIEST_TAB_SHADOW)
engine->addStrategiesNoInit("dps", "shadow debuff", "shadow aoe", nullptr);
else if (tab == PRIEST_TAB_DISCIPLINE)
engine->addStrategiesNoInit("heal", nullptr);
else
engine->addStrategiesNoInit("holy heal", nullptr);
engine->addStrategiesNoInit("dps assist", "cure", nullptr);
break;
case CLASS_MAGE:
if (tab == MAGE_TAB_ARCANE)
engine->addStrategiesNoInit("arcane", nullptr);
else if (tab == MAGE_TAB_FIRE)
{
if (player->HasSpell(44614) /*Frostfire Bolt*/ && player->HasAura(15047) /*Ice Shards*/)
engine->addStrategiesNoInit("frostfire", nullptr);
else
engine->addStrategiesNoInit("fire", nullptr);
}
else
engine->addStrategiesNoInit("frost", nullptr);
engine->addStrategiesNoInit("dps", "dps assist", "cure", "aoe", nullptr);
break;
case CLASS_WARRIOR:
if (tab == WARRIOR_TAB_PROTECTION)
engine->addStrategiesNoInit("tank", "tank assist", "aoe", nullptr);
else if (tab == WARRIOR_TAB_ARMS || !player->HasSpell(1680)) // Whirlwind
engine->addStrategiesNoInit("arms", "aoe", "dps assist", nullptr);
else
engine->addStrategiesNoInit("fury", "aoe", "dps assist", nullptr);
break;
case CLASS_SHAMAN:
if (tab == SHAMAN_TAB_ELEMENTAL)
engine->addStrategiesNoInit("ele", "stoneskin", "wrath", "mana spring", "wrath of air", nullptr);
else if (tab == SHAMAN_TAB_RESTORATION)
engine->addStrategiesNoInit("resto", "stoneskin", "flametongue", "mana spring", "wrath of air", nullptr);
else
engine->addStrategiesNoInit("enh", "strength of earth", "magma", "healing stream", "windfury", nullptr);
engine->addStrategiesNoInit("dps assist", "cure", "aoe", nullptr);
break;
case CLASS_PALADIN:
if (tab == PALADIN_TAB_PROTECTION)
engine->addStrategiesNoInit("tank", "tank assist", "bthreat", "barmor", "cure", nullptr);
else if (tab == PALADIN_TAB_HOLY)
engine->addStrategiesNoInit("heal", "dps assist", "cure", "bcast", nullptr);
else
engine->addStrategiesNoInit("dps", "dps assist", "cure", "baoe", nullptr);
break;
case CLASS_DRUID:
if (tab == DRUID_TAB_BALANCE)
{
engine->addStrategiesNoInit("caster", "cure", "caster aoe", "dps assist", nullptr);
engine->addStrategy("caster debuff", false);
}
else if (tab == DRUID_TAB_RESTORATION)
engine->addStrategiesNoInit("heal", "cure", "dps assist", nullptr);
else
{
if (player->HasSpell(768) /*cat form*/ && !player->HasAura(16931) /*thick hide*/)
engine->addStrategiesNoInit("cat", "dps assist", nullptr);
else
engine->addStrategiesNoInit("bear", "tank assist", nullptr);
}
break;
case CLASS_HUNTER:
if (tab == HUNTER_TAB_BEAST_MASTERY)
engine->addStrategiesNoInit("bm", nullptr);
else if (tab == HUNTER_TAB_MARKSMANSHIP)
engine->addStrategiesNoInit("mm", nullptr);
else
engine->addStrategiesNoInit("surv", nullptr);
engine->addStrategiesNoInit("cc", "dps assist", "aoe", nullptr);
break;
case CLASS_ROGUE:
if (tab == ROGUE_TAB_ASSASSINATION || tab == ROGUE_TAB_SUBTLETY)
engine->addStrategiesNoInit("melee", "dps assist", "aoe", nullptr);
else
engine->addStrategiesNoInit("dps", "dps assist", "aoe", nullptr);
break;
case CLASS_WARLOCK:
if (tab == WARLOCK_TAB_AFFLICTION)
engine->addStrategiesNoInit("affli", "curse of agony", nullptr);
else if (tab == WARLOCK_TAB_DEMONOLOGY)
engine->addStrategiesNoInit("demo", "curse of agony", "meta melee", nullptr);
else
engine->addStrategiesNoInit("destro", "curse of elements", nullptr);
engine->addStrategiesNoInit("cc", "dps assist", "aoe", nullptr);
break;
case CLASS_DEATH_KNIGHT:
if (tab == DEATH_KNIGHT_TAB_BLOOD)
engine->addStrategiesNoInit("blood", "tank assist", nullptr);
else if (tab == DEATH_KNIGHT_TAB_FROST)
engine->addStrategiesNoInit("frost", "frost aoe", "dps assist", nullptr);
else
engine->addStrategiesNoInit("unholy", "unholy aoe", "dps assist", nullptr);
break;
}
if (PlayerbotAI::IsTank(player, true))
engine->addStrategy("tank face", false);
if (PlayerbotAI::IsMelee(player, true) && PlayerbotAI::IsDps(player, true))
engine->addStrategy("behind", false);
if (PlayerbotAI::IsHeal(player, true))
{
if (sPlayerbotAIConfig->autoSaveMana)
engine->addStrategy("save mana", false);
if (!sPlayerbotAIConfig->IsRestrictedHealerDPSMap(player->GetMapId()))
engine->addStrategy("healer dps", false);
}
if (facade->IsRealPlayer() || sRandomPlayerbotMgr->IsRandomBot(player))
{
if (!player->GetGroup())
{
// change for heal spec
engine->addStrategy("boost", false);
engine->addStrategy("dps assist", false);
engine->removeStrategy("threat", false);
switch (player->getClass())
{
case CLASS_PRIEST:
{
if (tab != PRIEST_TAB_SHADOW)
engine->addStrategiesNoInit("holy dps", "shadow debuff", "shadow aoe", nullptr);
break;
}
case CLASS_DRUID:
{
if (tab == DRUID_TAB_RESTORATION)
{
engine->addStrategiesNoInit("caster", "caster aoe", nullptr);
engine->addStrategy("caster debuff", false);
}
break;
}
case CLASS_SHAMAN:
{
if (tab == SHAMAN_TAB_RESTORATION)
engine->addStrategiesNoInit("caster", "caster aoe", "bmana", nullptr);
break;
}
case CLASS_PALADIN:
{
if (tab == PALADIN_TAB_HOLY)
engine->addStrategiesNoInit("dps", "dps assist", "baoe", nullptr);
break;
}
default:
break;
}
}
}
if (sRandomPlayerbotMgr->IsRandomBot(player))
engine->ChangeStrategy(sPlayerbotAIConfig->randomBotCombatStrategies);
else
engine->ChangeStrategy(sPlayerbotAIConfig->combatStrategies);
// Battleground switch
if (player->InBattleground() && player->GetBattleground())
{
BattlegroundTypeId bgType = player->GetBattlegroundTypeId();
if (bgType == BATTLEGROUND_RB)
bgType = player->GetBattleground()->GetBgTypeID(true);
if (bgType == BATTLEGROUND_WS)
engine->addStrategy("warsong", false);
if (bgType == BATTLEGROUND_AB)
engine->addStrategy("arathi", false);
if (bgType == BATTLEGROUND_AV)
engine->addStrategy("alterac", false);
if (bgType == BATTLEGROUND_EY)
engine->addStrategy("eye", false);
if (bgType == BATTLEGROUND_IC)
engine->addStrategy("isle", false);
if (player->InArena())
{
engine->addStrategy("arena", false);
engine->addStrategiesNoInit("boost", "racials", "chat", "default", "aoe", "cast time", "dps assist", nullptr);
}
else
engine->addStrategiesNoInit("boost", "racials", "chat", "default", "aoe", "potions", "cast time", "dps assist", nullptr);
engine->removeStrategy("custom::say", false);
engine->removeStrategy("flee", false);
engine->removeStrategy("threat", false);
engine->addStrategy("boost", false);
}
}
Engine* AiFactory::createCombatEngine(Player* player, PlayerbotAI* const facade, AiObjectContext* aiObjectContext)
{
Engine* engine = new Engine(facade, aiObjectContext);
AddDefaultCombatStrategies(player, facade, engine);
engine->Init();
return engine;
}
void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const facade, Engine* nonCombatEngine)
{
uint8 tab = GetPlayerSpecTab(player);
switch (player->getClass())
{
case CLASS_PRIEST:
nonCombatEngine->addStrategiesNoInit("dps assist", "cure", nullptr);
break;
case CLASS_PALADIN:
if (tab == PALADIN_TAB_PROTECTION)
{
nonCombatEngine->addStrategiesNoInit("bthreat", "tank assist", "barmor", nullptr);
if (player->GetLevel() >= 20)
nonCombatEngine->addStrategy("bhealth", false);
else
nonCombatEngine->addStrategy("bdps", false);
}
else if (tab == PALADIN_TAB_HOLY)
nonCombatEngine->addStrategiesNoInit("dps assist", "bmana", "bcast", nullptr);
else
nonCombatEngine->addStrategiesNoInit("dps assist", "bdps", "baoe", nullptr);
nonCombatEngine->addStrategiesNoInit("cure", nullptr);
break;
case CLASS_HUNTER:
nonCombatEngine->addStrategiesNoInit("bdps", "dps assist", "pet", nullptr);
break;
case CLASS_SHAMAN:
if (tab == SHAMAN_TAB_ELEMENTAL || tab == SHAMAN_TAB_RESTORATION)
nonCombatEngine->addStrategy("bmana", false);
else
nonCombatEngine->addStrategy("bdps", false);
nonCombatEngine->addStrategiesNoInit("dps assist", "cure", nullptr);
break;
case CLASS_MAGE:
if (tab == MAGE_TAB_ARCANE || tab == MAGE_TAB_FIRE)
nonCombatEngine->addStrategy("bdps", false);
else
nonCombatEngine->addStrategy("bmana", false);
nonCombatEngine->addStrategiesNoInit("dps assist", "cure", nullptr);
break;
case CLASS_DRUID:
if (tab == DRUID_TAB_FERAL)
{
if (player->GetLevel() >= 20 && !player->HasAura(16931) /*thick hide*/)
nonCombatEngine->addStrategy("dps assist", false);
else
nonCombatEngine->addStrategy("tank assist", false);
}
else
nonCombatEngine->addStrategiesNoInit("dps assist", "cure", nullptr);
break;
case CLASS_WARRIOR:
if (tab == WARRIOR_TAB_PROTECTION)
nonCombatEngine->addStrategy("tank assist", false);
else
nonCombatEngine->addStrategy("dps assist", false);
break;
case CLASS_WARLOCK:
if (tab == WARLOCK_TAB_AFFLICTION)
nonCombatEngine->addStrategiesNoInit("felhunter", "spellstone", nullptr);
else if (tab == WARLOCK_TAB_DEMONOLOGY)
nonCombatEngine->addStrategiesNoInit("felguard", "spellstone", nullptr);
else if (tab == WARLOCK_TAB_DESTRUCTION)
nonCombatEngine->addStrategiesNoInit("imp", "firestone", nullptr);
nonCombatEngine->addStrategiesNoInit("dps assist", "ss self", nullptr);
break;
case CLASS_DEATH_KNIGHT:
if (tab == DEATH_KNIGHT_TAB_BLOOD)
nonCombatEngine->addStrategy("tank assist", false);
else
nonCombatEngine->addStrategy("dps assist", false);
break;
default:
nonCombatEngine->addStrategy("dps assist", false);
break;
}
if (!player->InBattleground())
{
nonCombatEngine->addStrategiesNoInit("nc", "food", "chat", "follow", "default", "quest", "loot",
"gather", "duel", "pvp", "buff", "mount", "emote", nullptr);
}
if (sPlayerbotAIConfig->autoSaveMana && PlayerbotAI::IsHeal(player, true))
nonCombatEngine->addStrategy("save mana", false);
if ((sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground())
{
Player* master = facade->GetMaster();
// let 25% of free bots start duels.
if (!urand(0, 3))
nonCombatEngine->addStrategy("start duel", false);
if (sPlayerbotAIConfig->randomBotJoinLfg)
nonCombatEngine->addStrategy("lfg", false);
if (!player->GetGroup() || player->GetGroup()->GetLeaderGUID() == player->GetGUID())
{
// let 25% of random not grouped (or grp leader) bots help other players
// if (!urand(0, 3))
// nonCombatEngine->addStrategy("attack tagged");
// nonCombatEngine->addStrategy("pvp", false);
// nonCombatEngine->addStrategy("collision");
// nonCombatEngine->addStrategy("group");
// nonCombatEngine->addStrategy("guild");
nonCombatEngine->addStrategy("grind", false);
if (sPlayerbotAIConfig->enableNewRpgStrategy)
nonCombatEngine->addStrategy("new rpg", false);
else if (sPlayerbotAIConfig->autoDoQuests)
{
// nonCombatEngine->addStrategy("travel");
nonCombatEngine->addStrategy("rpg", false);
}
else
nonCombatEngine->addStrategy("move random", false);
if (sPlayerbotAIConfig->randomBotJoinBG)
nonCombatEngine->addStrategy("bg", false);
// if (!master || GET_PLAYERBOT_AI(master))
// nonCombatEngine->addStrategy("maintenance");
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->randomBotNonCombatStrategies);
}
else
{
if (facade)
{
if (master)
{
PlayerbotAI* masterBotAI = GET_PLAYERBOT_AI(master);
if (masterBotAI || sRandomPlayerbotMgr->IsRandomBot(player))
{
// nonCombatEngine->addStrategy("pvp", false);
// nonCombatEngine->addStrategy("collision");
// nonCombatEngine->addStrategy("group");
// nonCombatEngine->addStrategy("guild");
// if (sPlayerbotAIConfig->autoDoQuests)
// {
// // nonCombatEngine->addStrategy("travel");
// nonCombatEngine->addStrategy("rpg");
// }
// else
// {
// nonCombatEngine->addStrategy("move random");
// }
// if (masterBotAI)
// nonCombatEngine->addStrategy("maintenance");
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->randomBotNonCombatStrategies);
}
else
{
// nonCombatEngine->addStrategy("pvp", false);
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->nonCombatStrategies);
}
}
}
}
}
else
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->nonCombatStrategies);
// Battleground switch
if (player->InBattleground() && player->GetBattleground())
{
nonCombatEngine->addStrategiesNoInit("nc", "chat", "default", "buff", "food", "mount", "pvp", "dps assist",
"attack tagged", "emote", nullptr);
nonCombatEngine->removeStrategy("custom::say", false);
nonCombatEngine->removeStrategy("travel", false);
nonCombatEngine->removeStrategy("rpg", false);
nonCombatEngine->removeStrategy("grind", false);
BattlegroundTypeId bgType = player->GetBattlegroundTypeId();
if (bgType == BATTLEGROUND_RB)
bgType = player->GetBattleground()->GetBgTypeID(true);
if ((bgType <= BATTLEGROUND_EY || bgType == BATTLEGROUND_IC) &&
!player->InArena()) // do not add for not supported bg or arena
nonCombatEngine->addStrategy("battleground", false);
if (bgType == BATTLEGROUND_WS)
nonCombatEngine->addStrategy("warsong", false);
if (bgType == BATTLEGROUND_AV)
nonCombatEngine->addStrategy("alterac", false);
if (bgType == BATTLEGROUND_AB)
nonCombatEngine->addStrategy("arathi", false);
if (bgType == BATTLEGROUND_EY)
nonCombatEngine->addStrategy("eye", false);
if (bgType == BATTLEGROUND_IC)
nonCombatEngine->addStrategy("isle", false);
if (player->InArena())
{
nonCombatEngine->addStrategy("arena", false);
nonCombatEngine->removeStrategy("mount", false);
}
}
}
Engine* AiFactory::createNonCombatEngine(Player* player, PlayerbotAI* const facade, AiObjectContext* aiObjectContext)
{
Engine* nonCombatEngine = new Engine(facade, aiObjectContext);
AddDefaultNonCombatStrategies(player, facade, nonCombatEngine);
nonCombatEngine->Init();
return nonCombatEngine;
}
void AiFactory::AddDefaultDeadStrategies(Player* player, PlayerbotAI* const facade, Engine* deadEngine)
{
(void)facade; // unused and remove warning
deadEngine->addStrategiesNoInit("dead", "stay", "chat", "default", "follow", nullptr);
if (sRandomPlayerbotMgr->IsRandomBot(player) && !player->GetGroup())
deadEngine->removeStrategy("follow", false);
}
Engine* AiFactory::createDeadEngine(Player* player, PlayerbotAI* const facade, AiObjectContext* AiObjectContext)
{
Engine* deadEngine = new Engine(facade, AiObjectContext);
AddDefaultDeadStrategies(player, facade, deadEngine);
deadEngine->Init();
return deadEngine;
}