diff --git a/zone/command.cpp b/zone/command.cpp index 83d035952..81725d064 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -433,6 +433,7 @@ int command_init(void) command_add("version", "- Display current version of EQEmu server", 0, command_version) || command_add("viewnpctype", "[npctype id] - Show info about an npctype", 100, command_viewnpctype) || command_add("viewpetition", "[petition number] - View a petition", 20, command_viewpetition) || + command_add("viewzoneloot", "[item id] - Allows you to search a zone's loot for a specific item ID. (0 shows all loot in the zone)", 80, command_viewzoneloot) || command_add("wc", "[wear slot] [material] - Sends an OP_WearChange for your target", 200, command_wc) || command_add("weather", "[0/1/2/3] (Off/Rain/Snow/Manual) - Change the weather", 80, command_weather) || command_add("who", "[search]", 20, command_who) || @@ -14106,6 +14107,115 @@ void command_network(Client *c, const Seperator *sep) } } +void command_viewzoneloot(Client *c, const Seperator *sep) +{ + std::map zone_loot_list; + auto npc_list = entity_list.GetNPCList(); + uint32 loot_amount = 0, loot_id = 1, search_item_id = 0; + if (sep->argnum == 1 && sep->IsNumber(1)) { + search_item_id = atoi(sep->arg[1]); + } else if (sep->argnum == 1 && !sep->IsNumber(1)) { + c->Message( + Chat::Yellow, + "Usage: #viewzoneloot [item id]" + ); + return; + } + for (auto npc_entity : npc_list) { + auto current_npc_item_list = npc_entity.second->GetItemList(); + zone_loot_list.insert({ npc_entity.second->GetID(), current_npc_item_list }); + } + for (auto loot_item : zone_loot_list) { + uint32 current_entity_id = loot_item.first; + auto current_item_list = loot_item.second; + auto current_npc = entity_list.GetNPCByID(current_entity_id); + std::string npc_link; + if (current_npc) { + std::string npc_name = current_npc->GetCleanName(); + uint32 instance_id = zone->GetInstanceID(); + uint32 zone_id = zone->GetZoneID(); + std::string command_link = EQ::SayLinkEngine::GenerateQuestSaylink( + fmt::format( + "#{} {} {} {} {}", + (instance_id != 0 ? "zoneinstance" : "zone"), + (instance_id != 0 ? instance_id : zone_id), + current_npc->GetX(), + current_npc->GetY(), + current_npc->GetZ() + ), + false, + "Goto" + ); + npc_link = fmt::format( + " NPC: {} (ID {}) [{}]", + npc_name, + current_entity_id, + command_link + ); + } + + for (auto current_item : current_item_list) { + if (search_item_id == 0 || current_item->item_id == search_item_id) { + EQ::SayLinkEngine linker; + linker.SetLinkType(EQ::saylink::SayLinkLootItem); + linker.SetLootData(current_item); + c->Message( + Chat::White, + fmt::format( + "{}. {} ({}){}", + loot_id, + linker.GenerateLink(), + current_item->item_id, + npc_link + ).c_str() + ); + loot_id++; + loot_amount++; + } + } + } + + + if (search_item_id != 0) { + std::string drop_string = ( + loot_amount > 0 ? + fmt::format( + "dropping in {} {}", + loot_amount, + (loot_amount > 1 ? "places" : "place") + ) : + "not dropping" + ); + c->Message( + Chat::White, + fmt::format( + "{} ({}) is {}.", + database.CreateItemLink(search_item_id), + search_item_id, + drop_string + ).c_str() + ); + } else { + std::string drop_string = ( + loot_amount > 0 ? + fmt::format( + "{} {} {}", + (loot_amount > 1 ? "items" : "item"), + (loot_amount > 1 ? "are" : "is"), + (loot_amount > 1 ? "dropping" : "not dropping") + ) : + "items are dropping" + ); + c->Message( + Chat::White, + fmt::format( + "{} {}.", + loot_amount, + drop_string + ).c_str() + ); + } +} // All new code added to command.cpp should be BEFORE this comment line. Do no append code to this file below the BOTS code block. #ifdef BOTS #include "bot_command.h" diff --git a/zone/command.h b/zone/command.h index 303e0f132..041fd8832 100644 --- a/zone/command.h +++ b/zone/command.h @@ -354,6 +354,7 @@ void command_zone(Client *c, const Seperator *sep); void command_zone_instance(Client *c, const Seperator *sep); void command_zonebootup(Client *c, const Seperator *sep); void command_zonelock(Client *c, const Seperator *sep); +void command_viewzoneloot(Client *c, const Seperator *sep); void command_zoneshutdown(Client *c, const Seperator *sep); void command_zonespawn(Client *c, const Seperator *sep); void command_zonestatus(Client *c, const Seperator *sep); diff --git a/zone/npc.h b/zone/npc.h index 995542e0d..121503215 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -198,6 +198,7 @@ public: void RemoveItem(uint32 item_id, uint16 quantity = 0, uint16 slot = 0); void CheckTrivialMinMaxLevelDrop(Mob *killer); void ClearItemList(); + inline const ItemList &GetItemList() { return itemlist; } ServerLootItem_Struct* GetItem(int slot_id); void AddCash(uint16 in_copper, uint16 in_silver, uint16 in_gold, uint16 in_platinum); void AddCash();