diff options
author | Shauren <shauren.trinity@gmail.com> | 2024-09-17 15:35:20 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2024-09-17 15:35:20 +0200 |
commit | 1f60e76b7f157af6a24fa3c962b59f3391b21e75 (patch) | |
tree | 3ca7f084b56c54c1d1fa91669255fc62a4a00070 | |
parent | 2639bf25e77ddb5f46c1dc9ed1d992cd33026ade (diff) |
Core/Commands: Refactor .additem to use typed args
-rw-r--r-- | src/server/scripts/Commands/cs_misc.cpp | 249 |
1 files changed, 46 insertions, 203 deletions
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index fae41f2d995..8275a80d887 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1153,74 +1153,57 @@ public: return true; } - static bool HandleAddItemCommand(ChatHandler* handler, char const* args) + static bool HandleAddItemCommandHelper(ChatHandler* handler, Player* player, Player* playerTarget, + Variant<Hyperlink<item>, uint32, std::string_view> const& itemArg, Optional<int32> countArg, + Optional<std::string_view> const& bonusListIdString, Optional<uint8> itemContextArg) { - if (!*args) - return false; - uint32 itemId = 0; - - if (args[0] == '[') // [name] manual form - { - char const* itemNameStr = strtok((char*)args, "]"); - - if (itemNameStr && itemNameStr[0]) + if (Hyperlink<::item> const* itemLinkData = std::get_if<Hyperlink<::item>>(&itemArg)) + itemId = (*itemLinkData)->Item->GetId(); + else if (uint32 const* itemIdPtr = std::get_if<uint32>(&itemArg)) + itemId = *itemIdPtr; + else if (std::string_view const* itemNameText = std::get_if<std::string_view>(&itemArg)) + { + std::string itemName(*itemNameText); + if (itemName.starts_with('[')) + itemName.erase(0, 1); + if (itemName.ends_with(']')) + itemName.pop_back(); + + auto itr = std::ranges::find_if(sItemSparseStore, [&itemName](ItemSparseEntry const* sparse) { - std::string itemName = itemNameStr+1; - auto itr = std::find_if(sItemSparseStore.begin(), sItemSparseStore.end(), [&itemName](ItemSparseEntry const* sparse) - { - for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1)) - if (itemName == sparse->Display[i]) - return true; - return false; - }); - - if (itr == sItemSparseStore.end()) - { - handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemNameStr+1); - handler->SetSentErrorMessage(true); - return false; - } - - itemId = itr->ID; - } - else + for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1)) + if (itemName == sparse->Display[i]) + return true; return false; - } - else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r - { - char const* id = handler->extractKeyFromLink((char*)args, "Hitem"); - if (!id) + }); + + if (itr == sItemSparseStore.end()) + { + handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemName.c_str()); + handler->SetSentErrorMessage(true); return false; + } - itemId = Trinity::StringTo<uint32>(id).value_or(0); + itemId = itr->ID; } - char const* ccount = strtok(nullptr, " "); - - int32 count = 1; - - if (ccount) - count = strtol(ccount, nullptr, 10); - + int32 count = countArg.value_or(1); if (count == 0) count = 1; std::vector<int32> bonusListIDs; - char const* bonuses = strtok(nullptr, " "); - - char const* context = strtok(nullptr, " "); // semicolon separated bonuslist ids (parse them after all arguments are extracted by strtok!) - if (bonuses) - for (std::string_view token : Trinity::Tokenize(bonuses, ';', false)) + if (bonusListIdString) + for (std::string_view token : Trinity::Tokenize(*bonusListIdString, ';', false)) if (Optional<int32> bonusListId = Trinity::StringTo<int32>(token); bonusListId && *bonusListId) bonusListIDs.push_back(*bonusListId); ItemContext itemContext = ItemContext::NONE; - if (context) + if (itemContextArg) { - itemContext = ItemContext(Trinity::StringTo<uint8>(context).value_or(0)); + itemContext = ItemContext(*itemContextArg); if (itemContext < ItemContext::Max) { std::vector<int32> contextBonuses = ItemBonusMgr::GetBonusListsForItem(itemId, itemContext); @@ -1228,11 +1211,6 @@ public: } } - Player* player = handler->GetSession()->GetPlayer(); - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - playerTarget = player; - ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId); if (!itemTemplate) { @@ -1307,164 +1285,29 @@ public: return true; } - static bool HandleAddItemToCommand(ChatHandler* handler, char const* args) + static bool HandleAddItemCommand(ChatHandler* handler, + Variant<Hyperlink<::item>, uint32, std::string_view> const& item, Optional<int32> countArg, + Optional<std::string_view> const& bonusListIdString, Optional<uint8> itemContextArg) { - if (!*args) - return false; - Player* player = handler->GetSession()->GetPlayer(); - Player* playerTarget = nullptr; - if (!handler->extractPlayerTarget((char*)args, &playerTarget)) - { - handler->SetSentErrorMessage(true); - return false; - } + Player* playerTarget = handler->getSelectedPlayerOrSelf(); - char* tailArgs = strtok(nullptr, ""); - if (!tailArgs) - return false; - - uint32 itemId = 0; - - if (tailArgs[0] == '[') // [name] manual form - { - char const* itemNameStr = strtok(tailArgs, "]"); - - if (itemNameStr && itemNameStr[0]) - { - std::string itemName = itemNameStr+1; - auto itr = std::find_if(sItemSparseStore.begin(), sItemSparseStore.end(), [&itemName](ItemSparseEntry const* sparse) - { - for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1)) - if (itemName == sparse->Display[i]) - return true; - return false; - }); - - if (itr == sItemSparseStore.end()) - { - handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemNameStr+1); - handler->SetSentErrorMessage(true); - return false; - } - - itemId = itr->ID; - } - else - return false; - } - else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r - { - char const* id = handler->extractKeyFromLink(tailArgs, "Hitem"); - if (!id) - return false; - - itemId = Trinity::StringTo<uint32>(id).value_or(0); - } - - char const* ccount = strtok(nullptr, " "); - - int32 count = 1; - - if (ccount) - count = strtol(ccount, nullptr, 10); - - if (count == 0) - count = 1; - - std::vector<int32> bonusListIDs; - char const* bonuses = strtok(nullptr, " "); - - char const* context = strtok(nullptr, " "); - - // semicolon separated bonuslist ids (parse them after all arguments are extracted by strtok!) - if (bonuses) - for (std::string_view token : Trinity::Tokenize(bonuses, ';', false)) - if (Optional<int32> bonusListId = Trinity::StringTo<int32>(token); bonusListId && *bonusListId) - bonusListIDs.push_back(*bonusListId); - - ItemContext itemContext = ItemContext::NONE; - if (context) - { - itemContext = ItemContext(Trinity::StringTo<uint8>(context).value_or(0)); - if (itemContext < ItemContext::Max) - { - std::vector<int32> contextBonuses = ItemBonusMgr::GetBonusListsForItem(itemId, itemContext); - bonusListIDs.insert(bonusListIDs.begin(), contextBonuses.begin(), contextBonuses.end()); - } - } - - ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId); - if (!itemTemplate) - { - handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); - handler->SetSentErrorMessage(true); - return false; - } - - // Subtract - if (count < 0) - { - uint32 destroyedItemCount = playerTarget->DestroyItemCount(itemId, -count, true, false); - - if (destroyedItemCount > 0) - { - // output the amount of items successfully destroyed - handler->PSendSysMessage(LANG_REMOVEITEM, itemId, destroyedItemCount, handler->GetNameLink(playerTarget).c_str()); - - // check to see if we were unable to destroy all of the amount requested. - uint32 unableToDestroyItemCount = -count - destroyedItemCount; - if (unableToDestroyItemCount > 0) - { - // output message for the amount of items we couldn't destroy - handler->PSendSysMessage(LANG_REMOVEITEM_FAILURE, itemId, unableToDestroyItemCount, handler->GetNameLink(playerTarget).c_str()); - } - } - else - { - // failed to destroy items of the amount requested - handler->PSendSysMessage(LANG_REMOVEITEM_FAILURE, itemId, -count, handler->GetNameLink(playerTarget).c_str()); - } - - return true; - } - - // Adding items - uint32 noSpaceForCount = 0; - - // check space and find places - ItemPosCountVec dest; - InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount); - if (msg != EQUIP_ERR_OK) // convert to possible store amount - count -= noSpaceForCount; + return HandleAddItemCommandHelper(handler, player, playerTarget, item, countArg, bonusListIdString, itemContextArg); + } - if (count == 0 || dest.empty()) // can't add any + static bool HandleAddItemToCommand(ChatHandler* handler, PlayerIdentifier const& target, + Variant<Hyperlink<::item>, uint32, std::string_view> const& item, Optional<int32> countArg, + Optional<std::string_view> const& bonusListIdString, Optional<uint8> itemContextArg) + { + Player* player = handler->GetSession()->GetPlayer(); + if (!target.IsConnected()) { - handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); handler->SetSentErrorMessage(true); return false; } - Item* item = playerTarget->StoreNewItem(dest, itemId, true, GenerateItemRandomBonusListId(itemId), GuidSet(), itemContext, - bonusListIDs.empty() ? nullptr : &bonusListIDs); - - // remove binding (let GM give it to another player later) - if (player == playerTarget) - for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) - if (Item* item1 = player->GetItemByPos(itr->pos)) - item1->SetBinding(false); - - if (count > 0 && item) - { - player->SendNewItem(item, count, false, true); - if (player != playerTarget) - playerTarget->SendNewItem(item, count, true, false); - } - - if (noSpaceForCount > 0) - handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); - - return true; + return HandleAddItemCommandHelper(handler, player, target.GetConnectedPlayer(), item, countArg, bonusListIdString, itemContextArg); } static bool HandleAddItemSetCommand(ChatHandler* handler, Variant<Hyperlink<itemset>, uint32> itemSetId, Optional<std::string_view> bonuses, Optional<uint8> context) |