AnvilBlockMixin.java 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package com.hexdragon.enchrebirth.mixin.block;
  2. import com.hexdragon.enchrebirth.block.anvil.AnvilTileEntity;
  3. import com.hexdragon.enchrebirth.registry.RegMain;
  4. import net.minecraft.block.*;
  5. import net.minecraft.inventory.InventoryHelper;
  6. import net.minecraft.inventory.container.INamedContainerProvider;
  7. import net.minecraft.state.DirectionProperty;
  8. import net.minecraft.state.StateContainer;
  9. import net.minecraft.tileentity.TileEntity;
  10. import net.minecraft.util.Direction;
  11. import net.minecraft.util.math.BlockPos;
  12. import net.minecraft.util.math.shapes.ISelectionContext;
  13. import net.minecraft.util.math.shapes.VoxelShape;
  14. import net.minecraft.util.math.shapes.VoxelShapes;
  15. import net.minecraft.world.IBlockReader;
  16. import net.minecraft.world.World;
  17. import net.minecraftforge.common.extensions.IForgeBlock;
  18. import org.spongepowered.asm.mixin.Mixin;
  19. import org.spongepowered.asm.mixin.Shadow;
  20. import org.spongepowered.asm.mixin.injection.At;
  21. import org.spongepowered.asm.mixin.injection.Inject;
  22. import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
  23. import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
  24. import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
  25. @Mixin(AnvilBlock.class)
  26. public abstract class AnvilBlockMixin extends FallingBlock implements IForgeBlock {
  27. public AnvilBlockMixin(Properties properties) {super(properties);}
  28. // 将铁砧的处理事件替换为 Mod 所提供的事件
  29. @Inject(method = "getContainer", at = @At(value = "HEAD"), cancellable = true, locals = LocalCapture.CAPTURE_FAILEXCEPTION)
  30. private void getContainer(BlockState state, World worldIn, BlockPos pos, CallbackInfoReturnable<INamedContainerProvider> cir) {
  31. cir.setReturnValue((INamedContainerProvider) worldIn.getTileEntity(pos));
  32. cir.cancel();
  33. }
  34. // 注册 TileEntity
  35. @Override public boolean hasTileEntity(BlockState state) {
  36. return true;
  37. }
  38. @Override public TileEntity createTileEntity(BlockState state, IBlockReader world) {
  39. if (state.isIn(Blocks.ANVIL)) {
  40. return new AnvilTileEntity.PerfectAnvilTileEntity();
  41. } else if (state.isIn(Blocks.CHIPPED_ANVIL)) {
  42. return new AnvilTileEntity.ChippedAnvilTileEntity();
  43. } else if (state.isIn(Blocks.DAMAGED_ANVIL)) {
  44. return new AnvilTileEntity.DamagedAnvilTileEntity();
  45. } else if (state.isIn(RegMain.blockPerfectNetheriteAnvil.get())) {
  46. return new AnvilTileEntity.PerfectNetheriteAnvilTileEntity();
  47. } else if (state.isIn(RegMain.blockChippedNetheriteAnvil.get())) {
  48. return new AnvilTileEntity.ChippedNetheriteAnvilTileEntity();
  49. } else {
  50. return new AnvilTileEntity.DamagedNetheriteAnvilTileEntity();
  51. }
  52. }
  53. // 当破坏时掉落内容物
  54. @Override public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
  55. if (!state.isIn(newState.getBlock())) {
  56. TileEntity tileentity = worldIn.getTileEntity(pos);
  57. if (tileentity instanceof AnvilTileEntity)
  58. InventoryHelper.dropItems(worldIn, pos, ((AnvilTileEntity) tileentity).getItems());
  59. super.onReplaced(state, worldIn, pos, newState, isMoving);
  60. }
  61. }
  62. // 将铁砧的碰撞箱降低 1 像素
  63. @Shadow public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
  64. private static final VoxelShape PART_BASE = Block.makeCuboidShape(2.0D, 0.0D, 2.0D, 14.0D, 4.0D, 14.0D);
  65. private static final VoxelShape PART_LOWER_X = Block.makeCuboidShape(3.0D, 4.0D, 4.0D, 13.0D, 5.0D, 12.0D);
  66. private static final VoxelShape PART_MID_X = Block.makeCuboidShape(4.0D, 5.0D, 6.0D, 12.0D, 10.0D, 10.0D);
  67. private static final VoxelShape PART_UPPER_X = Block.makeCuboidShape(0.0D, 10.0D, 3.0D, 16.0D, 15.0D, 13.0D);
  68. private static final VoxelShape PART_LOWER_Z = Block.makeCuboidShape(4.0D, 4.0D, 3.0D, 12.0D, 5.0D, 13.0D);
  69. private static final VoxelShape PART_MID_Z = Block.makeCuboidShape(6.0D, 5.0D, 4.0D, 10.0D, 10.0D, 12.0D);
  70. private static final VoxelShape PART_UPPER_Z = Block.makeCuboidShape(3.0D, 10.0D, 0.0D, 13.0D, 15.0D, 16.0D);
  71. private static final VoxelShape X_AXIS_AABB = VoxelShapes.or(PART_BASE, PART_LOWER_X, PART_MID_X, PART_UPPER_X);
  72. private static final VoxelShape Z_AXIS_AABB = VoxelShapes.or(PART_BASE, PART_LOWER_Z, PART_MID_Z, PART_UPPER_Z);
  73. @Inject(method = "getShape", at = @At(value = "HEAD"), cancellable = true, locals = LocalCapture.CAPTURE_FAILEXCEPTION)
  74. private void getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context, CallbackInfoReturnable<VoxelShape> cir) {
  75. cir.setReturnValue(state.get(FACING).getAxis() == Direction.Axis.X ? X_AXIS_AABB : Z_AXIS_AABB);
  76. cir.cancel();
  77. }
  78. // 添加 MATERIAL BlockState
  79. @Inject(method = "fillStateContainer", at = @At(value = "HEAD"), locals = LocalCapture.CAPTURE_FAILEXCEPTION)
  80. protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder, CallbackInfo cir) {
  81. builder.add(RegMain.blockStateMaterial);
  82. }
  83. // 阻止下界合金砧因为摔落而损坏
  84. @Inject(method = "damage", at = @At(value = "HEAD"), cancellable = true, locals = LocalCapture.CAPTURE_FAILEXCEPTION)
  85. private static void damage(BlockState state, CallbackInfoReturnable<BlockState> cir) {
  86. if (state.isIn(RegMain.blockDamagedNetheriteAnvil.get()) || state.isIn(RegMain.blockChippedNetheriteAnvil.get()) || state.isIn(RegMain.blockPerfectNetheriteAnvil.get())) {
  87. cir.setReturnValue(state.getBlock().getDefaultState().with(FACING, state.get(FACING)));
  88. cir.cancel();
  89. }
  90. }
  91. // TODO : <重要> 破坏下界合金砧没有掉落物
  92. // TODO : [010] 绘制下界合金砧的材质(也可以修改原版铁砧的材质以让它有更大的区分度?)
  93. }