TU19: merge Minecraft.World/Containers

keeping virtual destructors where possible
This commit is contained in:
Tropical 2026-03-21 15:18:52 -05:00
parent db0a6b2e6a
commit f25cd66f4d
56 changed files with 1412 additions and 373 deletions

View file

@ -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<std::shared_ptr<ItemInstance> >();
slots = new std::vector<Slot*>();
containerId = 0;
changeUid = 0;
m_bNeedsRendered = false;
containerListeners = new std::vector<ContainerListener*>();
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<std::shared_ptr<ItemInstance> >* 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<std::shared_ptr<ItemInstance> >* AbstractContainerMenu::getItems() {
std::vector<std::shared_ptr<ItemInstance> >* items =
new std::vector<std::shared_ptr<ItemInstance> >();
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<ItemInstance> current = slots->at(i)->getItem();
std::shared_ptr<ItemInstance> expected = lastSlots->at(i);
for (unsigned int i = 0; i < slots.size(); i++) {
std::shared_ptr<ItemInstance> current = slots.at(i)->getItem();
std::shared_ptr<ItemInstance> 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<ItemInstance> current = slots->at(i)->getItem();
std::shared_ptr<ItemInstance> expected = lastSlots->at(i);
for (unsigned int i = 0; i < slots.size(); i++) {
std::shared_ptr<ItemInstance> current = slots.at(i)->getItem();
std::shared_ptr<ItemInstance> 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> player,
Slot* AbstractContainerMenu::getSlotFor(std::shared_ptr<Container> 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<Container> c,
return NULL;
}
Slot* AbstractContainerMenu::getSlot(int index) { return slots->at(index); }
Slot* AbstractContainerMenu::getSlot(int index) { return slots.at(index); }
std::shared_ptr<ItemInstance> AbstractContainerMenu::quickMoveStack(
std::shared_ptr<Player> 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<ItemInstance> AbstractContainerMenu::quickMoveStack(
}
std::shared_ptr<ItemInstance> AbstractContainerMenu::clicked(
int slotIndex, int buttonNum, int clickType,
std::shared_ptr<Player> player) {
int slotIndex, int buttonNum, int clickType, std::shared_ptr<Player> player,
bool looped) // 4J Added looped param
{
std::shared_ptr<ItemInstance> clickedEntity = nullptr;
std::shared_ptr<Inventory> 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<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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<ItemInstance>(
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<ItemInstance> AbstractContainerMenu::clicked(
} else {
if (slotIndex < 0) return nullptr;
Slot* slot = slots->at(slotIndex);
Slot* slot = slots.at(slotIndex);
if (slot != NULL) {
std::shared_ptr<ItemInstance> clicked = slot->getItem();
std::shared_ptr<ItemInstance> carried = inventory->getCarried();
@ -190,7 +283,9 @@ std::shared_ptr<ItemInstance> 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<ItemInstance> 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<ItemInstance> current =
inventory->getItem(buttonNum);
@ -304,21 +399,78 @@ std::shared_ptr<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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> 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> player) {
}
void AbstractContainerMenu::
slotsChanged() // 4J used to take a std::shared_ptr<Container> but wasn't
// using it, so removed to simplify things
slotsChanged() // 4J used to take a shared_ptr<Container> 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<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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<Slot*>* quickCraftSlots, int quickCraftingType,
std::shared_ptr<ItemInstance> 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> container) {
if (container == NULL) return 0;
int count = 0;
float totalPct = 0;
for (int i = 0; i < container->getContainerSize(); i++) {
std::shared_ptr<ItemInstance> 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<ItemInstance> item, int slotId) {
return true;
}

View file

@ -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<std::shared_ptr<ItemInstance> >* lastSlots;
std::vector<Slot*>* slots;
std::vector<std::shared_ptr<ItemInstance> > lastSlots;
std::vector<Slot*> slots;
int containerId;
private:
short changeUid;
int quickcraftType;
int quickcraftStatus;
std::unordered_set<Slot*> quickcraftSlots;
private:
bool m_bNeedsRendered; // 4J added
protected:
std::vector<ContainerListener*>* containerListeners;
std::vector<ContainerListener*> 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<std::shared_ptr<ItemInstance> >* getItems();
void sendData(int id, int value);
virtual void removeSlotListener(ContainerListener* listener);
virtual std::vector<std::shared_ptr<ItemInstance> >* getItems();
virtual void sendData(int id, int value);
virtual void broadcastChanges();
virtual bool needsRendered();
virtual bool clickMenuButton(std::shared_ptr<Player> player, int buttonId);
Slot* getSlotFor(std::shared_ptr<Container> c, int index);
Slot* getSlot(int index);
virtual Slot* getSlotFor(std::shared_ptr<Container> c, int index);
virtual Slot* getSlot(int index);
virtual std::shared_ptr<ItemInstance> quickMoveStack(
std::shared_ptr<Player> player, int slotIndex);
virtual std::shared_ptr<ItemInstance> clicked(
int slotIndex, int buttonNum, int clickType,
std::shared_ptr<Player> player);
std::shared_ptr<Player> player,
bool looped = false); // 4J added looped param
virtual bool mayCombine(Slot* slot, std::shared_ptr<ItemInstance> item);
virtual bool canTakeItemForPickAll(std::shared_ptr<ItemInstance> 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> 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<ItemInstance> item,
bool ignoreSize);
static void getQuickCraftSlotCount(
std::unordered_set<Slot*>* quickCraftSlots, int quickCraftingType,
std::shared_ptr<ItemInstance> item, int carry);
bool canDragTo(Slot* slot);
static int getRedstoneSignalFromContainer(
std::shared_ptr<Container> container);
// 4J Added
virtual bool isValidIngredient(std::shared_ptr<ItemInstance> item,
int slotId);
};

View file

@ -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) {}

View file

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

View file

@ -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> inventory, Level* level,
int xt, int yt, int zt, std::shared_ptr<Player> player) {
AnvilMenu::AnvilMenu(std::shared_ptr<Inventory> inventory, Level* level, int xt,
int yt, int zt, std::shared_ptr<Player> player) {
resultSlots = std::shared_ptr<ResultContainer>(new ResultContainer());
repairSlots = std::shared_ptr<RepairContainer>(
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> inventory, Level* level,
}
}
void RepairMenu::slotsChanged(std::shared_ptr<Container> container) {
void AnvilMenu::slotsChanged(std::shared_ptr<Container> container) {
AbstractContainerMenu::slotsChanged();
if (container == repairSlots) createResult();
}
void RepairMenu::createResult() {
void AnvilMenu::createResult() {
std::shared_ptr<ItemInstance> 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> player) {
void AnvilMenu::removed(std::shared_ptr<Player> player) {
AbstractContainerMenu::removed(player);
if (level->isClientSide) return;
@ -334,16 +348,16 @@ void RepairMenu::removed(std::shared_ptr<Player> player) {
}
}
bool RepairMenu::stillValid(std::shared_ptr<Player> player) {
bool AnvilMenu::stillValid(std::shared_ptr<Player> 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<ItemInstance> RepairMenu::quickMoveStack(
std::shared_ptr<ItemInstance> AnvilMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> clicked = nullptr;
Slot* slot = slots->at(slotIndex);
Slot* slot = slots.at(slotIndex);
if (slot != NULL && slot->hasItem()) {
std::shared_ptr<ItemInstance> stack = slot->getItem();
clicked = stack->copy();
@ -379,10 +393,16 @@ std::shared_ptr<ItemInstance> 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<ItemInstance> item = getSlot(RESULT_SLOT)->getItem();
if (name.empty()) {
item->resetHoverName();
} else {
item->setHoverName(itemName);
}
}
createResult();
}
}

View file

@ -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> inventory, Level* level, int xt,
int yt, int zt, std::shared_ptr<Player> player);
AnvilMenu(std::shared_ptr<Inventory> inventory, Level* level, int xt,
int yt, int zt, std::shared_ptr<Player> player);
void slotsChanged(std::shared_ptr<Container> container);
void createResult();

View file

@ -13,6 +13,9 @@ ArmorSlot::ArmorSlot(int slotNum, std::shared_ptr<Container> container, int id,
int ArmorSlot::getMaxStackSize() { return 1; }
bool ArmorSlot::mayPlace(std::shared_ptr<ItemInstance> item) {
if (item == NULL) {
return false;
}
if (dynamic_cast<ArmorItem*>(item->getItem()) != NULL) {
return dynamic_cast<ArmorItem*>(item->getItem())->slot == slotNum;
}
@ -26,25 +29,24 @@ bool ArmorSlot::mayPlace(std::shared_ptr<ItemInstance> item) {
Icon* ArmorSlot::getNoItemIcon() { return ArmorItem::getEmptyIcon(slotNum); }
//
// bool ArmorSlot::mayCombine(std::shared_ptr<ItemInstance> item)
// bool ArmorSlot::mayCombine(shared_ptr<ItemInstance> item)
//{
// std::shared_ptr<ItemInstance> thisItemI = getItem();
// shared_ptr<ItemInstance> 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<ItemInstance>
// ArmorSlot::combine(std::shared_ptr<ItemInstance> item)
// shared_ptr<ItemInstance> ArmorSlot::combine(shared_ptr<ItemInstance> item)
//{
// std::shared_ptr<CraftingContainer> craftSlots =
//std::shared_ptr<CraftingContainer>( new CraftingContainer(NULL, 2, 2) );
// shared_ptr<CraftingContainer> craftSlots =
// shared_ptr<CraftingContainer>( new CraftingContainer(NULL, 2, 2) );
// craftSlots->setItem(0, item);
// craftSlots->setItem(1, getItem()); // Armour item needs to go second
// std::shared_ptr<ItemInstance> result =
//ArmorDyeRecipe::assembleDyedArmor(craftSlots); craftSlots->setItem(0,
//nullptr); craftSlots->setItem(1, nullptr); return result;
// shared_ptr<ItemInstance> result =
// ArmorDyeRecipe::assembleDyedArmor(craftSlots); craftSlots->setItem(0,
// nullptr); craftSlots->setItem(1, nullptr); return result;
//}

View file

@ -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<Container> inventory,
std::shared_ptr<BeaconTileEntity> 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<BeaconTileEntity> BeaconMenu::getBeacon() { return beacon; }
bool BeaconMenu::stillValid(std::shared_ptr<Player> player) {
return beacon->stillValid(player);
}
std::shared_ptr<ItemInstance> BeaconMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> clicked = nullptr;
Slot* slot = slots.at(slotIndex);
if (slot != NULL && slot->hasItem()) {
std::shared_ptr<ItemInstance> 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> container,
int slot, int x, int y)
: Slot(container, slot, x, y) {}
bool BeaconMenu::PaymentSlot::mayPlace(std::shared_ptr<ItemInstance> 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; }

View file

@ -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> container, int slot, int x,
int y);
bool mayPlace(std::shared_ptr<ItemInstance> 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<BeaconTileEntity> beacon;
PaymentSlot* paymentSlot;
// copied values because container/client system is retarded
int levels;
int primaryPower;
int secondaryPower;
public:
BeaconMenu(std::shared_ptr<Container> inventory,
std::shared_ptr<BeaconTileEntity> beacon);
void addSlotListener(ContainerListener* listener);
void setData(int id, int value);
std::shared_ptr<BeaconTileEntity> getBeacon();
bool stillValid(std::shared_ptr<Player> player);
std::shared_ptr<ItemInstance> quickMoveStack(std::shared_ptr<Player> player,
int slotIndex);
};

View file

@ -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> player) {
std::shared_ptr<ItemInstance> BrewingStandMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> 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<ItemInstance> stack = slot->getItem();
@ -97,7 +97,7 @@ std::shared_ptr<ItemInstance> 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<ItemInstance> 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> player, std::shared_ptr<ItemInstance> carried) {
carried->onCraftedBy(
this->player->level,
std::dynamic_pointer_cast<Player>(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;
}
}

View file

@ -4,9 +4,9 @@
#include "ClientSideMerchant.h"
ClientSideMerchant::ClientSideMerchant(std::shared_ptr<Player> 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<ItemInstance> item) {}
int ClientSideMerchant::getDisplayName() { return m_name; }
std::wstring ClientSideMerchant::getDisplayName() { return m_name; }

View file

@ -13,10 +13,11 @@ private:
MerchantContainer* container;
std::shared_ptr<Player> source;
MerchantRecipeList* currentOffers;
int m_name;
std::wstring m_name;
public:
ClientSideMerchant(std::shared_ptr<Player> source, int name);
ClientSideMerchant(std::shared_ptr<Player> 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<ItemInstance> item);
int getDisplayName();
std::wstring getDisplayName();
};

View file

@ -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<Container> c1,
@ -12,11 +12,33 @@ CompoundContainer::CompoundContainer(int name, std::shared_ptr<Container> 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<Container> 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<ItemInstance> 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<ItemInstance> item) {
return true;
}

View file

@ -13,23 +13,21 @@ public:
CompoundContainer(int name, std::shared_ptr<Container> c1,
std::shared_ptr<Container> c2);
unsigned int getContainerSize();
int getName();
std::shared_ptr<ItemInstance> getItem(unsigned int slot);
std::shared_ptr<ItemInstance> removeItem(unsigned int slot, int i);
std::shared_ptr<ItemInstance> removeItemNoUpdate(int slot);
void setItem(unsigned int slot, std::shared_ptr<ItemInstance> item);
int getMaxStackSize();
void setChanged();
bool stillValid(std::shared_ptr<Player> player);
virtual int getContainerType();
virtual unsigned int getContainerSize();
virtual bool contains(std::shared_ptr<Container> c);
virtual std::wstring getName();
virtual std::wstring getCustomName();
virtual bool hasCustomName();
virtual std::shared_ptr<ItemInstance> getItem(unsigned int slot);
virtual std::shared_ptr<ItemInstance> removeItem(unsigned int slot, int i);
virtual std::shared_ptr<ItemInstance> removeItemNoUpdate(int slot);
virtual void setItem(unsigned int slot, std::shared_ptr<ItemInstance> item);
virtual int getMaxStackSize();
virtual void setChanged();
virtual bool stillValid(std::shared_ptr<Player> player);
virtual void startOpen();
virtual void stopOpen();
virtual bool canPlaceItem(int slot, std::shared_ptr<ItemInstance> item);
};

View file

@ -1,2 +0,0 @@
#include "../Platform/stdafx.h"
#include "Container.h"

View file

@ -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<ItemInstance> getItem(unsigned int slot) = 0;
virtual std::shared_ptr<ItemInstance> removeItem(unsigned int slot,
@ -15,10 +18,14 @@ public:
virtual std::shared_ptr<ItemInstance> removeItemNoUpdate(int slot) = 0;
virtual void setItem(unsigned int slot,
std::shared_ptr<ItemInstance> 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> player) = 0;
virtual void startOpen() = 0;
virtual void stopOpen() = 0;
};
virtual bool canPlaceItem(int slot, std::shared_ptr<ItemInstance> item) = 0;
};

View file

@ -12,7 +12,7 @@ ContainerMenu::ContainerMenu(std::shared_ptr<Container> inventory,
std::shared_ptr<Container> 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> player) {
std::shared_ptr<ItemInstance> ContainerMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> clicked = nullptr;
Slot* slot = slots->at(slotIndex);
Slot* slot = slots.at(slotIndex);
if (slot != NULL && slot->hasItem()) {
std::shared_ptr<ItemInstance> 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> player) {
container->stopOpen();
}
std::shared_ptr<Container> ContainerMenu::getContainer() { return container; }
std::shared_ptr<ItemInstance> ContainerMenu::clicked(
int slotIndex, int buttonNum, int clickType,
std::shared_ptr<Player> player) {
std::shared_ptr<ItemInstance> out =
AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, player);
int slotIndex, int buttonNum, int clickType, std::shared_ptr<Player> player,
bool looped) // 4J Added looped param
{
std::shared_ptr<ItemInstance> out = AbstractContainerMenu::clicked(
slotIndex, buttonNum, clickType, player, looped);
#ifdef _EXTENDED_ACHIEVEMENTS
std::shared_ptr<LocalPlayer> localPlayer =
@ -88,7 +91,7 @@ std::shared_ptr<ItemInstance> ContainerMenu::clicked(
int cobblecount = 0;
for (int i = 0; i < container->getContainerSize(); i++) {
std::shared_ptr<ItemInstance> 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<ItemInstance> 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
{

View file

@ -16,10 +16,11 @@ public:
virtual bool stillValid(std::shared_ptr<Player> player);
virtual std::shared_ptr<ItemInstance> quickMoveStack(
std::shared_ptr<Player> player, int slotIndex);
void removed(std::shared_ptr<Player> player);
virtual void removed(std::shared_ptr<Player> player);
virtual std::shared_ptr<Container> getContainer();
// 4J ADDED,
virtual std::shared_ptr<ItemInstance> clicked(
int slotIndex, int buttonNum, int clickType,
std::shared_ptr<Player> player);
std::shared_ptr<Player> player, bool looped = false);
};

View file

@ -32,7 +32,11 @@ std::shared_ptr<ItemInstance> 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<ItemInstance> CraftingContainer::removeItemNoUpdate(int slot) {
if ((*items)[slot] != NULL) {
@ -77,4 +81,9 @@ void CraftingContainer::setChanged() {}
bool CraftingContainer::stillValid(std::shared_ptr<Player> player) {
return true;
}
bool CraftingContainer::canPlaceItem(int slot,
std::shared_ptr<ItemInstance> item) {
return true;
}

View file

@ -18,7 +18,9 @@ public:
virtual unsigned int getContainerSize();
virtual std::shared_ptr<ItemInstance> getItem(unsigned int slot);
std::shared_ptr<ItemInstance> 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<ItemInstance> removeItemNoUpdate(int slot);
virtual std::shared_ptr<ItemInstance> 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<ItemInstance> item);
};

View file

@ -25,9 +25,9 @@ CraftingMenu::CraftingMenu(std::shared_ptr<Inventory> inventory, Level* level,
resultSlots = std::shared_ptr<ResultContainer>(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> inventory, Level* level,
slotsChanged(); // 4J - removed craftSlots parameter, see comment below
}
void CraftingMenu::slotsChanged() // 4J used to take a
// std::shared_ptr<Container> but wasn't
// using it, so removed to simplify things
void CraftingMenu::slotsChanged() // 4J used to take a shared_ptr<Container>
// 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> player) {
std::shared_ptr<ItemInstance> CraftingMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> clicked = nullptr;
Slot* slot = slots->at(slotIndex);
Slot* slot = slots.at(slotIndex);
if (slot != NULL && slot->hasItem()) {
std::shared_ptr<ItemInstance> stack = slot->getItem();
clicked = stack->copy();
@ -119,4 +119,10 @@ std::shared_ptr<ItemInstance> CraftingMenu::quickMoveStack(
}
}
return clicked;
}
bool CraftingMenu::canTakeItemForPickAll(std::shared_ptr<ItemInstance> carried,
Slot* target) {
return target->container != resultSlots &&
AbstractContainerMenu::canTakeItemForPickAll(carried, target);
}

View file

@ -35,4 +35,10 @@ public:
virtual bool stillValid(std::shared_ptr<Player> player);
virtual std::shared_ptr<ItemInstance> quickMoveStack(
std::shared_ptr<Player> player, int slotIndex);
virtual bool canTakeItemForPickAll(std::shared_ptr<ItemInstance> carried,
Slot* target);
int getX() { return x; }
int getY() { return y; }
int getZ() { return z; }
};

View file

@ -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<ItemInstance> item) {
return true;
}

View file

@ -15,4 +15,5 @@ public:
EnchantmentContainer(EnchantmentMenu* menu);
virtual int getMaxStackSize();
virtual void setChanged();
virtual bool canPlaceItem(int slot, std::shared_ptr<ItemInstance> item);
};

View file

@ -17,9 +17,9 @@ EnchantmentMenu::EnchantmentMenu(std::shared_ptr<Inventory> 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> container
// but wasn't using it, so removed to simplify things
void EnchantmentMenu::slotsChanged() // 4J used to take a shared_ptr<Container>
// container but wasn't using it, so
// removed to simplify things
{
std::shared_ptr<ItemInstance> item = enchantSlots->getItem(0);
@ -144,7 +144,7 @@ bool EnchantmentMenu::clickMenuButton(std::shared_ptr<Player> player, int i) {
std::vector<EnchantmentInstance*>* 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> player) {
std::shared_ptr<ItemInstance> EnchantmentMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> 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<ItemInstance> stack = slot->getItem();

View file

@ -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> inventory, Level* level,
int xt, int yt, int zt)
: AbstractContainerMenu() {
m_canMakeFireworks = false;
m_canMakeCharge = false;
m_canMakeFade = false;
craftSlots =
std::shared_ptr<CraftingContainer>(new CraftingContainer(this, 3, 3));
resultSlots = std::shared_ptr<ResultContainer>(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<Container>
// 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> player) {
AbstractContainerMenu::removed(player);
if (level->isClientSide) return;
for (int i = 0; i < 9; i++) {
std::shared_ptr<ItemInstance> item = craftSlots->removeItemNoUpdate(i);
if (item != NULL) {
player->drop(item);
}
}
}
bool FireworksMenu::stillValid(std::shared_ptr<Player> player) { return true; }
std::shared_ptr<ItemInstance> FireworksMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> clicked = nullptr;
Slot* slot = slots.at(slotIndex);
if (slot != NULL && slot->hasItem()) {
std::shared_ptr<ItemInstance> 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<ItemInstance> carried,
Slot* target) {
return target->container != resultSlots &&
AbstractContainerMenu::canTakeItemForPickAll(carried, target);
}
bool FireworksMenu::isValidIngredient(std::shared_ptr<ItemInstance> item,
int slotId) {
if (item == NULL || slotId == RESULT_SLOT) return true;
return FireworksRecipe::isValidIngredient(item, m_canMakeFireworks,
m_canMakeCharge, m_canMakeFade);
}

View file

@ -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<CraftingContainer> craftSlots;
std::shared_ptr<Container> resultSlots;
private:
Level* level;
int x, y, z;
bool m_canMakeFireworks;
bool m_canMakeCharge;
bool m_canMakeFade;
public:
FireworksMenu(std::shared_ptr<Inventory> inventory, Level* level, int xt,
int yt, int zt);
virtual void
slotsChanged(); // 4J used to take a std::shared_ptr<Container> but wasn't
// using it, so removed to simplify things
virtual void removed(std::shared_ptr<Player> player);
virtual bool stillValid(std::shared_ptr<Player> player);
virtual std::shared_ptr<ItemInstance> quickMoveStack(
std::shared_ptr<Player> player, int slotIndex);
virtual bool canTakeItemForPickAll(std::shared_ptr<ItemInstance> carried,
Slot* target);
// 4J Added
virtual bool isValidIngredient(std::shared_ptr<ItemInstance> item,
int slotId);
};

View file

@ -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> player) {
std::shared_ptr<ItemInstance> FurnaceMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> 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<ItemInstance> FurnaceMenu::quickMoveStack(
}
std::shared_ptr<ItemInstance> FurnaceMenu::clicked(
int slotIndex, int buttonNum, int clickType,
std::shared_ptr<Player> player) {
int slotIndex, int buttonNum, int clickType, std::shared_ptr<Player> player,
bool looped) // 4J Added looped param
{
bool charcoalUsed = furnace->wasCharcoalUsed();
std::shared_ptr<ItemInstance> out =
AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, player);
std::shared_ptr<ItemInstance> out = AbstractContainerMenu::clicked(
slotIndex, buttonNum, clickType, player, looped);
#ifdef _EXTENDED_ACHIEVEMENTS
if (charcoalUsed && (out != nullptr) &&

View file

@ -35,7 +35,8 @@ public:
virtual std::shared_ptr<ItemInstance> quickMoveStack(
std::shared_ptr<Player> player, int slotIndex);
// 4J Added looped param
virtual std::shared_ptr<ItemInstance> clicked(
int slotIndex, int buttonNum, int clickType,
std::shared_ptr<Player> player);
std::shared_ptr<Player> player, bool looped = false);
};

View file

@ -0,0 +1,62 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.inventory.h"
#include "HopperMenu.h"
HopperMenu::HopperMenu(std::shared_ptr<Container> inventory,
std::shared_ptr<Container> 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> player) {
return hopper->stillValid(player);
}
std::shared_ptr<ItemInstance> HopperMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> clicked = nullptr;
Slot* slot = slots.at(slotIndex);
if (slot != NULL && slot->hasItem()) {
std::shared_ptr<ItemInstance> 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> player) {
AbstractContainerMenu::removed(player);
hopper->stopOpen();
}
std::shared_ptr<Container> HopperMenu::getContainer() { return hopper; }

View file

@ -0,0 +1,25 @@
#pragma once
#include "AbstractContainerMenu.h"
class HopperMenu : public AbstractContainerMenu {
private:
std::shared_ptr<Container> 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<Container> inventory,
std::shared_ptr<Container> hopper);
bool stillValid(std::shared_ptr<Player> player);
std::shared_ptr<ItemInstance> quickMoveStack(std::shared_ptr<Player> player,
int slotIndex);
void removed(std::shared_ptr<Player> player);
std::shared_ptr<Container> getContainer();
};

View file

@ -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<Container> horseInventory)
: Slot(horseInventory, EntityHorse::INV_SLOT_SADDLE, 8, 18) {}
bool HorseSaddleSlot::mayPlace(std::shared_ptr<ItemInstance> item) {
return Slot::mayPlace(item) && item->id == Item::saddle_Id && !hasItem();
}
HorseArmorSlot::HorseArmorSlot(HorseInventoryMenu* parent,
std::shared_ptr<Container> horseInventory)
: Slot(horseInventory, EntityHorse::INV_SLOT_ARMOR, 8, 18 * 2) {
m_parent = parent;
}
bool HorseArmorSlot::mayPlace(std::shared_ptr<ItemInstance> 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<Container> playerInventory,
std::shared_ptr<Container> horseInventory,
std::shared_ptr<EntityHorse> 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> player) {
return horseContainer->stillValid(player) && horse->isAlive() &&
horse->distanceTo(player) < 8;
}
std::shared_ptr<ItemInstance> HorseInventoryMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> clicked = nullptr;
Slot* slot = slots.at(slotIndex);
if (slot != NULL && slot->hasItem()) {
std::shared_ptr<ItemInstance> 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> player) {
AbstractContainerMenu::removed(player);
horseContainer->stopOpen();
}
std::shared_ptr<Container> HorseInventoryMenu::getContainer() {
return horseContainer;
}

View file

@ -0,0 +1,44 @@
#pragma once
#include "AbstractContainerMenu.h"
#include "Slot.h"
class HorseInventoryMenu;
class HorseSaddleSlot : public Slot {
public:
HorseSaddleSlot(std::shared_ptr<Container> horseInventory);
bool mayPlace(std::shared_ptr<ItemInstance> item);
};
class HorseArmorSlot : public Slot {
private:
HorseInventoryMenu* m_parent;
public:
HorseArmorSlot(HorseInventoryMenu* parent,
std::shared_ptr<Container> horseInventory);
bool mayPlace(std::shared_ptr<ItemInstance> item);
bool isActive();
};
class HorseInventoryMenu : public AbstractContainerMenu {
friend class HorseArmorSlot;
private:
std::shared_ptr<Container> horseContainer;
std::shared_ptr<EntityHorse> horse;
public:
HorseInventoryMenu(std::shared_ptr<Container> playerInventory,
std::shared_ptr<Container> horseInventory,
std::shared_ptr<EntityHorse> horse);
bool stillValid(std::shared_ptr<Player> player);
std::shared_ptr<ItemInstance> quickMoveStack(std::shared_ptr<Player> player,
int slotIndex);
void removed(std::shared_ptr<Player> player);
std::shared_ptr<Container> getContainer();
};

View file

@ -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<ItemInstance> 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<ItemInstance> 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<ItemInstance>(
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<ItemInstance>(
new ItemInstance(Item::items[item->id], oldSlotCount, data));
} else {
items[selected] = std::shared_ptr<ItemInstance>(
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<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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> entity) {
std::shared_ptr<ItemInstance> 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<ArmorItem*>(armor[i]->getItem()) != NULL) {
armor[i]->hurt(dmg, std::dynamic_pointer_cast<Mob>(
player->shared_from_this()));
armor[i]->hurtAndBreak((int)dmg,
std::dynamic_pointer_cast<LivingEntity>(
player->shared_from_this()));
if (armor[i]->count == 0) {
armor[i] = nullptr;
}
@ -577,10 +602,10 @@ bool Inventory::stillValid(std::shared_ptr<Player> player) {
bool Inventory::contains(std::shared_ptr<ItemInstance> 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<ItemInstance> item) {
return true;
}
void Inventory::replaceWith(std::shared_ptr<Inventory> 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<Inventory> 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> itemInstance) {
@ -608,7 +639,7 @@ int Inventory::countMatches(std::shared_ptr<ItemInstance> 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))

View file

@ -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<ItemInstance> heldItem;
@ -37,7 +35,6 @@ public:
std::shared_ptr<ItemInstance> 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<ItemInstance> getResourceItem(int type, int iAuxVal);
bool hasResource(int type);
void swapSlots(int from, int to);
bool add(std::shared_ptr<ItemInstance> item);
std::shared_ptr<ItemInstance> removeItem(unsigned int slot, int count);
virtual std::shared_ptr<ItemInstance> removeItemNoUpdate(int slot);
void setItem(unsigned int slot, std::shared_ptr<ItemInstance> item);
float getDestroySpeed(Tile* tile);
ListTag<CompoundTag>* save(ListTag<CompoundTag>* listTag);
void load(ListTag<CompoundTag>* inventoryList);
unsigned int getContainerSize();
std::shared_ptr<ItemInstance> getItem(unsigned int slot);
int getName();
std::wstring getName();
std::wstring getCustomName();
bool hasCustomName();
int getMaxStackSize();
int getAttackDamage(std::shared_ptr<Entity> entity);
bool canDestroy(Tile* tile);
std::shared_ptr<ItemInstance> getArmor(int layer);
int getArmorValue();
void hurtArmor(int dmg);
void hurtArmor(float dmg);
void dropAll();
void setChanged();
bool isSame(std::shared_ptr<Inventory> copy);
private:
@ -122,17 +96,13 @@ private:
public:
std::shared_ptr<Inventory> copy();
void setCarried(std::shared_ptr<ItemInstance> carried);
std::shared_ptr<ItemInstance> getCarried();
bool stillValid(std::shared_ptr<Player> player);
bool contains(std::shared_ptr<ItemInstance> itemInstance);
virtual void startOpen();
virtual void stopOpen();
bool canPlaceItem(int slot, std::shared_ptr<ItemInstance> item);
void replaceWith(std::shared_ptr<Inventory> other);
int countMatches(std::shared_ptr<ItemInstance> itemInstance); // 4J Added

View file

@ -65,9 +65,9 @@ void InventoryMenu::_init(std::shared_ptr<Inventory> inventory, bool active) {
slotsChanged(); // 4J removed craftSlots parameter, see comment below
}
void InventoryMenu::slotsChanged() // 4J used to take a
// std::shared_ptr<Container> but wasn't
// using it, so removed to simplify things
void InventoryMenu::slotsChanged() // 4J used to take a shared_ptr<Container>
// 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> player) { return true; }
std::shared_ptr<ItemInstance> InventoryMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> 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<ItemInstance> stack = slot->getItem();
@ -211,18 +211,25 @@ bool InventoryMenu::mayCombine(Slot* slot, std::shared_ptr<ItemInstance> item) {
return slot->mayCombine(item);
}
bool InventoryMenu::canTakeItemForPickAll(std::shared_ptr<ItemInstance> carried,
Slot* target) {
return target->container != resultSlots &&
AbstractContainerMenu::canTakeItemForPickAll(carried, target);
}
// 4J-JEV: Added for achievement 'Iron Man'.
std::shared_ptr<ItemInstance> InventoryMenu::clicked(
int slotIndex, int buttonNum, int clickType,
std::shared_ptr<Player> player) {
std::shared_ptr<ItemInstance> out =
AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, player);
int slotIndex, int buttonNum, int clickType, std::shared_ptr<Player> player,
bool looped) // 4J Added looped param
{
std::shared_ptr<ItemInstance> 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])) {

View file

@ -41,9 +41,11 @@ public:
virtual std::shared_ptr<ItemInstance> quickMoveStack(
std::shared_ptr<Player> player, int slotIndex);
virtual bool mayCombine(Slot* slot, std::shared_ptr<ItemInstance> item);
virtual bool canTakeItemForPickAll(std::shared_ptr<ItemInstance> carried,
Slot* target);
// 4J ADDED,
virtual std::shared_ptr<ItemInstance> clicked(
int slotIndex, int buttonNum, int clickType,
std::shared_ptr<Player> player);
std::shared_ptr<Player> player, bool looped = false);
};

View file

@ -15,19 +15,19 @@ MenuBackup::MenuBackup(std::shared_ptr<Inventory> 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]);
}
}

