diff --git a/Horion/Command/Commands/GiveCommand.cpp b/Horion/Command/Commands/GiveCommand.cpp index 9612f8c9..915695bc 100644 --- a/Horion/Command/Commands/GiveCommand.cpp +++ b/Horion/Command/Commands/GiveCommand.cpp @@ -12,73 +12,149 @@ bool GiveCommand::execute(std::vector* args) { assertTrue(args->size() > 2); int itemId = 0; - char count = static_cast(assertInt(args->at(2))); + uint32_t fullCount = static_cast(assertInt(args->at(2))); + unsigned int stackCount = fullCount / 64; // Get the amount of stacks we have. + char count = fullCount % 64; // Get the amount we have left. char itemData = 0; - if (args->size() > 3) + if (args->size() > 3) { itemData = static_cast(assertInt(args->at(3))); + } try { itemId = std::stoi(args->at(1)); } catch (const std::invalid_argument&) { } + + //clientMessageF("%sDEBUG:%s Will give %d stacks!", RED, GREEN, stackCount); + //clientMessageF("%sDEBUG:%s Will give %d as a remainder!", RED, GREEN, count); + + // Give us all the stacks of the items we want. + for (unsigned int i = 0; i < stackCount; i++) { + //clientMessageF("%sDEBUG:%s Giving stack %d of items!", RED, GREEN, i + 1); + std::string tag; + bool success = false; + + if (args->size() > 4) { + std::string tag = Utils::getClipboardText(); + } + if (itemId == 0) { + TextHolder tempText(args->at(1)); + success = giveItem(64, tempText, itemData, tag); + } else { + success = giveItem(64, itemId, itemData, tag); + } + // If one of these fail. Then something went wrong. + // Return to prevent a possible spam of error messages. + if (!success) return true; + } + + // Now give us our remainder. + if (count >= 1) { + //clientMessageF("%sDEBUG:%s Giving remaining %d items!", RED, GREEN, count); + std::string tag; + bool success = false; + + if (args->size() > 4) { + std::string tag = Utils::getClipboardText(); + } + if (itemId == 0) { + TextHolder tempText(args->at(1)); + success = giveItem(count, tempText, itemData, tag); + } else { + success = giveItem(count, itemId, itemData, tag); + } + if (!success) return true; + } + + clientMessageF("%sSuccessfully gave items!", GREEN); + return true; +} - C_Inventory* inv = g_Data.getLocalPlayer()->getSupplies()->inventory; - C_ItemStack* yot = nullptr; +bool GiveCommand::giveItem(uint8_t count, int itemId, uint8_t itemData, std::string &tag) { + C_Inventory *inv = g_Data.getLocalPlayer()->getSupplies()->inventory; + C_ItemStack *itemStack = nullptr; auto transactionManager = g_Data.getLocalPlayer()->getTransactionManager(); - if (itemId == 0) { - TextHolder tempText(args->at(1)); - std::unique_ptr ItemPtr = std::make_unique(); - std::unique_ptr buffer = std::make_unique(); - C_Item*** cStack = ItemRegistry::lookUpByName(ItemPtr.get(), buffer.get(), tempText); - if (*cStack == nullptr) { - clientMessageF("%sInvalid item name!", RED); - return true; - } - yot = new C_ItemStack(***cStack, count, itemData); - } else { - std::unique_ptr ItemPtr = std::make_unique(); - C_Item*** cStack = ItemRegistry::getItemFromId(ItemPtr.get(), itemId); - if (cStack == nullptr || *cStack == nullptr || **cStack == nullptr) { - clientMessageF("%sInvalid item ID!", RED); - return true; - } - yot = new C_ItemStack(***cStack, count, itemData); + std::unique_ptr ItemPtr = std::make_unique(); + C_Item ***cStack = ItemRegistry::getItemFromId(ItemPtr.get(), itemId); + if (cStack == nullptr || *cStack == nullptr || **cStack == nullptr) { + clientMessageF("%sInvalid item ID!", RED); + return false; } + itemStack = new C_ItemStack(***cStack, count, itemData); - if (yot != nullptr) - yot->count = count; + if (itemStack != nullptr) { + itemStack->count = count; + } int slot = inv->getFirstEmptySlot(); - if (args->size() > 4) { - std::string tag = Utils::getClipboardText(); - if (tag.size() > 1 && tag.front() == MojangsonToken::COMPOUND_START.getSymbol() && tag.back() == MojangsonToken::COMPOUND_END.getSymbol()) { - yot->setUserData(std::move(Mojangson::parseTag(tag))); - } + if (tag.size() > 1 && tag.front() == MojangsonToken::COMPOUND_START.getSymbol() && tag.back() == MojangsonToken::COMPOUND_END.getSymbol()) { + //itemStack->setUserData(std::move(Mojangson::parseTag(tag))); + itemStack->fromTag(*Mojangson::parseTag(tag)); } - ItemDescriptor* desc = nullptr; - desc = new ItemDescriptor((*yot->item)->itemId, itemData); + ItemDescriptor *desc = new ItemDescriptor((*itemStack->item)->itemId, itemData); + + // If we add the second action, Only one stack will come through for some reason. + // Otherwise all stacks will come through but will be buggy till dropped or + // till the world is saved then reloaded. - C_InventoryAction* firstAction = nullptr; - C_InventoryAction* secondAction = nullptr; + C_InventoryAction *firstAction = new C_InventoryAction(slot, desc, nullptr, itemStack, nullptr, count, 507, 99999); + //C_InventoryAction *secondAction = new C_InventoryAction(slot, nullptr, desc, nullptr, itemStack, count); - firstAction = new C_InventoryAction(0, desc,nullptr,yot, nullptr,count, 507, 99999); - secondAction = new C_InventoryAction(slot, nullptr, desc,nullptr, yot,count); + transactionManager->addInventoryAction(*firstAction); + //transactionManager->addInventoryAction(*secondAction); - //firstAction = new C_InventoryAction(0,yot, nullptr, 507, 99999); - //secondAction = new C_InventoryAction(slot, nullptr, yot); + delete firstAction; + //delete secondAction; + delete desc; + + inv->addItemToFirstEmptySlot(itemStack); + return true; +} + +bool GiveCommand::giveItem(uint8_t count, TextHolder &text, uint8_t itemData, std::string &tag) { + C_Inventory *inv = g_Data.getLocalPlayer()->getSupplies()->inventory; + C_ItemStack *itemStack = nullptr; + auto transactionManager = g_Data.getLocalPlayer()->getTransactionManager(); + + std::unique_ptr ItemPtr = std::make_unique(); + std::unique_ptr buffer = std::make_unique(); + C_Item ***cStack = ItemRegistry::lookUpByName(ItemPtr.get(), buffer.get(), text); + if (*cStack == nullptr) { + clientMessageF("%sInvalid item name!", RED); + return false; + } + itemStack = new C_ItemStack(***cStack, count, itemData); + + if (itemStack != nullptr) { + itemStack->count = count; + } + + int slot = inv->getFirstEmptySlot(); + + if (tag.size() > 1 && tag.front() == MojangsonToken::COMPOUND_START.getSymbol() && tag.back() == MojangsonToken::COMPOUND_END.getSymbol()) { + //itemStack->setUserData(std::move(Mojangson::parseTag(tag))); + itemStack->fromTag(*Mojangson::parseTag(tag)); + } + + ItemDescriptor *desc = new ItemDescriptor((*itemStack->item)->itemId, itemData); + + // If we add the second action, Only one stack will come through for some reason. + // Otherwise all stacks will come through but will be buggy till dropped or + // till the world is saved then reloaded. + + C_InventoryAction *firstAction = new C_InventoryAction(slot, desc, nullptr, itemStack, nullptr, count, 507, 99999); + //C_InventoryAction *secondAction = new C_InventoryAction(slot, nullptr, desc, nullptr, itemStack, count); transactionManager->addInventoryAction(*firstAction); - transactionManager->addInventoryAction(*secondAction); + //transactionManager->addInventoryAction(*secondAction); delete firstAction; - delete secondAction; + //delete secondAction; delete desc; - inv->addItemToFirstEmptySlot(yot); - - clientMessageF("%sSuccessfully given item!", GREEN); + inv->addItemToFirstEmptySlot(itemStack); return true; } diff --git a/Horion/Command/Commands/GiveCommand.h b/Horion/Command/Commands/GiveCommand.h index f9cf9fd8..7f071491 100644 --- a/Horion/Command/Commands/GiveCommand.h +++ b/Horion/Command/Commands/GiveCommand.h @@ -7,4 +7,7 @@ class GiveCommand : public IMCCommand { // Inherited via IMCCommand virtual bool execute(std::vector* args) override; +private: + bool giveItem(uint8_t count, int itemId, uint8_t itemData, std::string &tag); + bool giveItem(uint8_t count, TextHolder &text, uint8_t itemData, std::string &tag); };