#include "../../Platform/stdafx.h" #include "../../Headers/com.mojang.nbt.h" #include "TileEntity.h" #include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.entity.item.h" #include "../../Headers/net.minecraft.world.entity.player.h" #include "../../Headers/net.minecraft.world.item.h" #include "DispenserTileEntity.h" DispenserTileEntity::DispenserTileEntity() : TileEntity() { items = ItemInstanceArray(9); random = new Random(); name = L""; } DispenserTileEntity::~DispenserTileEntity() { delete[] items.data; delete random; } unsigned int DispenserTileEntity::getContainerSize() { return 9; } std::shared_ptr DispenserTileEntity::getItem(unsigned int slot) { return items[slot]; } std::shared_ptr DispenserTileEntity::removeItem(unsigned int slot, int count) { if (items[slot] != NULL) { if (items[slot]->count <= count) { std::shared_ptr item = items[slot]; items[slot] = nullptr; setChanged(); // 4J Stu - Fix for duplication glitch if (item->count <= 0) return nullptr; return item; } else { std::shared_ptr i = items[slot]->remove(count); if (items[slot]->count == 0) items[slot] = nullptr; setChanged(); // 4J Stu - Fix for duplication glitch if (i->count <= 0) return nullptr; return i; } } return nullptr; } std::shared_ptr DispenserTileEntity::removeItemNoUpdate( int slot) { if (items[slot] != NULL) { std::shared_ptr item = items[slot]; items[slot] = nullptr; return item; } return nullptr; } // 4J-PB added for spawn eggs not being useable due to limits, so add them in // again void DispenserTileEntity::AddItemBack(std::shared_ptr item, unsigned int slot) { if (items[slot] != NULL) { // just increment the count of the items if (item->id == items[slot]->id) { items[slot]->count++; setChanged(); } } else { items[slot] = item; if (item != NULL && item->count > getMaxStackSize()) item->count = getMaxStackSize(); setChanged(); } } /** * Removes an item with the given id and returns true if one was found. * * @param itemId * @return */ bool DispenserTileEntity::removeProjectile(int itemId) { for (unsigned int i = 0; i < items.length; i++) { if (items[i] != NULL && items[i]->id == itemId) { std::shared_ptr removedItem = removeItem(i, 1); return removedItem != NULL; } } return false; } int DispenserTileEntity::getRandomSlot() { int replaceSlot = -1; int replaceOdds = 1; for (unsigned int i = 0; i < items.length; i++) { if (items[i] != NULL && random->nextInt(replaceOdds++) == 0) { replaceSlot = i; } } return replaceSlot; } void DispenserTileEntity::setItem(unsigned int slot, std::shared_ptr item) { items[slot] = item; if (item != NULL && item->count > getMaxStackSize()) item->count = getMaxStackSize(); setChanged(); } int DispenserTileEntity::addItem(std::shared_ptr item) { for (int i = 0; i < items.length; i++) { if (items[i] == NULL || items[i]->id == 0) { setItem(i, item); return i; } } return -1; } std::wstring DispenserTileEntity::getName() { return hasCustomName() ? name : app.GetString(IDS_TILE_DISPENSER); } std::wstring DispenserTileEntity::getCustomName() { return hasCustomName() ? name : L""; } void DispenserTileEntity::setCustomName(const std::wstring& name) { this->name = name; } bool DispenserTileEntity::hasCustomName() { return !name.empty(); } void DispenserTileEntity::load(CompoundTag* base) { TileEntity::load(base); ListTag* inventoryList = (ListTag*)base->getList(L"Items"); delete[] items.data; items = ItemInstanceArray(getContainerSize()); for (int i = 0; i < inventoryList->size(); i++) { CompoundTag* tag = inventoryList->get(i); unsigned int slot = tag->getByte(L"Slot") & 0xff; if (slot >= 0 && slot < items.length) items[slot] = ItemInstance::fromTag(tag); } if (base->contains(L"CustomName")) name = base->getString(L"CustomName"); } void DispenserTileEntity::save(CompoundTag* base) { TileEntity::save(base); ListTag* listTag = new ListTag; for (unsigned int i = 0; i < items.length; i++) { if (items[i] != NULL) { CompoundTag* tag = new CompoundTag(); tag->putByte(L"Slot", (uint8_t)i); items[i]->save(tag); listTag->add(tag); } } base->put(L"Items", listTag); if (hasCustomName()) base->putString(L"CustomName", name); } int DispenserTileEntity::getMaxStackSize() { return Container::LARGE_MAX_STACK_SIZE; } bool DispenserTileEntity::stillValid(std::shared_ptr player) { if (level->getTileEntity(x, y, z) != shared_from_this()) return false; if (player->distanceToSqr(x + 0.5, y + 0.5, z + 0.5) > 8 * 8) return false; return true; } void DispenserTileEntity::setChanged() { return TileEntity::setChanged(); } void DispenserTileEntity::startOpen() {} void DispenserTileEntity::stopOpen() {} bool DispenserTileEntity::canPlaceItem(int slot, std::shared_ptr item) { return true; } // 4J Added std::shared_ptr DispenserTileEntity::clone() { std::shared_ptr result = std::shared_ptr(new DispenserTileEntity()); TileEntity::clone(result); for (unsigned int i = 0; i < items.length; i++) { if (items[i] != NULL) { result->items[i] = ItemInstance::clone(items[i]); } } return result; }