View file

@ -14,5 +14,5 @@ public:
virtual void overrideOffers(MerchantRecipeList* recipeList) = 0;
virtual void notifyTrade(MerchantRecipe* activeRecipe) = 0;
virtual void notifyTradeUpdated(std::shared_ptr<ItemInstance> item) = 0;
virtual int getDisplayName() = 0;
};
virtual std::wstring getDisplayName() = 0;
};

View file

@ -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<ItemInstance> item) {
return true;
}
void MerchantContainer::setChanged() { updateSellItem(); }
void MerchantContainer::updateSellItem() {

View file

@ -30,11 +30,14 @@ private:
public:
std::shared_ptr<ItemInstance> removeItemNoUpdate(int slot);
void setItem(unsigned int slot, std::shared_ptr<ItemInstance> item);
int getName();
std::wstring getName();
std::wstring getCustomName();
bool hasCustomName();
int getMaxStackSize();
bool stillValid(std::shared_ptr<Player> player);
void startOpen();
void stopOpen();
bool canPlaceItem(int slot, std::shared_ptr<ItemInstance> item);
void setChanged();
void updateSellItem();
MerchantRecipe* getActiveRecipe();

View file

@ -42,8 +42,8 @@ void MerchantMenu::broadcastChanges() {
AbstractContainerMenu::broadcastChanges();
}
// 4J used to take a std::shared_ptr<Container> but wasn't using it, so removed
// to simplify things
// 4J used to take a shared_ptr<Container> but wasn't using it, so removed to
// simplify things
void MerchantMenu::slotsChanged() {
tradeContainer->updateSellItem();
AbstractContainerMenu::slotsChanged();
@ -64,7 +64,7 @@ std::shared_ptr<ItemInstance> MerchantMenu::quickMoveStack(
std::shared_ptr<ItemInstance> 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<ItemInstance> stack = slot->getItem();
clicked = stack->copy();

View file

@ -125,10 +125,11 @@ MerchantRecipeList* MerchantRecipeList::createFromStream(
}
void MerchantRecipeList::load(CompoundTag* tag) {
ListTag<Tag>* list = tag->getList(L"Recipes");
ListTag<CompoundTag>* list =
(ListTag<CompoundTag>*)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<MerchantRecipe*>::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(); }

View file

@ -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<ItemInstance> item) {
return true;
}

View file

@ -2,14 +2,15 @@
#include "SimpleContainer.h"
class RepairMenu;
class AnvilMenu;
class RepairContainer : public SimpleContainer,
public std::enable_shared_from_this<RepairContainer> {
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<ItemInstance> item);
};

View file

@ -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> container,
int slot, int x, int y)
: Slot(container, slot, x, y) {
@ -28,19 +28,19 @@ bool RepairResultSlot::mayPickup(std::shared_ptr<Player> player) {
void RepairResultSlot::onTake(std::shared_ptr<Player> player,
std::shared_ptr<ItemInstance> 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<ItemInstance> 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> 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);
}

View file

@ -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> container, int slot, int x,
int y);

