From 0e2f6df4d38cd45fd35c305a096601288c5acb0e Mon Sep 17 00:00:00 2001 From: Space Walker <48224626+SpaceWalkerRS@users.noreply.github.com> Date: Wed, 25 Jan 2023 17:28:05 +0100 Subject: [PATCH] Allow setting qc range with `quasiConnectivity` setting (#1617) * add quasiConnectivityRange setting * make sure qc range respects different world heights * check if source == null in qc range validator * merge the two qc settings * Set minimum range down to zero (no qc) --- src/main/java/carpet/CarpetSettings.java | 28 +++++++++++++-- .../carpet/helpers/QuasiConnectivity.java | 24 +++++++++++++ .../carpet/mixins/DispenserBlock_qcMixin.java | 34 +++++++++++-------- .../mixins/PistonBaseBlock_qcMixin.java | 34 +++++++++---------- 4 files changed, 86 insertions(+), 34 deletions(-) create mode 100644 src/main/java/carpet/helpers/QuasiConnectivity.java diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java index 0a2cee9d..1e4849cf 100644 --- a/src/main/java/carpet/CarpetSettings.java +++ b/src/main/java/carpet/CarpetSettings.java @@ -341,8 +341,32 @@ public class CarpetSettings ) public static boolean antiCheatDisabled = false; - @Rule(desc = "Pistons, droppers and dispensers react if block above them is powered", category = CREATIVE) - public static boolean quasiConnectivity = true; + private static class QuasiConnectivityValidator extends Validator { + + @Override + public Integer validate(CommandSourceStack source, CarpetRule changingRule, Integer newValue, String userInput) { + int minRange = 0; + int maxRange = 1; + + if (source == null) { + maxRange = Integer.MAX_VALUE; + } else { + for (Level level : source.getServer().getAllLevels()) { + maxRange = Math.max(maxRange, level.getHeight() - 1); + } + } + + return (newValue >= minRange && newValue <= maxRange) ? newValue : null; + } + } + + @Rule( + desc = "Pistons, droppers, and dispensers check for power to the block(s) above them.", + extra = { "Defines the range at which pistons, droppers, and dispensers check for 'quasi power'." }, + category = CREATIVE, + validate = QuasiConnectivityValidator.class + ) + public static int quasiConnectivity = 1; @Rule( desc = "Players can flip and rotate blocks when holding cactus", diff --git a/src/main/java/carpet/helpers/QuasiConnectivity.java b/src/main/java/carpet/helpers/QuasiConnectivity.java new file mode 100644 index 00000000..0f8d221e --- /dev/null +++ b/src/main/java/carpet/helpers/QuasiConnectivity.java @@ -0,0 +1,24 @@ +package carpet.helpers; + +import carpet.CarpetSettings; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; + +public class QuasiConnectivity { + + public static boolean hasQuasiSignal(Level level, BlockPos pos) { + for (int i = 1; i <= CarpetSettings.quasiConnectivity; i++) { + BlockPos above = pos.above(i); + + if (level.isOutsideBuildHeight(above)) { + break; + } + if (level.hasNeighborSignal(above)) { + return true; + } + } + + return false; + } +} diff --git a/src/main/java/carpet/mixins/DispenserBlock_qcMixin.java b/src/main/java/carpet/mixins/DispenserBlock_qcMixin.java index 69d0ecfd..6444c1a6 100644 --- a/src/main/java/carpet/mixins/DispenserBlock_qcMixin.java +++ b/src/main/java/carpet/mixins/DispenserBlock_qcMixin.java @@ -1,25 +1,29 @@ package carpet.mixins; -import carpet.CarpetSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.DispenserBlock; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; +import carpet.helpers.QuasiConnectivity; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.DispenserBlock; +import net.minecraft.world.level.block.state.BlockState; + @Mixin(DispenserBlock.class) -public class DispenserBlock_qcMixin -{ - @Redirect(method = "neighborChanged", at = @At( +public class DispenserBlock_qcMixin { + + @Redirect( + method = "neighborChanged", + at = @At( value = "INVOKE", - target = "Lnet/minecraft/world/level/Level;hasNeighborSignal(Lnet/minecraft/core/BlockPos;)Z", - ordinal = 1 - )) - private boolean checkUpPower(Level world, BlockPos blockPos_1) - { - if (!CarpetSettings.quasiConnectivity) - return false; - return world.hasNeighborSignal(blockPos_1); + ordinal = 1, + target = "Lnet/minecraft/world/level/Level;hasNeighborSignal(Lnet/minecraft/core/BlockPos;)Z" + ) + ) + private boolean carpet_hasQuasiSignal(Level _level, BlockPos above, BlockState state, Level level, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean movedByPiston) { + return QuasiConnectivity.hasQuasiSignal(level, pos); } } diff --git a/src/main/java/carpet/mixins/PistonBaseBlock_qcMixin.java b/src/main/java/carpet/mixins/PistonBaseBlock_qcMixin.java index 74d46e1f..87ee3b4f 100644 --- a/src/main/java/carpet/mixins/PistonBaseBlock_qcMixin.java +++ b/src/main/java/carpet/mixins/PistonBaseBlock_qcMixin.java @@ -1,29 +1,29 @@ package carpet.mixins; -import carpet.CarpetSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.piston.PistonBaseBlock; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import carpet.helpers.QuasiConnectivity; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.piston.PistonBaseBlock; + @Mixin(PistonBaseBlock.class) -public class PistonBaseBlock_qcMixin -{ - @Inject(method = "getNeighborSignal", cancellable = true, at = @At( +public class PistonBaseBlock_qcMixin { + + @Inject( + method = "getNeighborSignal", + cancellable = true, + at = @At( value = "INVOKE", target = "Lnet/minecraft/core/BlockPos;above()Lnet/minecraft/core/BlockPos;" - )) - private void cancelUpCheck(Level world_1, BlockPos blockPos_1, Direction direction_1, CallbackInfoReturnable cir) - { - if (!CarpetSettings.quasiConnectivity) - { - cir.setReturnValue(false); - cir.cancel(); - } + ) + ) + private void carpet_checkQuasiSignal(Level level, BlockPos pos, Direction facing, CallbackInfoReturnable cir) { + cir.setReturnValue(QuasiConnectivity.hasQuasiSignal(level, pos)); } - }