From 4a79a46da5650ea2e6908d45296983ae6b661ef6 Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Sat, 2 May 2026 21:18:54 +0200 Subject: [PATCH] Add argument "all" to "rep" command and new "emblems" command (#2035) ## Summary - restrict `reputation all` to a curated list of WotLK/BC/Classic faction IDs (filtered by team) - reuse a shared formatter for reputation lines - add an `emblems` chat command to report emblem counts ### Multibot will need a update image image image image --------- Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com> Co-authored-by: bash Co-authored-by: Revision Co-authored-by: kadeshar --- src/Ai/Base/Actions/TellEmblemsAction.cpp | 39 ++++++++ src/Ai/Base/Actions/TellEmblemsAction.h | 21 +++++ src/Ai/Base/Actions/TellReputationAction.cpp | 89 ++++++++++++++----- src/Ai/Base/Actions/TellReputationAction.h | 6 ++ src/Ai/Base/ChatActionContext.h | 3 + src/Ai/Base/ChatTriggerContext.h | 2 + .../Strategy/ChatCommandHandlerStrategy.cpp | 6 +- 7 files changed, 143 insertions(+), 23 deletions(-) create mode 100644 src/Ai/Base/Actions/TellEmblemsAction.cpp create mode 100644 src/Ai/Base/Actions/TellEmblemsAction.h diff --git a/src/Ai/Base/Actions/TellEmblemsAction.cpp b/src/Ai/Base/Actions/TellEmblemsAction.cpp new file mode 100644 index 000000000..4d69baa11 --- /dev/null +++ b/src/Ai/Base/Actions/TellEmblemsAction.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2016+ AzerothCore , 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 "TellEmblemsAction.h" + +#include + +#include "Event.h" +#include "Playerbots.h" + +bool TellEmblemsAction::Execute(Event /*event*/) +{ + static std::array const emblemIds = { + 29434, // Badge of Justice + 40752, // Emblem of Heroism + 40753, // Emblem of Valor + 45624, // Emblem of Conquest + 47241, // Emblem of Triumph + 49426 // Emblem of Frost + }; + + botAI->TellMaster("=== Emblems ==="); + + for (uint32 itemId : emblemIds) + { + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId); + if (!proto) + continue; + + uint32 count = bot->GetItemCount(itemId, false); + std::ostringstream out; + out << chat->FormatItem(proto, count); + botAI->TellMaster(out); + } + + return true; +} diff --git a/src/Ai/Base/Actions/TellEmblemsAction.h b/src/Ai/Base/Actions/TellEmblemsAction.h new file mode 100644 index 000000000..570fb2d04 --- /dev/null +++ b/src/Ai/Base/Actions/TellEmblemsAction.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2016+ AzerothCore , 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. + */ + +#ifndef _PLAYERBOT_TELLEMBLEMSACTION_H +#define _PLAYERBOT_TELLEMBLEMSACTION_H + +#include "InventoryAction.h" + +class PlayerbotAI; + +class TellEmblemsAction : public InventoryAction +{ +public: + TellEmblemsAction(PlayerbotAI* botAI) : InventoryAction(botAI, "emblems") {} + + bool Execute(Event event) override; +}; + +#endif diff --git a/src/Ai/Base/Actions/TellReputationAction.cpp b/src/Ai/Base/Actions/TellReputationAction.cpp index 0ccff606a..22c11e165 100644 --- a/src/Ai/Base/Actions/TellReputationAction.cpp +++ b/src/Ai/Base/Actions/TellReputationAction.cpp @@ -5,34 +5,23 @@ #include "TellReputationAction.h" +#include + #include "Event.h" #include "PlayerbotAI.h" #include "ReputationMgr.h" -bool TellReputationAction::Execute(Event /*event*/) +#include "SharedDefines.h" + +std::string TellReputationAction::BuildReputationLine(FactionEntry const* entry) { - Player* master = GetMaster(); - if (!master) - return false; - - ObjectGuid selection = master->GetTarget(); - if (selection.IsEmpty()) - return false; - - Unit* unit = ObjectAccessor::GetUnit(*master, selection); - if (!unit) - return false; - - FactionTemplateEntry const* factionTemplate = unit->GetFactionTemplateEntry(); - uint32 faction = factionTemplate->faction; - FactionEntry const* entry = sFactionStore.LookupEntry(faction); - int32 reputation = bot->GetReputationMgr().GetReputation(faction); + ReputationMgr& repMgr = bot->GetReputationMgr(); + ReputationRank rank = repMgr.GetRank(entry); + int32 reputation = repMgr.GetReputation(entry->ID); std::ostringstream out; - out << entry->name[0] << ": "; - out << "|cff"; + out << entry->name[0] << ": |cff"; - ReputationRank rank = bot->GetReputationMgr().GetRank(entry); switch (rank) { case REP_HATED: @@ -71,7 +60,65 @@ bool TellReputationAction::Execute(Event /*event*/) base -= ReputationMgr::PointsInRank[i]; out << " (" << (reputation - base) << "/" << ReputationMgr::PointsInRank[rank] << ")"; - botAI->TellMaster(out); + return out.str(); +} + +bool TellReputationAction::Execute(Event event) +{ + std::string const param = event.getParam(); + if (param == "all") + { + ReputationMgr& repMgr = bot->GetReputationMgr(); + std::vector lines; + + FactionStateList const& stateList = repMgr.GetStateList(); + lines.reserve(stateList.size()); + + for (auto const& itr : stateList) + { + FactionState const& faction = itr.second; + if (!(faction.Flags & FACTION_FLAG_VISIBLE)) + continue; + + if (faction.Flags & (FACTION_FLAG_HIDDEN | FACTION_FLAG_INVISIBLE_FORCED) && + !(faction.Flags & FACTION_FLAG_SPECIAL)) + continue; + + FactionEntry const* entry = sFactionStore.LookupEntry(faction.ID); + if (!entry) + continue; + + lines.push_back(BuildReputationLine(entry)); + } + + std::sort(lines.begin(), lines.end()); + + botAI->TellMaster("=== Reputations ==="); + for (auto const& line : lines) + botAI->TellMaster(line); + + return true; + } + + Player* master = GetMaster(); + if (!master) + return false; + + ObjectGuid selection = master->GetTarget(); + if (selection.IsEmpty()) + return false; + + Unit* unit = ObjectAccessor::GetUnit(*master, selection); + if (!unit) + return false; + + FactionTemplateEntry const* factionTemplate = unit->GetFactionTemplateEntry(); + + FactionEntry const* entry = sFactionStore.LookupEntry(factionTemplate->faction); + if (!entry) + return false; + + botAI->TellMaster(BuildReputationLine(entry)); return true; } diff --git a/src/Ai/Base/Actions/TellReputationAction.h b/src/Ai/Base/Actions/TellReputationAction.h index 3adaa66d5..d97d0d177 100644 --- a/src/Ai/Base/Actions/TellReputationAction.h +++ b/src/Ai/Base/Actions/TellReputationAction.h @@ -6,8 +6,11 @@ #ifndef _PLAYERBOT_TELLREPUTATIONACTION_H #define _PLAYERBOT_TELLREPUTATIONACTION_H +#include + #include "Action.h" +struct FactionEntry; class PlayerbotAI; class TellReputationAction : public Action @@ -16,6 +19,9 @@ public: TellReputationAction(PlayerbotAI* botAI) : Action(botAI, "reputation") {} bool Execute(Event event) override; + +private: + std::string BuildReputationLine(FactionEntry const* entry); }; #endif diff --git a/src/Ai/Base/ChatActionContext.h b/src/Ai/Base/ChatActionContext.h index af51c23ae..497ae2e9c 100644 --- a/src/Ai/Base/ChatActionContext.h +++ b/src/Ai/Base/ChatActionContext.h @@ -66,6 +66,7 @@ #include "TaxiAction.h" #include "TeleportAction.h" #include "TellCastFailedAction.h" +#include "TellEmblemsAction.h" #include "TellItemCountAction.h" #include "TellLosAction.h" #include "TellReputationAction.h" @@ -120,6 +121,7 @@ public: creators["teleport"] = &ChatActionContext::teleport; creators["taxi"] = &ChatActionContext::taxi; creators["repair"] = &ChatActionContext::repair; + creators["emblems"] = &ChatActionContext::emblems; creators["use"] = &ChatActionContext::use; creators["item count"] = &ChatActionContext::item_count; creators["equip"] = &ChatActionContext::equip; @@ -276,6 +278,7 @@ private: static Action* item_count(PlayerbotAI* botAI) { return new TellItemCountAction(botAI); } static Action* use(PlayerbotAI* botAI) { return new UseItemAction(botAI); } static Action* repair(PlayerbotAI* botAI) { return new RepairAllAction(botAI); } + static Action* emblems(PlayerbotAI* botAI) { return new TellEmblemsAction(botAI); } static Action* taxi(PlayerbotAI* botAI) { return new TaxiAction(botAI); } static Action* teleport(PlayerbotAI* botAI) { return new TeleportAction(botAI); } static Action* release(PlayerbotAI* botAI) { return new ReleaseSpiritAction(botAI); } diff --git a/src/Ai/Base/ChatTriggerContext.h b/src/Ai/Base/ChatTriggerContext.h index 7742a9305..ef8827c29 100644 --- a/src/Ai/Base/ChatTriggerContext.h +++ b/src/Ai/Base/ChatTriggerContext.h @@ -41,6 +41,7 @@ public: creators["teleport"] = &ChatTriggerContext::teleport; creators["taxi"] = &ChatTriggerContext::taxi; creators["repair"] = &ChatTriggerContext::repair; + creators["emblems"] = &ChatTriggerContext::emblems; creators["u"] = &ChatTriggerContext::use; creators["use"] = &ChatTriggerContext::use; creators["c"] = &ChatTriggerContext::item_count; @@ -235,6 +236,7 @@ private: static Trigger* item_count(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "c"); } static Trigger* use(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "use"); } static Trigger* repair(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "repair"); } + static Trigger* emblems(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "emblems"); } static Trigger* taxi(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "taxi"); } static Trigger* teleport(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "teleport"); } static Trigger* q(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "q"); } diff --git a/src/Ai/Base/Strategy/ChatCommandHandlerStrategy.cpp b/src/Ai/Base/Strategy/ChatCommandHandlerStrategy.cpp index 8d5449ef3..2e4503c18 100644 --- a/src/Ai/Base/Strategy/ChatCommandHandlerStrategy.cpp +++ b/src/Ai/Base/Strategy/ChatCommandHandlerStrategy.cpp @@ -114,6 +114,7 @@ void ChatCommandHandlerStrategy::InitTriggers(std::vector& trigger triggers.push_back(new TriggerNode("pet attack", { NextAction("pet attack", relevance) })); triggers.push_back(new TriggerNode("roll", { NextAction("roll", relevance) })); triggers.push_back(new TriggerNode("focus heal", { NextAction("focus heal targets", relevance) })); + triggers.push_back(new TriggerNode("emblems", { NextAction("emblems", relevance) })); } ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : PassTroughStrategy(botAI) @@ -138,6 +139,7 @@ ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : Pas supported.push_back("teleport"); supported.push_back("taxi"); supported.push_back("repair"); + supported.push_back("emblems"); supported.push_back("talents"); supported.push_back("spells"); supported.push_back("co"); @@ -202,8 +204,8 @@ ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : Pas supported.push_back("unlock items"); supported.push_back("unlock traded item"); supported.push_back("tame"); - supported.push_back("glyphs"); // Added for custom Glyphs - supported.push_back("glyph equip"); // Added for custom Glyphs + supported.push_back("glyphs"); + supported.push_back("glyph equip"); supported.push_back("pet"); supported.push_back("pet attack"); supported.push_back("wait for attack time");