diff --git a/Minecraft.World/Containers/AbstractContainerMenu.cpp b/Minecraft.World/Containers/AbstractContainerMenu.cpp index b084acc5a..8da2a07af 100644 --- a/Minecraft.World/Containers/AbstractContainerMenu.cpp +++ b/Minecraft.World/Containers/AbstractContainerMenu.cpp @@ -1,6 +1,7 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.entity.player.h" #include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.level.redstone.h" #include "Slot.h" #include "AbstractContainerMenu.h" @@ -8,40 +9,31 @@ // to initialise the member variables // TODO Make sure all derived classes also call this AbstractContainerMenu::AbstractContainerMenu() { - lastSlots = new std::vector >(); - slots = new std::vector(); containerId = 0; changeUid = 0; - m_bNeedsRendered = false; - containerListeners = new std::vector(); + quickcraftType = -1; + quickcraftStatus = 0; + + m_bNeedsRendered = false; } AbstractContainerMenu::~AbstractContainerMenu() { - delete lastSlots; - for (unsigned int i = 0; i < slots->size(); i++) { - delete slots->at(i); + for (unsigned int i = 0; i < slots.size(); i++) { + delete slots.at(i); } - delete slots; - delete containerListeners; } Slot* AbstractContainerMenu::addSlot(Slot* slot) { - slot->index = (int)slots->size(); - slots->push_back(slot); - lastSlots->push_back(nullptr); + slot->index = (int)slots.size(); + slots.push_back(slot); + lastSlots.push_back(nullptr); return slot; } void AbstractContainerMenu::addSlotListener(ContainerListener* listener) { - // TODO 4J Add exceptions - /* - if (containerListeners->contains(listener)) { - throw new IllegalArgumentException("Listener already listening"); - } - */ - containerListeners->push_back(listener); + containerListeners.push_back(listener); std::vector >* items = getItems(); listener->refreshContainer(this, items); @@ -49,34 +41,46 @@ void AbstractContainerMenu::addSlotListener(ContainerListener* listener) { broadcastChanges(); } +void AbstractContainerMenu::removeSlotListener(ContainerListener* listener) { + AUTO_VAR(it, find(containerListeners.begin(), containerListeners.end(), + listener)); + if (it != containerListeners.end()) containerListeners.erase(it); +} + std::vector >* AbstractContainerMenu::getItems() { std::vector >* items = new std::vector >(); - AUTO_VAR(itEnd, slots->end()); - for (AUTO_VAR(it, slots->begin()); it != itEnd; it++) { + AUTO_VAR(itEnd, slots.end()); + for (AUTO_VAR(it, slots.begin()); it != itEnd; it++) { items->push_back((*it)->getItem()); } return items; } void AbstractContainerMenu::sendData(int id, int value) { - AUTO_VAR(itEnd, containerListeners->end()); - for (AUTO_VAR(it, containerListeners->begin()); it != itEnd; it++) { + AUTO_VAR(itEnd, containerListeners.end()); + for (AUTO_VAR(it, containerListeners.begin()); it != itEnd; it++) { (*it)->setContainerData(this, id, value); } } void AbstractContainerMenu::broadcastChanges() { - for (unsigned int i = 0; i < slots->size(); i++) { - std::shared_ptr current = slots->at(i)->getItem(); - std::shared_ptr expected = lastSlots->at(i); + for (unsigned int i = 0; i < slots.size(); i++) { + std::shared_ptr current = slots.at(i)->getItem(); + std::shared_ptr expected = lastSlots.at(i); if (!ItemInstance::matches(expected, current)) { - expected = current == NULL ? nullptr : current->copy(); - (*lastSlots)[i] = expected; + // 4J Stu - Added 0 count check. There is a bug in the Java with + // anvils that means this broadcast happens while we are in the + // middle of quickmoving, and before the slot properly gets set to + // null + expected = (current == NULL || current->count == 0) + ? nullptr + : current->copy(); + lastSlots[i] = expected; m_bNeedsRendered = true; - AUTO_VAR(itEnd, containerListeners->end()); - for (AUTO_VAR(it, containerListeners->begin()); it != itEnd; it++) { + AUTO_VAR(itEnd, containerListeners.end()); + for (AUTO_VAR(it, containerListeners.begin()); it != itEnd; it++) { (*it)->slotChanged(this, i, expected); } } @@ -87,12 +91,12 @@ bool AbstractContainerMenu::needsRendered() { bool needsRendered = m_bNeedsRendered; m_bNeedsRendered = false; - for (unsigned int i = 0; i < slots->size(); i++) { - std::shared_ptr current = slots->at(i)->getItem(); - std::shared_ptr expected = lastSlots->at(i); + for (unsigned int i = 0; i < slots.size(); i++) { + std::shared_ptr current = slots.at(i)->getItem(); + std::shared_ptr expected = lastSlots.at(i); if (!ItemInstance::matches(expected, current)) { expected = current == NULL ? nullptr : current->copy(); - (*lastSlots)[i] = expected; + lastSlots[i] = expected; needsRendered = true; } } @@ -107,8 +111,8 @@ bool AbstractContainerMenu::clickMenuButton(std::shared_ptr player, Slot* AbstractContainerMenu::getSlotFor(std::shared_ptr c, int index) { - AUTO_VAR(itEnd, slots->end()); - for (AUTO_VAR(it, slots->begin()); it != itEnd; it++) { + AUTO_VAR(itEnd, slots.end()); + for (AUTO_VAR(it, slots.begin()); it != itEnd; it++) { Slot* slot = *it; // slots->at(i); if (slot->isAt(c, index)) { return slot; @@ -117,11 +121,11 @@ Slot* AbstractContainerMenu::getSlotFor(std::shared_ptr c, return NULL; } -Slot* AbstractContainerMenu::getSlot(int index) { return slots->at(index); } +Slot* AbstractContainerMenu::getSlot(int index) { return slots.at(index); } std::shared_ptr AbstractContainerMenu::quickMoveStack( std::shared_ptr player, int slotIndex) { - Slot* slot = slots->at(slotIndex); + Slot* slot = slots.at(slotIndex); if (slot != NULL) { return slot->getItem(); } @@ -129,16 +133,91 @@ std::shared_ptr AbstractContainerMenu::quickMoveStack( } std::shared_ptr AbstractContainerMenu::clicked( - int slotIndex, int buttonNum, int clickType, - std::shared_ptr player) { + int slotIndex, int buttonNum, int clickType, std::shared_ptr player, + bool looped) // 4J Added looped param +{ std::shared_ptr clickedEntity = nullptr; std::shared_ptr inventory = player->inventory; - if ((clickType == CLICK_PICKUP || clickType == CLICK_QUICK_MOVE) && - (buttonNum == 0 || buttonNum == 1)) { - if (slotIndex == CLICKED_OUTSIDE) { + if (clickType == CLICK_QUICK_CRAFT) { + int expectedStatus = quickcraftStatus; + quickcraftStatus = getQuickcraftHeader(buttonNum); + + if ((expectedStatus != QUICKCRAFT_HEADER_CONTINUE || + quickcraftStatus != QUICKCRAFT_HEADER_END) && + expectedStatus != quickcraftStatus) { + resetQuickCraft(); + } else if (inventory->getCarried() == NULL) { + resetQuickCraft(); + } else if (quickcraftStatus == QUICKCRAFT_HEADER_START) { + quickcraftType = getQuickcraftType(buttonNum); + + if (isValidQuickcraftType(quickcraftType)) { + quickcraftStatus = QUICKCRAFT_HEADER_CONTINUE; + quickcraftSlots.clear(); + } else { + resetQuickCraft(); + } + } else if (quickcraftStatus == QUICKCRAFT_HEADER_CONTINUE) { + Slot* slot = slots.at(slotIndex); + + if (slot != NULL && + canItemQuickReplace(slot, inventory->getCarried(), true) && + slot->mayPlace(inventory->getCarried()) && + inventory->getCarried()->count > quickcraftSlots.size() && + canDragTo(slot)) { + quickcraftSlots.insert(slot); + } + } else if (quickcraftStatus == QUICKCRAFT_HEADER_END) { + if (!quickcraftSlots.empty()) { + std::shared_ptr source = + inventory->getCarried()->copy(); + int remaining = inventory->getCarried()->count; + + for (AUTO_VAR(it, quickcraftSlots.begin()); + it != quickcraftSlots.end(); ++it) { + Slot* slot = *it; + if (slot != NULL && + canItemQuickReplace(slot, inventory->getCarried(), + true) && + slot->mayPlace(inventory->getCarried()) && + inventory->getCarried()->count >= + quickcraftSlots.size() && + canDragTo(slot)) { + std::shared_ptr copy = source->copy(); + int carry = + slot->hasItem() ? slot->getItem()->count : 0; + getQuickCraftSlotCount(&quickcraftSlots, quickcraftType, + copy, carry); + + if (copy->count > copy->getMaxStackSize()) + copy->count = copy->getMaxStackSize(); + if (copy->count > slot->getMaxStackSize()) + copy->count = slot->getMaxStackSize(); + + remaining -= copy->count - carry; + slot->set(copy); + } + } + + source->count = remaining; + if (source->count <= 0) { + source = nullptr; + } + inventory->setCarried(source); + } + + resetQuickCraft(); + } else { + resetQuickCraft(); + } + } else if (quickcraftStatus != QUICKCRAFT_HEADER_START) { + resetQuickCraft(); + } else if ((clickType == CLICK_PICKUP || clickType == CLICK_QUICK_MOVE) && + (buttonNum == 0 || buttonNum == 1)) { + if (slotIndex == SLOT_CLICKED_OUTSIDE) { if (inventory->getCarried() != NULL) { - if (slotIndex == CLICKED_OUTSIDE) { + if (slotIndex == SLOT_CLICKED_OUTSIDE) { if (buttonNum == 0) { player->drop(inventory->getCarried()); inventory->setCarried(nullptr); @@ -151,23 +230,37 @@ std::shared_ptr AbstractContainerMenu::clicked( } } } else if (clickType == CLICK_QUICK_MOVE) { - Slot* slot = slots->at(slotIndex); + if (slotIndex < 0) return nullptr; + Slot* slot = slots.at(slotIndex); if (slot != NULL && slot->mayPickup(player)) { std::shared_ptr piiClicked = quickMoveStack(player, slotIndex); if (piiClicked != NULL) { - // int oldSize = piiClicked->count; // 4J - Commented 1.8.2 - // and replaced with below int oldType = piiClicked->id; - clickedEntity = piiClicked->copy(); + // 4J Stu - We ignore the return value for loopClicks, so + // don't make a copy + if (!looped) { + clickedEntity = piiClicked->copy(); + } + + // 4J Stu - Remove the reference to this before we start a + // recursive loop + piiClicked = nullptr; if (slot != NULL) { if (slot->getItem() != NULL && slot->getItem()->id == oldType) { - // 4J Stu - Brought forward loopClick from 1.2 to - // fix infinite recursion bug in creative - loopClick(slotIndex, buttonNum, true, player); + if (looped) { + // Return a non-null value to indicate that we + // want to loop more + clickedEntity = std::shared_ptr( + new ItemInstance(0, 1, 0)); + } else { + // 4J Stu - Brought forward loopClick from 1.2 + // to fix infinite recursion bug in creative + loopClick(slotIndex, buttonNum, true, player); + } } } } @@ -175,7 +268,7 @@ std::shared_ptr AbstractContainerMenu::clicked( } else { if (slotIndex < 0) return nullptr; - Slot* slot = slots->at(slotIndex); + Slot* slot = slots.at(slotIndex); if (slot != NULL) { std::shared_ptr clicked = slot->getItem(); std::shared_ptr carried = inventory->getCarried(); @@ -190,7 +283,9 @@ std::shared_ptr AbstractContainerMenu::clicked( if (c > slot->getMaxStackSize()) { c = slot->getMaxStackSize(); } - slot->set(carried->remove(c)); + if (carried->count >= c) { + slot->set(carried->remove(c)); + } if (carried->count == 0) { inventory->setCarried(nullptr); } @@ -268,7 +363,7 @@ std::shared_ptr AbstractContainerMenu::clicked( } } } else if (clickType == CLICK_SWAP && buttonNum >= 0 && buttonNum < 9) { - Slot* slot = slots->at(slotIndex); + Slot* slot = slots.at(slotIndex); if (slot->mayPickup(player)) { std::shared_ptr current = inventory->getItem(buttonNum); @@ -304,21 +399,78 @@ std::shared_ptr AbstractContainerMenu::clicked( } } else if (clickType == CLICK_CLONE && player->abilities.instabuild && inventory->getCarried() == NULL && slotIndex >= 0) { - Slot* slot = slots->at(slotIndex); + Slot* slot = slots.at(slotIndex); if (slot != NULL && slot->hasItem()) { std::shared_ptr copy = slot->getItem()->copy(); copy->count = copy->getMaxStackSize(); inventory->setCarried(copy); } + } else if (clickType == CLICK_THROW && inventory->getCarried() == NULL && + slotIndex >= 0) { + Slot* slot = slots.at(slotIndex); + if (slot != NULL && slot->hasItem() && slot->mayPickup(player)) { + std::shared_ptr item = + slot->remove(buttonNum == 0 ? 1 : slot->getItem()->count); + slot->onTake(player, item); + player->drop(item); + } + } else if (clickType == CLICK_PICKUP_ALL && slotIndex >= 0) { + Slot* slot = slots.at(slotIndex); + std::shared_ptr carried = inventory->getCarried(); + + if (carried != NULL && + (slot == NULL || !slot->hasItem() || !slot->mayPickup(player))) { + int start = buttonNum == 0 ? 0 : slots.size() - 1; + int step = buttonNum == 0 ? 1 : -1; + + for (int pass = 0; pass < 2; pass++) { + // In the first pass, we only get partial stacks. + for (int i = start; i >= 0 && i < slots.size() && + carried->count < carried->getMaxStackSize(); + i += step) { + Slot* target = slots.at(i); + + if (target->hasItem() && + canItemQuickReplace(target, carried, true) && + target->mayPickup(player) && + canTakeItemForPickAll(carried, target)) { + if (pass == 0 && + target->getItem()->count == + target->getItem()->getMaxStackSize()) + continue; + int count = std::min( + carried->getMaxStackSize() - carried->count, + target->getItem()->count); + std::shared_ptr removed = + target->remove(count); + carried->count += count; + + if (removed->count <= 0) { + target->set(nullptr); + } + target->onTake(player, removed); + } + } + } + } + + broadcastChanges(); } return clickedEntity; } +bool AbstractContainerMenu::canTakeItemForPickAll( + std::shared_ptr carried, Slot* target) { + return true; +} + // 4J Stu - Brought forward from 1.2 to fix infinite recursion bug in creative void AbstractContainerMenu::loopClick(int slotIndex, int buttonNum, bool quickKeyHeld, std::shared_ptr player) { - clicked(slotIndex, buttonNum, CLICK_QUICK_MOVE, player); + while (clicked(slotIndex, buttonNum, CLICK_QUICK_MOVE, player, true) != + NULL) { + } } bool AbstractContainerMenu::mayCombine(Slot* slot, @@ -335,8 +487,8 @@ void AbstractContainerMenu::removed(std::shared_ptr player) { } void AbstractContainerMenu:: - slotsChanged() // 4J used to take a std::shared_ptr but wasn't - // using it, so removed to simplify things + slotsChanged() // 4J used to take a shared_ptr but wasn't using + // it, so removed to simplify things { broadcastChanges(); } @@ -392,7 +544,7 @@ bool AbstractContainerMenu::moveItemStackTo( if (itemStack->isStackable()) { while (itemStack->count > 0 && ((!backwards && destSlot < endSlot) || (backwards && destSlot >= startSlot))) { - Slot* slot = slots->at(destSlot); + Slot* slot = slots.at(destSlot); std::shared_ptr target = slot->getItem(); if (target != NULL && target->id == itemStack->id && (!itemStack->isStackedByData() || @@ -430,7 +582,7 @@ bool AbstractContainerMenu::moveItemStackTo( } while ((!backwards && destSlot < endSlot) || (backwards && destSlot >= startSlot)) { - Slot* slot = slots->at(destSlot); + Slot* slot = slots.at(destSlot); std::shared_ptr target = slot->getItem(); if (target == NULL) { @@ -454,3 +606,82 @@ bool AbstractContainerMenu::moveItemStackTo( bool AbstractContainerMenu::isOverrideResultClick(int slotNum, int buttonNum) { return false; } + +int AbstractContainerMenu::getQuickcraftType(int mask) { + return (mask >> 2) & 0x3; +} + +int AbstractContainerMenu::getQuickcraftHeader(int mask) { return mask & 0x3; } + +int AbstractContainerMenu::getQuickcraftMask(int header, int type) { + return (header & 0x3) | ((type & 0x3) << 2); +} + +bool AbstractContainerMenu::isValidQuickcraftType(int type) { + return type == QUICKCRAFT_TYPE_CHARITABLE || type == QUICKCRAFT_TYPE_GREEDY; +} + +void AbstractContainerMenu::resetQuickCraft() { + quickcraftStatus = QUICKCRAFT_HEADER_START; + quickcraftSlots.clear(); +} + +bool AbstractContainerMenu::canItemQuickReplace( + Slot* slot, std::shared_ptr item, bool ignoreSize) { + bool canReplace = slot == NULL || !slot->hasItem(); + + if (slot != NULL && slot->hasItem() && item != NULL && + item->sameItem(slot->getItem()) && + ItemInstance::tagMatches(slot->getItem(), item)) { + canReplace |= slot->getItem()->count + (ignoreSize ? 0 : item->count) <= + item->getMaxStackSize(); + } + + return canReplace; +} + +void AbstractContainerMenu::getQuickCraftSlotCount( + std::unordered_set* quickCraftSlots, int quickCraftingType, + std::shared_ptr item, int carry) { + switch (quickCraftingType) { + case QUICKCRAFT_TYPE_CHARITABLE: + item->count = + Mth::floor(item->count / (float)quickCraftSlots->size()); + break; + case QUICKCRAFT_TYPE_GREEDY: + item->count = 1; + break; + } + + item->count += carry; +} + +bool AbstractContainerMenu::canDragTo(Slot* slot) { return true; } + +int AbstractContainerMenu::getRedstoneSignalFromContainer( + std::shared_ptr container) { + if (container == NULL) return 0; + int count = 0; + float totalPct = 0; + + for (int i = 0; i < container->getContainerSize(); i++) { + std::shared_ptr item = container->getItem(i); + + if (item != NULL) { + totalPct += + item->count / (float)std::min(container->getMaxStackSize(), + item->getMaxStackSize()); + count++; + } + } + + totalPct /= container->getContainerSize(); + return Mth::floor(totalPct * (Redstone::SIGNAL_MAX - 1)) + + (count > 0 ? 1 : 0); +} + +// 4J Added +bool AbstractContainerMenu::isValidIngredient( + std::shared_ptr item, int slotId) { + return true; +} \ No newline at end of file diff --git a/Minecraft.World/Containers/AbstractContainerMenu.h b/Minecraft.World/Containers/AbstractContainerMenu.h index fd3b1596b..9b24bf03b 100644 --- a/Minecraft.World/Containers/AbstractContainerMenu.h +++ b/Minecraft.World/Containers/AbstractContainerMenu.h @@ -12,12 +12,21 @@ class Container; class AbstractContainerMenu { public: - static const int CLICKED_OUTSIDE = -999; + static const int SLOT_CLICKED_OUTSIDE = -999; static const int CLICK_PICKUP = 0; static const int CLICK_QUICK_MOVE = 1; static const int CLICK_SWAP = 2; static const int CLICK_CLONE = 3; + static const int CLICK_THROW = 4; + static const int CLICK_QUICK_CRAFT = 5; + static const int CLICK_PICKUP_ALL = 6; + + static const int QUICKCRAFT_TYPE_CHARITABLE = 0; + static const int QUICKCRAFT_TYPE_GREEDY = 1; + static const int QUICKCRAFT_HEADER_START = 0; + static const int QUICKCRAFT_HEADER_CONTINUE = 1; + static const int QUICKCRAFT_HEADER_END = 2; // 4J Stu - Added these to fix problem with items picked up while in the // creative menu replacing slots in the creative menu @@ -25,16 +34,22 @@ public: static const int CONTAINER_ID_INVENTORY = 0; static const int CONTAINER_ID_CREATIVE = -2; - std::vector >* lastSlots; - std::vector* slots; + std::vector > lastSlots; + std::vector slots; int containerId; private: short changeUid; + + int quickcraftType; + int quickcraftStatus; + std::unordered_set quickcraftSlots; + +private: bool m_bNeedsRendered; // 4J added protected: - std::vector* containerListeners; + std::vector containerListeners; // 4J Stu - The java does not have ctor here (being an abstract) but we need // one to initialise the member variables @@ -46,19 +61,23 @@ protected: public: virtual ~AbstractContainerMenu(); virtual void addSlotListener(ContainerListener* listener); - std::vector >* getItems(); - void sendData(int id, int value); + virtual void removeSlotListener(ContainerListener* listener); + virtual std::vector >* getItems(); + virtual void sendData(int id, int value); virtual void broadcastChanges(); virtual bool needsRendered(); virtual bool clickMenuButton(std::shared_ptr player, int buttonId); - Slot* getSlotFor(std::shared_ptr c, int index); - Slot* getSlot(int index); + virtual Slot* getSlotFor(std::shared_ptr c, int index); + virtual Slot* getSlot(int index); virtual std::shared_ptr quickMoveStack( std::shared_ptr player, int slotIndex); virtual std::shared_ptr clicked( int slotIndex, int buttonNum, int clickType, - std::shared_ptr player); + std::shared_ptr player, + bool looped = false); // 4J added looped param virtual bool mayCombine(Slot* slot, std::shared_ptr item); + virtual bool canTakeItemForPickAll(std::shared_ptr carried, + Slot* target); protected: virtual void loopClick(int slotIndex, int buttonNum, bool quickKeyHeld, @@ -85,7 +104,7 @@ public: virtual bool stillValid(std::shared_ptr player) = 0; // 4J Stu Added for UI - unsigned int getSize() { return (unsigned int)slots->size(); } + unsigned int getSize() { return (unsigned int)slots.size(); } protected: // 4J Stu - Changes to return bool brought forward from 1.2 @@ -94,4 +113,27 @@ protected: public: virtual bool isOverrideResultClick(int slotNum, int buttonNum); + + static int getQuickcraftType(int mask); + static int getQuickcraftHeader(int mask); + static int getQuickcraftMask(int header, int type); + static bool isValidQuickcraftType(int type); + +protected: + void resetQuickCraft(); + +public: + static bool canItemQuickReplace(Slot* slot, + std::shared_ptr item, + bool ignoreSize); + static void getQuickCraftSlotCount( + std::unordered_set* quickCraftSlots, int quickCraftingType, + std::shared_ptr item, int carry); + bool canDragTo(Slot* slot); + static int getRedstoneSignalFromContainer( + std::shared_ptr container); + + // 4J Added + virtual bool isValidIngredient(std::shared_ptr item, + int slotId); }; diff --git a/Minecraft.World/Containers/AnimalChest.cpp b/Minecraft.World/Containers/AnimalChest.cpp new file mode 100644 index 000000000..5014152f7 --- /dev/null +++ b/Minecraft.World/Containers/AnimalChest.cpp @@ -0,0 +1,10 @@ +#include "../Platform/stdafx.h" + +#include "AnimalChest.h" + +AnimalChest::AnimalChest(const std::wstring& name, int size) + : SimpleContainer(IDS_CONTAINER_ANIMAL, name, false, size) {} + +AnimalChest::AnimalChest(int iTitle, const std::wstring& name, + bool hasCustomName, int size) + : SimpleContainer(iTitle, name, hasCustomName, size) {} \ No newline at end of file diff --git a/Minecraft.World/Containers/AnimalChest.h b/Minecraft.World/Containers/AnimalChest.h new file mode 100644 index 000000000..122757c6d --- /dev/null +++ b/Minecraft.World/Containers/AnimalChest.h @@ -0,0 +1,10 @@ +#pragma once + +#include "SimpleContainer.h" + +class AnimalChest : public SimpleContainer { +public: + AnimalChest(const std::wstring& name, int size); + AnimalChest(int iTitle, const std::wstring& name, bool hasCustomName, + int size); // 4J Added iTitle param +}; \ No newline at end of file diff --git a/Minecraft.World/Containers/RepairMenu.cpp b/Minecraft.World/Containers/AnvilMenu.cpp similarity index 87% rename from Minecraft.World/Containers/RepairMenu.cpp rename to Minecraft.World/Containers/AnvilMenu.cpp index 487f91d41..fb4628255 100644 --- a/Minecraft.World/Containers/RepairMenu.cpp +++ b/Minecraft.World/Containers/AnvilMenu.cpp @@ -4,20 +4,20 @@ #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.item.enchantment.h" -#include "RepairMenu.h" +#include "AnvilMenu.h" -RepairMenu::RepairMenu(std::shared_ptr inventory, Level* level, - int xt, int yt, int zt, std::shared_ptr player) { +AnvilMenu::AnvilMenu(std::shared_ptr inventory, Level* level, int xt, + int yt, int zt, std::shared_ptr player) { resultSlots = std::shared_ptr(new ResultContainer()); repairSlots = std::shared_ptr( - new RepairContainer(this, IDS_REPAIR_AND_NAME, 2)); + new RepairContainer(this, IDS_REPAIR_AND_NAME, true, 2)); cost = 0; repairItemCountCost = 0; this->level = level; - this->x = xt; - this->y = yt; - this->z = zt; + x = xt; + y = yt; + z = zt; this->player = player; addSlot(new Slot(repairSlots, INPUT_SLOT, 27, 43 + 4)); @@ -38,13 +38,13 @@ RepairMenu::RepairMenu(std::shared_ptr inventory, Level* level, } } -void RepairMenu::slotsChanged(std::shared_ptr container) { +void AnvilMenu::slotsChanged(std::shared_ptr container) { AbstractContainerMenu::slotsChanged(); if (container == repairSlots) createResult(); } -void RepairMenu::createResult() { +void AnvilMenu::createResult() { std::shared_ptr input = repairSlots->getItem(INPUT_SLOT); cost = 0; int price = 0; @@ -148,7 +148,9 @@ void RepairMenu::createResult() { int extra = level - current; bool compatible = enchantment->canEnchant(input); - if (player->abilities.instabuild) compatible = true; + if (player->abilities.instabuild || + input->id == EnchantedBookItem::enchantedBook_Id) + compatible = true; for (AUTO_VAR(it2, enchantments->begin()); it2 != enchantments->end(); ++it2) { @@ -203,9 +205,21 @@ void RepairMenu::createResult() { } } - if (itemName.length() > 0 && - !equalsIgnoreCase(itemName, input->getHoverName()) && - itemName.length() > 0) { + if (itemName.empty()) { + if (input->hasCustomHoverName()) { + namingCost = input->isDamageableItem() ? 7 : input->count * 5; + + price += namingCost; + if (DEBUG_COST) { + app.DebugPrintf( + "Un-naming cost; price is now %d (went up by %d)", + price, namingCost); + } + result->resetHoverName(); + } + } else if (itemName.length() > 0 && + !equalsIgnoreCase(itemName, input->getHoverName()) && + itemName.length() > 0) { namingCost = input->isDamageableItem() ? 7 : input->count * 5; price += namingCost; @@ -309,20 +323,20 @@ void RepairMenu::createResult() { } } -void RepairMenu::sendData(int id, int value) { +void AnvilMenu::sendData(int id, int value) { AbstractContainerMenu::sendData(id, value); } -void RepairMenu::addSlotListener(ContainerListener* listener) { +void AnvilMenu::addSlotListener(ContainerListener* listener) { AbstractContainerMenu::addSlotListener(listener); listener->setContainerData(this, DATA_TOTAL_COST, cost); } -void RepairMenu::setData(int id, int value) { +void AnvilMenu::setData(int id, int value) { if (id == DATA_TOTAL_COST) cost = value; } -void RepairMenu::removed(std::shared_ptr player) { +void AnvilMenu::removed(std::shared_ptr player) { AbstractContainerMenu::removed(player); if (level->isClientSide) return; @@ -334,16 +348,16 @@ void RepairMenu::removed(std::shared_ptr player) { } } -bool RepairMenu::stillValid(std::shared_ptr player) { +bool AnvilMenu::stillValid(std::shared_ptr player) { if (level->getTile(x, y, z) != Tile::anvil_Id) return false; if (player->distanceToSqr(x + 0.5, y + 0.5, z + 0.5) > 8 * 8) return false; return true; } -std::shared_ptr RepairMenu::quickMoveStack( +std::shared_ptr AnvilMenu::quickMoveStack( std::shared_ptr player, int slotIndex) { std::shared_ptr clicked = nullptr; - Slot* slot = slots->at(slotIndex); + Slot* slot = slots.at(slotIndex); if (slot != NULL && slot->hasItem()) { std::shared_ptr stack = slot->getItem(); clicked = stack->copy(); @@ -379,10 +393,16 @@ std::shared_ptr RepairMenu::quickMoveStack( return clicked; } -void RepairMenu::setItemName(const std::wstring& name) { - this->itemName = name; +void AnvilMenu::setItemName(const std::wstring& name) { + itemName = name; if (getSlot(RESULT_SLOT)->hasItem()) { - getSlot(RESULT_SLOT)->getItem()->setHoverName(itemName); + std::shared_ptr item = getSlot(RESULT_SLOT)->getItem(); + + if (name.empty()) { + item->resetHoverName(); + } else { + item->setHoverName(itemName); + } } createResult(); -} +} \ No newline at end of file diff --git a/Minecraft.World/Containers/RepairMenu.h b/Minecraft.World/Containers/AnvilMenu.h similarity index 88% rename from Minecraft.World/Containers/RepairMenu.h rename to Minecraft.World/Containers/AnvilMenu.h index 4c9d3462e..eea6ab5a0 100644 --- a/Minecraft.World/Containers/RepairMenu.h +++ b/Minecraft.World/Containers/AnvilMenu.h @@ -2,7 +2,7 @@ #include "AbstractContainerMenu.h" -class RepairMenu : public AbstractContainerMenu { +class AnvilMenu : public AbstractContainerMenu { friend class RepairResultSlot; private: @@ -41,8 +41,8 @@ private: public: using AbstractContainerMenu::slotsChanged; - RepairMenu(std::shared_ptr inventory, Level* level, int xt, - int yt, int zt, std::shared_ptr player); + AnvilMenu(std::shared_ptr inventory, Level* level, int xt, + int yt, int zt, std::shared_ptr player); void slotsChanged(std::shared_ptr container); void createResult(); diff --git a/Minecraft.World/Containers/ArmorSlot.cpp b/Minecraft.World/Containers/ArmorSlot.cpp index 774a480e9..843112db3 100644 --- a/Minecraft.World/Containers/ArmorSlot.cpp +++ b/Minecraft.World/Containers/ArmorSlot.cpp @@ -13,6 +13,9 @@ ArmorSlot::ArmorSlot(int slotNum, std::shared_ptr container, int id, int ArmorSlot::getMaxStackSize() { return 1; } bool ArmorSlot::mayPlace(std::shared_ptr item) { + if (item == NULL) { + return false; + } if (dynamic_cast(item->getItem()) != NULL) { return dynamic_cast(item->getItem())->slot == slotNum; } @@ -26,25 +29,24 @@ bool ArmorSlot::mayPlace(std::shared_ptr item) { Icon* ArmorSlot::getNoItemIcon() { return ArmorItem::getEmptyIcon(slotNum); } // -// bool ArmorSlot::mayCombine(std::shared_ptr item) +// bool ArmorSlot::mayCombine(shared_ptr item) //{ -// std::shared_ptr thisItemI = getItem(); +// shared_ptr thisItemI = getItem(); // if(thisItemI == NULL || item == NULL) return false; // // ArmorItem *thisItem = (ArmorItem *)thisItemI->getItem(); // bool thisIsDyableArmor = thisItem->getMaterial() == -//ArmorItem::ArmorMaterial::CLOTH; bool itemIsDye = item->id == -//Item::dye_powder_Id; return thisIsDyableArmor && itemIsDye; +// ArmorItem::ArmorMaterial::CLOTH; bool itemIsDye = item->id == +// Item::dye_powder_Id; return thisIsDyableArmor && itemIsDye; //} // -// std::shared_ptr -// ArmorSlot::combine(std::shared_ptr item) +// shared_ptr ArmorSlot::combine(shared_ptr item) //{ -// std::shared_ptr craftSlots = -//std::shared_ptr( new CraftingContainer(NULL, 2, 2) ); +// shared_ptr craftSlots = +// shared_ptr( new CraftingContainer(NULL, 2, 2) ); // craftSlots->setItem(0, item); // craftSlots->setItem(1, getItem()); // Armour item needs to go second -// std::shared_ptr result = -//ArmorDyeRecipe::assembleDyedArmor(craftSlots); craftSlots->setItem(0, -//nullptr); craftSlots->setItem(1, nullptr); return result; +// shared_ptr result = +// ArmorDyeRecipe::assembleDyedArmor(craftSlots); craftSlots->setItem(0, +// nullptr); craftSlots->setItem(1, nullptr); return result; //} \ No newline at end of file diff --git a/Minecraft.World/Containers/BeaconMenu.cpp b/Minecraft.World/Containers/BeaconMenu.cpp new file mode 100644 index 000000000..0992c4749 --- /dev/null +++ b/Minecraft.World/Containers/BeaconMenu.cpp @@ -0,0 +1,114 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.level.tile.entity.h" +#include "BeaconMenu.h" + +BeaconMenu::BeaconMenu(std::shared_ptr inventory, + std::shared_ptr beacon) { + this->beacon = beacon; + + addSlot(paymentSlot = + new BeaconMenu::PaymentSlot(beacon, PAYMENT_SLOT, 136, 110)); + + int xo = 36; + int yo = 137; + + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 9; x++) { + addSlot( + new Slot(inventory, x + y * 9 + 9, xo + x * 18, yo + y * 18)); + } + } + for (int x = 0; x < 9; x++) { + addSlot(new Slot(inventory, x, xo + x * 18, 58 + yo)); + } + + levels = beacon->getLevels(); + primaryPower = beacon->getPrimaryPower(); + secondaryPower = beacon->getSecondaryPower(); +} + +void BeaconMenu::addSlotListener(ContainerListener* listener) { + AbstractContainerMenu::addSlotListener(listener); + + listener->setContainerData(this, 0, levels); + listener->setContainerData(this, 1, primaryPower); + listener->setContainerData(this, 2, secondaryPower); +} + +void BeaconMenu::setData(int id, int value) { + if (id == 0) beacon->setLevels(value); + if (id == 1) beacon->setPrimaryPower(value); + if (id == 2) beacon->setSecondaryPower(value); +} + +std::shared_ptr BeaconMenu::getBeacon() { return beacon; } + +bool BeaconMenu::stillValid(std::shared_ptr player) { + return beacon->stillValid(player); +} + +std::shared_ptr BeaconMenu::quickMoveStack( + std::shared_ptr player, int slotIndex) { + std::shared_ptr clicked = nullptr; + Slot* slot = slots.at(slotIndex); + if (slot != NULL && slot->hasItem()) { + std::shared_ptr stack = slot->getItem(); + clicked = stack->copy(); + + if (slotIndex == PAYMENT_SLOT) { + if (!moveItemStackTo(stack, INV_SLOT_START, USE_ROW_SLOT_END, + true)) { + return nullptr; + } + slot->onQuickCraft(stack, clicked); + } else if (!paymentSlot->hasItem() && paymentSlot->mayPlace(stack) && + stack->count == 1) { + if (!moveItemStackTo(stack, PAYMENT_SLOT, PAYMENT_SLOT + 1, + false)) { + return nullptr; + } + } else if (slotIndex >= INV_SLOT_START && slotIndex < INV_SLOT_END) { + if (!moveItemStackTo(stack, USE_ROW_SLOT_START, USE_ROW_SLOT_END, + false)) { + return nullptr; + } + } else if (slotIndex >= USE_ROW_SLOT_START && + slotIndex < USE_ROW_SLOT_END) { + if (!moveItemStackTo(stack, INV_SLOT_START, INV_SLOT_END, false)) { + return nullptr; + } + } else { + if (!moveItemStackTo(stack, INV_SLOT_START, USE_ROW_SLOT_END, + false)) { + return nullptr; + } + } + if (stack->count == 0) { + slot->set(nullptr); + } else { + slot->setChanged(); + } + if (stack->count == clicked->count) { + return nullptr; + } else { + slot->onTake(player, stack); + } + } + return clicked; +} + +BeaconMenu::PaymentSlot::PaymentSlot(std::shared_ptr container, + int slot, int x, int y) + : Slot(container, slot, x, y) {} + +bool BeaconMenu::PaymentSlot::mayPlace(std::shared_ptr item) { + if (item != NULL) { + return (item->id == Item::emerald_Id || item->id == Item::diamond_Id || + item->id == Item::goldIngot_Id || + item->id == Item::ironIngot_Id); + } + return false; +} + +int BeaconMenu::PaymentSlot::getMaxStackSize() { return 1; } \ No newline at end of file diff --git a/Minecraft.World/Containers/BeaconMenu.h b/Minecraft.World/Containers/BeaconMenu.h new file mode 100644 index 000000000..a49ce7be3 --- /dev/null +++ b/Minecraft.World/Containers/BeaconMenu.h @@ -0,0 +1,45 @@ +#pragma once + +#include "AbstractContainerMenu.h" +#include "Slot.h" + +class BeaconTileEntity; + +class BeaconMenu : public AbstractContainerMenu { +private: + class PaymentSlot : public Slot { + public: + PaymentSlot(std::shared_ptr container, int slot, int x, + int y); + + bool mayPlace(std::shared_ptr item); + int getMaxStackSize(); + }; + +public: + static const int PAYMENT_SLOT = 0; + static const int INV_SLOT_START = PAYMENT_SLOT + 1; + static const int INV_SLOT_END = INV_SLOT_START + 9 * 3; + static const int USE_ROW_SLOT_START = INV_SLOT_END; + static const int USE_ROW_SLOT_END = USE_ROW_SLOT_START + 9; + +private: + std::shared_ptr beacon; + PaymentSlot* paymentSlot; + + // copied values because container/client system is retarded + int levels; + int primaryPower; + int secondaryPower; + +public: + BeaconMenu(std::shared_ptr inventory, + std::shared_ptr beacon); + + void addSlotListener(ContainerListener* listener); + void setData(int id, int value); + std::shared_ptr getBeacon(); + bool stillValid(std::shared_ptr player); + std::shared_ptr quickMoveStack(std::shared_ptr player, + int slotIndex); +}; \ No newline at end of file diff --git a/Minecraft.World/Containers/BrewingStandMenu.cpp b/Minecraft.World/Containers/BrewingStandMenu.cpp index 14c13d796..a832870ab 100644 --- a/Minecraft.World/Containers/BrewingStandMenu.cpp +++ b/Minecraft.World/Containers/BrewingStandMenu.cpp @@ -44,8 +44,8 @@ void BrewingStandMenu::broadcastChanges() { AbstractContainerMenu::broadcastChanges(); // for (int i = 0; i < containerListeners->size(); i++) - for (AUTO_VAR(it, containerListeners->begin()); - it != containerListeners->end(); ++it) { + for (AUTO_VAR(it, containerListeners.begin()); + it != containerListeners.end(); ++it) { ContainerListener* listener = *it; // containerListeners.at(i); if (tc != brewingStand->getBrewTime()) { listener->setContainerData(this, 0, brewingStand->getBrewTime()); @@ -65,11 +65,11 @@ bool BrewingStandMenu::stillValid(std::shared_ptr player) { std::shared_ptr BrewingStandMenu::quickMoveStack( std::shared_ptr player, int slotIndex) { std::shared_ptr clicked = nullptr; - Slot* slot = slots->at(slotIndex); - Slot* IngredientSlot = slots->at(INGREDIENT_SLOT); - Slot* PotionSlot1 = slots->at(BOTTLE_SLOT_START); - Slot* PotionSlot2 = slots->at(BOTTLE_SLOT_START + 1); - Slot* PotionSlot3 = slots->at(BOTTLE_SLOT_START + 2); + Slot* slot = slots.at(slotIndex); + Slot* IngredientSlot = slots.at(INGREDIENT_SLOT); + Slot* PotionSlot1 = slots.at(BOTTLE_SLOT_START); + Slot* PotionSlot2 = slots.at(BOTTLE_SLOT_START + 1); + Slot* PotionSlot3 = slots.at(BOTTLE_SLOT_START + 2); if (slot != NULL && slot->hasItem()) { std::shared_ptr stack = slot->getItem(); @@ -97,7 +97,7 @@ std::shared_ptr BrewingStandMenu::quickMoveStack( // 4J-PB - if the item is an ingredient, quickmove it into the // ingredient slot if ((Item::items[stack->id]->hasPotionBrewingFormula() || - (stack->id == Item::netherStalkSeeds_Id)) && + (stack->id == Item::netherwart_seeds_Id)) && (!IngredientSlot->hasItem() || (stack->id == IngredientSlot->getItem()->id))) { if (!moveItemStackTo(stack, INGREDIENT_SLOT, @@ -122,7 +122,7 @@ std::shared_ptr BrewingStandMenu::quickMoveStack( // 4J-PB - if the item is an ingredient, quickmove it into the // ingredient slot if ((Item::items[stack->id]->hasPotionBrewingFormula() || - (stack->id == Item::netherStalkSeeds_Id)) && + (stack->id == Item::netherwart_seeds_Id)) && (!IngredientSlot->hasItem() || (stack->id == IngredientSlot->getItem()->id))) { if (!moveItemStackTo(stack, INGREDIENT_SLOT, @@ -178,9 +178,6 @@ int BrewingStandMenu::PotionSlot::getMaxStackSize() { return 1; } void BrewingStandMenu::PotionSlot::onTake( std::shared_ptr player, std::shared_ptr carried) { - carried->onCraftedBy( - this->player->level, - std::dynamic_pointer_cast(this->player->shared_from_this()), 1); if (carried->id == Item::potion_Id && carried->getAuxValue() > 0) this->player->awardStat(GenericStats::potion(), GenericStats::param_potion()); @@ -209,7 +206,7 @@ bool BrewingStandMenu::IngredientsSlot::mayPlace( return Item::items[item->id]->hasPotionBrewingFormula(); } else { return Item::items[item->id]->hasPotionBrewingFormula() || - item->id == Item::netherStalkSeeds_Id || + item->id == Item::netherwart_seeds_Id || item->id == Item::bucket_water_Id; } } diff --git a/Minecraft.World/Containers/ClientSideMerchant.cpp b/Minecraft.World/Containers/ClientSideMerchant.cpp index 725dd1df4..7394b6eb1 100644 --- a/Minecraft.World/Containers/ClientSideMerchant.cpp +++ b/Minecraft.World/Containers/ClientSideMerchant.cpp @@ -4,9 +4,9 @@ #include "ClientSideMerchant.h" ClientSideMerchant::ClientSideMerchant(std::shared_ptr source, - int name) { + const std::wstring& name) { this->source = source; - // 4J Stu - Need to do this after creating as a std::shared_ptr + // 4J Stu - Need to do this after creating as a shared_ptr container = NULL; // new MerchantContainer(source, this); currentOffers = NULL; m_name = name; @@ -46,4 +46,4 @@ void ClientSideMerchant::notifyTrade(MerchantRecipe* activeRecipe) { void ClientSideMerchant::notifyTradeUpdated( std::shared_ptr item) {} -int ClientSideMerchant::getDisplayName() { return m_name; } \ No newline at end of file +std::wstring ClientSideMerchant::getDisplayName() { return m_name; } \ No newline at end of file diff --git a/Minecraft.World/Containers/ClientSideMerchant.h b/Minecraft.World/Containers/ClientSideMerchant.h index 25322c452..30d41e60b 100644 --- a/Minecraft.World/Containers/ClientSideMerchant.h +++ b/Minecraft.World/Containers/ClientSideMerchant.h @@ -13,10 +13,11 @@ private: MerchantContainer* container; std::shared_ptr source; MerchantRecipeList* currentOffers; - int m_name; + std::wstring m_name; public: - ClientSideMerchant(std::shared_ptr source, int name); + ClientSideMerchant(std::shared_ptr source, + const std::wstring& name); ~ClientSideMerchant(); void createContainer(); // 4J Added @@ -27,5 +28,5 @@ public: void overrideOffers(MerchantRecipeList* recipeList); void notifyTrade(MerchantRecipe* activeRecipe); void notifyTradeUpdated(std::shared_ptr item); - int getDisplayName(); + std::wstring getDisplayName(); }; \ No newline at end of file diff --git a/Minecraft.World/Containers/CompoundContainer.cpp b/Minecraft.World/Containers/CompoundContainer.cpp index 5265f3e1f..d450b64a9 100644 --- a/Minecraft.World/Containers/CompoundContainer.cpp +++ b/Minecraft.World/Containers/CompoundContainer.cpp @@ -1,6 +1,6 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.entity.player.h" - +#include "../Network/Packets/ContainerOpenPacket.h" #include "CompoundContainer.h" CompoundContainer::CompoundContainer(int name, std::shared_ptr c1, @@ -12,11 +12,33 @@ CompoundContainer::CompoundContainer(int name, std::shared_ptr c1, this->c2 = c2; } +int CompoundContainer::getContainerType() { + return ContainerOpenPacket::LARGE_CHEST; +} + unsigned int CompoundContainer::getContainerSize() { return c1->getContainerSize() + c2->getContainerSize(); } -int CompoundContainer::getName() { return name; } +bool CompoundContainer::contains(std::shared_ptr c) { + return c1 == c || c2 == c; +} + +std::wstring CompoundContainer::getName() { + if (c1->hasCustomName()) return c1->getName(); + if (c2->hasCustomName()) return c2->getName(); + return app.GetString(name); +} + +std::wstring CompoundContainer::getCustomName() { + if (c1->hasCustomName()) return c1->getName(); + if (c2->hasCustomName()) return c2->getName(); + return L""; +} + +bool CompoundContainer::hasCustomName() { + return c1->hasCustomName() || c2->hasCustomName(); +} std::shared_ptr CompoundContainer::getItem(unsigned int slot) { if (slot >= c1->getContainerSize()) @@ -67,4 +89,9 @@ void CompoundContainer::startOpen() { void CompoundContainer::stopOpen() { c1->stopOpen(); c2->stopOpen(); +} + +bool CompoundContainer::canPlaceItem(int slot, + std::shared_ptr item) { + return true; } \ No newline at end of file diff --git a/Minecraft.World/Containers/CompoundContainer.h b/Minecraft.World/Containers/CompoundContainer.h index 02ad7570d..86f8c8afe 100644 --- a/Minecraft.World/Containers/CompoundContainer.h +++ b/Minecraft.World/Containers/CompoundContainer.h @@ -13,23 +13,21 @@ public: CompoundContainer(int name, std::shared_ptr c1, std::shared_ptr c2); - unsigned int getContainerSize(); - - int getName(); - - std::shared_ptr getItem(unsigned int slot); - - std::shared_ptr removeItem(unsigned int slot, int i); - std::shared_ptr removeItemNoUpdate(int slot); - - void setItem(unsigned int slot, std::shared_ptr item); - - int getMaxStackSize(); - - void setChanged(); - - bool stillValid(std::shared_ptr player); + virtual int getContainerType(); + virtual unsigned int getContainerSize(); + virtual bool contains(std::shared_ptr c); + virtual std::wstring getName(); + virtual std::wstring getCustomName(); + virtual bool hasCustomName(); + virtual std::shared_ptr getItem(unsigned int slot); + virtual std::shared_ptr removeItem(unsigned int slot, int i); + virtual std::shared_ptr removeItemNoUpdate(int slot); + virtual void setItem(unsigned int slot, std::shared_ptr item); + virtual int getMaxStackSize(); + virtual void setChanged(); + virtual bool stillValid(std::shared_ptr player); virtual void startOpen(); virtual void stopOpen(); + virtual bool canPlaceItem(int slot, std::shared_ptr item); }; \ No newline at end of file diff --git a/Minecraft.World/Containers/Container.cpp b/Minecraft.World/Containers/Container.cpp deleted file mode 100644 index c02ed6134..000000000 --- a/Minecraft.World/Containers/Container.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "../Platform/stdafx.h" -#include "Container.h" diff --git a/Minecraft.World/Containers/Container.h b/Minecraft.World/Containers/Container.h index 82ec0b6df..33503eec9 100644 --- a/Minecraft.World/Containers/Container.h +++ b/Minecraft.World/Containers/Container.h @@ -8,6 +8,9 @@ public: virtual ~Container() {} static const int LARGE_MAX_STACK_SIZE = 64; + // 4J-JEV: Added to distinguish between ender, bonus, small and large chests + virtual int getContainerType() { return -1; } + virtual unsigned int getContainerSize() = 0; virtual std::shared_ptr getItem(unsigned int slot) = 0; virtual std::shared_ptr removeItem(unsigned int slot, @@ -15,10 +18,14 @@ public: virtual std::shared_ptr removeItemNoUpdate(int slot) = 0; virtual void setItem(unsigned int slot, std::shared_ptr item) = 0; - virtual int getName() = 0; + virtual std::wstring getName() = 0; + virtual std::wstring + getCustomName() = 0; // 4J Stu added for sending over the network + virtual bool hasCustomName() = 0; virtual int getMaxStackSize() = 0; virtual void setChanged() = 0; virtual bool stillValid(std::shared_ptr player) = 0; virtual void startOpen() = 0; virtual void stopOpen() = 0; -}; + virtual bool canPlaceItem(int slot, std::shared_ptr item) = 0; +}; \ No newline at end of file diff --git a/Minecraft.World/Containers/ContainerMenu.cpp b/Minecraft.World/Containers/ContainerMenu.cpp index e88558a72..0218ecf2d 100644 --- a/Minecraft.World/Containers/ContainerMenu.cpp +++ b/Minecraft.World/Containers/ContainerMenu.cpp @@ -12,7 +12,7 @@ ContainerMenu::ContainerMenu(std::shared_ptr inventory, std::shared_ptr container) : AbstractContainerMenu() { this->container = container; - this->containerRows = container->getContainerSize() / 9; + containerRows = container->getContainerSize() / 9; container->startOpen(); int yo = (containerRows - 4) * 18; @@ -41,13 +41,13 @@ bool ContainerMenu::stillValid(std::shared_ptr player) { std::shared_ptr ContainerMenu::quickMoveStack( std::shared_ptr player, int slotIndex) { std::shared_ptr clicked = nullptr; - Slot* slot = slots->at(slotIndex); + Slot* slot = slots.at(slotIndex); if (slot != NULL && slot->hasItem()) { std::shared_ptr stack = slot->getItem(); clicked = stack->copy(); if (slotIndex < containerRows * 9) { - if (!moveItemStackTo(stack, containerRows * 9, (int)slots->size(), + if (!moveItemStackTo(stack, containerRows * 9, (int)slots.size(), true)) { // 4J Stu - Brought forward from 1.2 return nullptr; @@ -72,11 +72,14 @@ void ContainerMenu::removed(std::shared_ptr player) { container->stopOpen(); } +std::shared_ptr ContainerMenu::getContainer() { return container; } + std::shared_ptr ContainerMenu::clicked( - int slotIndex, int buttonNum, int clickType, - std::shared_ptr player) { - std::shared_ptr out = - AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, player); + int slotIndex, int buttonNum, int clickType, std::shared_ptr player, + bool looped) // 4J Added looped param +{ + std::shared_ptr out = AbstractContainerMenu::clicked( + slotIndex, buttonNum, clickType, player, looped); #ifdef _EXTENDED_ACHIEVEMENTS std::shared_ptr localPlayer = @@ -88,7 +91,7 @@ std::shared_ptr ContainerMenu::clicked( int cobblecount = 0; for (int i = 0; i < container->getContainerSize(); i++) { std::shared_ptr item = container->getItem(i); - if ((item != nullptr) && (item->id == Tile::stoneBrick_Id)) { + if ((item != nullptr) && (item->id == Tile::cobblestone_Id)) { cobblecount += item->GetCount(); } } @@ -99,8 +102,8 @@ std::shared_ptr ContainerMenu::clicked( StatsCounter* sc = Minecraft::GetInstance()->stats[localPlayer->GetXboxPad()]; int minedCount = - sc->getTotalValue(GenericStats::blocksMined(Tile::rock_Id)) + - sc->getTotalValue(GenericStats::blocksMined(Tile::stoneBrick_Id)); + sc->getTotalValue(GenericStats::blocksMined(Tile::stone_Id)) + + sc->getTotalValue(GenericStats::blocksMined(Tile::cobblestone_Id)); if (cobblecount >= 1728 && minedCount >= 1728) #endif { diff --git a/Minecraft.World/Containers/ContainerMenu.h b/Minecraft.World/Containers/ContainerMenu.h index 59bc388cb..76415eb45 100644 --- a/Minecraft.World/Containers/ContainerMenu.h +++ b/Minecraft.World/Containers/ContainerMenu.h @@ -16,10 +16,11 @@ public: virtual bool stillValid(std::shared_ptr player); virtual std::shared_ptr quickMoveStack( std::shared_ptr player, int slotIndex); - void removed(std::shared_ptr player); + virtual void removed(std::shared_ptr player); + virtual std::shared_ptr getContainer(); // 4J ADDED, virtual std::shared_ptr clicked( int slotIndex, int buttonNum, int clickType, - std::shared_ptr player); + std::shared_ptr player, bool looped = false); }; diff --git a/Minecraft.World/Containers/CraftingContainer.cpp b/Minecraft.World/Containers/CraftingContainer.cpp index b69482551..69617969a 100644 --- a/Minecraft.World/Containers/CraftingContainer.cpp +++ b/Minecraft.World/Containers/CraftingContainer.cpp @@ -32,7 +32,11 @@ std::shared_ptr CraftingContainer::getItem(unsigned int x, return getItem(pos); } -int CraftingContainer::getName() { return 0; } +std::wstring CraftingContainer::getName() { return L""; } + +std::wstring CraftingContainer::getCustomName() { return L""; } + +bool CraftingContainer::hasCustomName() { return false; } std::shared_ptr CraftingContainer::removeItemNoUpdate(int slot) { if ((*items)[slot] != NULL) { @@ -77,4 +81,9 @@ void CraftingContainer::setChanged() {} bool CraftingContainer::stillValid(std::shared_ptr player) { return true; +} + +bool CraftingContainer::canPlaceItem(int slot, + std::shared_ptr item) { + return true; } \ No newline at end of file diff --git a/Minecraft.World/Containers/CraftingContainer.h b/Minecraft.World/Containers/CraftingContainer.h index 37885af62..71e7eb524 100644 --- a/Minecraft.World/Containers/CraftingContainer.h +++ b/Minecraft.World/Containers/CraftingContainer.h @@ -18,7 +18,9 @@ public: virtual unsigned int getContainerSize(); virtual std::shared_ptr getItem(unsigned int slot); std::shared_ptr getItem(unsigned int x, unsigned int y); - virtual int getName(); + virtual std::wstring getName(); + virtual std::wstring getCustomName(); + virtual bool hasCustomName(); virtual std::shared_ptr removeItemNoUpdate(int slot); virtual std::shared_ptr removeItem(unsigned int slot, int count); @@ -29,4 +31,6 @@ public: void startOpen() {} // TODO Auto-generated method stub void stopOpen() {} // TODO Auto-generated method stub -}; + + virtual bool canPlaceItem(int slot, std::shared_ptr item); +}; \ No newline at end of file diff --git a/Minecraft.World/Containers/CraftingMenu.cpp b/Minecraft.World/Containers/CraftingMenu.cpp index 1b675b464..2f5da7042 100644 --- a/Minecraft.World/Containers/CraftingMenu.cpp +++ b/Minecraft.World/Containers/CraftingMenu.cpp @@ -25,9 +25,9 @@ CraftingMenu::CraftingMenu(std::shared_ptr inventory, Level* level, resultSlots = std::shared_ptr(new ResultContainer()); this->level = level; - this->x = xt; - this->y = yt; - this->z = zt; + x = xt; + y = yt; + z = zt; addSlot(new ResultSlot(inventory->player, craftSlots, resultSlots, 0, 120 + 4, 31 + 4)); @@ -50,9 +50,9 @@ CraftingMenu::CraftingMenu(std::shared_ptr inventory, Level* level, slotsChanged(); // 4J - removed craftSlots parameter, see comment below } -void CraftingMenu::slotsChanged() // 4J used to take a - // std::shared_ptr but wasn't - // using it, so removed to simplify things +void CraftingMenu::slotsChanged() // 4J used to take a shared_ptr + // but wasn't using it, so removed to + // simplify things { resultSlots->setItem(0, Recipes::getInstance()->getItemFor(craftSlots, level)); @@ -79,7 +79,7 @@ bool CraftingMenu::stillValid(std::shared_ptr player) { std::shared_ptr CraftingMenu::quickMoveStack( std::shared_ptr player, int slotIndex) { std::shared_ptr clicked = nullptr; - Slot* slot = slots->at(slotIndex); + Slot* slot = slots.at(slotIndex); if (slot != NULL && slot->hasItem()) { std::shared_ptr stack = slot->getItem(); clicked = stack->copy(); @@ -119,4 +119,10 @@ std::shared_ptr CraftingMenu::quickMoveStack( } } return clicked; +} + +bool CraftingMenu::canTakeItemForPickAll(std::shared_ptr carried, + Slot* target) { + return target->container != resultSlots && + AbstractContainerMenu::canTakeItemForPickAll(carried, target); } \ No newline at end of file diff --git a/Minecraft.World/Containers/CraftingMenu.h b/Minecraft.World/Containers/CraftingMenu.h index c59ee7ce1..07f50e199 100644 --- a/Minecraft.World/Containers/CraftingMenu.h +++ b/Minecraft.World/Containers/CraftingMenu.h @@ -35,4 +35,10 @@ public: virtual bool stillValid(std::shared_ptr player); virtual std::shared_ptr quickMoveStack( std::shared_ptr player, int slotIndex); + virtual bool canTakeItemForPickAll(std::shared_ptr carried, + Slot* target); + + int getX() { return x; } + int getY() { return y; } + int getZ() { return z; } }; \ No newline at end of file diff --git a/Minecraft.World/Containers/EnchantmentContainer.cpp b/Minecraft.World/Containers/EnchantmentContainer.cpp index 5cf155da8..1cf3e214f 100644 --- a/Minecraft.World/Containers/EnchantmentContainer.cpp +++ b/Minecraft.World/Containers/EnchantmentContainer.cpp @@ -3,7 +3,7 @@ #include "EnchantmentContainer.h" EnchantmentContainer::EnchantmentContainer(EnchantmentMenu* menu) - : SimpleContainer(IDS_ENCHANT, 1), m_menu(menu) {} + : SimpleContainer(IDS_ENCHANT, L"", false, 1), m_menu(menu) {} int EnchantmentContainer::getMaxStackSize() { return 1; } @@ -11,3 +11,8 @@ void EnchantmentContainer::setChanged() { SimpleContainer::setChanged(); m_menu->slotsChanged(); // Remove this param as it's not needed } + +bool EnchantmentContainer::canPlaceItem(int slot, + std::shared_ptr item) { + return true; +} \ No newline at end of file diff --git a/Minecraft.World/Containers/EnchantmentContainer.h b/Minecraft.World/Containers/EnchantmentContainer.h index ac764563a..a8717f0fd 100644 --- a/Minecraft.World/Containers/EnchantmentContainer.h +++ b/Minecraft.World/Containers/EnchantmentContainer.h @@ -15,4 +15,5 @@ public: EnchantmentContainer(EnchantmentMenu* menu); virtual int getMaxStackSize(); virtual void setChanged(); + virtual bool canPlaceItem(int slot, std::shared_ptr item); }; \ No newline at end of file diff --git a/Minecraft.World/Containers/EnchantmentMenu.cpp b/Minecraft.World/Containers/EnchantmentMenu.cpp index 1c1bb52ac..4d481081e 100644 --- a/Minecraft.World/Containers/EnchantmentMenu.cpp +++ b/Minecraft.World/Containers/EnchantmentMenu.cpp @@ -17,9 +17,9 @@ EnchantmentMenu::EnchantmentMenu(std::shared_ptr inventory, } this->level = level; - this->x = xt; - this->y = yt; - this->z = zt; + x = xt; + y = yt; + z = zt; addSlot(new EnchantmentSlot(enchantSlots, 0, 21 + 4, 43 + 4)); for (int y = 0; y < 3; y++) { @@ -49,8 +49,8 @@ void EnchantmentMenu::broadcastChanges() { // 4J Added m_costsChanged to stop continually sending update packets even // when no changes have been made if (m_costsChanged) { - for (int i = 0; i < containerListeners->size(); i++) { - ContainerListener* listener = containerListeners->at(i); + for (int i = 0; i < containerListeners.size(); i++) { + ContainerListener* listener = containerListeners.at(i); listener->setContainerData(this, 0, costs[0]); listener->setContainerData(this, 1, costs[1]); listener->setContainerData(this, 2, costs[2]); @@ -68,9 +68,9 @@ void EnchantmentMenu::setData(int id, int value) { } } -void EnchantmentMenu:: - slotsChanged() // 4J used to take a std::shared_ptr container - // but wasn't using it, so removed to simplify things +void EnchantmentMenu::slotsChanged() // 4J used to take a shared_ptr + // container but wasn't using it, so + // removed to simplify things { std::shared_ptr item = enchantSlots->getItem(0); @@ -144,7 +144,7 @@ bool EnchantmentMenu::clickMenuButton(std::shared_ptr player, int i) { std::vector* newEnchantment = EnchantmentHelper::selectEnchantment(&random, item, costs[i]); if (newEnchantment != NULL) { - player->withdrawExperienceLevels(costs[i]); + player->giveExperienceLevels(-costs[i]); if (isBook) item->id = Item::enchantedBook_Id; int randomIndex = isBook ? random.nextInt(newEnchantment->size()) : -1; @@ -190,8 +190,8 @@ bool EnchantmentMenu::stillValid(std::shared_ptr player) { std::shared_ptr EnchantmentMenu::quickMoveStack( std::shared_ptr player, int slotIndex) { std::shared_ptr clicked = nullptr; - Slot* slot = slots->at(slotIndex); - Slot* IngredientSlot = slots->at(INGREDIENT_SLOT); + Slot* slot = slots.at(slotIndex); + Slot* IngredientSlot = slots.at(INGREDIENT_SLOT); if (slot != NULL && slot->hasItem()) { std::shared_ptr stack = slot->getItem(); diff --git a/Minecraft.World/Containers/FireworksMenu.cpp b/Minecraft.World/Containers/FireworksMenu.cpp new file mode 100644 index 000000000..8ae25c7e9 --- /dev/null +++ b/Minecraft.World/Containers/FireworksMenu.cpp @@ -0,0 +1,136 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.entity.player.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.tile.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.item.crafting.h" +#include "CraftingContainer.h" +#include "ResultContainer.h" +#include "ResultSlot.h" +#include "FireworksMenu.h" + +FireworksMenu::FireworksMenu(std::shared_ptr inventory, Level* level, + int xt, int yt, int zt) + : AbstractContainerMenu() { + m_canMakeFireworks = false; + m_canMakeCharge = false; + m_canMakeFade = false; + + craftSlots = + std::shared_ptr(new CraftingContainer(this, 3, 3)); + resultSlots = std::shared_ptr(new ResultContainer()); + + this->level = level; + x = xt; + y = yt; + z = zt; + addSlot(new ResultSlot(inventory->player, craftSlots, resultSlots, 0, + 120 + 4, 31 + 4)); + + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 3; x++) { + addSlot(new Slot(craftSlots, x + y * 3, 30 + x * 18, 17 + y * 18)); + } + } + + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 9; x++) { + addSlot( + new Slot(inventory, x + y * 9 + 9, 8 + x * 18, 84 + y * 18)); + } + } + for (int x = 0; x < 9; x++) { + addSlot(new Slot(inventory, x, 8 + x * 18, 142)); + } + + slotsChanged(); // 4J - removed craftSlots parameter, see comment below +} + +void FireworksMenu::slotsChanged() // 4J used to take a shared_ptr + // but wasn't using it, so removed to + // simplify things +{ + FireworksRecipe::updatePossibleRecipes(craftSlots, &m_canMakeFireworks, + &m_canMakeCharge, &m_canMakeFade); + resultSlots->setItem(0, Recipes::getInstance()->getItemFor( + craftSlots, level, Recipes::pFireworksRecipes)); +} + +void FireworksMenu::removed(std::shared_ptr player) { + AbstractContainerMenu::removed(player); + if (level->isClientSide) return; + + for (int i = 0; i < 9; i++) { + std::shared_ptr item = craftSlots->removeItemNoUpdate(i); + if (item != NULL) { + player->drop(item); + } + } +} + +bool FireworksMenu::stillValid(std::shared_ptr player) { return true; } + +std::shared_ptr FireworksMenu::quickMoveStack( + std::shared_ptr player, int slotIndex) { + std::shared_ptr clicked = nullptr; + Slot* slot = slots.at(slotIndex); + if (slot != NULL && slot->hasItem()) { + std::shared_ptr stack = slot->getItem(); + clicked = stack->copy(); + + if (slotIndex == RESULT_SLOT) { + if (!moveItemStackTo(stack, INV_SLOT_START, USE_ROW_SLOT_END, + true)) { + return nullptr; + } + slot->onQuickCraft(stack, clicked); + } else if (slotIndex >= INV_SLOT_START && slotIndex < INV_SLOT_END) { + if (isValidIngredient(stack, -1) && + moveItemStackTo(stack, CRAFT_SLOT_START, CRAFT_SLOT_END, + false)) { + } else if (!moveItemStackTo(stack, USE_ROW_SLOT_START, + USE_ROW_SLOT_END, false)) { + return nullptr; + } + } else if (slotIndex >= USE_ROW_SLOT_START && + slotIndex < USE_ROW_SLOT_END) { + if (isValidIngredient(stack, -1) && + moveItemStackTo(stack, CRAFT_SLOT_START, CRAFT_SLOT_END, + false)) { + } else if (!moveItemStackTo(stack, INV_SLOT_START, INV_SLOT_END, + false)) { + return nullptr; + } + } else { + if (!moveItemStackTo(stack, INV_SLOT_START, USE_ROW_SLOT_END, + false)) { + return nullptr; + } + } + if (stack->count == 0) { + slot->set(nullptr); + } else { + slot->setChanged(); + } + if (stack->count == clicked->count) { + // nothing moved + return nullptr; + } else { + slot->onTake(player, stack); + } + } + return clicked; +} + +bool FireworksMenu::canTakeItemForPickAll(std::shared_ptr carried, + Slot* target) { + return target->container != resultSlots && + AbstractContainerMenu::canTakeItemForPickAll(carried, target); +} + +bool FireworksMenu::isValidIngredient(std::shared_ptr item, + int slotId) { + if (item == NULL || slotId == RESULT_SLOT) return true; + return FireworksRecipe::isValidIngredient(item, m_canMakeFireworks, + m_canMakeCharge, m_canMakeFade); +} \ No newline at end of file diff --git a/Minecraft.World/Containers/FireworksMenu.h b/Minecraft.World/Containers/FireworksMenu.h new file mode 100644 index 000000000..c6774f46a --- /dev/null +++ b/Minecraft.World/Containers/FireworksMenu.h @@ -0,0 +1,48 @@ +#pragma once + +#include "AbstractContainerMenu.h" + +class CraftingContainer; +class Container; + +class FireworksMenu : public AbstractContainerMenu { + // 4J Stu Made these public for UI menus, perhaps should make friend class? +public: + static const int RESULT_SLOT = 0; + static const int CRAFT_SLOT_START = 1; + static const int CRAFT_SLOT_END = CRAFT_SLOT_START + 9; + static const int INV_SLOT_START = CRAFT_SLOT_END; + static const int INV_SLOT_END = INV_SLOT_START + (9 * 3); + static const int USE_ROW_SLOT_START = INV_SLOT_END; + static const int USE_ROW_SLOT_END = USE_ROW_SLOT_START + 9; + +public: + std::shared_ptr craftSlots; + std::shared_ptr resultSlots; + +private: + Level* level; + int x, y, z; + + bool m_canMakeFireworks; + bool m_canMakeCharge; + bool m_canMakeFade; + +public: + FireworksMenu(std::shared_ptr inventory, Level* level, int xt, + int yt, int zt); + + virtual void + slotsChanged(); // 4J used to take a std::shared_ptr but wasn't + // using it, so removed to simplify things + virtual void removed(std::shared_ptr player); + virtual bool stillValid(std::shared_ptr player); + virtual std::shared_ptr quickMoveStack( + std::shared_ptr player, int slotIndex); + virtual bool canTakeItemForPickAll(std::shared_ptr carried, + Slot* target); + + // 4J Added + virtual bool isValidIngredient(std::shared_ptr item, + int slotId); +}; \ No newline at end of file diff --git a/Minecraft.World/Containers/FurnaceMenu.cpp b/Minecraft.World/Containers/FurnaceMenu.cpp index 17fb4aeea..986b1e389 100644 --- a/Minecraft.World/Containers/FurnaceMenu.cpp +++ b/Minecraft.World/Containers/FurnaceMenu.cpp @@ -44,8 +44,8 @@ void FurnaceMenu::addSlotListener(ContainerListener* listener) { void FurnaceMenu::broadcastChanges() { AbstractContainerMenu::broadcastChanges(); - AUTO_VAR(itEnd, containerListeners->end()); - for (AUTO_VAR(it, containerListeners->begin()); it != itEnd; it++) { + AUTO_VAR(itEnd, containerListeners.end()); + for (AUTO_VAR(it, containerListeners.begin()); it != itEnd; it++) { ContainerListener* listener = *it; // containerListeners->at(i); if (tc != furnace->tickCount) { listener->setContainerData(this, 0, furnace->tickCount); @@ -76,7 +76,7 @@ bool FurnaceMenu::stillValid(std::shared_ptr player) { std::shared_ptr FurnaceMenu::quickMoveStack( std::shared_ptr player, int slotIndex) { std::shared_ptr clicked = nullptr; - Slot* slot = slots->at(slotIndex); + Slot* slot = slots.at(slotIndex); // Slot *IngredientSlot = slots->at(INGREDIENT_SLOT); bool charcoalUsed = furnace->wasCharcoalUsed(); @@ -140,12 +140,13 @@ std::shared_ptr FurnaceMenu::quickMoveStack( } std::shared_ptr FurnaceMenu::clicked( - int slotIndex, int buttonNum, int clickType, - std::shared_ptr player) { + int slotIndex, int buttonNum, int clickType, std::shared_ptr player, + bool looped) // 4J Added looped param +{ bool charcoalUsed = furnace->wasCharcoalUsed(); - std::shared_ptr out = - AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, player); + std::shared_ptr out = AbstractContainerMenu::clicked( + slotIndex, buttonNum, clickType, player, looped); #ifdef _EXTENDED_ACHIEVEMENTS if (charcoalUsed && (out != nullptr) && diff --git a/Minecraft.World/Containers/FurnaceMenu.h b/Minecraft.World/Containers/FurnaceMenu.h index 03a05ee7c..8032215af 100644 --- a/Minecraft.World/Containers/FurnaceMenu.h +++ b/Minecraft.World/Containers/FurnaceMenu.h @@ -35,7 +35,8 @@ public: virtual std::shared_ptr quickMoveStack( std::shared_ptr player, int slotIndex); + // 4J Added looped param virtual std::shared_ptr clicked( int slotIndex, int buttonNum, int clickType, - std::shared_ptr player); + std::shared_ptr player, bool looped = false); }; diff --git a/Minecraft.World/Containers/HopperMenu.cpp b/Minecraft.World/Containers/HopperMenu.cpp new file mode 100644 index 000000000..ad1fdc301 --- /dev/null +++ b/Minecraft.World/Containers/HopperMenu.cpp @@ -0,0 +1,62 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.inventory.h" +#include "HopperMenu.h" + +HopperMenu::HopperMenu(std::shared_ptr inventory, + std::shared_ptr hopper) { + this->hopper = hopper; + hopper->startOpen(); + int yo = 51; + + for (int x = 0; x < hopper->getContainerSize(); x++) { + addSlot(new Slot(hopper, x, 44 + x * 18, 20)); + } + + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 9; x++) { + addSlot( + new Slot(inventory, x + y * 9 + 9, 8 + x * 18, y * 18 + yo)); + } + } + for (int x = 0; x < 9; x++) { + addSlot(new Slot(inventory, x, 8 + x * 18, 58 + yo)); + } +} + +bool HopperMenu::stillValid(std::shared_ptr player) { + return hopper->stillValid(player); +} + +std::shared_ptr HopperMenu::quickMoveStack( + std::shared_ptr player, int slotIndex) { + std::shared_ptr clicked = nullptr; + Slot* slot = slots.at(slotIndex); + if (slot != NULL && slot->hasItem()) { + std::shared_ptr stack = slot->getItem(); + clicked = stack->copy(); + + if (slotIndex < hopper->getContainerSize()) { + if (!moveItemStackTo(stack, hopper->getContainerSize(), + slots.size(), true)) { + return nullptr; + } + } else { + if (!moveItemStackTo(stack, 0, hopper->getContainerSize(), false)) { + return nullptr; + } + } + if (stack->count == 0) { + slot->set(nullptr); + } else { + slot->setChanged(); + } + } + return clicked; +} + +void HopperMenu::removed(std::shared_ptr player) { + AbstractContainerMenu::removed(player); + hopper->stopOpen(); +} + +std::shared_ptr HopperMenu::getContainer() { return hopper; } \ No newline at end of file diff --git a/Minecraft.World/Containers/HopperMenu.h b/Minecraft.World/Containers/HopperMenu.h new file mode 100644 index 000000000..f724685b0 --- /dev/null +++ b/Minecraft.World/Containers/HopperMenu.h @@ -0,0 +1,25 @@ +#pragma once + +#include "AbstractContainerMenu.h" + +class HopperMenu : public AbstractContainerMenu { +private: + std::shared_ptr hopper; + +public: + static const int CONTENTS_SLOT_START = 0; + static const int INV_SLOT_START = CONTENTS_SLOT_START + 5; + static const int INV_SLOT_END = INV_SLOT_START + 9 * 3; + static const int USE_ROW_SLOT_START = INV_SLOT_END; + static const int USE_ROW_SLOT_END = USE_ROW_SLOT_START + 9; + +public: + HopperMenu(std::shared_ptr inventory, + std::shared_ptr hopper); + + bool stillValid(std::shared_ptr player); + std::shared_ptr quickMoveStack(std::shared_ptr player, + int slotIndex); + void removed(std::shared_ptr player); + std::shared_ptr getContainer(); +}; \ No newline at end of file diff --git a/Minecraft.World/Containers/HorseInventoryMenu.cpp b/Minecraft.World/Containers/HorseInventoryMenu.cpp new file mode 100644 index 000000000..e4766aaef --- /dev/null +++ b/Minecraft.World/Containers/HorseInventoryMenu.cpp @@ -0,0 +1,116 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.entity.animal.h" +#include "HorseInventoryMenu.h" + +HorseSaddleSlot::HorseSaddleSlot(std::shared_ptr horseInventory) + : Slot(horseInventory, EntityHorse::INV_SLOT_SADDLE, 8, 18) {} + +bool HorseSaddleSlot::mayPlace(std::shared_ptr item) { + return Slot::mayPlace(item) && item->id == Item::saddle_Id && !hasItem(); +} + +HorseArmorSlot::HorseArmorSlot(HorseInventoryMenu* parent, + std::shared_ptr horseInventory) + : Slot(horseInventory, EntityHorse::INV_SLOT_ARMOR, 8, 18 * 2) { + m_parent = parent; +} + +bool HorseArmorSlot::mayPlace(std::shared_ptr item) { + return Slot::mayPlace(item) && m_parent->horse->canWearArmor() && + EntityHorse::isHorseArmor(item->id); +} + +bool HorseArmorSlot::isActive() { return m_parent->horse->canWearArmor(); } + +HorseInventoryMenu::HorseInventoryMenu( + std::shared_ptr playerInventory, + std::shared_ptr horseInventory, + std::shared_ptr horse) { + horseContainer = horseInventory; + this->horse = horse; + int containerRows = 3; + horseInventory->startOpen(); + + int yo = (containerRows - 4) * 18; + + // equipment slots + addSlot(new HorseSaddleSlot(horseInventory)); + addSlot(new HorseArmorSlot(this, horseInventory)); + + if (horse->isChestedHorse()) { + for (int y = 0; y < containerRows; y++) { + for (int x = 0; x < 5; x++) { + addSlot(new Slot(horseInventory, + EntityHorse::INV_BASE_COUNT + x + y * 5, + 80 + x * 18, 18 + y * 18)); + } + } + } + + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 9; x++) { + addSlot(new Slot(playerInventory, x + y * 9 + 9, 8 + x * 18, + 102 + y * 18 + yo)); + } + } + for (int x = 0; x < 9; x++) { + addSlot(new Slot(playerInventory, x, 8 + x * 18, 160 + yo)); + } +} + +bool HorseInventoryMenu::stillValid(std::shared_ptr player) { + return horseContainer->stillValid(player) && horse->isAlive() && + horse->distanceTo(player) < 8; +} + +std::shared_ptr HorseInventoryMenu::quickMoveStack( + std::shared_ptr player, int slotIndex) { + std::shared_ptr clicked = nullptr; + Slot* slot = slots.at(slotIndex); + if (slot != NULL && slot->hasItem()) { + std::shared_ptr stack = slot->getItem(); + clicked = stack->copy(); + + if (slotIndex < horseContainer->getContainerSize()) { + if (!moveItemStackTo(stack, horseContainer->getContainerSize(), + slots.size(), true)) { + return nullptr; + } + } else { + if (getSlot(EntityHorse::INV_SLOT_ARMOR)->mayPlace(stack) && + !getSlot(EntityHorse::INV_SLOT_ARMOR)->hasItem()) { + if (!moveItemStackTo(stack, EntityHorse::INV_SLOT_ARMOR, + EntityHorse::INV_SLOT_ARMOR + 1, false)) { + return nullptr; + } + } else if (getSlot(EntityHorse::INV_SLOT_SADDLE)->mayPlace(stack)) { + if (!moveItemStackTo(stack, EntityHorse::INV_SLOT_SADDLE, + EntityHorse::INV_SLOT_SADDLE + 1, false)) { + return nullptr; + } + } else if (horseContainer->getContainerSize() <= + EntityHorse::INV_BASE_COUNT || + !moveItemStackTo(stack, EntityHorse::INV_BASE_COUNT, + horseContainer->getContainerSize(), + false)) { + return nullptr; + } + } + if (stack->count == 0) { + slot->set(nullptr); + } else { + slot->setChanged(); + } + } + return clicked; +} + +void HorseInventoryMenu::removed(std::shared_ptr player) { + AbstractContainerMenu::removed(player); + horseContainer->stopOpen(); +} + +std::shared_ptr HorseInventoryMenu::getContainer() { + return horseContainer; +} \ No newline at end of file diff --git a/Minecraft.World/Containers/HorseInventoryMenu.h b/Minecraft.World/Containers/HorseInventoryMenu.h new file mode 100644 index 000000000..3ed23061e --- /dev/null +++ b/Minecraft.World/Containers/HorseInventoryMenu.h @@ -0,0 +1,44 @@ +#pragma once + +#include "AbstractContainerMenu.h" +#include "Slot.h" + +class HorseInventoryMenu; + +class HorseSaddleSlot : public Slot { +public: + HorseSaddleSlot(std::shared_ptr horseInventory); + + bool mayPlace(std::shared_ptr item); +}; + +class HorseArmorSlot : public Slot { +private: + HorseInventoryMenu* m_parent; + +public: + HorseArmorSlot(HorseInventoryMenu* parent, + std::shared_ptr horseInventory); + + bool mayPlace(std::shared_ptr item); + bool isActive(); +}; + +class HorseInventoryMenu : public AbstractContainerMenu { + friend class HorseArmorSlot; + +private: + std::shared_ptr horseContainer; + std::shared_ptr horse; + +public: + HorseInventoryMenu(std::shared_ptr playerInventory, + std::shared_ptr horseInventory, + std::shared_ptr horse); + + bool stillValid(std::shared_ptr player); + std::shared_ptr quickMoveStack(std::shared_ptr player, + int slotIndex); + void removed(std::shared_ptr player); + std::shared_ptr getContainer(); +}; \ No newline at end of file diff --git a/Minecraft.World/Containers/Inventory.cpp b/Minecraft.World/Containers/Inventory.cpp index acebcf17a..3e518fdd0 100644 --- a/Minecraft.World/Containers/Inventory.cpp +++ b/Minecraft.World/Containers/Inventory.cpp @@ -13,9 +13,9 @@ const int Inventory::MAX_INVENTORY_STACK_SIZE = 64; const int Inventory::INVENTORY_SIZE = 4 * 9; const int Inventory::SELECTION_SIZE = 9; -// 4J Stu - The Pllayer is managed by std::shared_ptrs elsewhere, but it owns us -// so we don't want to also keep a std::shared_ptr of it. If we pass it on we -// should use shared_from_this() though +// 4J Stu - The Pllayer is managed by shared_ptrs elsewhere, but it owns us so +// we don't want to also keep a shared_ptr of it. If we pass it on we should use +// shared_from_this() though Inventory::Inventory(Player* player) { items = ItemInstanceArray(INVENTORY_SIZE); armor = ItemInstanceArray(4); @@ -128,30 +128,56 @@ void Inventory::swapPaint(int wheel) { while (selected >= 9) selected -= 9; } -void Inventory::clearInventory() { - for (unsigned int i = 0; i < items.length; i++) { +int Inventory::clearInventory(int id, int data) { + int count = 0; + for (int i = 0; i < items.length; i++) { + std::shared_ptr item = items[i]; + if (item == NULL) continue; + if (id > -1 && item->id != id) continue; + if (data > -1 && item->getAuxValue() != data) continue; + + count += item->count; items[i] = nullptr; } - for (unsigned int i = 0; i < armor.length; i++) { + for (int i = 0; i < armor.length; i++) { + std::shared_ptr item = armor[i]; + if (item == NULL) continue; + if (id > -1 && item->id != id) continue; + if (data > -1 && item->getAuxValue() != data) continue; + + count += item->count; armor[i] = nullptr; } + + if (carried != NULL) { + if (id > -1 && carried->id != id) return count; + if (data > -1 && carried->getAuxValue() != data) return count; + + count += carried->count; + setCarried(nullptr); + } + + return count; } void Inventory::replaceSlot(Item* item, int data) { if (item != NULL) { - int oldSlot = getSlot(item->id, data); - if (oldSlot >= 0) { - items[oldSlot] = items[selected]; - } - - // It's too easy to accidentally pick block and lose enchanted - // items. + // It's too easy to accidentally pick block and lose enchanted items. if (heldItem != NULL && heldItem->isEnchantable() && getSlot(heldItem->id, heldItem->getDamageValue()) == selected) { return; } - items[selected] = std::shared_ptr( - new ItemInstance(Item::items[item->id], 1, data)); + + int oldSlot = getSlot(item->id, data); + if (oldSlot >= 0) { + int oldSlotCount = items[oldSlot]->count; + items[oldSlot] = items[selected]; + items[selected] = std::shared_ptr( + new ItemInstance(Item::items[item->id], oldSlotCount, data)); + } else { + items[selected] = std::shared_ptr( + new ItemInstance(Item::items[item->id], 1, data)); + } } } @@ -270,8 +296,8 @@ void Inventory::swapSlots(int from, int to) { } bool Inventory::add(std::shared_ptr item) { - // 4J Stu - Fix for duplication glitch - if (item->count <= 0) return true; + if (item == NULL) return false; + if (item->count == 0) return false; if (!item->isDamaged()) { int lastSize; @@ -305,7 +331,7 @@ bool Inventory::add(std::shared_ptr item) { item->GetCount())); items[slot] = ItemInstance::clone(item); - items[slot]->popTime = Inventory::POP_TIME_DURATION; + items[slot]->popTime = POP_TIME_DURATION; item->count = 0; return true; } else if (player->abilities.instabuild) { @@ -460,16 +486,14 @@ std::shared_ptr Inventory::getItem(unsigned int slot) { */ } -int Inventory::getName() { return IDS_INVENTORY; } +std::wstring Inventory::getName() { return app.GetString(IDS_INVENTORY); } + +std::wstring Inventory::getCustomName() { return L""; } + +bool Inventory::hasCustomName() { return false; } int Inventory::getMaxStackSize() { return MAX_INVENTORY_STACK_SIZE; } -int Inventory::getAttackDamage(std::shared_ptr entity) { - std::shared_ptr item = getItem(selected); - if (item != NULL) return item->getAttackDamage(entity); - return 1; -} - bool Inventory::canDestroy(Tile* tile) { if (tile->material->isAlwaysDestroyable()) return true; @@ -496,7 +520,7 @@ int Inventory::getArmorValue() { return val; } -void Inventory::hurtArmor(int dmg) { +void Inventory::hurtArmor(float dmg) { dmg = dmg / 4; if (dmg < 1) { dmg = 1; @@ -504,8 +528,9 @@ void Inventory::hurtArmor(int dmg) { for (unsigned int i = 0; i < armor.length; i++) { if (armor[i] != NULL && dynamic_cast(armor[i]->getItem()) != NULL) { - armor[i]->hurt(dmg, std::dynamic_pointer_cast( - player->shared_from_this())); + armor[i]->hurtAndBreak((int)dmg, + std::dynamic_pointer_cast( + player->shared_from_this())); if (armor[i]->count == 0) { armor[i] = nullptr; } @@ -577,10 +602,10 @@ bool Inventory::stillValid(std::shared_ptr player) { bool Inventory::contains(std::shared_ptr itemInstance) { for (unsigned int i = 0; i < armor.length; i++) { - if (armor[i] != NULL && armor[i]->equals(itemInstance)) return true; + if (armor[i] != NULL && armor[i]->sameItem(itemInstance)) return true; } for (unsigned int i = 0; i < items.length; i++) { - if (items[i] != NULL && items[i]->equals(itemInstance)) return true; + if (items[i] != NULL && items[i]->sameItem(itemInstance)) return true; } return false; } @@ -593,6 +618,10 @@ void Inventory::stopOpen() { // TODO Auto-generated method stub } +bool Inventory::canPlaceItem(int slot, std::shared_ptr item) { + return true; +} + void Inventory::replaceWith(std::shared_ptr other) { for (int i = 0; i < items.length; i++) { items[i] = ItemInstance::clone(other->items[i]); @@ -600,6 +629,8 @@ void Inventory::replaceWith(std::shared_ptr other) { for (int i = 0; i < armor.length; i++) { armor[i] = ItemInstance::clone(other->armor[i]); } + + selected = other->selected; } int Inventory::countMatches(std::shared_ptr itemInstance) { @@ -608,7 +639,7 @@ int Inventory::countMatches(std::shared_ptr itemInstance) { // for (unsigned int i = 0; i < armor.length; i++) //{ // if (armor[i] != NULL && armor[i]->sameItem(itemInstance)) count += - //items[i]->count; + // items[i]->count; // } for (unsigned int i = 0; i < items.length; i++) { if (items[i] != NULL && items[i]->sameItemWithTags(itemInstance)) diff --git a/Minecraft.World/Containers/Inventory.h b/Minecraft.World/Containers/Inventory.h index 9ffbcacb0..82b8db031 100644 --- a/Minecraft.World/Containers/Inventory.h +++ b/Minecraft.World/Containers/Inventory.h @@ -1,5 +1,4 @@ #pragma once - #include "Container.h" #include "../IO/NBT/ListTag.h" #include "../Items/ItemInstance.h" @@ -21,8 +20,7 @@ public: ItemInstanceArray armor; int selected; - Player* - player; // This is owned by std::shared_ptrs, but we are owned by it + Player* player; // This is owned by shared_ptrs, but we are owned by it private: std::shared_ptr heldItem; @@ -37,7 +35,6 @@ public: std::shared_ptr getSelected(); // 4J-PB - Added for the in-game tooltips bool IsHeldItem(); - static int getSelectionSize(); private: @@ -48,13 +45,9 @@ private: public: int getFreeSlot(); - void grabTexture(int id, int data, bool checkData, bool mayReplace); - void swapPaint(int wheel); - - void clearInventory(); - + int clearInventory(int id, int data); void replaceSlot(Item* item, int data); private: @@ -62,7 +55,6 @@ private: public: void tick(); - bool removeResource(int type); // 4J-PB added to get the right resource from the inventory for removal @@ -76,44 +68,26 @@ public: std::shared_ptr getResourceItem(int type, int iAuxVal); bool hasResource(int type); - void swapSlots(int from, int to); - bool add(std::shared_ptr item); - std::shared_ptr removeItem(unsigned int slot, int count); virtual std::shared_ptr removeItemNoUpdate(int slot); - void setItem(unsigned int slot, std::shared_ptr item); - float getDestroySpeed(Tile* tile); - ListTag* save(ListTag* listTag); - void load(ListTag* inventoryList); - unsigned int getContainerSize(); - std::shared_ptr getItem(unsigned int slot); - - int getName(); - + std::wstring getName(); + std::wstring getCustomName(); + bool hasCustomName(); int getMaxStackSize(); - - int getAttackDamage(std::shared_ptr entity); - bool canDestroy(Tile* tile); - std::shared_ptr getArmor(int layer); - int getArmorValue(); - - void hurtArmor(int dmg); - + void hurtArmor(float dmg); void dropAll(); - void setChanged(); - bool isSame(std::shared_ptr copy); private: @@ -122,17 +96,13 @@ private: public: std::shared_ptr copy(); - void setCarried(std::shared_ptr carried); - std::shared_ptr getCarried(); - bool stillValid(std::shared_ptr player); - bool contains(std::shared_ptr itemInstance); - virtual void startOpen(); virtual void stopOpen(); + bool canPlaceItem(int slot, std::shared_ptr item); void replaceWith(std::shared_ptr other); int countMatches(std::shared_ptr itemInstance); // 4J Added diff --git a/Minecraft.World/Containers/InventoryMenu.cpp b/Minecraft.World/Containers/InventoryMenu.cpp index 2a83d89bf..ffc027a2b 100644 --- a/Minecraft.World/Containers/InventoryMenu.cpp +++ b/Minecraft.World/Containers/InventoryMenu.cpp @@ -65,9 +65,9 @@ void InventoryMenu::_init(std::shared_ptr inventory, bool active) { slotsChanged(); // 4J removed craftSlots parameter, see comment below } -void InventoryMenu::slotsChanged() // 4J used to take a - // std::shared_ptr but wasn't - // using it, so removed to simplify things +void InventoryMenu::slotsChanged() // 4J used to take a shared_ptr + // but wasn't using it, so removed to + // simplify things { MemSect(23); resultSlots->setItem( @@ -92,12 +92,12 @@ bool InventoryMenu::stillValid(std::shared_ptr player) { return true; } std::shared_ptr InventoryMenu::quickMoveStack( std::shared_ptr player, int slotIndex) { std::shared_ptr clicked = nullptr; - Slot* slot = slots->at(slotIndex); + Slot* slot = slots.at(slotIndex); - Slot* HelmetSlot = slots->at(ARMOR_SLOT_START); - Slot* ChestplateSlot = slots->at(ARMOR_SLOT_START + 1); - Slot* LeggingsSlot = slots->at(ARMOR_SLOT_START + 2); - Slot* BootsSlot = slots->at(ARMOR_SLOT_START + 3); + Slot* HelmetSlot = slots.at(ARMOR_SLOT_START); + Slot* ChestplateSlot = slots.at(ARMOR_SLOT_START + 1); + Slot* LeggingsSlot = slots.at(ARMOR_SLOT_START + 2); + Slot* BootsSlot = slots.at(ARMOR_SLOT_START + 3); if (slot != NULL && slot->hasItem()) { std::shared_ptr stack = slot->getItem(); @@ -211,18 +211,25 @@ bool InventoryMenu::mayCombine(Slot* slot, std::shared_ptr item) { return slot->mayCombine(item); } +bool InventoryMenu::canTakeItemForPickAll(std::shared_ptr carried, + Slot* target) { + return target->container != resultSlots && + AbstractContainerMenu::canTakeItemForPickAll(carried, target); +} + // 4J-JEV: Added for achievement 'Iron Man'. std::shared_ptr InventoryMenu::clicked( - int slotIndex, int buttonNum, int clickType, - std::shared_ptr player) { - std::shared_ptr out = - AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, player); + int slotIndex, int buttonNum, int clickType, std::shared_ptr player, + bool looped) // 4J Added looped param +{ + std::shared_ptr out = AbstractContainerMenu::clicked( + slotIndex, buttonNum, clickType, player, looped); #ifdef _EXTENDED_ACHIEVEMENTS static int ironItems[4] = {Item::helmet_iron_Id, Item::chestplate_iron_Id, Item::leggings_iron_Id, Item::boots_iron_Id}; for (int i = ARMOR_SLOT_START; i < ARMOR_SLOT_END; i++) { - Slot* slot = slots->at(i); + Slot* slot = slots.at(i); if ((slot == NULL) || (!slot->hasItem()) || (slot->getItem()->getItem()->id != ironItems[i - ARMOR_SLOT_START])) { diff --git a/Minecraft.World/Containers/InventoryMenu.h b/Minecraft.World/Containers/InventoryMenu.h index de96f4bd7..5ed51d581 100644 --- a/Minecraft.World/Containers/InventoryMenu.h +++ b/Minecraft.World/Containers/InventoryMenu.h @@ -41,9 +41,11 @@ public: virtual std::shared_ptr quickMoveStack( std::shared_ptr player, int slotIndex); virtual bool mayCombine(Slot* slot, std::shared_ptr item); + virtual bool canTakeItemForPickAll(std::shared_ptr carried, + Slot* target); // 4J ADDED, virtual std::shared_ptr clicked( int slotIndex, int buttonNum, int clickType, - std::shared_ptr player); + std::shared_ptr player, bool looped = false); }; diff --git a/Minecraft.World/Containers/MenuBackup.cpp b/Minecraft.World/Containers/MenuBackup.cpp index b64e5145d..4e4c98d31 100644 --- a/Minecraft.World/Containers/MenuBackup.cpp +++ b/Minecraft.World/Containers/MenuBackup.cpp @@ -15,19 +15,19 @@ MenuBackup::MenuBackup(std::shared_ptr inventory, void MenuBackup::save(short changeUid) { ItemInstanceArray* backup = - new ItemInstanceArray((int)menu->slots->size() + 1); + new ItemInstanceArray((int)menu->slots.size() + 1); (*backup)[0] = ItemInstance::clone(inventory->getCarried()); - for (unsigned int i = 0; i < menu->slots->size(); i++) { - (*backup)[i + 1] = ItemInstance::clone(menu->slots->at(i)->getItem()); + for (unsigned int i = 0; i < menu->slots.size(); i++) { + (*backup)[i + 1] = ItemInstance::clone(menu->slots.at(i)->getItem()); } - // TODO Is std::unordered_map use correct? + // TODO Is unordered_map use correct? // Was backups.put(changeUid, backup); (*backups)[changeUid] = backup; } // Cannot use delete as function name as it is a reserved keyword void MenuBackup::deleteBackup(short changeUid) { - // TODO Is the std::unordered_map use correct? + // TODO Is the unordered_map use correct? // 4J Was backups.remove(changeUid); backups->erase(changeUid); } @@ -36,7 +36,7 @@ void MenuBackup::rollback(short changeUid) { ItemInstanceArray* backup = backups->at(changeUid); backups->clear(); inventory->setCarried((*backup)[0]); - for (unsigned int i = 0; i < menu->slots->size(); i++) { - menu->slots->at(i)->set((*backup)[i + 1]); + for (unsigned int i = 0; i < menu->slots.size(); i++) { + menu->slots.at(i)->set((*backup)[i + 1]); } } \ No newline at end of file diff --git a/Minecraft.World/Containers/Merchant.h b/Minecraft.World/Containers/Merchant.h index e2c6b34ac..8c9e74f04 100644 --- a/Minecraft.World/Containers/Merchant.h +++ b/Minecraft.World/Containers/Merchant.h @@ -14,5 +14,5 @@ public: virtual void overrideOffers(MerchantRecipeList* recipeList) = 0; virtual void notifyTrade(MerchantRecipe* activeRecipe) = 0; virtual void notifyTradeUpdated(std::shared_ptr item) = 0; - virtual int getDisplayName() = 0; -}; + virtual std::wstring getDisplayName() = 0; +}; \ No newline at end of file diff --git a/Minecraft.World/Containers/MerchantContainer.cpp b/Minecraft.World/Containers/MerchantContainer.cpp index 5f12e4cd8..b4d5986ed 100644 --- a/Minecraft.World/Containers/MerchantContainer.cpp +++ b/Minecraft.World/Containers/MerchantContainer.cpp @@ -74,7 +74,11 @@ void MerchantContainer::setItem(unsigned int slot, } } -int MerchantContainer::getName() { return merchant->getDisplayName(); } +std::wstring MerchantContainer::getName() { return merchant->getDisplayName(); } + +std::wstring MerchantContainer::getCustomName() { return L""; } + +bool MerchantContainer::hasCustomName() { return false; } int MerchantContainer::getMaxStackSize() { return Container::LARGE_MAX_STACK_SIZE; @@ -88,6 +92,11 @@ void MerchantContainer::startOpen() {} void MerchantContainer::stopOpen() {} +bool MerchantContainer::canPlaceItem(int slot, + std::shared_ptr item) { + return true; +} + void MerchantContainer::setChanged() { updateSellItem(); } void MerchantContainer::updateSellItem() { diff --git a/Minecraft.World/Containers/MerchantContainer.h b/Minecraft.World/Containers/MerchantContainer.h index 173490f83..76c676a9c 100644 --- a/Minecraft.World/Containers/MerchantContainer.h +++ b/Minecraft.World/Containers/MerchantContainer.h @@ -30,11 +30,14 @@ private: public: std::shared_ptr removeItemNoUpdate(int slot); void setItem(unsigned int slot, std::shared_ptr item); - int getName(); + std::wstring getName(); + std::wstring getCustomName(); + bool hasCustomName(); int getMaxStackSize(); bool stillValid(std::shared_ptr player); void startOpen(); void stopOpen(); + bool canPlaceItem(int slot, std::shared_ptr item); void setChanged(); void updateSellItem(); MerchantRecipe* getActiveRecipe(); diff --git a/Minecraft.World/Containers/MerchantMenu.cpp b/Minecraft.World/Containers/MerchantMenu.cpp index 34a95d5ef..637f6b289 100644 --- a/Minecraft.World/Containers/MerchantMenu.cpp +++ b/Minecraft.World/Containers/MerchantMenu.cpp @@ -42,8 +42,8 @@ void MerchantMenu::broadcastChanges() { AbstractContainerMenu::broadcastChanges(); } -// 4J used to take a std::shared_ptr but wasn't using it, so removed -// to simplify things +// 4J used to take a shared_ptr but wasn't using it, so removed to +// simplify things void MerchantMenu::slotsChanged() { tradeContainer->updateSellItem(); AbstractContainerMenu::slotsChanged(); @@ -64,7 +64,7 @@ std::shared_ptr MerchantMenu::quickMoveStack( std::shared_ptr clicked = nullptr; Slot* slot = NULL; - if (slotIndex < slots->size()) slot = slots->at(slotIndex); + if (slotIndex < slots.size()) slot = slots.at(slotIndex); if (slot != NULL && slot->hasItem()) { std::shared_ptr stack = slot->getItem(); clicked = stack->copy(); diff --git a/Minecraft.World/Containers/MerchantRecipeList.cpp b/Minecraft.World/Containers/MerchantRecipeList.cpp index a30a3f818..3e0426032 100644 --- a/Minecraft.World/Containers/MerchantRecipeList.cpp +++ b/Minecraft.World/Containers/MerchantRecipeList.cpp @@ -125,10 +125,11 @@ MerchantRecipeList* MerchantRecipeList::createFromStream( } void MerchantRecipeList::load(CompoundTag* tag) { - ListTag* list = tag->getList(L"Recipes"); + ListTag* list = + (ListTag*)tag->getList(L"Recipes"); for (int i = 0; i < list->size(); i++) { - CompoundTag* recipeTag = (CompoundTag*)list->get(i); + CompoundTag* recipeTag = list->get(i); m_recipes.push_back(new MerchantRecipe(recipeTag)); } } @@ -169,4 +170,4 @@ std::vector::iterator MerchantRecipeList::erase( size_t MerchantRecipeList::size() { return m_recipes.size(); } -bool MerchantRecipeList::empty() { return m_recipes.empty(); } +bool MerchantRecipeList::empty() { return m_recipes.empty(); } \ No newline at end of file diff --git a/Minecraft.World/Containers/RepairContainer.cpp b/Minecraft.World/Containers/RepairContainer.cpp index 464d5fd63..53dfa21c5 100644 --- a/Minecraft.World/Containers/RepairContainer.cpp +++ b/Minecraft.World/Containers/RepairContainer.cpp @@ -1,13 +1,19 @@ #include "../Platform/stdafx.h" -#include "RepairMenu.h" +#include "AnvilMenu.h" #include "RepairContainer.h" -RepairContainer::RepairContainer(RepairMenu* menu, int name, int size) - : SimpleContainer(name, size) { +RepairContainer::RepairContainer(AnvilMenu* menu, int name, bool customName, + int size) + : SimpleContainer(name, L"", customName, size) { m_menu = menu; } void RepairContainer::setChanged() { SimpleContainer::setChanged(); m_menu->slotsChanged(shared_from_this()); +} + +bool RepairContainer::canPlaceItem(int slot, + std::shared_ptr item) { + return true; } \ No newline at end of file diff --git a/Minecraft.World/Containers/RepairContainer.h b/Minecraft.World/Containers/RepairContainer.h index 33fb5c1b9..edb7a6756 100644 --- a/Minecraft.World/Containers/RepairContainer.h +++ b/Minecraft.World/Containers/RepairContainer.h @@ -2,14 +2,15 @@ #include "SimpleContainer.h" -class RepairMenu; +class AnvilMenu; class RepairContainer : public SimpleContainer, public std::enable_shared_from_this { private: - RepairMenu* m_menu; + AnvilMenu* m_menu; public: - RepairContainer(RepairMenu* menu, int name, int size); + RepairContainer(AnvilMenu* menu, int name, bool customName, int size); void setChanged(); + bool canPlaceItem(int slot, std::shared_ptr item); }; \ No newline at end of file diff --git a/Minecraft.World/Containers/RepairResultSlot.cpp b/Minecraft.World/Containers/RepairResultSlot.cpp index bbe228a23..5291605c2 100644 --- a/Minecraft.World/Containers/RepairResultSlot.cpp +++ b/Minecraft.World/Containers/RepairResultSlot.cpp @@ -5,7 +5,7 @@ #include "../Headers/net.minecraft.world.entity.player.h" #include "RepairResultSlot.h" -RepairResultSlot::RepairResultSlot(RepairMenu* menu, int xt, int yt, int zt, +RepairResultSlot::RepairResultSlot(AnvilMenu* menu, int xt, int yt, int zt, std::shared_ptr container, int slot, int x, int y) : Slot(container, slot, x, y) { @@ -28,19 +28,19 @@ bool RepairResultSlot::mayPickup(std::shared_ptr player) { void RepairResultSlot::onTake(std::shared_ptr player, std::shared_ptr carried) { if (!player->abilities.instabuild) - player->withdrawExperienceLevels(m_menu->cost); - m_menu->repairSlots->setItem(RepairMenu::INPUT_SLOT, nullptr); + player->giveExperienceLevels(-m_menu->cost); + m_menu->repairSlots->setItem(AnvilMenu::INPUT_SLOT, nullptr); if (m_menu->repairItemCountCost > 0) { std::shared_ptr addition = - m_menu->repairSlots->getItem(RepairMenu::ADDITIONAL_SLOT); + m_menu->repairSlots->getItem(AnvilMenu::ADDITIONAL_SLOT); if (addition != NULL && addition->count > m_menu->repairItemCountCost) { addition->count -= m_menu->repairItemCountCost; - m_menu->repairSlots->setItem(RepairMenu::ADDITIONAL_SLOT, addition); + m_menu->repairSlots->setItem(AnvilMenu::ADDITIONAL_SLOT, addition); } else { - m_menu->repairSlots->setItem(RepairMenu::ADDITIONAL_SLOT, nullptr); + m_menu->repairSlots->setItem(AnvilMenu::ADDITIONAL_SLOT, nullptr); } } else { - m_menu->repairSlots->setItem(RepairMenu::ADDITIONAL_SLOT, nullptr); + m_menu->repairSlots->setItem(AnvilMenu::ADDITIONAL_SLOT, nullptr); } m_menu->cost = 0; @@ -52,11 +52,12 @@ void RepairResultSlot::onTake(std::shared_ptr player, int dmg = data >> 2; if (++dmg > 2) { - m_menu->level->setTile(xt, yt, zt, 0); + m_menu->level->removeTile(xt, yt, zt); m_menu->level->levelEvent(LevelEvent::SOUND_ANVIL_BROKEN, xt, yt, zt, 0); } else { - m_menu->level->setData(xt, yt, zt, dir | (dmg << 2)); + m_menu->level->setData(xt, yt, zt, dir | (dmg << 2), + Tile::UPDATE_CLIENTS); m_menu->level->levelEvent(LevelEvent::SOUND_ANVIL_USED, xt, yt, zt, 0); } diff --git a/Minecraft.World/Containers/RepairResultSlot.h b/Minecraft.World/Containers/RepairResultSlot.h index bbc6b6e3b..1f8f0f4ea 100644 --- a/Minecraft.World/Containers/RepairResultSlot.h +++ b/Minecraft.World/Containers/RepairResultSlot.h @@ -2,15 +2,15 @@ #include "Slot.h" -class RepairMenu; +class AnvilMenu; class RepairResultSlot : public Slot { private: - RepairMenu* m_menu; + AnvilMenu* m_menu; int xt, yt, zt; public: - RepairResultSlot(RepairMenu* menu, int xt, int yt, int zt, + RepairResultSlot(AnvilMenu* menu, int xt, int yt, int zt, std::shared_ptr container, int slot, int x, int y); diff --git a/Minecraft.World/Containers/ResultContainer.cpp b/Minecraft.World/Containers/ResultContainer.cpp index fd38f5cbe..722d60e58 100644 --- a/Minecraft.World/Containers/ResultContainer.cpp +++ b/Minecraft.World/Containers/ResultContainer.cpp @@ -2,32 +2,34 @@ #include "../Headers/net.minecraft.world.entity.player.h" #include "ResultContainer.h" -ResultContainer::ResultContainer() : Container() { - items = new ItemInstanceArray(1); -} +ResultContainer::ResultContainer() : Container() {} unsigned int ResultContainer::getContainerSize() { return 1; } std::shared_ptr ResultContainer::getItem(unsigned int slot) { - return (*items)[0]; + return items[0]; } -int ResultContainer::getName() { return 0; } +std::wstring ResultContainer::getName() { return L""; } + +std::wstring ResultContainer::getCustomName() { return L""; } + +bool ResultContainer::hasCustomName() { return false; } std::shared_ptr ResultContainer::removeItem(unsigned int slot, int count) { - if ((*items)[0] != NULL) { - std::shared_ptr item = (*items)[0]; - (*items)[0] = nullptr; + if (items[0] != NULL) { + std::shared_ptr item = items[0]; + items[0] = nullptr; return item; } return nullptr; } std::shared_ptr ResultContainer::removeItemNoUpdate(int slot) { - if ((*items)[0] != NULL) { - std::shared_ptr item = (*items)[0]; - (*items)[0] = nullptr; + if (items[0] != NULL) { + std::shared_ptr item = items[0]; + items[0] = nullptr; return item; } return nullptr; @@ -35,7 +37,7 @@ std::shared_ptr ResultContainer::removeItemNoUpdate(int slot) { void ResultContainer::setItem(unsigned int slot, std::shared_ptr item) { - (*items)[0] = item; + items[0] = item; } int ResultContainer::getMaxStackSize() { @@ -46,4 +48,9 @@ void ResultContainer::setChanged() {} bool ResultContainer::stillValid(std::shared_ptr player) { return true; +} + +bool ResultContainer::canPlaceItem(int slot, + std::shared_ptr item) { + return true; } \ No newline at end of file diff --git a/Minecraft.World/Containers/ResultContainer.h b/Minecraft.World/Containers/ResultContainer.h index 3f1e4a360..69ed8ed1e 100644 --- a/Minecraft.World/Containers/ResultContainer.h +++ b/Minecraft.World/Containers/ResultContainer.h @@ -4,16 +4,17 @@ class ResultContainer : public Container { private: - ItemInstanceArray* items; + std::shared_ptr items[1]; public: // 4J Stu Added a ctor to init items ResultContainer(); - virtual ~ResultContainer() {} virtual unsigned int getContainerSize(); virtual std::shared_ptr getItem(unsigned int slot); - virtual int getName(); + virtual std::wstring getName(); + virtual std::wstring getCustomName(); + virtual bool hasCustomName(); virtual std::shared_ptr removeItem(unsigned int slot, int count); virtual std::shared_ptr removeItemNoUpdate(int slot); @@ -21,7 +22,7 @@ public: virtual int getMaxStackSize(); virtual void setChanged(); virtual bool stillValid(std::shared_ptr player); - - void startOpen() {} // TODO Auto-generated method stub - void stopOpen() {} // TODO Auto-generated method stub -}; + virtual void startOpen() {} // TODO Auto-generated method stub + virtual void stopOpen() {} // TODO Auto-generated method stub + virtual bool canPlaceItem(int slot, std::shared_ptr item); +}; \ No newline at end of file diff --git a/Minecraft.World/Containers/ResultSlot.cpp b/Minecraft.World/Containers/ResultSlot.cpp index 1d661d84a..30bdbb60f 100644 --- a/Minecraft.World/Containers/ResultSlot.cpp +++ b/Minecraft.World/Containers/ResultSlot.cpp @@ -83,28 +83,26 @@ void ResultSlot::onTake(std::shared_ptr player, craftSlots->removeItem(i, 1); if (item->getItem()->hasCraftingRemainingItem()) { - // (TheApathetic) std::shared_ptr craftResult = std::shared_ptr(new ItemInstance( item->getItem()->getCraftingRemainingItem())); /* - * Try to place this in the player's inventory (See we.java - * for new method) + * Try to place this in the player's inventory (See we.java for + * new method) */ if (item->getItem()->shouldMoveCraftingResultToInventory( item) && - this->player->inventory->add(craftResult)) { + player->inventory->add(craftResult)) { continue; } - // If this slot is now empty, place it there (current - // behavior) + // If this slot is now empty, place it there (current behavior) if (craftSlots->getItem(i) == NULL) { craftSlots->setItem(i, craftResult); } else { // Finally, if nothing else, just drop the item - this->player->drop(craftResult); + player->drop(craftResult); } } } diff --git a/Minecraft.World/Containers/SimpleContainer.cpp b/Minecraft.World/Containers/SimpleContainer.cpp index d0711c582..2651ca487 100644 --- a/Minecraft.World/Containers/SimpleContainer.cpp +++ b/Minecraft.World/Containers/SimpleContainer.cpp @@ -5,8 +5,11 @@ #include "SimpleContainer.h" -SimpleContainer::SimpleContainer(int name, int size) { +SimpleContainer::SimpleContainer(int name, std::wstring stringName, + bool customName, int size) { this->name = name; + this->stringName = stringName; + this->customName = customName; this->size = size; items = new ItemInstanceArray(size); @@ -44,12 +47,12 @@ std::shared_ptr SimpleContainer::removeItem(unsigned int slot, if ((*items)[slot]->count <= count) { std::shared_ptr item = (*items)[slot]; (*items)[slot] = nullptr; - this->setChanged(); + setChanged(); return item; } else { std::shared_ptr i = (*items)[slot]->remove(count); if ((*items)[slot]->count == 0) (*items)[slot] = nullptr; - this->setChanged(); + setChanged(); return i; } } @@ -70,29 +73,42 @@ void SimpleContainer::setItem(unsigned int slot, (*items)[slot] = item; if (item != NULL && item->count > getMaxStackSize()) item->count = getMaxStackSize(); - this->setChanged(); + setChanged(); } unsigned int SimpleContainer::getContainerSize() { return size; } -int SimpleContainer::getName() { return name; } +std::wstring SimpleContainer::getName() { + return stringName.empty() ? app.GetString(name) : stringName; +} + +std::wstring SimpleContainer::getCustomName() { + return hasCustomName() ? stringName : L""; +} + +bool SimpleContainer::hasCustomName() { return customName; } + +void SimpleContainer::setCustomName(const std::wstring& name) { + customName = true; + this->stringName = name; +} int SimpleContainer::getMaxStackSize() { return Container::LARGE_MAX_STACK_SIZE; } void SimpleContainer::setChanged() { - // 4J - removing this as we don't seem to have any implementation of a - // listener containerChanged function, and shared_from_this is proving - // tricky to add to containers -#if 0 - if (listeners != NULL) for (unsigned int i = 0; i < listeners->size(); i++) - { - listeners->at(i)->containerChanged(shared_from_this()); - } -#endif + if (listeners != NULL) + for (unsigned int i = 0; i < listeners->size(); i++) { + listeners->at(i)->containerChanged(); // shared_from_this()); + } } bool SimpleContainer::stillValid(std::shared_ptr player) { return true; +} + +bool SimpleContainer::canPlaceItem(int slot, + std::shared_ptr item) { + return true; } \ No newline at end of file diff --git a/Minecraft.World/Containers/SimpleContainer.h b/Minecraft.World/Containers/SimpleContainer.h index b13f08a9b..74392b3f3 100644 --- a/Minecraft.World/Containers/SimpleContainer.h +++ b/Minecraft.World/Containers/SimpleContainer.h @@ -6,34 +6,33 @@ class SimpleContainer : public Container { private: int name; + std::wstring stringName; int size; ItemInstanceArray* items; std::vector* listeners; + bool customName; public: - SimpleContainer(int name, int size); + SimpleContainer(int name, std::wstring stringName, bool customName, + int size); - void addListener(net_minecraft_world::ContainerListener* listener); - - void removeListener(net_minecraft_world::ContainerListener* listener); - - std::shared_ptr getItem(unsigned int slot); - - std::shared_ptr removeItem(unsigned int slot, int count); - std::shared_ptr removeItemNoUpdate(int slot); - - void setItem(unsigned int slot, std::shared_ptr item); - - unsigned int getContainerSize(); - - int getName(); - - int getMaxStackSize(); - - void setChanged(); - - bool stillValid(std::shared_ptr player); - - void startOpen() {} // TODO Auto-generated method stub - void stopOpen() {} // TODO Auto-generated method stub + virtual void addListener(net_minecraft_world::ContainerListener* listener); + virtual void removeListener( + net_minecraft_world::ContainerListener* listener); + virtual std::shared_ptr getItem(unsigned int slot); + virtual std::shared_ptr removeItem(unsigned int slot, + int count); + virtual std::shared_ptr removeItemNoUpdate(int slot); + virtual void setItem(unsigned int slot, std::shared_ptr item); + virtual unsigned int getContainerSize(); + virtual std::wstring getName(); + virtual std::wstring getCustomName(); + virtual bool hasCustomName(); + virtual void setCustomName(const std::wstring& name); + virtual int getMaxStackSize(); + virtual void setChanged(); + virtual bool stillValid(std::shared_ptr player); + virtual void startOpen() {} // TODO Auto-generated method stub + virtual void stopOpen() {} // TODO Auto-generated method stub + virtual bool canPlaceItem(int slot, std::shared_ptr item); }; \ No newline at end of file diff --git a/Minecraft.World/Containers/Slot.cpp b/Minecraft.World/Containers/Slot.cpp index fca1e6641..5eee6da94 100644 --- a/Minecraft.World/Containers/Slot.cpp +++ b/Minecraft.World/Containers/Slot.cpp @@ -84,6 +84,8 @@ bool Slot::isAt(std::shared_ptr c, int s) { bool Slot::mayPickup(std::shared_ptr player) { return true; } +bool Slot::isActive() { return true; } + bool Slot::mayCombine(std::shared_ptr second) { std::shared_ptr first = getItem(); diff --git a/Minecraft.World/Containers/Slot.h b/Minecraft.World/Containers/Slot.h index e365217d8..748ac5256 100644 --- a/Minecraft.World/Containers/Slot.h +++ b/Minecraft.World/Containers/Slot.h @@ -37,6 +37,7 @@ public: virtual std::shared_ptr remove(int c); virtual bool isAt(std::shared_ptr c, int s); virtual bool mayPickup(std::shared_ptr player); + virtual bool isActive(); virtual bool mayCombine(std::shared_ptr item); // 4J Added virtual std::shared_ptr combine( std::shared_ptr item); // 4J Added diff --git a/Minecraft.World/Containers/TrapMenu.cpp b/Minecraft.World/Containers/TrapMenu.cpp index 947a372e6..a48c7648c 100644 --- a/Minecraft.World/Containers/TrapMenu.cpp +++ b/Minecraft.World/Containers/TrapMenu.cpp @@ -34,7 +34,7 @@ bool TrapMenu::stillValid(std::shared_ptr player) { std::shared_ptr TrapMenu::quickMoveStack( std::shared_ptr player, int slotIndex) { std::shared_ptr clicked = nullptr; - Slot* slot = slots->at(slotIndex); + Slot* slot = slots.at(slotIndex); if (slot != NULL && slot->hasItem()) { std::shared_ptr stack = slot->getItem(); clicked = stack->copy(); diff --git a/Minecraft.World/Containers/WorldlyContainer.h b/Minecraft.World/Containers/WorldlyContainer.h new file mode 100644 index 000000000..0453f602a --- /dev/null +++ b/Minecraft.World/Containers/WorldlyContainer.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Container.h" + +class WorldlyContainer : public Container { +public: + virtual intArray getSlotsForFace(int face) = 0; + virtual bool canPlaceItemThroughFace(int slot, + std::shared_ptr item, + int face) = 0; + virtual bool canTakeItemThroughFace(int slot, + std::shared_ptr item, + int face) = 0; +}; \ No newline at end of file