Refactor PistionStructureResolver API for better Compatiblity (#1775)

* Implement better handling for custom block interactions within the `PistionStructureResolver`

- Switch to a opt in system for piston interaction methods by moving to a dedicated interface and removing mixin that injects such into every block
- Default to vanilla code for slime blocks and honey blocks behavior.
- Keep `BlockBehaviourInterface` and `BlockBehaviour_customStickyMixin` for compatibility reasons
This commit is contained in:
Blodhgarm authored and GitHub committed 2023-08-01 13:29:49 +02:00
1 parent 1a73edbf76
commit f564a9c491
9 files changed
+57 -114

No files matched your search

@@ -1,20 +0,0 @@
package carpet.fakes;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
public interface BlockBehaviourInterface {
/**
* @return whether this block is sticky in any way when moved by pistons
*/
public boolean isSticky(BlockState state);
/**
* @return whether the neighboring block is pulled along if this block is moved by pistons
*/
public boolean isStickyToNeighbor(Level level, BlockPos pos, BlockState state, BlockPos neighborPos, BlockState neighborState, Direction dir, Direction moveDir);
}
@@ -0,0 +1,28 @@
package carpet.fakes;
import carpet.mixins.PistonStructureResolver_customStickyMixin;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.piston.PistonStructureResolver;
import net.minecraft.world.level.block.state.BlockState;
/**
* Opt-in Interface that allows for more control on a blocks interaction within the {@link PistonStructureResolver} via {@link PistonStructureResolver_customStickyMixin}
*/
public interface BlockPistonBehaviourInterface {
/**
* @return whether this block is sticky in any way when moved by pistons
*/
default boolean isSticky(BlockState state) {
return false;
}
/**
* @return whether the neighboring block is pulled along if this block is moved by pistons
*/
default boolean isStickyToNeighbor(Level level, BlockPos pos, BlockState state, BlockPos neighborPos, BlockState neighborState, Direction dir, Direction moveDir) {
return false;
}
}
@@ -1,25 +0,0 @@
package carpet.mixins;
import org.spongepowered.asm.mixin.Mixin;
import carpet.fakes.BlockBehaviourInterface;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
@Mixin(BlockBehaviour.class)
public class BlockBehaviour_customStickyMixin implements BlockBehaviourInterface {
@Override
public boolean isSticky(BlockState state) {
return false;
}
@Override
public boolean isStickyToNeighbor(Level level, BlockPos pos, BlockState state, BlockPos neighborPos, BlockState neighborState, Direction dir, Direction moveDir) {
return false;
}
}
@@ -1,10 +1,10 @@
package carpet.mixins; package carpet.mixins;
import carpet.fakes.BlockPistonBehaviourInterface;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import carpet.CarpetSettings; import carpet.CarpetSettings;
import carpet.CarpetSettings.ChainStoneMode; import carpet.CarpetSettings.ChainStoneMode;
import carpet.fakes.BlockBehaviourInterface;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@@ -17,7 +17,7 @@ import net.minecraft.world.level.block.EndRodBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@Mixin(ChainBlock.class) @Mixin(ChainBlock.class)
public class ChainBlock_customStickyMixin implements BlockBehaviourInterface { public class ChainBlock_customStickyMixin implements BlockPistonBehaviourInterface {
@Override @Override
public boolean isSticky(BlockState state) { public boolean isSticky(BlockState state) {
@@ -1,9 +1,9 @@
package carpet.mixins; package carpet.mixins;
import carpet.fakes.BlockPistonBehaviourInterface;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import carpet.CarpetSettings; import carpet.CarpetSettings;
import carpet.fakes.BlockBehaviourInterface;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@@ -16,7 +16,7 @@ import net.minecraft.world.level.block.state.properties.ChestType;
import static net.minecraft.world.level.block.ChestBlock.getConnectedDirection; import static net.minecraft.world.level.block.ChestBlock.getConnectedDirection;
@Mixin(ChestBlock.class) @Mixin(ChestBlock.class)
public class ChestBlock_customStickyMixin implements BlockBehaviourInterface { public class ChestBlock_customStickyMixin implements BlockPistonBehaviourInterface {
@Override @Override
public boolean isSticky(BlockState state) { public boolean isSticky(BlockState state) {
@@ -35,6 +35,7 @@ public class ChestBlock_customStickyMixin implements BlockBehaviourInterface {
if (type == ChestType.SINGLE || neighborType == ChestType.SINGLE) { if (type == ChestType.SINGLE || neighborType == ChestType.SINGLE) {
return false; return false;
} }
return getConnectedDirection(state) == dir; return getConnectedDirection(state) == dir;
} }
} }
@@ -1,26 +0,0 @@
package carpet.mixins;
import org.spongepowered.asm.mixin.Mixin;
import carpet.fakes.BlockBehaviourInterface;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.HoneyBlock;
import net.minecraft.world.level.block.state.BlockState;
@Mixin(HoneyBlock.class)
public class HoneyBlock_customStickyMixin implements BlockBehaviourInterface {
@Override
public boolean isSticky(BlockState state) {
return true;
}
@Override
public boolean isStickyToNeighbor(Level level, BlockPos pos, BlockState state, BlockPos neighborPos, BlockState neighborState, Direction dir, Direction moveDir) {
return !neighborState.is(Blocks.SLIME_BLOCK);
}
}
@@ -3,13 +3,14 @@ package carpet.mixins;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import carpet.fakes.BlockBehaviourInterface; import carpet.fakes.BlockPistonBehaviourInterface;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@@ -18,11 +19,13 @@ import net.minecraft.world.level.block.piston.PistonStructureResolver;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@Mixin(PistonStructureResolver.class) @Mixin(PistonStructureResolver.class)
public class PistonStructureResolver_customStickyMixin { public abstract class PistonStructureResolver_customStickyMixin {
@Shadow @Final private Level level; @Shadow @Final private Level level;
@Shadow @Final private Direction pushDirection; @Shadow @Final private Direction pushDirection;
@Shadow private static boolean canStickToEachOther(BlockState blockState, BlockState blockState2) { return false; }
@Inject( @Inject(
method = "isSticky", method = "isSticky",
cancellable = true, cancellable = true,
@@ -31,12 +34,14 @@ public class PistonStructureResolver_customStickyMixin {
) )
) )
private static void isSticky(BlockState state, CallbackInfoReturnable<Boolean> cir) { private static void isSticky(BlockState state, CallbackInfoReturnable<Boolean> cir) {
cir.setReturnValue(((BlockBehaviourInterface)state.getBlock()).isSticky(state)); if(state.getBlock() instanceof BlockPistonBehaviourInterface behaviourInterface){
cir.setReturnValue(behaviourInterface.isSticky(state));
}
} }
// fields that are needed because @Redirects cannot capture locals // fields that are needed because @Redirects cannot capture locals
private BlockPos pos_addBlockLine; @Unique private BlockPos pos_addBlockLine;
private BlockPos behindPos_addBlockLine; @Unique private BlockPos behindPos_addBlockLine;
@Inject( @Inject(
method = "addBlockLine", method = "addBlockLine",
@@ -60,12 +65,16 @@ public class PistonStructureResolver_customStickyMixin {
) )
) )
private boolean onAddBlockLineCanStickToEachOther(BlockState state, BlockState behindState) { private boolean onAddBlockLineCanStickToEachOther(BlockState state, BlockState behindState) {
return ((BlockBehaviourInterface)state.getBlock()).isStickyToNeighbor(level, pos_addBlockLine, state, behindPos_addBlockLine, behindState, pushDirection.getOpposite(), pushDirection); if (state.getBlock() instanceof BlockPistonBehaviourInterface behaviourInterface) {
return behaviourInterface.isStickyToNeighbor(level, pos_addBlockLine, state, behindPos_addBlockLine, behindState, pushDirection.getOpposite(), pushDirection);
}
return canStickToEachOther(state, behindState);
} }
// fields that are needed because @Redirects cannot capture locals // fields that are needed because @Redirects cannot capture locals
private Direction dir_addBranchingBlocks; @Unique private Direction dir_addBranchingBlocks;
private BlockPos neighborPos_addBranchingBlocks; @Unique private BlockPos neighborPos_addBranchingBlocks;
@Inject( @Inject(
method = "addBranchingBlocks", method = "addBranchingBlocks",
@@ -89,6 +98,10 @@ public class PistonStructureResolver_customStickyMixin {
) )
) )
private boolean onAddBranchingBlocksCanStickToEachOther(BlockState neighborState, BlockState state, BlockPos pos) { private boolean onAddBranchingBlocksCanStickToEachOther(BlockState neighborState, BlockState state, BlockPos pos) {
return ((BlockBehaviourInterface)state.getBlock()).isStickyToNeighbor(level, pos, state, neighborPos_addBranchingBlocks, neighborState, dir_addBranchingBlocks, pushDirection); if (state.getBlock() instanceof BlockPistonBehaviourInterface behaviourInterface) {
return behaviourInterface.isStickyToNeighbor(level, pos, state, neighborPos_addBranchingBlocks, neighborState, dir_addBranchingBlocks, pushDirection);
}
return canStickToEachOther(neighborState, state);
} }
} }
@@ -1,26 +0,0 @@
package carpet.mixins;
import org.spongepowered.asm.mixin.Mixin;
import carpet.fakes.BlockBehaviourInterface;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.SlimeBlock;
import net.minecraft.world.level.block.state.BlockState;
@Mixin(SlimeBlock.class)
public class SlimeBlock_customStickyMixin implements BlockBehaviourInterface {
@Override
public boolean isSticky(BlockState state) {
return true;
}
@Override
public boolean isStickyToNeighbor(Level level, BlockPos pos, BlockState state, BlockPos neighborPos, BlockState neighborState, Direction dir, Direction moveDir) {
return !neighborState.is(Blocks.HONEY_BLOCK);
}
}
+2 -4
View File
@@ -178,13 +178,11 @@
"SculkSensorBlockEntityVibrationConfig_sculkSensorRangeMixin", "SculkSensorBlockEntityVibrationConfig_sculkSensorRangeMixin",
"CollectingNeighborUpdaterAccessor", "CollectingNeighborUpdaterAccessor",
"BlockBehaviour_customStickyMixin",
"BlockBehaviourBlockStateBase_mixin", "BlockBehaviourBlockStateBase_mixin",
"ChainBlock_customStickyMixin", "ChainBlock_customStickyMixin",
"ChestBlock_customStickyMixin", "ChestBlock_customStickyMixin",
"HoneyBlock_customStickyMixin", "PistonStructureResolver_customStickyMixin"
"PistonStructureResolver_customStickyMixin",
"SlimeBlock_customStickyMixin"
], ],
"client": [ "client": [
"ClientLevel_tickSpeedMixin", "ClientLevel_tickSpeedMixin",