AnvilTileEntity.java 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package com.hexdragon.enchrebirth.block.anvil;
  2. import com.hexdragon.enchrebirth.registry.RegMain;
  3. import net.minecraft.block.Block;
  4. import net.minecraft.block.BlockState;
  5. import net.minecraft.block.Blocks;
  6. import net.minecraft.entity.player.PlayerInventory;
  7. import net.minecraft.inventory.ItemStackHelper;
  8. import net.minecraft.inventory.container.Container;
  9. import net.minecraft.item.ItemStack;
  10. import net.minecraft.nbt.CompoundNBT;
  11. import net.minecraft.network.NetworkManager;
  12. import net.minecraft.network.play.server.SUpdateTileEntityPacket;
  13. import net.minecraft.tileentity.LockableLootTileEntity;
  14. import net.minecraft.tileentity.TileEntityType;
  15. import net.minecraft.util.IWorldPosCallable;
  16. import net.minecraft.util.NonNullList;
  17. import net.minecraft.util.text.ITextComponent;
  18. import net.minecraft.util.text.TranslationTextComponent;
  19. import net.minecraftforge.common.util.Constants;
  20. import javax.annotation.Nullable;
  21. // 铁砧 TileEntity,用于引导自定义模型与存储物品 NBT
  22. public class AnvilTileEntity extends LockableLootTileEntity {
  23. protected ITextComponent getDefaultName() {return new TranslationTextComponent("gui.anvil.title");}
  24. // 构造函数,为了支持不同损坏度的铁砧复读了 6 次
  25. public static class PerfectAnvilTileEntity extends AnvilTileEntity {
  26. public PerfectAnvilTileEntity() { super(RegMain.tileEntityPerfectAnvil.get()); }
  27. }
  28. public static class ChippedAnvilTileEntity extends AnvilTileEntity {
  29. public ChippedAnvilTileEntity() { super(RegMain.tileEntityChippedAnvil.get()); }
  30. }
  31. public static class DamagedAnvilTileEntity extends AnvilTileEntity {
  32. public DamagedAnvilTileEntity() { super(RegMain.tileEntityDamagedAnvil.get()); }
  33. }
  34. public static class PerfectNetheriteAnvilTileEntity extends AnvilTileEntity {
  35. public PerfectNetheriteAnvilTileEntity() { super(RegMain.tileEntityPerfectNetheriteAnvil.get()); }
  36. }
  37. public static class ChippedNetheriteAnvilTileEntity extends AnvilTileEntity {
  38. public ChippedNetheriteAnvilTileEntity() { super(RegMain.tileEntityChippedNetheriteAnvil.get()); }
  39. }
  40. public static class DamagedNetheriteAnvilTileEntity extends AnvilTileEntity {
  41. public DamagedNetheriteAnvilTileEntity() { super(RegMain.tileEntityDamagedNetheriteAnvil.get()); }
  42. }
  43. public AnvilTileEntity(TileEntityType<?> typeIn) { super(typeIn); }
  44. // 物品栏
  45. public NonNullList<ItemStack> inventory = NonNullList.withSize(2, ItemStack.EMPTY);
  46. public int getSizeInventory() {return 2;}
  47. public NonNullList<ItemStack> getItems() {
  48. return this.inventory;
  49. }
  50. public void setItems(NonNullList<ItemStack> itemsIn) {
  51. this.inventory = itemsIn;
  52. }
  53. public boolean isItemValidForSlot(int index, ItemStack stack) {
  54. // 只允许将物品放入(这个方法只影响自动化,从 GUI 放入需要在 Slot 里写)
  55. return Block.getBlockFromItem(stack.getItem()) == Blocks.AIR;
  56. }
  57. // NBT 交互
  58. public CompoundNBT write(CompoundNBT compound) {
  59. super.write(compound);
  60. if (!this.checkLootAndWrite(compound)) ItemStackHelper.saveAllItems(compound, this.inventory);
  61. return compound;
  62. }
  63. public void read(BlockState state, CompoundNBT nbt) {
  64. super.read(state, nbt);
  65. this.inventory = NonNullList.withSize(this.getSizeInventory(), ItemStack.EMPTY);
  66. if (!this.checkLootAndRead(nbt)) ItemStackHelper.loadAllItems(nbt, this.inventory);
  67. }
  68. // 支持从服务器接受数据,以在物品改变时同步显示
  69. @Nullable public SUpdateTileEntityPacket getUpdatePacket() {return new SUpdateTileEntityPacket(pos, 0, getUpdateTag());}
  70. @Override public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {handleUpdateTag(null, pkt.getNbtCompound());}
  71. public CompoundNBT getUpdateTag() {return write(new CompoundNBT());}
  72. // 物品更新触发的事件
  73. private Container container = null;
  74. public void markDirty() {
  75. super.markDirty();
  76. if (container != null) container.onCraftMatrixChanged(this); // 通知 Container 改变输出内容
  77. world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), Constants.BlockFlags.BLOCK_UPDATE); // 通知客户端更新物品模型渲染
  78. }
  79. protected Container createMenu(int id, PlayerInventory player) {
  80. AnvilContainerRe container = new AnvilContainerRe(id, player, IWorldPosCallable.of(this.world, this.pos));
  81. this.container = container;
  82. return container;
  83. }
  84. // TODO : [难顶] 让漏斗只能从上方注入物品(由于 Forge 接管了漏斗代码,需要使用它的 Capability,什么 SidedInventory 不管用),不过这个写起来还是不太对的样子
  85. /*@Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
  86. if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
  87. return LazyOptional.of(() -> new ItemStackHandler() {
  88. @Override public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
  89. if (side != Direction.UP) return ItemStack.EMPTY;
  90. return super.insertItem(slot, stack, simulate);
  91. }
  92. }).cast();
  93. }
  94. return super.getCapability(cap, side);
  95. }*/
  96. // TODO : 让目前的机制修改根据游戏难度略有变化
  97. // TODO : 由于目前的铁砧判断方式,它现在不接受线,因为线有对应的方块……
  98. // TODO : 让铁砧可以根据物品栏里的物品数量向比较器输出红石信号
  99. }