Dynamic delay

This commit is contained in:
Yunfan Li
2024-08-14 18:27:13 +08:00
parent 7b0bb20078
commit 2ddaae9ef0
17 changed files with 279 additions and 159 deletions

View File

@@ -271,6 +271,9 @@ AiPlayerbot.DispelAuraDuration = 700
# Delay between two bot actions
AiPlayerbot.ReactDelay = 100
# Dynamically adjust react delay for bots in different status to reduce server delays
AiPlayerbot.DynamicReactDelay = 1
# Inactivity delay
AiPlayerbot.PassiveDelay = 10000

View File

@@ -276,116 +276,116 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
if (!player->InBattleground())
{
engine->addStrategies("racials", "chat", "default", "cast time", "duel", "boost", nullptr);
engine->addStrategiesNoInit("racials", "chat", "default", "cast time", "duel", "boost", nullptr);
}
if (sPlayerbotAIConfig->autoSaveMana)
{
engine->addStrategy("auto save mana");
engine->addStrategy("smana", false);
}
if (sPlayerbotAIConfig->autoAvoidAoe && facade->HasRealPlayerMaster())
{
engine->addStrategy("avoid aoe");
engine->addStrategy("aaoe", false);
}
engine->addStrategy("combat formation");
engine->addStrategy("formation", false);
switch (player->getClass())
{
case CLASS_PRIEST:
if (tab == 2)
{
engine->addStrategies("dps", "shadow debuff", "shadow aoe", nullptr);
engine->addStrategiesNoInit("dps", "shadow debuff", "shadow aoe", nullptr);
}
else if (tab == PRIEST_TAB_DISIPLINE)
{
engine->addStrategies("heal", nullptr);
engine->addStrategiesNoInit("heal", nullptr);
}
else
{
engine->addStrategies("holy heal", nullptr);
engine->addStrategiesNoInit("holy heal", nullptr);
}
engine->addStrategies("dps assist", "cure", nullptr);
engine->addStrategiesNoInit("dps assist", "cure", nullptr);
break;
case CLASS_MAGE:
if (tab == 0)
engine->addStrategies("arcane", "arcane aoe", nullptr);
engine->addStrategiesNoInit("arcane", "arcane aoe", nullptr);
else if (tab == 1)
engine->addStrategies("fire", "fire aoe", nullptr);
engine->addStrategiesNoInit("fire", "fire aoe", nullptr);
else
engine->addStrategies("frost", "frost aoe", nullptr);
engine->addStrategiesNoInit("frost", "frost aoe", nullptr);
engine->addStrategies("dps", "dps assist", "cure", nullptr);
engine->addStrategiesNoInit("dps", "dps assist", "cure", nullptr);
break;
case CLASS_WARRIOR:
if (tab == 2)
engine->addStrategies("tank", "tank assist", "aoe", "mark rti", nullptr);
engine->addStrategiesNoInit("tank", "tank assist", "aoe", "mark rti", nullptr);
else if (player->GetLevel() < 36 || tab == 0)
engine->addStrategies("arms", "aoe", "dps assist", /*"behind",*/ nullptr);
engine->addStrategiesNoInit("arms", "aoe", "dps assist", /*"behind",*/ nullptr);
else
engine->addStrategies("fury", "aoe", "dps assist", /*"behind",*/ nullptr);
engine->addStrategiesNoInit("fury", "aoe", "dps assist", /*"behind",*/ nullptr);
break;
case CLASS_SHAMAN:
if (tab == 0)
engine->addStrategies("caster", "caster aoe", "bmana", nullptr);
engine->addStrategiesNoInit("caster", "caster aoe", "bmana", nullptr);
else if (tab == 2)
engine->addStrategies("heal", "bmana", nullptr);
engine->addStrategiesNoInit("heal", "bmana", nullptr);
else
engine->addStrategies("melee", "melee aoe", "bdps", nullptr);
engine->addStrategiesNoInit("melee", "melee aoe", "bdps", nullptr);
engine->addStrategies("dps assist", "cure", "totems", nullptr);
engine->addStrategiesNoInit("dps assist", "cure", "totems", nullptr);
break;
case CLASS_PALADIN:
if (tab == 1)
engine->addStrategies("tank", "tank assist", "bthreat", "barmor", "cure", nullptr);
engine->addStrategiesNoInit("tank", "tank assist", "bthreat", "barmor", "cure", nullptr);
else if (tab == 0)
engine->addStrategies("heal", "dps assist", "cure", "bcast", nullptr);
engine->addStrategiesNoInit("heal", "dps assist", "cure", "bcast", nullptr);
else
engine->addStrategies("dps", "dps assist", "cure", "baoe", nullptr);
engine->addStrategiesNoInit("dps", "dps assist", "cure", "baoe", nullptr);
break;
case CLASS_DRUID:
if (tab == 0)
{
engine->addStrategies("caster", "cure", "caster aoe", "dps assist", nullptr);
engine->addStrategy("caster debuff");
engine->addStrategiesNoInit("caster", "cure", "caster aoe", "dps assist", nullptr);
engine->addStrategy("caster debuff", false);
}
else if (tab == 2)
engine->addStrategies("heal", "cure", "dps assist", nullptr);
engine->addStrategiesNoInit("heal", "cure", "dps assist", nullptr);
else
{
if (player->GetLevel() >= 20 && !player->HasAura(16931) /*thick hide*/)
{
engine->addStrategies("cat", "dps assist", nullptr);
engine->addStrategiesNoInit("cat", "dps assist", nullptr);
}
else
{
engine->addStrategies("bear", "tank assist", nullptr);
engine->addStrategiesNoInit("bear", "tank assist", nullptr);
}
}
break;
case CLASS_HUNTER:
engine->addStrategies("dps", "aoe", "bdps", "dps assist", nullptr);
engine->addStrategy("dps debuff");
engine->addStrategiesNoInit("dps", "aoe", "bdps", "dps assist", nullptr);
engine->addStrategy("dps debuff", false);
break;
case CLASS_ROGUE:
if (tab == ROGUE_TAB_ASSASSINATION)
{
engine->addStrategies("melee", "dps assist", "aoe", /*"behind",*/ nullptr);
engine->addStrategiesNoInit("melee", "dps assist", "aoe", /*"behind",*/ nullptr);
}
else
{
engine->addStrategies("dps", "dps assist", "aoe", /*"behind",*/ nullptr);
engine->addStrategiesNoInit("dps", "dps assist", "aoe", /*"behind",*/ nullptr);
}
break;
case CLASS_WARLOCK:
engine->addStrategies("dps assist", "dps", "dps debuff", "aoe", nullptr);
engine->addStrategiesNoInit("dps assist", "dps", "dps debuff", "aoe", nullptr);
break;
case CLASS_DEATH_KNIGHT:
if (tab == 0)
engine->addStrategies("blood", "tank assist", nullptr);
engine->addStrategiesNoInit("blood", "tank assist", nullptr);
else if (tab == 1)
engine->addStrategies("frost", "frost aoe", "dps assist", nullptr);
engine->addStrategiesNoInit("frost", "frost aoe", "dps assist", nullptr);
else
engine->addStrategies("unholy", "unholy aoe", "dps assist", nullptr);
engine->addStrategiesNoInit("unholy", "unholy aoe", "dps assist", nullptr);
break;
}
@@ -395,9 +395,9 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
if (!player->GetGroup())
{
// change for heal spec
engine->addStrategy("boost");
engine->addStrategy("dps assist");
engine->removeStrategy("threat");
engine->addStrategy("boost", false);
engine->addStrategy("dps assist", false);
engine->removeStrategy("threat", false);
// engine-
switch (player->getClass())
{
@@ -405,7 +405,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
{
if (tab != PRIEST_TAB_SHADOW)
{
engine->addStrategies("holy dps", "shadow debuff", "shadow aoe", nullptr);
engine->addStrategiesNoInit("holy dps", "shadow debuff", "shadow aoe", nullptr);
}
break;
}
@@ -413,8 +413,8 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
{
if (tab == DRUID_TAB_RESTORATION)
{
engine->addStrategies("caster", "caster aoe", nullptr);
engine->addStrategy("caster debuff");
engine->addStrategiesNoInit("caster", "caster aoe", nullptr);
engine->addStrategy("caster debuff", false);
}
break;
}
@@ -422,7 +422,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
{
if (tab == SHAMAN_TAB_RESTORATION)
{
engine->addStrategies("caster", "caster aoe", "bmana", nullptr);
engine->addStrategiesNoInit("caster", "caster aoe", "bmana", nullptr);
}
break;
}
@@ -430,7 +430,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
{
if (tab == PALADIN_TAB_HOLY)
{
engine->addStrategies("dps", "dps assist", "baoe", nullptr);
engine->addStrategiesNoInit("dps", "dps assist", "baoe", nullptr);
}
break;
}
@@ -452,40 +452,40 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
bgType = player->GetBattleground()->GetBgTypeID(true);
if (bgType == BATTLEGROUND_WS)
engine->addStrategy("warsong");
engine->addStrategy("warsong", false);
if (bgType == BATTLEGROUND_AB)
engine->addStrategy("arathi");
engine->addStrategy("arathi", false);
if (bgType == BATTLEGROUND_AV)
engine->addStrategy("alterac");
engine->addStrategy("alterac", false);
if (bgType == BATTLEGROUND_EY)
engine->addStrategy("eye");
engine->addStrategy("eye", false);
if (bgType == BATTLEGROUND_IC)
engine->addStrategy("isle");
engine->addStrategy("isle", false);
if (player->InArena())
{
engine->addStrategy("arena");
engine->addStrategy("arena", false);
}
engine->addStrategies("boost", "racials", "chat", "default", "aoe", "potions", "cast time", "dps assist",
engine->addStrategiesNoInit("boost", "racials", "chat", "default", "aoe", "potions", "cast time", "dps assist",
nullptr);
engine->removeStrategy("custom::say");
engine->removeStrategy("flee");
engine->removeStrategy("threat");
engine->addStrategy("boost");
engine->removeStrategy("custom::say", false);
engine->removeStrategy("flee", false);
engine->removeStrategy("threat", false);
engine->addStrategy("boost", false);
if ((player->getClass() == CLASS_DRUID && tab == 2) || (player->getClass() == CLASS_SHAMAN && tab == 2))
engine->addStrategies("caster", "caster aoe", nullptr);
engine->addStrategiesNoInit("caster", "caster aoe", nullptr);
if (player->getClass() == CLASS_DRUID && tab == 1)
engine->addStrategies(/*"behind",*/ "dps", nullptr);
engine->addStrategiesNoInit(/*"behind",*/ "dps", nullptr);
if (player->getClass() == CLASS_ROGUE)
engine->addStrategies(/*"behind",*/ "stealth", nullptr);
engine->addStrategiesNoInit(/*"behind",*/ "stealth", nullptr);
}
}
@@ -493,6 +493,7 @@ Engine* AiFactory::createCombatEngine(Player* player, PlayerbotAI* const facade,
{
Engine* engine = new Engine(facade, aiObjectContext);
AddDefaultCombatStrategies(player, facade, engine);
engine->Init();
return engine;
}
@@ -503,103 +504,103 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
switch (player->getClass())
{
case CLASS_PRIEST:
nonCombatEngine->addStrategies("dps assist", "cure", nullptr);
nonCombatEngine->addStrategiesNoInit("dps assist", "cure", nullptr);
break;
case CLASS_PALADIN:
if (tab == 1)
{
nonCombatEngine->addStrategies("bthreat", "tank assist", "barmor", nullptr);
nonCombatEngine->addStrategiesNoInit("bthreat", "tank assist", "barmor", nullptr);
if (player->GetLevel() >= 20)
{
nonCombatEngine->addStrategy("bstats");
nonCombatEngine->addStrategy("bstats", false);
}
else
{
nonCombatEngine->addStrategy("bdps");
nonCombatEngine->addStrategy("bdps", false);
}
}
else if (tab == 0)
nonCombatEngine->addStrategies("dps assist", "bmana", "bcast", nullptr);
nonCombatEngine->addStrategiesNoInit("dps assist", "bmana", "bcast", nullptr);
else
nonCombatEngine->addStrategies("dps assist", "bdps", "baoe", nullptr);
nonCombatEngine->addStrategiesNoInit("dps assist", "bdps", "baoe", nullptr);
nonCombatEngine->addStrategies("cure", nullptr);
nonCombatEngine->addStrategiesNoInit("cure", nullptr);
break;
case CLASS_HUNTER:
nonCombatEngine->addStrategies("bdps", "dps assist", "pet", nullptr);
nonCombatEngine->addStrategiesNoInit("bdps", "dps assist", "pet", nullptr);
break;
case CLASS_SHAMAN:
if (tab == 0 || tab == 2)
nonCombatEngine->addStrategy("bmana");
nonCombatEngine->addStrategy("bmana", false);
else
nonCombatEngine->addStrategy("bdps");
nonCombatEngine->addStrategy("bdps", false);
nonCombatEngine->addStrategies("dps assist", "cure", nullptr);
nonCombatEngine->addStrategiesNoInit("dps assist", "cure", nullptr);
break;
case CLASS_MAGE:
if (tab == MAGE_TAB_ARCANE || tab == MAGE_TAB_FIRE)
nonCombatEngine->addStrategy("bdps");
nonCombatEngine->addStrategy("bdps", false);
else
nonCombatEngine->addStrategy("bmana");
nonCombatEngine->addStrategy("bmana", false);
nonCombatEngine->addStrategies("dps assist", "cure", nullptr);
nonCombatEngine->addStrategiesNoInit("dps assist", "cure", nullptr);
break;
case CLASS_DRUID:
if (tab == 1)
{
if (player->GetLevel() >= 20 && !player->HasAura(16931) /*thick hide*/)
{
nonCombatEngine->addStrategy("dps assist");
nonCombatEngine->addStrategy("dps assist", false);
}
else
{
nonCombatEngine->addStrategy("tank assist");
nonCombatEngine->addStrategy("tank assist", false);
}
}
else
nonCombatEngine->addStrategies("dps assist", "cure", nullptr);
nonCombatEngine->addStrategiesNoInit("dps assist", "cure", nullptr);
break;
case CLASS_WARRIOR:
if (tab == 2)
nonCombatEngine->addStrategy("tank assist");
nonCombatEngine->addStrategy("tank assist", false);
else
nonCombatEngine->addStrategy("dps assist");
nonCombatEngine->addStrategy("dps assist", false);
break;
case CLASS_WARLOCK:
if (tab == WARLOCK_TAB_AFFLICATION)
{
nonCombatEngine->addStrategies("bmana", nullptr);
nonCombatEngine->addStrategiesNoInit("bmana", nullptr);
}
else if (tab == WARLOCK_TAB_DEMONOLOGY)
{
nonCombatEngine->addStrategies("bdps", nullptr);
nonCombatEngine->addStrategiesNoInit("bdps", nullptr);
}
else if (tab == WARLOCK_TAB_DESTRUCTION)
{
nonCombatEngine->addStrategies("bhealth", nullptr);
nonCombatEngine->addStrategiesNoInit("bhealth", nullptr);
}
nonCombatEngine->addStrategies("dps assist", nullptr);
nonCombatEngine->addStrategiesNoInit("dps assist", nullptr);
break;
case CLASS_DEATH_KNIGHT:
if (tab == 0)
nonCombatEngine->addStrategy("tank assist");
nonCombatEngine->addStrategy("tank assist", false);
else
nonCombatEngine->addStrategy("dps assist");
nonCombatEngine->addStrategy("dps assist", false);
break;
default:
nonCombatEngine->addStrategy("dps assist");
nonCombatEngine->addStrategy("dps assist", false);
break;
}
if (!player->InBattleground())
{
nonCombatEngine->addStrategies("nc", "food", "chat", "follow", "default", "quest", "loot", "gather", "duel",
nonCombatEngine->addStrategiesNoInit("nc", "food", "chat", "follow", "default", "quest", "loot", "gather", "duel",
"buff", "mount", "emote", nullptr);
}
if (sPlayerbotAIConfig->autoSaveMana)
{
nonCombatEngine->addStrategy("auto save mana");
nonCombatEngine->addStrategy("smana", false);
}
if ((sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground())
{
@@ -607,10 +608,10 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
// let 25% of free bots start duels.
if (!urand(0, 3))
nonCombatEngine->addStrategy("start duel");
nonCombatEngine->addStrategy("start duel", false);
if (sPlayerbotAIConfig->randomBotJoinLfg)
nonCombatEngine->addStrategy("lfg");
nonCombatEngine->addStrategy("lfg", false);
if (!player->GetGroup() || player->GetGroup()->GetLeaderGUID() == player->GetGUID())
{
@@ -618,24 +619,24 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
// if (!urand(0, 3))
// nonCombatEngine->addStrategy("attack tagged");
nonCombatEngine->addStrategy("pvp");
nonCombatEngine->addStrategy("pvp", false);
// nonCombatEngine->addStrategy("collision");
nonCombatEngine->addStrategy("grind");
nonCombatEngine->addStrategy("grind", false);
// nonCombatEngine->addStrategy("group");
// nonCombatEngine->addStrategy("guild");
if (sPlayerbotAIConfig->autoDoQuests)
{
// nonCombatEngine->addStrategy("travel");
nonCombatEngine->addStrategy("rpg");
nonCombatEngine->addStrategy("rpg", false);
}
else
{
nonCombatEngine->addStrategy("move random");
nonCombatEngine->addStrategy("move random", false);
}
if (sPlayerbotAIConfig->randomBotJoinBG)
nonCombatEngine->addStrategy("bg");
nonCombatEngine->addStrategy("bg", false);
// if (!master || GET_PLAYERBOT_AI(master))
// nonCombatEngine->addStrategy("maintenance");
@@ -651,7 +652,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
PlayerbotAI* masterBotAI = GET_PLAYERBOT_AI(master);
if (masterBotAI || sRandomPlayerbotMgr->IsRandomBot(player))
{
nonCombatEngine->addStrategy("pvp");
nonCombatEngine->addStrategy("pvp", false);
// nonCombatEngine->addStrategy("collision");
// nonCombatEngine->addStrategy("group");
// nonCombatEngine->addStrategy("guild");
@@ -671,7 +672,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
}
else
{
nonCombatEngine->addStrategy("pvp");
nonCombatEngine->addStrategy("pvp", false);
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->nonCombatStrategies);
}
}
@@ -687,12 +688,12 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
// Battleground switch
if (player->InBattleground() && player->GetBattleground())
{
nonCombatEngine->addStrategies("nc", "chat", "default", "buff", "food", "mount", "pvp", "dps assist",
nonCombatEngine->addStrategiesNoInit("nc", "chat", "default", "buff", "food", "mount", "pvp", "dps assist",
"attack tagged", "emote", nullptr);
nonCombatEngine->removeStrategy("custom::say");
nonCombatEngine->removeStrategy("travel");
nonCombatEngine->removeStrategy("rpg");
nonCombatEngine->removeStrategy("grind");
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)
@@ -700,27 +701,27 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
if ((bgType <= BATTLEGROUND_EY || bgType == BATTLEGROUND_IC) &&
!player->InArena()) // do not add for not supported bg or arena
nonCombatEngine->addStrategy("battleground");
nonCombatEngine->addStrategy("battleground", false);
if (bgType == BATTLEGROUND_WS)
nonCombatEngine->addStrategy("warsong");
nonCombatEngine->addStrategy("warsong", false);
if (bgType == BATTLEGROUND_AV)
nonCombatEngine->addStrategy("alterac");
nonCombatEngine->addStrategy("alterac", false);
if (bgType == BATTLEGROUND_AB)
nonCombatEngine->addStrategy("arathi");
nonCombatEngine->addStrategy("arathi", false);
if (bgType == BATTLEGROUND_EY)
nonCombatEngine->addStrategy("eye");
nonCombatEngine->addStrategy("eye", false);
if (bgType == BATTLEGROUND_IC)
nonCombatEngine->addStrategy("isle");
nonCombatEngine->addStrategy("isle", false);
if (player->InArena())
{
nonCombatEngine->addStrategy("arena");
nonCombatEngine->removeStrategy("mount");
nonCombatEngine->addStrategy("arena", false);
nonCombatEngine->removeStrategy("mount", false);
}
}
}
@@ -730,17 +731,18 @@ Engine* AiFactory::createNonCombatEngine(Player* player, PlayerbotAI* const faca
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->addStrategies("dead", "stay", "chat", "default", "follow", nullptr);
deadEngine->addStrategiesNoInit("dead", "stay", "chat", "default", "follow", nullptr);
if (sRandomPlayerbotMgr->IsRandomBot(player) && !player->GetGroup())
{
deadEngine->removeStrategy("follow");
deadEngine->removeStrategy("follow", false);
}
}
@@ -748,5 +750,6 @@ Engine* AiFactory::createDeadEngine(Player* player, PlayerbotAI* const facade, A
{
Engine* deadEngine = new Engine(facade, AiObjectContext);
AddDefaultDeadStrategies(player, facade, deadEngine);
deadEngine->Init();
return deadEngine;
}

View File

@@ -342,16 +342,7 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
bool min = minimal;
UpdateAIInternal(elapsed, min);
inCombat = bot->IsInCombat();
// test fix lags because of BG
bool inBG = bot->InBattleground() || bot->InArena();
if (bot && !inCombat)
min = true;
if (HasRealPlayerMaster() || (sPlayerbotAIConfig->fastReactInBG && inBG))
min = false;
YieldThread(min);
YieldThread(GetReactDelay());
}
void PlayerbotAI::UpdateAIInternal([[maybe_unused]] uint32 elapsed, bool minimal)
@@ -940,6 +931,7 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
if (!AllowActivity())
return;
WorldPacket p(packet);
if (!p.empty() && (p.GetOpcode() == SMSG_MESSAGECHAT || p.GetOpcode() == SMSG_GM_MESSAGECHAT))
{
@@ -1584,6 +1576,9 @@ void PlayerbotAI::ResetStrategies(bool load)
AiFactory::AddDefaultNonCombatStrategies(bot, this, engines[BOT_STATE_NON_COMBAT]);
AiFactory::AddDefaultDeadStrategies(bot, this, engines[BOT_STATE_DEAD]);
for (uint8 i = 0; i < BOT_STATE_MAX; i++)
engines[i]->Init();
// if (load)
// sPlayerbotDbStore->Load(this);
}
@@ -2748,7 +2743,8 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell,
}
uint32 CastingTime = !spellInfo->IsChanneled() ? spellInfo->CalcCastTime(bot) : spellInfo->GetDuration();
if (CastingTime && bot->isMoving())
bool interruptOnMove = spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT;
if ((CastingTime || interruptOnMove) && bot->isMoving())
{
if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster()))
{
@@ -4795,7 +4791,8 @@ Item* PlayerbotAI::FindOilFor(Item* weapon) const
{
for (const auto& id : uPriorizedWizardOilIds)
{
if (oil = FindConsumable(id))
oil = FindConsumable(id);
if (oil)
return oil;
}
}
@@ -4804,7 +4801,8 @@ Item* PlayerbotAI::FindOilFor(Item* weapon) const
{
for (const auto& id : uPriorizedManaOilIds)
{
if (oil = FindConsumable(id))
oil = FindConsumable(id);
if (oil)
return oil;
}
}
@@ -5691,3 +5689,56 @@ std::set<uint32> PlayerbotAI::GetCurrentIncompleteQuestIds()
return result;
}
uint32 PlayerbotAI::GetReactDelay()
{
uint32 base = sPlayerbotAIConfig->reactDelay;
// old calculate method
if (!sPlayerbotAIConfig->dynamicReactDelay)
{
inCombat = bot->IsInCombat();
bool min = false;
// test fix lags because of BG
bool inBG = bot->InBattleground() || bot->InArena();
if (bot && !inCombat)
min = true;
if (HasRealPlayerMaster() || (sPlayerbotAIConfig->fastReactInBG && inBG))
min = false;
if (min)
return base * 10;
return base;
}
float multiplier = 1.0f;
if (HasRealPlayerMaster())
{
multiplier = 1.0f;
return base * multiplier;
}
bool inBg = bot->InBattleground() || bot->InArena();
if (inBg)
{
multiplier = sPlayerbotAIConfig->fastReactInBG ? 1.0f : 10.0f;
return base * multiplier;
}
if (bot->IsInCombat() || currentState == BOT_STATE_COMBAT)
{
multiplier = 5.0f;
return base * multiplier;
}
bool isResting = bot->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
if (!isResting)
{
multiplier = urand(5, 20);
return base * multiplier;
}
multiplier = urand(20, 200);
return base * multiplier;
}

View File

@@ -554,6 +554,7 @@ public:
uint32 GetInventoryItemsCountWithId(uint32 itemId);
bool HasItemInInventory(uint32 itemId);
std::vector<std::pair<const Quest*, uint32>> GetCurrentQuestsRequiringItemId(uint32 itemId);
uint32 GetReactDelay();
std::vector<const Quest*> GetAllCurrentQuests();
std::vector<const Quest*> GetCurrentIncompleteQuests();

View File

@@ -49,10 +49,10 @@ void PlayerbotAIBase::IncreaseNextCheckDelay(uint32 delay)
bool PlayerbotAIBase::CanUpdateAI() { return nextAICheckDelay == 0; }
void PlayerbotAIBase::YieldThread(bool delay)
void PlayerbotAIBase::YieldThread(uint32 delay)
{
if (nextAICheckDelay < sPlayerbotAIConfig->reactDelay)
nextAICheckDelay = delay ? sPlayerbotAIConfig->reactDelay * 10 : sPlayerbotAIConfig->reactDelay;
if (nextAICheckDelay < delay)
nextAICheckDelay = delay;
}
bool PlayerbotAIBase::IsActive() { return nextAICheckDelay < sPlayerbotAIConfig->maxWaitForMove; }

View File

@@ -7,6 +7,7 @@
#define _PLAYERBOT_PLAYERBOTAIBASE_H
#include "Define.h"
#include "PlayerbotAIConfig.h"
class PlayerbotAIBase
{
@@ -16,7 +17,7 @@ public:
bool CanUpdateAI();
void SetNextCheckDelay(uint32 const delay);
void IncreaseNextCheckDelay(uint32 delay);
void YieldThread(bool delay = false);
void YieldThread(uint32 delay = sPlayerbotAIConfig->reactDelay);
virtual void UpdateAI(uint32 elapsed, bool minimal = false);
virtual void UpdateAIInternal(uint32 elapsed, bool minimal = false) = 0;
bool IsActive();

View File

@@ -59,7 +59,8 @@ bool PlayerbotAIConfig::Initialize()
maxMovementSearchTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxMovementSearchTime", 3);
expireActionTime = sConfigMgr->GetOption<int32>("AiPlayerbot.ExpireActionTime", 5000);
dispelAuraDuration = sConfigMgr->GetOption<int32>("AiPlayerbot.DispelAuraDuration", 7000);
reactDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.ReactDelay", 500);
reactDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.ReactDelay", 100);
dynamicReactDelay = sConfigMgr->GetOption<bool>("AiPlayerbot.DynamicReactDelay", true);
passiveDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.PassiveDelay", 10000);
repeatDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.RepeatDelay", 2000);
errorDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.ErrorDelay", 5000);
@@ -77,7 +78,7 @@ bool PlayerbotAIConfig::Initialize()
fleeDistance = sConfigMgr->GetOption<float>("AiPlayerbot.FleeDistance", 7.5f);
aggroDistance = sConfigMgr->GetOption<float>("AiPlayerbot.AggroDistance", 22.0f);
tooCloseDistance = sConfigMgr->GetOption<float>("AiPlayerbot.TooCloseDistance", 5.0f);
meleeDistance = sConfigMgr->GetOption<float>("AiPlayerbot.MeleeDistance", 1.5f);
meleeDistance = sConfigMgr->GetOption<float>("AiPlayerbot.MeleeDistance", 0.75f);
followDistance = sConfigMgr->GetOption<float>("AiPlayerbot.FollowDistance", 1.5f);
whisperDistance = sConfigMgr->GetOption<float>("AiPlayerbot.WhisperDistance", 6000.0f);
contactDistance = sConfigMgr->GetOption<float>("AiPlayerbot.ContactDistance", 0.5f);

View File

@@ -58,6 +58,7 @@ public:
bool randomBotGuildNearby, randomBotInvitePlayer, inviteChat;
uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, maxMovementSearchTime, expireActionTime,
dispelAuraDuration, passiveDelay, repeatDelay, errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay;
bool dynamicReactDelay;
float sightDistance, spellDistance, reactDistance, grindDistance, lootDistance, shootDistance, fleeDistance,
tooCloseDistance, meleeDistance, followDistance, whisperDistance, contactDistance, aoeRadius, rpgDistance,
targetPosRecalcDistance, farDistance, healDistance, aggroDistance;

View File

@@ -29,6 +29,7 @@
#include "LFGMgr.h"
#include "MapMgr.h"
#include "PerformanceMonitor.h"
#include "PlayerbotAI.h"
#include "PlayerbotAIConfig.h"
#include "PlayerbotCommandServer.h"
#include "PlayerbotFactory.h"
@@ -2333,6 +2334,11 @@ void RandomPlayerbotMgr::PrintStats()
uint32 taxi = 0;
uint32 moving = 0;
uint32 mounted = 0;
uint32 inBg = 0;
uint32 rest = 0;
uint32 engine_noncombat = 0;
uint32 engine_combat = 0;
uint32 engine_dead = 0;
uint32 stateCount[MAX_TRAVEL_STATE + 1] = {0};
std::vector<std::pair<Quest const*, int32>> questCount;
for (PlayerBotMap::iterator i = playerBots.begin(); i != playerBots.end(); ++i)
@@ -2369,6 +2375,32 @@ void RandomPlayerbotMgr::PrintStats()
// if (!GetEventValue(botId, "dead"))
//++revive;
}
if (bot->IsInCombat())
{
++combat;
}
if (bot->isMoving())
{
++moving;
}
if (bot->IsMounted())
{
++mounted;
}
if (bot->InBattleground() || bot->InArena())
{
++inBg;
}
if (bot->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING))
{
++rest;
}
if (botAI->GetState() == BOT_STATE_NON_COMBAT)
++engine_noncombat;
else if (botAI->GetState() == BOT_STATE_COMBAT)
++engine_combat;
else
++engine_dead;
uint8 spec = AiFactory::GetPlayerSpecTab(bot);
switch (bot->getClass())
@@ -2490,8 +2522,15 @@ void RandomPlayerbotMgr::PrintStats()
LOG_INFO("playerbots", " On taxi: {}", taxi);
LOG_INFO("playerbots", " On mount: {}", mounted);
LOG_INFO("playerbots", " In combat: {}", combat);
LOG_INFO("playerbots", " In BG: {}", inBg);
LOG_INFO("playerbots", " In Rest: {}", rest);
LOG_INFO("playerbots", " Dead: {}", dead);
LOG_INFO("playerbots", "Bots engine:", dead);
LOG_INFO("playerbots", " Non-combat: {}", engine_noncombat);
LOG_INFO("playerbots", " Combat: {}", engine_combat);
LOG_INFO("playerbots", " Dead: {}", engine_dead);
LOG_INFO("playerbots", "Bots questing:");
LOG_INFO("playerbots", " Picking quests: {}",
stateCount[TRAVEL_STATE_TRAVEL_PICK_UP_QUEST] + stateCount[TRAVEL_STATE_WORK_PICK_UP_QUEST]);
@@ -2746,3 +2785,4 @@ ObjectGuid const RandomPlayerbotMgr::GetBattleMasterGUID(Player* bot, Battlegrou
return battleMasterGUID;
}

