[Commands] Add #viewzoneloot [item id] command. (#1382)

* [Commands] Add #viewzoneloot [item id] command.
- Allows GMs to search for a specific item across all the loot currently available on the spawned NPCs in the zone.
- Specifying item ID 0 will allow GMs to see all the droppable items, I tested in Sanctus Seru (a huge zone) and it sent approximately 1,200 messages, which didn't lag or desync my client.

* Adjustments.

* Adjustments.
This commit is contained in:
Alex 2021-06-12 12:32:36 -04:00 committed by GitHub
parent 00dd7c2b71
commit 6e12d2fd49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 112 additions and 0 deletions

View File

@ -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<uint32,ItemList> 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"

View File

@ -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);

View File

@ -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();