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)
This commit is contained in:
Space Walker authored and GitHub committed 2023-01-25 17:28:05 +01:00
1 parent f2c658bf03
commit 0e2f6df4d3
4 files changed
+86 -34

No files matched your search

+26 -2
View File
@@ -341,8 +341,32 @@ public class CarpetSettings
) )
public static boolean antiCheatDisabled = false; public static boolean antiCheatDisabled = false;
@Rule(desc = "Pistons, droppers and dispensers react if block above them is powered", category = CREATIVE) private static class QuasiConnectivityValidator extends Validator<Integer> {
public static boolean quasiConnectivity = true;
@Override
public Integer validate(CommandSourceStack source, CarpetRule<Integer> 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( @Rule(
desc = "Players can flip and rotate blocks when holding cactus", desc = "Players can flip and rotate blocks when holding cactus",
@@ -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;
}
}
@@ -1,25 +1,29 @@
package carpet.mixins; 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.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect; 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) @Mixin(DispenserBlock.class)
public class DispenserBlock_qcMixin public class DispenserBlock_qcMixin {
{
@Redirect(method = "neighborChanged", at = @At( @Redirect(
method = "neighborChanged",
at = @At(
value = "INVOKE", value = "INVOKE",
target = "Lnet/minecraft/world/level/Level;hasNeighborSignal(Lnet/minecraft/core/BlockPos;)Z", ordinal = 1,
ordinal = 1 target = "Lnet/minecraft/world/level/Level;hasNeighborSignal(Lnet/minecraft/core/BlockPos;)Z"
)) )
private boolean checkUpPower(Level world, BlockPos blockPos_1) )
{ private boolean carpet_hasQuasiSignal(Level _level, BlockPos above, BlockState state, Level level, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean movedByPiston) {
if (!CarpetSettings.quasiConnectivity) return QuasiConnectivity.hasQuasiSignal(level, pos);
return false;
return world.hasNeighborSignal(blockPos_1);
} }
} }
@@ -1,29 +1,29 @@
package carpet.mixins; 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.Mixin;
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.callback.CallbackInfoReturnable; 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) @Mixin(PistonBaseBlock.class)
public class PistonBaseBlock_qcMixin public class PistonBaseBlock_qcMixin {
{
@Inject(method = "getNeighborSignal", cancellable = true, at = @At( @Inject(
method = "getNeighborSignal",
cancellable = true,
at = @At(
value = "INVOKE", value = "INVOKE",
target = "Lnet/minecraft/core/BlockPos;above()Lnet/minecraft/core/BlockPos;" target = "Lnet/minecraft/core/BlockPos;above()Lnet/minecraft/core/BlockPos;"
)) )
private void cancelUpCheck(Level world_1, BlockPos blockPos_1, Direction direction_1, CallbackInfoReturnable<Boolean> cir) )
{ private void carpet_checkQuasiSignal(Level level, BlockPos pos, Direction facing, CallbackInfoReturnable<Boolean> cir) {
if (!CarpetSettings.quasiConnectivity) cir.setReturnValue(QuasiConnectivity.hasQuasiSignal(level, pos));
{
cir.setReturnValue(false);
cir.cancel();
}
} }
} }