View File

@@ -412,10 +412,10 @@ void PlayerbotFactory::Randomize(bool incremental)
void PlayerbotFactory::Refresh()
{
// Prepare();
if (!sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel)
{
InitEquipment(true);
}
// if (!sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel)
// {
// InitEquipment(true);
// }
ClearInventory();
InitAmmo();
InitFood();

View File

@@ -409,26 +409,26 @@ ActionResult Engine::ExecuteAction(std::string const name, Event event, std::str
return result ? ACTION_RESULT_OK : ACTION_RESULT_FAILED;
}
void Engine::addStrategy(std::string const name)
void Engine::addStrategy(std::string const name, bool init)
{
removeStrategy(name);
removeStrategy(name, init);
if (Strategy* strategy = aiObjectContext->GetStrategy(name))
{
std::set<std::string> siblings = aiObjectContext->GetSiblingStrategy(name);
for (std::set<std::string>::iterator i = siblings.begin(); i != siblings.end(); i++)
removeStrategy(*i);
removeStrategy(*i, init);
LogAction("S:+%s", strategy->getName().c_str());
strategies[strategy->getName()] = strategy;
}
Init();
if (init)
Init();
}
void Engine::addStrategies(std::string first, ...)
{
addStrategy(first);
addStrategy(first, false);
va_list vl;
va_start(vl, first);
@@ -438,13 +438,34 @@ void Engine::addStrategies(std::string first, ...)
{
cur = va_arg(vl, const char*);
if (cur)
addStrategy(cur);
addStrategy(cur, false);
} while (cur);
Init();
va_end(vl);
}
void Engine::addStrategiesNoInit(std::string first, ...)
{
addStrategy(first, false);
va_list vl;
va_start(vl, first);
const char* cur;
do
{
cur = va_arg(vl, const char*);
if (cur)
addStrategy(cur, false);
} while (cur);
va_end(vl);
}
bool Engine::removeStrategy(std::string const name)
bool Engine::removeStrategy(std::string const name, bool init)
{
std::map<std::string, Strategy*>::iterator i = strategies.find(name);
if (i == strategies.end())
@@ -452,7 +473,8 @@ bool Engine::removeStrategy(std::string const name)
LogAction("S:-%s", name.c_str());
strategies.erase(i);
Init();
if (init)
Init();
return true;
}

View File

@@ -65,9 +65,10 @@ public:
Engine(PlayerbotAI* botAI, AiObjectContext* factory);
void Init();
void addStrategy(std::string const name);
void addStrategy(std::string const name, bool init = true);
void addStrategies(std::string first, ...);
bool removeStrategy(std::string const name);
void addStrategiesNoInit(std::string first, ...);
bool removeStrategy(std::string const name, bool init = true);
bool HasStrategy(std::string const name);
void removeAllStrategies();
void toggleStrategy(std::string const name);

View File

@@ -60,7 +60,7 @@ public:
creators["emote"] = &StrategyContext::emote;
creators["passive"] = &StrategyContext::passive;
// creators["conserve mana"] = &StrategyContext::conserve_mana;
creators["auto save mana"] = &StrategyContext::auto_save_mana;
creators["smana"] = &StrategyContext::auto_save_mana;
creators["food"] = &StrategyContext::food;
creators["chat"] = &StrategyContext::chat;
creators["default"] = &StrategyContext::world_packet;
@@ -112,9 +112,9 @@ public:
creators["group"] = &StrategyContext::group;
creators["guild"] = &StrategyContext::guild;
creators["grind"] = &StrategyContext::grind;
creators["avoid aoe"] = &StrategyContext::avoid_aoe;
creators["aaoe"] = &StrategyContext::avoid_aoe;
creators["move random"] = &StrategyContext::move_random;
creators["combat formation"] = &StrategyContext::combat_formation;
creators["formation"] = &StrategyContext::combat_formation;
}
private:

