AnvilTileEntity.java 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package com.hexdragon.enchrebirth.block.anvil;
  2. import com.hexdragon.enchrebirth.Main;
  3. import com.hexdragon.enchrebirth.registry.RegMain;
  4. import net.minecraft.block.AnvilBlock;
  5. import net.minecraft.block.BlockState;
  6. import net.minecraft.entity.player.PlayerInventory;
  7. import net.minecraft.inventory.ISidedInventory;
  8. import net.minecraft.inventory.ItemStackHelper;
  9. import net.minecraft.inventory.container.Container;
  10. import net.minecraft.item.ItemStack;
  11. import net.minecraft.nbt.CompoundNBT;
  12. import net.minecraft.network.NetworkManager;
  13. import net.minecraft.network.play.server.SUpdateTileEntityPacket;
  14. import net.minecraft.tileentity.LockableLootTileEntity;
  15. import net.minecraft.tileentity.TileEntityType;
  16. import net.minecraft.util.Direction;
  17. import net.minecraft.util.IWorldPosCallable;
  18. import net.minecraft.util.NonNullList;
  19. import net.minecraft.util.text.ITextComponent;
  20. import net.minecraft.util.text.TranslationTextComponent;
  21. import net.minecraftforge.common.capabilities.Capability;
  22. import net.minecraftforge.common.util.Constants;
  23. import net.minecraftforge.common.util.LazyOptional;
  24. import net.minecraftforge.items.CapabilityItemHandler;
  25. import net.minecraftforge.items.wrapper.SidedInvWrapper;
  26. import javax.annotation.Nonnull;
  27. import javax.annotation.Nullable;
  28. // 铁砧 TileEntity,用于引导自定义模型与存储物品 NBT
  29. public class AnvilTileEntity extends LockableLootTileEntity implements ISidedInventory {
  30. protected ITextComponent getDefaultName() {return new TranslationTextComponent("gui.anvil.title");}
  31. // 构造函数,为了支持不同损坏度的铁砧复读了 6 次
  32. public static class PerfectAnvilTileEntity extends AnvilTileEntity {
  33. public PerfectAnvilTileEntity() { super(RegMain.tileEntityPerfectAnvil.get()); }
  34. }
  35. public static class ChippedAnvilTileEntity extends AnvilTileEntity {
  36. public ChippedAnvilTileEntity() { super(RegMain.tileEntityChippedAnvil.get()); }
  37. }
  38. public static class DamagedAnvilTileEntity extends AnvilTileEntity {
  39. public DamagedAnvilTileEntity() { super(RegMain.tileEntityDamagedAnvil.get()); }
  40. }
  41. public static class PerfectNetheriteAnvilTileEntity extends AnvilTileEntity {
  42. public PerfectNetheriteAnvilTileEntity() { super(RegMain.tileEntityPerfectNetheriteAnvil.get()); }
  43. }
  44. public static class ChippedNetheriteAnvilTileEntity extends AnvilTileEntity {
  45. public ChippedNetheriteAnvilTileEntity() { super(RegMain.tileEntityChippedNetheriteAnvil.get()); }
  46. }
  47. public static class DamagedNetheriteAnvilTileEntity extends AnvilTileEntity {
  48. public DamagedNetheriteAnvilTileEntity() { super(RegMain.tileEntityDamagedNetheriteAnvil.get()); }
  49. }
  50. public AnvilTileEntity(TileEntityType<?> typeIn) { super(typeIn); }
  51. // 物品栏基础
  52. public NonNullList<ItemStack> inventory = NonNullList.withSize(2, ItemStack.EMPTY);
  53. public int getSizeInventory() {return 2;}
  54. public NonNullList<ItemStack> getItems() {
  55. return this.inventory;
  56. }
  57. public void setItems(NonNullList<ItemStack> itemsIn) {
  58. this.inventory = itemsIn;
  59. }
  60. // NBT 交互
  61. public CompoundNBT write(CompoundNBT compound) {
  62. super.write(compound);
  63. if (!this.checkLootAndWrite(compound)) ItemStackHelper.saveAllItems(compound, this.inventory);
  64. return compound;
  65. }
  66. public void read(BlockState state, CompoundNBT nbt) {
  67. super.read(state, nbt);
  68. this.inventory = NonNullList.withSize(this.getSizeInventory(), ItemStack.EMPTY);
  69. if (!this.checkLootAndRead(nbt)) ItemStackHelper.loadAllItems(nbt, this.inventory);
  70. }
  71. // 支持从服务器接受数据,以在物品改变时同步显示
  72. @Nullable public SUpdateTileEntityPacket getUpdatePacket() {return new SUpdateTileEntityPacket(pos, 0, getUpdateTag());}
  73. @Override public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {handleUpdateTag(null, pkt.getNbtCompound());}
  74. public CompoundNBT getUpdateTag() {return write(new CompoundNBT());}
  75. // 物品更新触发的事件
  76. private Container container = null;
  77. public void markDirty() {
  78. super.markDirty();
  79. if (container != null) container.onCraftMatrixChanged(this); // 通知 Container 改变输出内容
  80. world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), Constants.BlockFlags.BLOCK_UPDATE); // 通知客户端更新物品模型渲染
  81. }
  82. protected Container createMenu(int id, PlayerInventory player) {
  83. AnvilContainerRe container = new AnvilContainerRe(id, player, IWorldPosCallable.of(this.world, this.pos), this);
  84. Main.LastTileEntity = this;
  85. this.container = container;
  86. return container;
  87. }
  88. // 控制漏斗的流入和流出
  89. @Override public int[] getSlotsForFace(Direction direction) {
  90. if (direction == Direction.UP) return new int[]{0, 1}; // 顶部可以向全部两格输入
  91. Direction blockDirection = this.getBlockState().get(AnvilBlock.FACING);
  92. if (direction == blockDirection.getOpposite()) return new int[]{0}; // 左侧只能输入到左侧
  93. if (direction == blockDirection) return new int[]{1}; // 右侧只能输入到右侧
  94. return new int[0]; // 其他侧拒绝访问
  95. }
  96. @Override public boolean canInsertItem(int index, ItemStack itemStackIn, @Nullable Direction direction) {
  97. Direction blockDirection = this.getBlockState().get(AnvilBlock.FACING);
  98. return direction == Direction.UP || direction == blockDirection || direction == blockDirection.getOpposite();
  99. }
  100. @Override public boolean canExtractItem(int index, ItemStack stack, Direction direction) {
  101. return false;
  102. }
  103. @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
  104. if (!this.removed && cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
  105. return LazyOptional.of(() -> new SidedInvWrapper(this, side)).cast();
  106. }
  107. return super.getCapability(cap, side);
  108. }
  109. // TODO : 让铁砧可以根据物品栏里的物品数量向比较器输出红石信号
  110. }