diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 7fadbcb1..defbd73d 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -519,7 +519,7 @@ AiPlayerbot.AutoGearScoreLimit = 0 # "taxi" (bots may use all flight paths, though they will not actually learn them) # "raid" (bots use cheats implemented into raid strategies) # To use multiple cheats, separate them by commas below (e.g., to enable all, use "gold,health,mana,power,raid,taxi") -# Default: taxi and raid are enabled +# Default: food, taxi, and raid are enabled AiPlayerbot.BotCheats = "food,taxi,raid" # @@ -1603,10 +1603,10 @@ AiPlayerbot.PremadeSpecLink.11.6.80 = 05320021--230033312031500531353013251 # # -# Applies a permanent buff to all bots simulating effects of spells, flasks, food, runes, etc. +# Applies automatically refreshing buffs to bots simulating effects of spells, flasks, food, runes, etc. # Requires sending the command "nc +worldbuff" in chat to a bot (or a group of bots) to enable # Each entry in the matrix should be formatted as follows: Entry:FactionID,ClassID,SpecID,MinimumLevel,MaximumLevel:SpellID1,SpellID2,etc.; -# Use 0 for any field to make it agnostic (e.g., 0 for FactionID means the entry will apply buffs to either faction) +# FactionID may be set to 0 for the entry to apply buffs to bots of either faction # The default entries create a cross-faction list of level 80 buffs for each implemented pve spec from the "Premade Specs" section # The default entries may be deleted or modified, and new custom entries may be added diff --git a/src/strategy/actions/BattleGroundJoinAction.cpp b/src/strategy/actions/BattleGroundJoinAction.cpp index 1877a5f2..fda822ef 100644 --- a/src/strategy/actions/BattleGroundJoinAction.cpp +++ b/src/strategy/actions/BattleGroundJoinAction.cpp @@ -688,7 +688,7 @@ bool BGLeaveAction::Execute(Event event) WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20); packet << type << unk2 << (uint32)_bgTypeId << unk << uint8(0); - bot->GetSession()->HandleBattleFieldPortOpcode(packet); + bot->GetSession()->QueuePacket(new WorldPacket(packet)); if (IsRandomBot) botAI->SetMaster(nullptr); @@ -917,7 +917,7 @@ bool BGStatusAction::Execute(Event event) WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20); packet << type << unk2 << (uint32)_bgTypeId << unk << action; - bot->GetSession()->HandleBattleFieldPortOpcode(packet); + bot->GetSession()->QueuePacket(new WorldPacket(packet)); botAI->ResetStrategies(false); if (!bot->GetBattleground()) @@ -972,7 +972,7 @@ bool BGStatusAction::Execute(Event event) WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20); action = 0; packet << type << unk2 << (uint32)_bgTypeId << unk << action; - bot->GetSession()->HandleBattleFieldPortOpcode(packet); + bot->GetSession()->QueuePacket(new WorldPacket(packet)); botAI->ResetStrategies(!IsRandomBot); botAI->GetAiObjectContext()->GetValue("bg type")->Set(0); @@ -1039,7 +1039,7 @@ bool BGStatusAction::Execute(Event event) WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20); packet << type << unk2 << (uint32)_bgTypeId << unk << action; - bot->GetSession()->HandleBattleFieldPortOpcode(packet); + bot->GetSession()->QueuePacket(new WorldPacket(packet)); botAI->ResetStrategies(false); if (!bot->GetBattleground()) diff --git a/src/strategy/actions/NonCombatActions.cpp b/src/strategy/actions/NonCombatActions.cpp index d3c49dec..262e0f20 100644 --- a/src/strategy/actions/NonCombatActions.cpp +++ b/src/strategy/actions/NonCombatActions.cpp @@ -13,10 +13,6 @@ bool DrinkAction::Execute(Event event) if (bot->IsInCombat()) return false; - bool hasMana = AI_VALUE2(bool, "has mana", "self target"); - if (!hasMana) - return false; - if (botAI->HasCheat(BotCheatMask::food)) { // if (bot->IsNonMeleeSpellCast(true)) @@ -54,7 +50,14 @@ bool DrinkAction::Execute(Event event) return UseItemAction::Execute(event); } -bool DrinkAction::isUseful() { return UseItemAction::isUseful() && AI_VALUE2(uint8, "mana", "self target") < 100; } +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() { diff --git a/src/strategy/shaman/ShamanActions.cpp b/src/strategy/shaman/ShamanActions.cpp index dbb83a0c..d4d0f98a 100644 --- a/src/strategy/shaman/ShamanActions.cpp +++ b/src/strategy/shaman/ShamanActions.cpp @@ -93,19 +93,26 @@ bool CastSpiritWalkAction::Execute(Event event) bool SetTotemAction::Execute(Event event) { - size_t spellIdsCount = sizeof(totemSpellIds) / sizeof(uint32); + const size_t spellIdsCount = sizeof(totemSpellIds) / sizeof(uint32); + if (spellIdsCount == 0) + return false; // early return uint32 totemSpell = 0; - for (int i = spellIdsCount - 1; i >= 0; --i) + + // Iterate backwards to prioritize the highest-rank totem spell the bot knows + for (size_t i = spellIdsCount; i-- > 0;) { - if (bot->HasSpell(totemSpellIds[i])) + const uint32 spellId = totemSpellIds[i]; + if (bot->HasSpell(spellId)) { - totemSpell = totemSpellIds[i]; + totemSpell = spellId; break; } } - if (!totemSpell) + + if (totemSpell == 0) return false; + bot->addActionButton(actionButtonId, totemSpell, ACTION_BUTTON_SPELL); return true; } diff --git a/src/strategy/shaman/ShamanTriggers.cpp b/src/strategy/shaman/ShamanTriggers.cpp index 35afbea1..cdee870c 100644 --- a/src/strategy/shaman/ShamanTriggers.cpp +++ b/src/strategy/shaman/ShamanTriggers.cpp @@ -424,6 +424,7 @@ bool SetTotemTrigger::IsActive() { if (!bot->HasSpell(SPELL_CALL_OF_THE_ELEMENTS)) return false; + if (!bot->HasSpell(requiredSpellId)) return false; @@ -431,13 +432,20 @@ bool SetTotemTrigger::IsActive() if (!button || button->GetType() != ACTION_BUTTON_SPELL || button->GetAction() == 0) return true; - size_t totemSpellIdsCount = sizeof(totemSpellIds) / sizeof(uint32); - for (size_t i = 0; i < totemSpellIdsCount; ++i) + const size_t totemSpellIdsCount = sizeof(totemSpellIds) / sizeof(uint32); + if (totemSpellIdsCount == 0) { - if (button->GetAction() == totemSpellIds[i]) + return false; + } + + for (int i = (int)totemSpellIdsCount - 1; i >= 0; --i) + { + const uint32 spellId = totemSpellIds[i]; + if (bot->HasSpell(spellId)) { - return false; + return button->GetAction() != spellId; } } - return true; + + return false; }