diff --git a/common/repositories/command_subsettings_repository.h b/common/repositories/command_subsettings_repository.h index 902109717..1eece3df4 100644 --- a/common/repositories/command_subsettings_repository.h +++ b/common/repositories/command_subsettings_repository.h @@ -120,6 +120,7 @@ public: {.parent_command = "set", .sub_command = "title_suffix", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "titlesuffix"}, {.parent_command = "set", .sub_command = "weather", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "weather"}, {.parent_command = "set", .sub_command = "zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zclip|zcolor|zheader|zonelock|zsafecoords|zsky|zunderworld"}, + {.parent_command = "show", .sub_command = "aas", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showaas"}, {.parent_command = "show", .sub_command = "aa_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showaapoints|showaapts"}, {.parent_command = "show", .sub_command = "aggro", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "aggro"}, {.parent_command = "show", .sub_command = "buffs", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showbuffs"}, diff --git a/zone/aa.cpp b/zone/aa.cpp index 4f9d6388f..b2affb44a 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -2207,3 +2207,97 @@ bool Client::HasAlreadyPurchasedRank(AA::Rank* rank) { return false; } + +void Client::ListPurchasedAAs(Client *to, std::string search_criteria) +{ + if (!to) { + return; + } + + std::map client_aa_ranks; + + for (auto &aa : zone->aa_abilities) { + AA::Ability *ability = aa.second.get(); + + AA::Rank *rank = ability->first; + while (rank) { + if (!CanUseAlternateAdvancementRank(rank)) { + break; + } + + if (HasAlreadyPurchasedRank(rank)) { + const std::string aa_name = zone->GetAAName(rank->id); + if ( + search_criteria.empty() || + Strings::Contains( + Strings::ToLower(aa_name), + Strings::ToLower(search_criteria) + ) + ) { + if (client_aa_ranks.find(aa_name) == client_aa_ranks.end()) { + client_aa_ranks[aa_name] = 1; + } else { + client_aa_ranks[aa_name]++; + } + } + } + + rank = rank->next; + } + } + + if (client_aa_ranks.empty()) { + to->Message( + Chat::White, + fmt::format( + "{} {} no purchased AAs{}.", + to->GetTargetDescription(this, TargetDescriptionType::UCYou), + this == to ? "have" : "has", + ( + !search_criteria.empty() ? + fmt::format( + " matching '{}'", + search_criteria + ) : + "" + ) + ).c_str() + ); + return; + } + + int aa_number = 1; + + for (const auto &aa : client_aa_ranks) { + to->Message( + Chat::White, + fmt::format( + "{}. {} (Rank {})", + aa_number, + aa.first, + aa.second + ).c_str() + ); + + aa_number++; + } + + to->Message( + Chat::White, + fmt::format( + "{} {} {} purchased AA{}{}.", + to->GetTargetDescription(this, TargetDescriptionType::UCYou), + this == to ? "have" : "has", + client_aa_ranks.size(), + client_aa_ranks.size() > 1 ? "s" : "", + ( + !search_criteria.empty() ? + fmt::format( + " matching '{}'", + search_criteria + ) : + "" + ) + ).c_str() + ); +} diff --git a/zone/client.h b/zone/client.h index c71f21ef3..367263579 100644 --- a/zone/client.h +++ b/zone/client.h @@ -908,6 +908,7 @@ public: void AutoGrantAAPoints(); void GrantAllAAPoints(uint8 unlock_level = 0); bool HasAlreadyPurchasedRank(AA::Rank* rank); + void ListPurchasedAAs(Client *to, std::string search_criteria = std::string()); bool SendGMCommand(std::string message, bool ignore_status = false); diff --git a/zone/gm_commands/show.cpp b/zone/gm_commands/show.cpp index fdea2b3e0..756eb9d93 100755 --- a/zone/gm_commands/show.cpp +++ b/zone/gm_commands/show.cpp @@ -1,4 +1,5 @@ #include "../client.h" +#include "show/aas.cpp" #include "show/aa_points.cpp" #include "show/aggro.cpp" #include "show/buffs.cpp" @@ -56,6 +57,7 @@ void command_show(Client *c, const Seperator *sep) }; std::vector commands = { + Cmd{.cmd = "aas", .u = "aas", .fn = ShowAAs, .a = {"#showaas"}}, Cmd{.cmd = "aa_points", .u = "aa_points", .fn = ShowAAPoints, .a = {"#showaapoints", "#showaapts"}}, Cmd{.cmd = "aggro", .u = "aggro [Distance] [-v] (-v is verbose Faction Information)", .fn = ShowAggro, .a = {"#aggro"}}, Cmd{.cmd = "buffs", .u = "buffs", .fn = ShowBuffs, .a = {"#showbuffs"}}, diff --git a/zone/gm_commands/show/aas.cpp b/zone/gm_commands/show/aas.cpp new file mode 100644 index 000000000..f631ac474 --- /dev/null +++ b/zone/gm_commands/show/aas.cpp @@ -0,0 +1,13 @@ +#include "../../client.h" + +void ShowAAs(Client *c, const Seperator *sep) +{ + Client *t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const std::string& search_criteria = sep->argnum >= 2 ? sep->argplus[2] : std::string(); + + t->ListPurchasedAAs(c, search_criteria); +}