package com.hexdragon.enchrebirth.block.anvil; import com.hexdragon.enchrebirth.registry.RegMain; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.ItemStackHelper; import net.minecraft.inventory.container.Container; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SUpdateTileEntityPacket; import net.minecraft.tileentity.LockableLootTileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.IWorldPosCallable; import net.minecraft.util.NonNullList; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; import net.minecraftforge.common.util.Constants; import javax.annotation.Nullable; // 铁砧 TileEntity,用于引导自定义模型与存储物品 NBT public class AnvilTileEntity extends LockableLootTileEntity { protected ITextComponent getDefaultName() {return new TranslationTextComponent("gui.anvil.title");} // 构造函数,为了支持不同损坏度的铁砧复读了 6 次 public static class PerfectAnvilTileEntity extends AnvilTileEntity { public PerfectAnvilTileEntity() { super(RegMain.tileEntityPerfectAnvil.get()); } } public static class ChippedAnvilTileEntity extends AnvilTileEntity { public ChippedAnvilTileEntity() { super(RegMain.tileEntityChippedAnvil.get()); } } public static class DamagedAnvilTileEntity extends AnvilTileEntity { public DamagedAnvilTileEntity() { super(RegMain.tileEntityDamagedAnvil.get()); } } public static class PerfectNetheriteAnvilTileEntity extends AnvilTileEntity { public PerfectNetheriteAnvilTileEntity() { super(RegMain.tileEntityPerfectNetheriteAnvil.get()); } } public static class ChippedNetheriteAnvilTileEntity extends AnvilTileEntity { public ChippedNetheriteAnvilTileEntity() { super(RegMain.tileEntityChippedNetheriteAnvil.get()); } } public static class DamagedNetheriteAnvilTileEntity extends AnvilTileEntity { public DamagedNetheriteAnvilTileEntity() { super(RegMain.tileEntityDamagedNetheriteAnvil.get()); } } public AnvilTileEntity(TileEntityType typeIn) { super(typeIn); } // 物品栏 public NonNullList inventory = NonNullList.withSize(2, ItemStack.EMPTY); public int getSizeInventory() {return 2;} public NonNullList getItems() { return this.inventory; } public void setItems(NonNullList itemsIn) { this.inventory = itemsIn; } public boolean isItemValidForSlot(int index, ItemStack stack) { // 只允许将物品放入(这个方法只影响自动化,从 GUI 放入需要在 Slot 里写) return Block.getBlockFromItem(stack.getItem()) == Blocks.AIR; } // NBT 交互 public CompoundNBT write(CompoundNBT compound) { super.write(compound); if (!this.checkLootAndWrite(compound)) ItemStackHelper.saveAllItems(compound, this.inventory); return compound; } public void read(BlockState state, CompoundNBT nbt) { super.read(state, nbt); this.inventory = NonNullList.withSize(this.getSizeInventory(), ItemStack.EMPTY); if (!this.checkLootAndRead(nbt)) ItemStackHelper.loadAllItems(nbt, this.inventory); } // 支持从服务器接受数据,以在物品改变时同步显示 @Nullable public SUpdateTileEntityPacket getUpdatePacket() {return new SUpdateTileEntityPacket(pos, 0, getUpdateTag());} @Override public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {handleUpdateTag(null, pkt.getNbtCompound());} public CompoundNBT getUpdateTag() {return write(new CompoundNBT());} // 物品更新触发的事件 private Container container = null; public void markDirty() { super.markDirty(); if (container != null) container.onCraftMatrixChanged(this); // 通知 Container 改变输出内容 world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), Constants.BlockFlags.BLOCK_UPDATE); // 通知客户端更新物品模型渲染 } protected Container createMenu(int id, PlayerInventory player) { AnvilContainerRe container = new AnvilContainerRe(id, player, IWorldPosCallable.of(this.world, this.pos)); this.container = container; return container; } // TODO : [难顶] 让漏斗只能从上方注入物品(由于 Forge 接管了漏斗代码,需要使用它的 Capability,什么 SidedInventory 不管用),不过这个写起来还是不太对的样子 /*@Nonnull @Override public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return LazyOptional.of(() -> new ItemStackHandler() { @Override public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { if (side != Direction.UP) return ItemStack.EMPTY; return super.insertItem(slot, stack, simulate); } }).cast(); } return super.getCapability(cap, side); }*/ // TODO : 让目前的机制修改根据游戏难度略有变化 // TODO : 由于目前的铁砧判断方式,它现在不接受线,因为线有对应的方块…… // TODO : 让铁砧可以根据物品栏里的物品数量向比较器输出红石信号 }