View File

@@ -92,7 +92,7 @@ public:
creators["reach party member to resurrect"] = &ActionContext::reach_party_member_to_resurrect;
creators["flee"] = &ActionContext::flee;
creators["flee with pet"] = &ActionContext::flee_with_pet;
creators["avoid aoe"] = &ActionContext::avoid_aoe;
creators["aaoe"] = &ActionContext::avoid_aoe;
creators["combat formation move"] = &ActionContext::combat_formation_move;
creators["disperse set"] = &ActionContext::disperse_set;
creators["gift of the naaru"] = &ActionContext::gift_of_the_naaru;
@@ -158,10 +158,8 @@ public:
creators["berserking"] = &ActionContext::berserking;
creators["use trinket"] = &ActionContext::use_trinket;
creators["auto talents"] = &ActionContext::auto_talents;
creators["auto learn spell"] = &ActionContext::auto_learn_spell;
creators["auto share quest"] = &ActionContext::auto_share_quest;
creators["auto teleport for level"] = &ActionContext::auto_teleport_for_level;
creators["auto upgrade equip"] = &ActionContext::auto_upgrade_equip;
creators["auto maintenance on levelup"] = &ActionContext::auto_maintenance_on_levelup;
creators["xp gain"] = &ActionContext::xp_gain;
creators["invite nearby"] = &ActionContext::invite_nearby;
creators["invite guild"] = &ActionContext::invite_guild;
@@ -331,10 +329,8 @@ private:
static Action* berserking(PlayerbotAI* botAI) { return new CastBerserkingAction(botAI); }
static Action* use_trinket(PlayerbotAI* botAI) { return new UseTrinketAction(botAI); }
static Action* auto_talents(PlayerbotAI* botAI) { return new AutoSetTalentsAction(botAI); }
static Action* auto_learn_spell(PlayerbotAI* botAI) { return new AutoLearnSpellAction(botAI); }
static Action* auto_share_quest(PlayerbotAI* ai) { return new AutoShareQuestAction(ai); }
static Action* auto_teleport_for_level(PlayerbotAI* botAI) { return new AutoTeleportForLevelAction(botAI); }
static Action* auto_upgrade_equip(PlayerbotAI* botAI) { return new AutoUpgradeEquipAction(botAI); }
static Action* auto_maintenance_on_levelup(PlayerbotAI* botAI) { return new AutoMaintenanceOnLevelupAction(botAI); }
static Action* xp_gain(PlayerbotAI* botAI) { return new XpGainAction(botAI); }
static Action* invite_nearby(PlayerbotAI* botAI) { return new InviteNearbyToGroupAction(botAI); }
static Action* invite_guild(PlayerbotAI* botAI) { return new InviteGuildToGroupAction(botAI); }

