#include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.entity.item.h" #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.inventory.h" #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.redstone.h" #include "MinecartContainer.h" void MinecartContainer::_init() { items = ItemInstanceArray(9 * 4); dropEquipment = true; // 4J Stu - This function call had to be moved here from the Entity ctor to // ensure that the derived version of the function is called this->defineSynchedData(); } MinecartContainer::MinecartContainer(Level* level) : Minecart(level) { _init(); } MinecartContainer::MinecartContainer(Level* level, double x, double y, double z) : Minecart(level, x, y, z) { _init(); } void MinecartContainer::destroy(DamageSource* source) { Minecart::destroy(source); for (int i = 0; i < getContainerSize(); i++) { std::shared_ptr item = getItem(i); if (item != NULL) { float xo = random->nextFloat() * 0.8f + 0.1f; float yo = random->nextFloat() * 0.8f + 0.1f; float zo = random->nextFloat() * 0.8f + 0.1f; while (item->count > 0) { int count = random->nextInt(21) + 10; if (count > item->count) count = item->count; item->count -= count; std::shared_ptr itemEntity = std::shared_ptr(new ItemEntity( level, x + xo, y + yo, z + zo, std::shared_ptr(new ItemInstance( item->id, count, item->getAuxValue())))); float pow = 0.05f; itemEntity->xd = (float)random->nextGaussian() * pow; itemEntity->yd = (float)random->nextGaussian() * pow + 0.2f; itemEntity->zd = (float)random->nextGaussian() * pow; level->addEntity(itemEntity); } } } } std::shared_ptr MinecartContainer::getItem(unsigned int slot) { return items[slot]; } std::shared_ptr MinecartContainer::removeItem(unsigned int slot, int count) { if (items[slot] != NULL) { if (items[slot]->count <= count) { std::shared_ptr item = items[slot]; items[slot] = nullptr; return item; } else { std::shared_ptr i = items[slot]->remove(count); if (items[slot]->count == 0) items[slot] = nullptr; return i; } } return nullptr; } std::shared_ptr MinecartContainer::removeItemNoUpdate(int slot) { if (items[slot] != NULL) { std::shared_ptr item = items[slot]; items[slot] = nullptr; return item; } return nullptr; } void MinecartContainer::setItem(unsigned int slot, std::shared_ptr item) { items[slot] = item; if (item != NULL && item->count > getMaxStackSize()) item->count = getMaxStackSize(); } void MinecartContainer::setChanged() {} bool MinecartContainer::stillValid(std::shared_ptr player) { if (removed) return false; if (player->distanceToSqr(shared_from_this()) > 8 * 8) return false; return true; } void MinecartContainer::startOpen() {} void MinecartContainer::stopOpen() {} bool MinecartContainer::canPlaceItem(int slot, std::shared_ptr item) { return true; } std::wstring MinecartContainer::getName() { return hasCustomName() ? getCustomName() : app.GetString(IDS_CONTAINER_MINECART); } int MinecartContainer::getMaxStackSize() { return Container::LARGE_MAX_STACK_SIZE; } void MinecartContainer::changeDimension(int i) { dropEquipment = false; Minecart::changeDimension(i); } void MinecartContainer::remove() { if (dropEquipment) { for (int i = 0; i < getContainerSize(); i++) { std::shared_ptr item = getItem(i); if (item != NULL) { float xo = random->nextFloat() * 0.8f + 0.1f; float yo = random->nextFloat() * 0.8f + 0.1f; float zo = random->nextFloat() * 0.8f + 0.1f; while (item->count > 0) { int count = random->nextInt(21) + 10; if (count > item->count) count = item->count; item->count -= count; std::shared_ptr itemEntity = std::shared_ptr(new ItemEntity( level, x + xo, y + yo, z + zo, std::shared_ptr(new ItemInstance( item->id, count, item->getAuxValue())))); if (item->hasTag()) { itemEntity->getItem()->setTag( (CompoundTag*)item->getTag()->copy()); } float pow = 0.05f; itemEntity->xd = (float)random->nextGaussian() * pow; itemEntity->yd = (float)random->nextGaussian() * pow + 0.2f; itemEntity->zd = (float)random->nextGaussian() * pow; level->addEntity(itemEntity); } } } } Minecart::remove(); } void MinecartContainer::addAdditonalSaveData(CompoundTag* base) { Minecart::addAdditonalSaveData(base); ListTag* listTag = new ListTag(); for (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); } void MinecartContainer::readAdditionalSaveData(CompoundTag* base) { Minecart::readAdditionalSaveData(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); int slot = tag->getByte(L"Slot") & 0xff; if (slot >= 0 && slot < items.length) items[slot] = ItemInstance::fromTag(tag); } } bool MinecartContainer::interact(std::shared_ptr player) { if (!level->isClientSide) { player->openContainer( std::dynamic_pointer_cast(shared_from_this())); } return true; } void MinecartContainer::applyNaturalSlowdown() { std::shared_ptr container = std::dynamic_pointer_cast(shared_from_this()); int emptiness = Redstone::SIGNAL_MAX - AbstractContainerMenu::getRedstoneSignalFromContainer(container); float keep = 0.98f + (emptiness * 0.001f); xd *= keep; yd *= 0; zd *= keep; }