diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/tracks/ControllerRailBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/tracks/ControllerRailBlock.java index b2175ffc2..d4ecf5998 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/tracks/ControllerRailBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/tracks/ControllerRailBlock.java @@ -17,11 +17,13 @@ import net.minecraft.util.Direction; import net.minecraft.util.Mirror; import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; +import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import static net.minecraft.state.properties.RailShape.*; @@ -32,12 +34,12 @@ import static net.minecraft.state.properties.RailShape.*; @SuppressWarnings("deprecation") public class ControllerRailBlock extends AbstractRailBlock implements IWrenchable { public static final EnumProperty SHAPE = BlockStateProperties.RAIL_SHAPE_STRAIGHT; - public static final IntegerProperty POWERED = BlockStateProperties.POWER_0_15; + public static final IntegerProperty POWER = BlockStateProperties.POWER_0_15; public static final BooleanProperty BACKWARDS = BooleanProperty.create("backwards"); public ControllerRailBlock(Properties p_i48444_2_) { super(true, p_i48444_2_); - this.setDefaultState(this.stateContainer.getBaseState().with(POWERED, 0).with(BACKWARDS, false).with(SHAPE, NORTH_SOUTH)); + this.setDefaultState(this.stateContainer.getBaseState().with(POWER, 0).with(BACKWARDS, false).with(SHAPE, NORTH_SOUTH)); } private static Vec3i getAccelerationVector(BlockState state) { @@ -82,7 +84,7 @@ public class ControllerRailBlock extends AbstractRailBlock implements IWrenchabl @Override protected void fillStateContainer(StateContainer.Builder p_206840_1_) { - p_206840_1_.add(SHAPE, POWERED, BACKWARDS); + p_206840_1_.add(SHAPE, POWER, BACKWARDS); } @Override @@ -90,7 +92,7 @@ public class ControllerRailBlock extends AbstractRailBlock implements IWrenchabl if (world.isRemote) return; Vec3d accelerationVec = new Vec3d(getAccelerationVector(state)); - double targetSpeed = cart.getMaxSpeedWithRail() * state.get(POWERED) / 15.; + double targetSpeed = cart.getMaxSpeedWithRail() * state.get(POWER) / 15.; if ((cart.getMotion().dotProduct(accelerationVec) >= 0 || cart.getMotion().lengthSquared() < 0.0001) && targetSpeed > 0) cart.setMotion(accelerationVec.scale(targetSpeed)); else @@ -99,9 +101,52 @@ public class ControllerRailBlock extends AbstractRailBlock implements IWrenchabl @Override protected void updateState(BlockState state, World world, BlockPos pos, Block block) { - int newPower = Math.max(world.getRedstonePowerFromNeighbors(pos), 0); // TODO: Add power calculation - if (state.get(POWERED) != newPower) - placeAndNotify(state.with(POWERED, newPower), pos, world); + int newPower = calculatePower(world, pos); + if (state.get(POWER) != newPower) + placeAndNotify(state.with(POWER, newPower), pos, world); + } + + private int calculatePower(World world, BlockPos pos) { + int newPower = world.getRedstonePowerFromNeighbors(pos); + if (newPower != 0) + return newPower; + + int forwardDistance = 0; + int backwardsDistance = 0; + BlockPos lastForwardRail = pos; + BlockPos lastBackwardsRail = pos; + int forwardPower = 0; + int backwardsPower = 0; + + for (int i = 0; i < 15; i++) { + BlockPos testPos = findNextRail(lastForwardRail, world, false); + if (testPos == null) + break; + forwardDistance++; + lastForwardRail = testPos; + forwardPower = world.getRedstonePowerFromNeighbors(testPos); + if (forwardPower != 0) + break; + } + for (int i = 0; i < 15; i++) { + BlockPos testPos = findNextRail(lastBackwardsRail, world, true); + if (testPos == null) + break; + backwardsDistance++; + lastBackwardsRail = testPos; + backwardsPower = world.getRedstonePowerFromNeighbors(testPos); + if (backwardsPower != 0) + break; + } + if (forwardDistance > 8 && backwardsDistance > 8) + return 0; + else if (backwardsPower == 0 && forwardDistance <= 8) + return forwardPower; + else if (forwardPower == 0 && backwardsDistance <= 8) + return backwardsPower; + else if (backwardsPower != 0 && forwardPower != 0) + return MathHelper.ceil((backwardsPower * forwardDistance + forwardPower * backwardsDistance) / (double) (forwardDistance + backwardsDistance)); + return 0; } @Override @@ -146,7 +191,7 @@ public class ControllerRailBlock extends AbstractRailBlock implements IWrenchabl case ASCENDING_SOUTH: return p_185499_1_.with(SHAPE, ASCENDING_WEST); case NORTH_SOUTH: - return p_185499_1_.with(SHAPE, EAST_WEST).with(SHAPE, NORTH_SOUTH).with(BACKWARDS, !p_185499_1_.get(BACKWARDS)); + return p_185499_1_.with(SHAPE, EAST_WEST).with(BACKWARDS, !p_185499_1_.get(BACKWARDS)); case EAST_WEST: return p_185499_1_.with(SHAPE, NORTH_SOUTH); } @@ -217,4 +262,31 @@ public class ControllerRailBlock extends AbstractRailBlock implements IWrenchabl if (state.get(SHAPE).isAscending()) world.notifyNeighborsOfStateChange(pos.up(), this); } + + @Nullable + private BlockPos findNextRail(BlockPos from, IBlockReader world, boolean reversed) { + BlockState current = world.getBlockState(from); + if (!(current.getBlock() instanceof ControllerRailBlock)) + return null; + Vec3i accelerationVec = getAccelerationVector(current); + BlockPos baseTestPos = reversed ? from.subtract(accelerationVec) : from.add(accelerationVec); + for (BlockPos testPos : new BlockPos[]{baseTestPos, baseTestPos.down(), baseTestPos.up()}) { + if (testPos.getY() > from.getY() && !current.get(SHAPE).isAscending()) + continue; + BlockState testState = world.getBlockState(testPos); + if (testState.getBlock() instanceof ControllerRailBlock && getAccelerationVector(testState).equals(accelerationVec)) + return testPos; + } + return null; + } + + @Override + public boolean hasComparatorInputOverride(BlockState state) { + return true; + } + + @Override + public int getComparatorInputOverride(BlockState state, World world, BlockPos pos) { + return state.get(POWER); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java index 08890929f..f6429ab37 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java @@ -251,7 +251,7 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt newFacing = test; } - if (preferredSpoutput != null && BasinBlock.canOutputTo(world, pos, preferredSpoutput)) + if (preferredSpoutput != null && BasinBlock.canOutputTo(world, pos, preferredSpoutput) && preferredSpoutput != Direction.UP) newFacing = preferredSpoutput; if (newFacing != currentFacing) diff --git a/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java b/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java index 5ef9c4042..e9432c225 100644 --- a/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java @@ -438,7 +438,7 @@ public class BlockStateGen { public static NonNullBiConsumer, RegistrateBlockstateProvider> controllerRail() { return (c, p) -> p.getVariantBuilder(c.get()) .forAllStates(state -> { - int power = state.get(ControllerRailBlock.POWERED); + int power = state.get(ControllerRailBlock.POWER); boolean backwards = state.get(ControllerRailBlock.BACKWARDS); String powerStr = power == 0 ? "off" : (power == 15 ? "on" : "analog"); RailShape shape = state.get(ControllerRailBlock.SHAPE);