View File

@@ -70,7 +70,7 @@ AvoidAoeStrategy::AvoidAoeStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
NextAction** AvoidAoeStrategy::getDefaultActions()
{
return NextAction::array(0, new NextAction("avoid aoe", ACTION_EMERGENCY), nullptr);
return NextAction::array(0, new NextAction("aaoe", ACTION_EMERGENCY), nullptr);
}
void AvoidAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)

View File

@@ -23,7 +23,7 @@ class AvoidAoeStrategy : public Strategy
{
public:
explicit AvoidAoeStrategy(PlayerbotAI* ai);
const std::string getName() override { return "avoid aoe"; }
const std::string getName() override { return "aaoe"; }
NextAction** getDefaultActions() override;
void InitMultipliers(std::vector<Multiplier*>& multipliers) override;
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
@@ -33,7 +33,7 @@ class CombatFormationStrategy : public Strategy
{
public:
CombatFormationStrategy(PlayerbotAI* ai) : Strategy(ai) {}
const std::string getName() override { return "combat formation"; }
const std::string getName() override { return "formation"; }
NextAction** getDefaultActions() override;
};

View File

@@ -49,7 +49,7 @@ class PlayerbotAI;
class HealerAutoSaveManaMultiplier : public Multiplier
{
public:
HealerAutoSaveManaMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "auto save mana") {}
HealerAutoSaveManaMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "smana") {}
float GetValue(Action* action) override;
};
@@ -60,7 +60,7 @@ public:
HealerAutoSaveManaStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
void InitMultipliers(std::vector<Multiplier*>& multipliers) override;
std::string const getName() override { return "auto save mana"; }
std::string const getName() override { return "smana"; }
};
#endif