From 6b219dc0e14a6bac60179fc42946af8bb63a1262 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Mon, 15 Nov 2021 09:51:21 +0100 Subject: [PATCH] feat(Scripts/Commands): implement new command: `.inventory count` (#9139) - Closes #8845 --- .../rev_1636656798364802400.sql | 6 + src/server/scripts/Commands/cs_misc.cpp | 143 +++++++++++++++++- 2 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1636656798364802400.sql diff --git a/data/sql/updates/pending_db_world/rev_1636656798364802400.sql b/data/sql/updates/pending_db_world/rev_1636656798364802400.sql new file mode 100644 index 000000000..5d1dba592 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1636656798364802400.sql @@ -0,0 +1,6 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1636656798364802400'); + +DELETE FROM `command` WHERE `name` IN ('inventory','inventory count'); +INSERT INTO `command` VALUES +('inventory',1,'Syntax: .inventory $subcommand \nType .inventory to see the list of possible subcommands or .help inventory $subcommand to see info on subcommands'), +('inventory count',1,'Syntax: .inventory count $playerName or $plaerGuid \nCount free slots in bags divided into different bag types.'); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index aef4a2569..f8fd1a4f3 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -59,6 +59,45 @@ static std::array itemQualityToString = "all" } }; +static std::array bagSpecsToString = +{ { + "normal", + "soul", + "herb", + "enchanting", + "engineering", + "gem", + "mining", + "leatherworking", + "inscription" +} }; + +constexpr uint32 bagSpecsColors[MAX_ITEM_SUBCLASS_CONTAINER] = +{ + 0xfff0de18, //YELLOW - Normal + 0xffa335ee, //PURPLE - Souls + 0xff1eff00, //GREEN - Herb + 0xffe37166, //PINK - Enchanting + 0xffa68b30, //BROWN - Engineering + 0xff0070dd, //BLUE - Gem + 0xffc1c8c9, //GREY - Mining + 0xfff5a925, //ORANGE - Leatherworking + 0xff54504f //DARK GREY - Inscription +}; + +static std::array bagSpecsColorToString = +{ { + "normal", + "soul", + "herb", + "enchanting", + "engineering", + "gem", + "mining", + "leatherworking", + "inscription" +} }; + class misc_commandscript : public CommandScript { public: @@ -89,12 +128,16 @@ public: }; static ChatCommandTable gearCommandTable = { - { "repair", SEC_GAMEMASTER, false, &HandleGearRepairCommand, "" }, - { "stats", SEC_PLAYER, false, &HandleGearStatsCommand, "" } + { "repair", SEC_GAMEMASTER, false, &HandleGearRepairCommand, "" }, + { "stats", SEC_PLAYER, false, &HandleGearStatsCommand, "" } }; static ChatCommandTable bagsCommandTable = { - { "clear", SEC_GAMEMASTER, false, &HandleBagsClearCommand, "" }, + { "clear", SEC_GAMEMASTER, false, &HandleBagsClearCommand, "" }, + }; + static ChatCommandTable inventoryCommandTable = + { + { "count", HandleInventoryCountCommand, SEC_MODERATOR, Console::No } }; static ChatCommandTable commandTable = { @@ -153,6 +196,7 @@ public: { "mailbox", SEC_MODERATOR, false, &HandleMailBoxCommand, "" }, { "string", SEC_GAMEMASTER, false, &HandleStringCommand, "" }, { "bags", SEC_GAMEMASTER, false, nullptr, "", bagsCommandTable }, + { "inventory", SEC_MODERATOR, false, nullptr, "", inventoryCommandTable } }; return commandTable; } @@ -3584,6 +3628,99 @@ public: return true; }; + + static bool HandleInventoryCountCommand(ChatHandler* handler, Optional player) + { + if (!player) + player = PlayerIdentifier::FromTargetOrSelf(handler); + + if (!player) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = player->GetConnectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + std::array freeSlotsInBags = { }; + uint32 freeSlotsForBags = 0; + bool haveFreeSlot = false; + // Check backpack + for (uint8 slot = INVENTORY_SLOT_ITEM_START; slot < INVENTORY_SLOT_ITEM_END; ++slot) + { + if (!target->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) + { + haveFreeSlot = true; + ++freeSlotsInBags[ITEM_SUBCLASS_CONTAINER]; + } + } + + // Check bags + for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + if (Bag* bag = target->GetBagByPos(i)) + { + if (ItemTemplate const* bagTemplate = bag->GetTemplate()) + { + if (bagTemplate->Class == ITEM_CLASS_CONTAINER || bagTemplate->Class == ITEM_CLASS_QUIVER) + { + haveFreeSlot = true; + freeSlotsInBags[bagTemplate->SubClass] += bag->GetFreeSlots(); + } + } + } + else + { + ++freeSlotsForBags; + } + } + + std::ostringstream str; + if (haveFreeSlot) + { + str << "Player " << target->GetName() << " have "; + bool initialize = true; + for (uint8 i = ITEM_SUBCLASS_CONTAINER; i < MAX_ITEM_SUBCLASS_CONTAINER; ++i) + { + if (uint32 freeSlots = freeSlotsInBags[i]) + { + std::string bagSpecString = bagSpecsToString[i]; + if (!initialize) + { + str << ", "; + } + + str << "|c"; + str << std::hex << bagSpecsColors[i] << std::dec; + str << freeSlots << " in " << bagSpecString << " bags|r"; + + initialize = false; + } + } + } + else + { + str << "Player " << target->GetName() << " does not have free slots in their bags"; + } + + if (freeSlotsForBags) + { + str << " and also has " << freeSlotsForBags << " free slots for bags"; + } + + str << "."; + + handler->SendSysMessage(str.str().c_str()); + + return true; + } }; void AddSC_misc_commandscript()