View file

@ -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<ItemInstance> 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<ItemInstance> ResultContainer::removeItem(unsigned int slot,
int count) {
if ((*items)[0] != NULL) {
std::shared_ptr<ItemInstance> item = (*items)[0];
(*items)[0] = nullptr;
if (items[0] != NULL) {
std::shared_ptr<ItemInstance> item = items[0];
items[0] = nullptr;
return item;
}
return nullptr;
}
std::shared_ptr<ItemInstance> ResultContainer::removeItemNoUpdate(int slot) {
if ((*items)[0] != NULL) {
std::shared_ptr<ItemInstance> item = (*items)[0];
(*items)[0] = nullptr;
if (items[0] != NULL) {
std::shared_ptr<ItemInstance> item = items[0];
items[0] = nullptr;
return item;
}
return nullptr;
@ -35,7 +37,7 @@ std::shared_ptr<ItemInstance> ResultContainer::removeItemNoUpdate(int slot) {
void ResultContainer::setItem(unsigned int slot,
std::shared_ptr<ItemInstance> item) {
(*items)[0] = item;
items[0] = item;
}
int ResultContainer::getMaxStackSize() {
@ -46,4 +48,9 @@ void ResultContainer::setChanged() {}
bool ResultContainer::stillValid(std::shared_ptr<Player> player) {
return true;
}
bool ResultContainer::canPlaceItem(int slot,
std::shared_ptr<ItemInstance> item) {
return true;
}

View file

@ -4,16 +4,17 @@
class ResultContainer : public Container {
private:
ItemInstanceArray* items;
std::shared_ptr<ItemInstance> items[1];
public:
// 4J Stu Added a ctor to init items
ResultContainer();
virtual ~ResultContainer() {}
virtual unsigned int getContainerSize();
virtual std::shared_ptr<ItemInstance> getItem(unsigned int slot);
virtual int getName();
virtual std::wstring getName();
virtual std::wstring getCustomName();
virtual bool hasCustomName();
virtual std::shared_ptr<ItemInstance> removeItem(unsigned int slot,
int count);
virtual std::shared_ptr<ItemInstance> removeItemNoUpdate(int slot);
@ -21,7 +22,7 @@ public:
virtual int getMaxStackSize();
virtual void setChanged();
virtual bool stillValid(std::shared_ptr<Player> 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<ItemInstance> item);
};

View file

@ -83,28 +83,26 @@ void ResultSlot::onTake(std::shared_ptr<Player> player,
craftSlots->removeItem(i, 1);
if (item->getItem()->hasCraftingRemainingItem()) {
// (TheApathetic)
std::shared_ptr<ItemInstance> craftResult =
std::shared_ptr<ItemInstance>(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);
}
}
}

View file

@ -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<ItemInstance> SimpleContainer::removeItem(unsigned int slot,
if ((*items)[slot]->count <= count) {
std::shared_ptr<ItemInstance> item = (*items)[slot];
(*items)[slot] = nullptr;
this->setChanged();
setChanged();
return item;
} else {
std::shared_ptr<ItemInstance> 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> player) {
return true;
}
bool SimpleContainer::canPlaceItem(int slot,
std::shared_ptr<ItemInstance> item) {
return true;
}

View file

@ -6,34 +6,33 @@
class SimpleContainer : public Container {
private:
int name;
std::wstring stringName;
int size;
ItemInstanceArray* items;
std::vector<net_minecraft_world::ContainerListener*>* 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<ItemInstance> getItem(unsigned int slot);
std::shared_ptr<ItemInstance> removeItem(unsigned int slot, int count);
std::shared_ptr<ItemInstance> removeItemNoUpdate(int slot);
void setItem(unsigned int slot, std::shared_ptr<ItemInstance> item);
unsigned int getContainerSize();
int getName();
int getMaxStackSize();
void setChanged();
bool stillValid(std::shared_ptr<Player> 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<ItemInstance> getItem(unsigned int slot);
virtual std::shared_ptr<ItemInstance> removeItem(unsigned int slot,
int count);
virtual std::shared_ptr<ItemInstance> removeItemNoUpdate(int slot);
virtual void setItem(unsigned int slot, std::shared_ptr<ItemInstance> 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> 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<ItemInstance> item);
};

View file

@ -84,6 +84,8 @@ bool Slot::isAt(std::shared_ptr<Container> c, int s) {
bool Slot::mayPickup(std::shared_ptr<Player> player) { return true; }
bool Slot::isActive() { return true; }
bool Slot::mayCombine(std::shared_ptr<ItemInstance> second) {
std::shared_ptr<ItemInstance> first = getItem();

View file

@ -37,6 +37,7 @@ public:
virtual std::shared_ptr<ItemInstance> remove(int c);
virtual bool isAt(std::shared_ptr<Container> c, int s);
virtual bool mayPickup(std::shared_ptr<Player> player);
virtual bool isActive();
virtual bool mayCombine(std::shared_ptr<ItemInstance> item); // 4J Added
virtual std::shared_ptr<ItemInstance> combine(
std::shared_ptr<ItemInstance> item); // 4J Added

View file

@ -34,7 +34,7 @@ bool TrapMenu::stillValid(std::shared_ptr<Player> player) {
std::shared_ptr<ItemInstance> TrapMenu::quickMoveStack(
std::shared_ptr<Player> player, int slotIndex) {
std::shared_ptr<ItemInstance> clicked = nullptr;
Slot* slot = slots->at(slotIndex);
Slot* slot = slots.at(slotIndex);
if (slot != NULL && slot->hasItem()) {
std::shared_ptr<ItemInstance> stack = slot->getItem();
clicked = stack->copy();

View file

@ -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<ItemInstance> item,
int face) = 0;
virtual bool canTakeItemThroughFace(int slot,
std::shared_ptr<ItemInstance> item,
int face) = 0;
};