diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java index f49d0da5..d2980d98 100644 --- a/src/main/java/carpet/CarpetSettings.java +++ b/src/main/java/carpet/CarpetSettings.java @@ -52,6 +52,7 @@ public class CarpetSettings public static boolean chainStoneStickToAll = false; public static Block structureBlockIgnoredBlock = Blocks.STRUCTURE_VOID; public static final int vanillaStructureBlockLimit = 48; + public static int updateSuppressionBlockSetting = -1; private static class LanguageValidator extends Validator { @Override public String validate(ServerCommandSource source, ParsedRule currentRule, String newValue, String string) { @@ -912,4 +913,48 @@ public class CarpetSettings category = {BUGFIX} ) public static boolean lightningKillsDropsFix = false; + + @Rule( + desc = "Placing an activator rail on top of a barrier block will update suppress when the rail turns off.", + extra = {"Entering an integer will make the update suppression block auto-reset","Integer entered is the delay in ticks for it to reset"}, + category = {CREATIVE, "extras"}, + options = {"false","true","1","6"}, + strict = false, + validate = updateSuppressionBlockModes.class + ) + public static String updateSuppressionBlock = "false"; + + public static int getInteger(String s) { + try { + return Integer.parseInt(s); + } catch(NumberFormatException e) { + return -1; + } + } + + private static class updateSuppressionBlockModes extends Validator { + @Override + public String validate(ServerCommandSource source, ParsedRule currentRule, String newValue, String string) { + if (!currentRule.get().equals(newValue)) { + if (newValue.equalsIgnoreCase("false")) { + updateSuppressionBlockSetting = -1; + } else if (newValue.equalsIgnoreCase("true")) { + updateSuppressionBlockSetting = 0; + } else { + int parsedInt = getInteger(newValue); + if (parsedInt <= 0) { + updateSuppressionBlockSetting = -1; + return "false"; + } else { + updateSuppressionBlockSetting = parsedInt; + } + } + } + return newValue; + } + @Override + public String description() { + return "Cannot be negative, can be true, false, or # > 0"; + } + } } diff --git a/src/main/java/carpet/mixins/BarrierBlock_updateSuppressionBlockMixin.java b/src/main/java/carpet/mixins/BarrierBlock_updateSuppressionBlockMixin.java new file mode 100644 index 00000000..480f85f8 --- /dev/null +++ b/src/main/java/carpet/mixins/BarrierBlock_updateSuppressionBlockMixin.java @@ -0,0 +1,55 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.block.BarrierBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.PoweredRailBlock; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; + +import java.util.Random; + +@Mixin(BarrierBlock.class) +public class BarrierBlock_updateSuppressionBlockMixin extends Block { + private boolean shouldPower = false; + + public BarrierBlock_updateSuppressionBlockMixin(Settings settings) { super(settings); } + + @Override + public int getWeakRedstonePower(BlockState state, BlockView world, BlockPos pos, Direction direction) { + return (shouldPower && direction == Direction.DOWN) ? 15 : 0; + } + + @Override + public void neighborUpdate(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) { + if (CarpetSettings.updateSuppressionBlockSetting != -1) { + if (fromPos.equals(pos.up())) { + BlockState stateAbove = world.getBlockState(fromPos); + if (stateAbove.isOf(Blocks.ACTIVATOR_RAIL) && !stateAbove.get(PoweredRailBlock.POWERED)) { + if (CarpetSettings.updateSuppressionBlockSetting > 0) { + world.getBlockTickScheduler().schedule(pos, this, CarpetSettings.updateSuppressionBlockSetting); + } + throw new StackOverflowError("updateSuppressionBlock"); + } + } + } + super.neighborUpdate(state, world, pos, block, fromPos, notify); + } + + @Override + public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + BlockPos posAbove = pos.up(); + BlockState stateAbove = world.getBlockState(posAbove); + if (stateAbove.isOf(Blocks.ACTIVATOR_RAIL) && !stateAbove.get(PoweredRailBlock.POWERED)) { + shouldPower = true; + world.setBlockState(posAbove, stateAbove.with(PoweredRailBlock.POWERED, true), 3); + shouldPower = false; + } + } +} diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index e5aebfd6..7d613bc4 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -4,6 +4,8 @@ "package": "carpet.mixins", "compatibilityLevel": "JAVA_16", "mixins": [ + "BarrierBlock_updateSuppressionBlockMixin", + "SpawnHelperInnerMixin", "CommandManagerMixin", @@ -234,4 +236,4 @@ "injectors": { "defaultRequire": 1 } -} +} \ No newline at end of file