diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 5f0e64d3..40a44683 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -172,8 +172,8 @@ AiPlayerbot.AllowSummonWhenMasterIsDead = 1 # default: 1 (always) AiPlayerbot.AllowSummonWhenBotIsDead = 1 -# Enable/Disable reviving the bots when summoning them -# default: 1 (enable) +# Enable/Disable reviving the bots when summoning them (0 = disable, 1 = disable in combat, 2 = enable) +# default: 1 (disable in combat) AiPlayerbot.ReviveBotWhenSummoned = 1 # Enable/Disable bot repair gear when summon (0 = no, 1 = yes) @@ -899,8 +899,8 @@ AiPlayerbot.PremadeSpecLink.8.1.60 = -0055030011302231053120321341 AiPlayerbot.PremadeSpecLink.8.1.80 = 23000503110003-0055030011302331053120321351 AiPlayerbot.PremadeSpecName.8.2 = frost pve AiPlayerbot.PremadeSpecGlyph.8.2 = 42742,43339,50045,43364,43361,42751 -AiPlayerbot.PremadeSpecLink.8.2.60 = --3533103310203100232102231151 -AiPlayerbot.PremadeSpecLink.8.2.80 = 23002322010203--0533003313203100232112231151 +AiPlayerbot.PremadeSpecLink.8.2.60 = --0533030313203100030152231151 +AiPlayerbot.PremadeSpecLink.8.2.80 = 23002303110003--0533030313203100030152231351 # # @@ -1289,7 +1289,7 @@ AiPlayerbot.RandomBotGuildCount = 20 AiPlayerbot.DeleteRandomBotGuilds = 0 # Chance bot chooses RPG (Teleport to random camp for their level) instead of grinding -AiPlayerbot.RandomBotRpgChance = 0.20 #unused now +AiPlayerbot.RandomBotRpgChance = 0.20 # Set randombots movement speed to walking anywhere AiPlayerbot.RandombotsWalkingRPG = 0 diff --git a/src/ChatHelper.cpp b/src/ChatHelper.cpp index cec5d696..a181ac89 100644 --- a/src/ChatHelper.cpp +++ b/src/ChatHelper.cpp @@ -288,7 +288,7 @@ std::string const ChatHelper::FormatQuest(Quest const* quest) std::string const ChatHelper::FormatGameobject(GameObject* go) { std::ostringstream out; - out << "|cFFFFFF00|Hfound:" << go->GetGUID().GetRawValue() << ":" << go->GetEntry() << ":" << "|h[" << go->GetGOInfo()->name << "]|h|r"; + out << "|cFFFFFF00|Hfound:" << go->GetGUID().GetRawValue() << ":" << go->GetEntry() << ":" << "|h[" << go->GetNameForLocaleIdx(sWorld->GetDefaultDbcLocale()) << "]|h|r"; return out.str(); } @@ -296,7 +296,7 @@ std::string const ChatHelper::FormatWorldobject(WorldObject* wo) { std::ostringstream out; out << "|cFFFFFF00|Hfound:" << wo->GetGUID().GetRawValue() << ":" << wo->GetEntry() << ":" << "|h["; - out << (wo->ToGameObject() ? ((GameObject*)wo)->GetGOInfo()->name : wo->GetName()) << "]|h|r"; + out << (wo->ToGameObject() ? ((GameObject*)wo)->GetNameForLocaleIdx(sWorld->GetDefaultDbcLocale()) : wo->GetNameForLocaleIdx(sWorld->GetDefaultDbcLocale())) << "]|h|r"; return out.str(); } @@ -327,7 +327,7 @@ std::string const ChatHelper::FormatWorldEntry(int32 entry) std::string const ChatHelper::FormatSpell(SpellInfo const* spellInfo) { std::ostringstream out; - out << "|cffffffff|Hspell:" << spellInfo->Id << "|h[" << spellInfo->SpellName[LOCALE_enUS] << "]|h|r"; + out << "|cffffffff|Hspell:" << spellInfo->Id << "|h[" << spellInfo->SpellName[sWorld->GetDefaultDbcLocale()] << "]|h|r"; return out.str(); } @@ -336,9 +336,11 @@ std::string const ChatHelper::FormatItem(ItemTemplate const* proto, uint32 count char color[32]; sprintf(color, "%x", ItemQualityColors[proto->Quality]); + const std::string &name = sObjectMgr->GetItemLocale(proto->ItemId)->Name[sWorld->GetDefaultDbcLocale()]; + std::ostringstream out; out << "|c" << color << "|Hitem:" << proto->ItemId - << ":0:0:0:0:0:0:0" << "|h[" << proto->Name1 + << ":0:0:0:0:0:0:0" << "|h[" << name << "]|h|r"; if (count > 1) diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 45f832d5..6a4c7b3f 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -350,7 +350,7 @@ void PlayerbotAI::UpdateAIInternal([[maybe_unused]] uint32 elapsed, bool minimal std::string const command = holder.GetCommand(); Player* owner = holder.GetOwner(); - if (!helper.ParseChatCommand(command, owner) && holder.GetType() == CHAT_MSG_WHISPER) + if (owner == master && !helper.ParseChatCommand(command, owner) && holder.GetType() == CHAT_MSG_WHISPER) { // To prevent spam caused by WIM if (!(command.rfind("WIM", 0) == 0) && diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index b28aeeba..94e290fe 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -279,7 +279,7 @@ bool PlayerbotAIConfig::Initialize() allowSummonInCombat = sConfigMgr->GetOption("AiPlayerbot.AllowSummonInCombat", true); allowSummonWhenMasterIsDead = sConfigMgr->GetOption("AiPlayerbot.AllowSummonWhenMasterIsDead", true); allowSummonWhenBotIsDead = sConfigMgr->GetOption("AiPlayerbot.AllowSummonWhenBotIsDead", true); - reviveBotWhenSummoned = sConfigMgr->GetOption("AiPlayerbot.ReviveBotWhenSummoned", true); + reviveBotWhenSummoned = sConfigMgr->GetOption("AiPlayerbot.ReviveBotWhenSummoned", 1); botRepairWhenSummon = sConfigMgr->GetOption("AiPlayerbot.BotRepairWhenSummon", true); autoInitOnly = sConfigMgr->GetOption("AiPlayerbot.AutoInitOnly", false); autoInitEquipLevelLimitRatio = sConfigMgr->GetOption("AiPlayerbot.AutoInitEquipLevelLimitRatio", 1.0); diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index 32bd1c59..5ce7d39e 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -220,7 +220,7 @@ class PlayerbotAIConfig bool allowSummonInCombat; bool allowSummonWhenMasterIsDead; bool allowSummonWhenBotIsDead; - bool reviveBotWhenSummoned; + int reviveBotWhenSummoned; bool botRepairWhenSummon; bool autoInitOnly; float autoInitEquipLevelLimitRatio; diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index 8ddf2086..21409f18 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -2620,6 +2620,16 @@ void PlayerbotFactory::InitMounts() for (uint32 type = 0; type < 4; type++) { + bool hasMount = false; + for (uint32 &spell : mounts[bot->getRace()][type]) { + if (bot->HasSpell(spell)) { + hasMount = true; + break; + } + } + if (hasMount) + continue; + if (bot->GetLevel() < secondmount && type == 1) continue; diff --git a/src/PlayerbotMgr.cpp b/src/PlayerbotMgr.cpp index c72e7a7b..f8923316 100644 --- a/src/PlayerbotMgr.cpp +++ b/src/PlayerbotMgr.cpp @@ -736,7 +736,7 @@ bool PlayerbotMgr::HandlePlayerbotMgrCommand(ChatHandler* handler, char const* a for (std::vector::iterator i = messages.begin(); i != messages.end(); ++i) { - handler->PSendSysMessage("%s", i->c_str()); + handler->PSendSysMessage("{}", i->c_str()); } return true; @@ -748,8 +748,8 @@ std::vector PlayerbotHolder::HandlePlayerbotCommand(char const* arg if (!*args) { - messages.push_back("usage: list/reload/tweak/self or add/init/remove PLAYERNAME"); - messages.push_back(" addclass CLASSNAME"); + messages.push_back("usage: list/reload/tweak/self or add/init/remove PLAYERNAME\n"); + messages.push_back("usage: addclass CLASSNAME"); return messages; } diff --git a/src/strategy/actions/AcceptInvitationAction.cpp b/src/strategy/actions/AcceptInvitationAction.cpp index ce2ea360..5bd261c1 100644 --- a/src/strategy/actions/AcceptInvitationAction.cpp +++ b/src/strategy/actions/AcceptInvitationAction.cpp @@ -4,17 +4,24 @@ #include "AcceptInvitationAction.h" #include "Event.h" +#include "ObjectAccessor.h" #include "PlayerbotAIConfig.h" #include "Playerbots.h" #include "PlayerbotSecurity.h" +#include "WorldPacket.h" bool AcceptInvitationAction::Execute(Event event) { Group* grp = bot->GetGroupInvite(); if (!grp) return false; + WorldPacket packet = event.getPacket(); + uint8 flag; + std::string name; + packet >> flag >> name; - Player* inviter = ObjectAccessor::FindPlayer(grp->GetLeaderGUID()); + // Player* inviter = ObjectAccessor::FindPlayer(grp->GetLeaderGUID()); + Player* inviter = ObjectAccessor::FindPlayerByName(name, true); if (!inviter) return false; diff --git a/src/strategy/actions/BattleGroundTactics.cpp b/src/strategy/actions/BattleGroundTactics.cpp index e2ec787c..07aca77b 100644 --- a/src/strategy/actions/BattleGroundTactics.cpp +++ b/src/strategy/actions/BattleGroundTactics.cpp @@ -2390,19 +2390,19 @@ static std::pair AV_AllianceDefendObjectives[] = static uint32 AB_AttackObjectives[] = { // Attack - { BG_AB_NODE_STABLES }, - { BG_AB_NODE_BLACKSMITH }, - { BG_AB_NODE_FARM }, - { BG_AB_NODE_LUMBER_MILL }, - { BG_AB_NODE_GOLD_MINE } + BG_AB_NODE_STABLES, + BG_AB_NODE_BLACKSMITH, + BG_AB_NODE_FARM, + BG_AB_NODE_LUMBER_MILL, + BG_AB_NODE_GOLD_MINE }; static uint32 EY_AttackObjectives[] = { - { POINT_FEL_REAVER }, - { POINT_BLOOD_ELF }, - { POINT_DRAENEI_RUINS }, - { POINT_MAGE_TOWER } + POINT_FEL_REAVER, + POINT_BLOOD_ELF, + POINT_DRAENEI_RUINS, + POINT_MAGE_TOWER }; // useful commands for fixing BG bugs and checking waypoints/paths diff --git a/src/strategy/actions/EmoteAction.cpp b/src/strategy/actions/EmoteAction.cpp index b13a7a12..2ef6e90a 100644 --- a/src/strategy/actions/EmoteAction.cpp +++ b/src/strategy/actions/EmoteAction.cpp @@ -447,7 +447,7 @@ bool EmoteActionBase::ReceiveEmote(Player* source, uint32 emote, bool verbal) case TEXT_EMOTE_RASP: emoteId = EMOTE_ONESHOT_RUDE; textEmote = TEXT_EMOTE_RASP; - emoteText = "Right back at you, bub!", LANG_UNIVERSAL; + emoteText = "Right back at you, bub!"; // , LANG_UNIVERSAL; break; case TEXT_EMOTE_ROAR: case TEXT_EMOTE_THREATEN: diff --git a/src/strategy/actions/GenericActions.cpp b/src/strategy/actions/GenericActions.cpp index 5e292369..9b16ee7a 100644 --- a/src/strategy/actions/GenericActions.cpp +++ b/src/strategy/actions/GenericActions.cpp @@ -20,6 +20,7 @@ bool TogglePetSpellAutoCastAction::Execute(Event event) { if (!pet) { return false; } + bool toggled = false; for (PetSpellMap::const_iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) { if(itr->second.state == PETSPELL_REMOVED) @@ -29,17 +30,29 @@ bool TogglePetSpellAutoCastAction::Execute(Event event) { const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (spellInfo->IsPassive()) continue; - + + bool shouldApply = true; // imp's spell, felhunte's intelligence, ghoul's leap, cat stealth if (spellId == 4511 || spellId == 1742 || spellId == 54424 || spellId == 57564 || spellId == 57565 || spellId == 57566 || spellId == 57567 || spellId == 47482 || spellId == 24450) { - pet->ToggleAutocast(spellInfo, false); - } else { - pet->ToggleAutocast(spellInfo, true); + shouldApply = false; + } + bool isAutoCast = false; + for (unsigned int &m_autospell : pet->m_autospells) + { + if (m_autospell == spellId) + { + isAutoCast = true; + break; + } + } + if (shouldApply != isAutoCast) { + pet->ToggleAutocast(spellInfo, shouldApply); + toggled = true; } } - return true; + return toggled; } bool PetAttackAction::Execute(Event event) diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 0aef8b4e..ed002f53 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -1595,7 +1595,7 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage() continue; } const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (spellInfo->IsPositive()) { + if (!spellInfo || spellInfo->IsPositive()) { continue; } float radius = (float)goInfo->trap.diameter / 2; diff --git a/src/strategy/actions/TellLosAction.cpp b/src/strategy/actions/TellLosAction.cpp index 8c729cf3..688599ff 100644 --- a/src/strategy/actions/TellLosAction.cpp +++ b/src/strategy/actions/TellLosAction.cpp @@ -6,6 +6,7 @@ #include "Event.h" #include "ChatHelper.h" #include "Playerbots.h" +#include "World.h" bool TellLosAction::Execute(Event event) { @@ -52,7 +53,7 @@ void TellLosAction::ListUnits(std::string const title, GuidVector units) for (ObjectGuid const guid : units) { if (Unit* unit = botAI->GetUnit(guid)) { - botAI->TellMaster(unit->GetName()); + botAI->TellMaster(unit->GetNameForLocaleIdx(sWorld->GetDefaultDbcLocale())); } } diff --git a/src/strategy/actions/UseMeetingStoneAction.cpp b/src/strategy/actions/UseMeetingStoneAction.cpp index 5cf93e14..2bc87266 100644 --- a/src/strategy/actions/UseMeetingStoneAction.cpp +++ b/src/strategy/actions/UseMeetingStoneAction.cpp @@ -206,7 +206,8 @@ bool SummonAction::Teleport(Player* summoner, Player* player) return false; } - if (bot->isDead() && sPlayerbotAIConfig->reviveBotWhenSummoned) + bool revive = sPlayerbotAIConfig->reviveBotWhenSummoned == 2 || (sPlayerbotAIConfig->reviveBotWhenSummoned == 1 && !master->IsInCombat()); + if (bot->isDead() && revive) { bot->ResurrectPlayer(1.0f, false); botAI->TellMasterNoFacing("I live, again!");