From 2768123b52961fd46fe2f5302eb5fad16990d5ad Mon Sep 17 00:00:00 2001 From: reidbhuntley Date: Tue, 11 Jan 2022 01:21:17 -0500 Subject: [PATCH] Everything --- src/main/java/com/simibubi/create/Create.java | 3 + .../content/contraptions/KineticDebugger.java | 10 +- .../base/DirectionalAxisKineticBlock.java | 25 +- .../base/DirectionalKineticBlock.java | 16 +- .../base/GeneratingKineticTileEntity.java | 89 ----- .../base/HorizontalAxisKineticBlock.java | 25 +- .../base/HorizontalKineticBlock.java | 14 +- .../content/contraptions/base/IRotate.java | 26 +- .../contraptions/base/KineticBlock.java | 3 +- .../contraptions/base/KineticTileEntity.java | 164 +++++---- .../base/KineticTileEntityRenderer.java | 4 +- .../base/RotatedPillarKineticBlock.java | 36 +- .../base/flwdata/KineticData.java | 6 +- .../components/actors/DrillBlock.java | 3 +- .../components/clock/CuckooClockBlock.java | 13 +- .../components/crank/HandCrankBlock.java | 10 +- .../components/crank/HandCrankTileEntity.java | 23 +- .../crusher/CrushingWheelBlock.java | 4 +- .../components/fan/EncasedFanBlock.java | 5 +- .../components/fan/EncasedFanTileEntity.java | 25 +- .../components/flywheel/FlywheelBlock.java | 3 +- .../flywheel/FlywheelTileEntity.java | 22 +- .../components/millstone/MillstoneBlock.java | 3 +- .../mixer/MechanicalMixerBlock.java | 2 +- .../components/motor/CreativeMotorBlock.java | 12 +- .../motor/CreativeMotorTileEntity.java | 6 +- .../press/MechanicalPressBlock.java | 2 +- .../contraptions/components/saw/SawBlock.java | 9 +- .../bearing/BearingBlock.java | 6 +- .../bearing/ClockworkBearingTileEntity.java | 5 +- .../bearing/MechanicalBearingTileEntity.java | 13 +- .../bearing/WindmillBearingTileEntity.java | 56 +-- .../gantry/GantryCarriageBlock.java | 18 +- .../gantry/GantryCarriageTileEntity.java | 19 -- .../pulley/PulleyTileEntity.java | 2 +- .../components/turntable/TurntableBlock.java | 10 +- .../waterwheel/WaterWheelBlock.java | 4 +- .../waterwheel/WaterWheelTileEntity.java | 24 +- .../contraptions/fluids/PumpTileEntity.java | 4 +- .../fluids/actors/HosePulleyBlock.java | 4 +- .../relays/advanced/GantryShaftBlock.java | 19 +- .../advanced/GantryShaftTileEntity.java | 62 ++-- .../relays/advanced/SpeedControllerBlock.java | 6 +- .../advanced/SpeedControllerTileEntity.java | 10 +- .../advanced/sequencer/Instruction.java | 21 +- .../sequencer/InstructionSpeedModifiers.java | 7 +- .../sequencer/SequencedGearshiftBlock.java | 75 ++-- .../SequencedGearshiftTileEntity.java | 55 ++- .../contraptions/relays/belt/BeltBlock.java | 8 +- .../relays/elementary/AbstractShaftBlock.java | 7 +- .../relays/elementary/CogWheelBlock.java | 13 +- .../relays/elementary/ShaftBlock.java | 5 - .../encased/AbstractEncasedShaftBlock.java | 2 +- .../relays/encased/AdjustablePulleyBlock.java | 6 - .../relays/encased/ClutchTileEntity.java | 12 +- .../relays/encased/EncasedBeltBlock.java | 2 +- .../relays/encased/EncasedCogInstance.java | 5 +- .../relays/encased/EncasedCogRenderer.java | 5 +- .../relays/encased/EncasedCogwheelBlock.java | 2 +- .../relays/encased/GearshiftBlock.java | 35 +- .../relays/encased/SplitShaftInstance.java | 11 +- .../relays/encased/SplitShaftRenderer.java | 7 +- .../contraptions/relays/gauge/GaugeBlock.java | 2 +- .../relays/gauge/SpeedGaugeTileEntity.java | 2 +- .../relays/gearbox/GearboxBlock.java | 32 +- .../relays/gearbox/GearboxInstance.java | 23 +- .../relays/gearbox/GearboxRenderer.java | 11 +- .../relays/gearbox/GearshiftTileEntity.java | 16 +- .../relays/gearbox/VerticalGearboxItem.java | 24 +- .../contraptions/solver/AllConnections.java | 321 +++++++++++++----- .../solver/ConnectionsBuilder.java | 54 +++ .../solver/IKineticController.java | 4 +- .../solver/KineticConnection.java | 11 + .../solver/KineticConnections.java | 136 ++------ .../solver/KineticConnectionsRegistry.java | 46 +++ .../solver/KineticControllerSerial.java | 6 +- .../contraptions/solver/KineticNetwork.java | 23 +- .../contraptions/solver/KineticNode.java | 71 ++-- .../contraptions/solver/KineticSolver.java | 23 +- .../contraptions/wrench/IWrenchable.java | 7 - .../armor/CopperBacktankBlock.java | 11 +- .../logistics/block/depot/EjectorBlock.java | 2 +- .../foundation/utility/DirectionHelper.java | 76 ++--- .../create/foundation/utility/Iterate.java | 22 +- 84 files changed, 1030 insertions(+), 996 deletions(-) delete mode 100644 src/main/java/com/simibubi/create/content/contraptions/base/GeneratingKineticTileEntity.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/solver/ConnectionsBuilder.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnection.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnectionsRegistry.java diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java index 23a54a7ec..7471a847a 100644 --- a/src/main/java/com/simibubi/create/Create.java +++ b/src/main/java/com/simibubi/create/Create.java @@ -2,6 +2,8 @@ package com.simibubi.create; import java.util.Random; +import com.simibubi.create.content.contraptions.solver.AllConnections; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -83,6 +85,7 @@ public class Create { ModLoadingContext modLoadingContext = ModLoadingContext.get(); AllSoundEvents.prepare(); + AllConnections.register(); AllBlocks.register(); AllItems.register(); AllFluids.register(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/KineticDebugger.java b/src/main/java/com/simibubi/create/content/contraptions/KineticDebugger.java index 4bf664f29..03318d4ba 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/KineticDebugger.java +++ b/src/main/java/com/simibubi/create/content/contraptions/KineticDebugger.java @@ -38,16 +38,20 @@ public class KineticDebugger { return; Level world = Minecraft.getInstance().level; - BlockPos toOutline = te.hasSource() ? te.source : te.getBlockPos(); + BlockPos toOutline = te.getSpeedSource().orElse(te.getBlockPos()); BlockState state = te.getBlockState(); VoxelShape shape = world.getBlockState(toOutline) .getBlockSupportShape(world, toOutline); - if (te.getTheoreticalSpeed() != 0 && !shape.isEmpty()) + if (te.getTheoreticalSpeed() != 0 && !shape.isEmpty()) { + int color = te.getSpeedSource().flatMap($ -> te.getNetworkID()) + .map(id -> Color.generateFromLong(id).getRGB()) + .orElse(0xffcc00); CreateClient.OUTLINER.chaseAABB("kineticSource", shape.bounds() .move(toOutline)) .lineWidth(1 / 16f) - .colored(te.hasSource() ? Color.generateFromLong(te.network).getRGB() : 0xffcc00); + .colored(color); + } if (state.getBlock() instanceof IRotate) { Axis axis = ((IRotate) state.getBlock()).getRotationAxis(state); diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/DirectionalAxisKineticBlock.java b/src/main/java/com/simibubi/create/content/contraptions/base/DirectionalAxisKineticBlock.java index 9de9138d8..ad8ee7229 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/DirectionalAxisKineticBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/DirectionalAxisKineticBlock.java @@ -95,23 +95,20 @@ public abstract class DirectionalAxisKineticBlock extends DirectionalKineticBloc BlockState blockState = reader.getBlockState(neighbourPos); Block block = blockState.getBlock(); return block instanceof IRotate - && ((IRotate) block).hasShaftTowards(reader, neighbourPos, blockState, facing.getOpposite()); + && ((IRotate) block).hasShaftTowards(blockState, facing.getOpposite(), reader, pos); + } + + public static Axis getRotationAxis(Axis facing, boolean alongFirstCoordinate) { + return switch (facing) { + case X -> alongFirstCoordinate ? Axis.Y : Axis.Z; + case Y -> alongFirstCoordinate ? Axis.X : Axis.Z; + case Z -> alongFirstCoordinate ? Axis.X : Axis.Y; + }; } @Override public Axis getRotationAxis(BlockState state) { - Axis pistonAxis = state.getValue(FACING) - .getAxis(); - boolean alongFirst = state.getValue(AXIS_ALONG_FIRST_COORDINATE); - - if (pistonAxis == Axis.X) - return alongFirst ? Axis.Y : Axis.Z; - if (pistonAxis == Axis.Y) - return alongFirst ? Axis.X : Axis.Z; - if (pistonAxis == Axis.Z) - return alongFirst ? Axis.X : Axis.Y; - - throw new IllegalStateException("Unknown axis??"); + return getRotationAxis(state.getValue(FACING).getAxis(), state.getValue(AXIS_ALONG_FIRST_COORDINATE)); } @Override @@ -122,7 +119,7 @@ public abstract class DirectionalAxisKineticBlock extends DirectionalKineticBloc } @Override - public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) { + public boolean hasShaftTowards(BlockState state, Direction face) { return face.getAxis() == getRotationAxis(state); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/DirectionalKineticBlock.java b/src/main/java/com/simibubi/create/content/contraptions/base/DirectionalKineticBlock.java index 0e5b90f47..c7848b3e0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/DirectionalKineticBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/DirectionalKineticBlock.java @@ -26,24 +26,24 @@ public abstract class DirectionalKineticBlock extends KineticBlock { super.createBlockStateDefinition(builder); } - public Direction getPreferredFacing(BlockPlaceContext context) { - Direction prefferedSide = null; + public static Direction getPreferredFacing(BlockPlaceContext context) { + Direction preferredSide = null; for (Direction side : Iterate.directions) { BlockState blockState = context.getLevel() .getBlockState(context.getClickedPos() .relative(side)); if (blockState.getBlock() instanceof IRotate) { - if (((IRotate) blockState.getBlock()).hasShaftTowards(context.getLevel(), context.getClickedPos() - .relative(side), blockState, side.getOpposite())) - if (prefferedSide != null && prefferedSide.getAxis() != side.getAxis()) { - prefferedSide = null; + if (((IRotate) blockState.getBlock()).hasShaftTowards( + blockState, side.getOpposite(), context.getLevel(), context.getClickedPos())) + if (preferredSide != null && preferredSide.getAxis() != side.getAxis()) { + preferredSide = null; break; } else { - prefferedSide = side; + preferredSide = side; } } } - return prefferedSide; + return preferredSide; } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/GeneratingKineticTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/base/GeneratingKineticTileEntity.java deleted file mode 100644 index d156a9cb2..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/base/GeneratingKineticTileEntity.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.simibubi.create.content.contraptions.base; - -import java.util.List; - -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraft.world.level.block.state.BlockState; - -public abstract class GeneratingKineticTileEntity extends KineticTileEntity { - - public boolean reActivateSource; - - public GeneratingKineticTileEntity(BlockEntityType typeIn, BlockPos pos, BlockState state) { - super(typeIn, pos, state); - } - - @Override - public void tick() { - super.tick(); - if (reActivateSource) { - updateGeneratedRotation(); - reActivateSource = false; - } - } - - @Override - public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { - boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking); - -// float stressBase = calculateAddedStressCapacity(); -// if (stressBase != 0 && IRotate.StressImpact.isEnabled()) { -// tooltip.add(componentSpacing.plainCopy().append(Lang.translate("gui.goggles.generator_stats"))); -// tooltip.add(componentSpacing.plainCopy().append(Lang.translate("tooltip.capacityProvided").withStyle(ChatFormatting.GRAY))); -// -// float speed = getTheoreticalSpeed(); -// if (speed != getGeneratedSpeed() && speed != 0) -// stressBase *= getGeneratedSpeed() / speed; -// -// speed = Math.abs(speed); -// float stressTotal = stressBase * speed; -// -// tooltip.add( -// componentSpacing.plainCopy() -// .append(new TextComponent(" " + IHaveGoggleInformation.format(stressTotal)) -// .append(Lang.translate("generic.unit.stress")) -// .withStyle(ChatFormatting.AQUA)) -// .append(" ") -// .append(Lang.translate("gui.goggles.at_current_speed").withStyle(ChatFormatting.DARK_GRAY))); -// -// added = true; -// } - - return added; - } - - public void updateGeneratedRotation() { -// float speed = getGeneratedSpeed(); -// float prevSpeed = this.speed; -// -// if (level.isClientSide) -// return; -// -// if (prevSpeed != speed) { -// if (!hasSource()) { -// SpeedLevel levelBefore = SpeedLevel.of(this.speed); -// SpeedLevel levelafter = SpeedLevel.of(speed); -// if (levelBefore != levelafter) -// effects.queueRotationIndicators(); -// } -// -// applyNewSpeed(prevSpeed, speed); -// } -// -// if (hasNetwork() && speed != 0) { -// KineticNetwork network = getOrCreateNetwork(); -// notifyStressCapacityChange(calculateAddedStressCapacity()); -// getOrCreateNetwork().updateStressFor(this, calculateStressApplied()); -// network.updateStress(); -// } -// -// onSpeedChanged(prevSpeed); -// sendData(); - } - - public Long createNetworkId() { - return worldPosition.asLong(); - } -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalAxisKineticBlock.java b/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalAxisKineticBlock.java index 77627e94d..721dee319 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalAxisKineticBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalAxisKineticBlock.java @@ -1,15 +1,11 @@ package com.simibubi.create.content.contraptions.base; -import com.simibubi.create.content.contraptions.solver.AllConnections; -import com.simibubi.create.content.contraptions.solver.KineticConnections; import com.simibubi.create.foundation.utility.Iterate; -import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.AxisDirection; import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; @@ -41,21 +37,21 @@ public abstract class HorizontalAxisKineticBlock extends KineticBlock { } public static Axis getPreferredHorizontalAxis(BlockPlaceContext context) { - Direction prefferedSide = null; + Direction preferredSide = null; for (Direction side : Iterate.horizontalDirections) { BlockState blockState = context.getLevel().getBlockState(context.getClickedPos().relative(side)); if (blockState.getBlock() instanceof IRotate) { - if (((IRotate) blockState.getBlock()).hasShaftTowards(context.getLevel(), context.getClickedPos().relative(side), - blockState, side.getOpposite())) - if (prefferedSide != null && prefferedSide.getAxis() != side.getAxis()) { - prefferedSide = null; + if (((IRotate) blockState.getBlock()).hasShaftTowards( + blockState, side.getOpposite(), context.getLevel(), context.getClickedPos())) + if (preferredSide != null && preferredSide.getAxis() != side.getAxis()) { + preferredSide = null; break; } else { - prefferedSide = side; + preferredSide = side; } } } - return prefferedSide == null ? null : prefferedSide.getAxis(); + return preferredSide == null ? null : preferredSide.getAxis(); } @Override @@ -64,12 +60,7 @@ public abstract class HorizontalAxisKineticBlock extends KineticBlock { } @Override - public KineticConnections getInitialConnections(BlockState state) { - return AllConnections.FULL_SHAFT.apply(state.getValue(HORIZONTAL_AXIS)); - } - - @Override - public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) { + public boolean hasShaftTowards(BlockState state, Direction face) { return face.getAxis() == state.getValue(HORIZONTAL_AXIS); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalKineticBlock.java b/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalKineticBlock.java index 297bec935..15d95f11c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalKineticBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalKineticBlock.java @@ -34,23 +34,23 @@ public abstract class HorizontalKineticBlock extends KineticBlock { } public Direction getPreferredHorizontalFacing(BlockPlaceContext context) { - Direction prefferedSide = null; + Direction preferredSide = null; for (Direction side : Iterate.horizontalDirections) { BlockState blockState = context.getLevel() .getBlockState(context.getClickedPos() .relative(side)); if (blockState.getBlock() instanceof IRotate) { - if (((IRotate) blockState.getBlock()).hasShaftTowards(context.getLevel(), context.getClickedPos() - .relative(side), blockState, side.getOpposite())) - if (prefferedSide != null && prefferedSide.getAxis() != side.getAxis()) { - prefferedSide = null; + if (((IRotate) blockState.getBlock()).hasShaftTowards( + blockState, side.getOpposite(), context.getLevel(), context.getClickedPos())) + if (preferredSide != null && preferredSide.getAxis() != side.getAxis()) { + preferredSide = null; break; } else { - prefferedSide = side; + preferredSide = side; } } } - return prefferedSide; + return preferredSide; } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/IRotate.java b/src/main/java/com/simibubi/create/content/contraptions/base/IRotate.java index 1c0c5b8c1..3ebce2998 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/IRotate.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/IRotate.java @@ -1,11 +1,12 @@ package com.simibubi.create.content.contraptions.base; import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; -import com.simibubi.create.content.contraptions.solver.AllConnections; -import com.simibubi.create.content.contraptions.solver.KineticConnections; +import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel; +import com.simibubi.create.content.contraptions.solver.ConnectionsBuilder; import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.item.ItemDescription; +import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; import net.minecraft.ChatFormatting; @@ -15,6 +16,7 @@ import net.minecraft.core.Direction.Axis; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.TextComponent; +import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.state.BlockState; @@ -121,12 +123,26 @@ public interface IRotate extends IWrenchable { } } - boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face); + boolean hasShaftTowards(BlockState state, Direction face); + + default boolean hasShaftTowards(BlockState state, Direction face, LevelReader level, BlockPos pos) { + return hasShaftTowards(state, face); + } Axis getRotationAxis(BlockState state); - default KineticConnections getInitialConnections(BlockState state) { - return AllConnections.EMPTY; + default ConnectionsBuilder buildInitialConnections(ConnectionsBuilder builder, BlockState state) { + for (Direction face : Iterate.directions) { + if (hasShaftTowards(state, face)) + builder = builder.withHalfShaft(face); + } + if (state.getBlock() instanceof ICogWheel cog) { + if (cog.isLargeCog()) + builder = builder.withLargeCog(getRotationAxis(state)); + if (cog.isSmallCog()) + builder = builder.withSmallCog(getRotationAxis(state)); + } + return builder; } default SpeedLevel getMinimumRequiredSpeedLevel() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticBlock.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticBlock.java index fc47fd6d4..9c1f3f131 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticBlock.java @@ -8,7 +8,6 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -22,7 +21,7 @@ public abstract class KineticBlock extends Block implements IRotate { } @Override - public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) { + public boolean hasShaftTowards(BlockState state, Direction face) { return false; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java index 8a6e37ffc..3ae6e85a2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java @@ -17,7 +17,7 @@ import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; import com.simibubi.create.content.contraptions.goggles.IHaveHoveringInformation; import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel; import com.simibubi.create.content.contraptions.relays.gearbox.GearboxBlock; -import com.simibubi.create.content.contraptions.solver.AllConnections; +import com.simibubi.create.content.contraptions.solver.ConnectionsBuilder; import com.simibubi.create.content.contraptions.solver.IKineticController; import com.simibubi.create.content.contraptions.solver.KineticConnections; import com.simibubi.create.content.contraptions.solver.KineticSolver; @@ -35,7 +35,6 @@ import net.minecraft.client.resources.language.I18n; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.AxisDirection; -import net.minecraft.core.Vec3i; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.network.chat.Component; @@ -53,37 +52,41 @@ import net.minecraftforge.fml.DistExecutor; public class KineticTileEntity extends SmartTileEntity implements IHaveGoggleInformation, IHaveHoveringInformation, FlywheelRendered, IKineticController { - public @Nullable Long network = null; - public @Nullable BlockPos source = null; - protected KineticEffectHandler effects; - protected float theoreticalSpeed; - protected KineticConnections clientConnections; - protected @Nullable BlockPos speedSource; - protected boolean overstressed; - protected float networkImpact; - protected float networkCapacity; + private float theoreticalSpeed; + private long networkID; + private @Nullable BlockPos speedSource; + private boolean overstressed; + private float networkImpact; + private float networkCapacity; + + private boolean kineticsInit; protected boolean wasMoved; private int flickerTally; private int validationCountdown; - private final KineticConnections connections; + private KineticConnections initialConnections; + private boolean initialConnectionsChanged; public KineticTileEntity(BlockEntityType typeIn, BlockPos pos, BlockState state) { super(typeIn, pos, state); - effects = new KineticEffectHandler(this); - - if (state.getBlock() instanceof IRotate rotate) { - connections = rotate.getInitialConnections(state); - } else { - connections = AllConnections.EMPTY; - } - clientConnections = connections; + updateInitialConnections(state); } - @Override public KineticConnections getConnections() { return connections; } + protected void updateInitialConnections(BlockState state) { + if (state.getBlock() instanceof IRotate rotate) { + initialConnections = rotate.buildInitialConnections(ConnectionsBuilder.builder(), state).build(); + if (getLevel() != null && !getLevel().isClientSide) { + initialConnectionsChanged = true; + } + } else { + initialConnections = KineticConnections.empty(); + } + } + + @Override public KineticConnections getConnections() { return initialConnections; } @Override public float getStressImpact() { return getDefaultStressImpact(); } @@ -102,13 +105,8 @@ public class KineticTileEntity extends SmartTileEntity return (float) BlockStressValues.getCapacity(getStressConfigKey()); } - - public float getRotationSpeedModifier(Vec3i offset) { - return getClientConnections().checkConnection(offset).orElse(0f); - } - - public float getRotationSpeedModifier(Direction face) { - return getRotationSpeedModifier(face.getNormal()); + public float getShaftSpeed(Direction face) { + return getSpeed() * getConnections().getShaftSpeedModifier(face); } @@ -127,7 +125,7 @@ public class KineticTileEntity extends SmartTileEntity if (level.isClientSide) { cachedBoundingBox = null; // cache the bounding box for every frame between ticks - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> this.tickAudio()); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> this::tickAudio); return; } @@ -165,6 +163,11 @@ public class KineticTileEntity extends SmartTileEntity } public void onSpeedChanged(float previousSpeed) { + if (!level.isClientSide && getSpeedSource().isEmpty()) { + if (SpeedLevel.of(previousSpeed) != SpeedLevel.of(getSpeed())) + effects.queueRotationIndicators(); + } + boolean fromOrToZero = (previousSpeed == 0) != (getSpeed() == 0); boolean directionSwap = !fromOrToZero && Math.signum(previousSpeed) != Math.signum(getSpeed()); if (fromOrToZero || directionSwap) @@ -179,13 +182,19 @@ public class KineticTileEntity extends SmartTileEntity @Override protected void write(CompoundTag compound, boolean clientPacket) { if (clientPacket) { - compound.putFloat("Speed", theoreticalSpeed); - compound.put("Connections", clientConnections.save(new CompoundTag())); - compound.putBoolean("Overstressed", overstressed); - compound.putFloat("Impact", networkImpact); - compound.putFloat("Capacity", networkCapacity); - if (speedSource != null) - compound.put("Source", NbtUtils.writeBlockPos(speedSource)); + if (initialConnectionsChanged) { + compound.putBoolean("UpdateConnections", true); + initialConnectionsChanged = false; + } + compound.putFloat("Speed", getTheoreticalSpeed()); + getNetworkID().ifPresent(id -> compound.putLong("Network", id)); + if (isOverstressed()) + compound.putBoolean("Overstressed", isOverstressed()); + if (getNetworkImpact() > 0) + compound.putFloat("Impact", getNetworkImpact()); + if (getNetworkCapacity() > 0) + compound.putFloat("Capacity", getNetworkCapacity()); + getSpeedSource().ifPresent(source -> compound.put("Source", NbtUtils.writeBlockPos(source))); } super.write(compound, clientPacket); @@ -194,9 +203,11 @@ public class KineticTileEntity extends SmartTileEntity @Override protected void read(CompoundTag tag, boolean clientPacket) { if (clientPacket) { + if (tag.getBoolean("UpdateConnections")) + updateInitialConnections(getBlockState()); updateFromSolver(tag.getFloat("Speed"), tag.contains("Source") ? NbtUtils.readBlockPos(tag.getCompound("Source")) : null, - KineticConnections.load(tag.getCompound("Connections")), + tag.getLong("Network"), tag.getBoolean("Overstressed"), tag.getFloat("Impact"), tag.getFloat("Capacity")); @@ -221,8 +232,8 @@ public class KineticTileEntity extends SmartTileEntity return Optional.ofNullable(speedSource); } - public KineticConnections getClientConnections() { - return clientConnections; + public Optional getNetworkID() { + return networkID == 0 ? Optional.empty() : Optional.of(networkID); } public boolean isOverstressed() { @@ -237,52 +248,41 @@ public class KineticTileEntity extends SmartTileEntity return networkCapacity; } - public void updateFromSolver(float theoreticalSpeed, @Nullable BlockPos speedSource, KineticConnections connections, + public void updateFromSolver(float theoreticalSpeed, @Nullable BlockPos speedSource, long networkID, boolean overstressed, float networkImpact, float networkCapacity) { float prevSpeed = getSpeed(); - BlockPos prevSpeedSource = getSpeedSource().orElse(null); - KineticConnections prevConnections = getClientConnections(); + BlockPos prevSpeedSource = this.speedSource; + long prevNetworkID = this.networkID; boolean prevOverstressed = isOverstressed(); float prevNetworkImpact = getNetworkImpact(); float prevNetworkCapacity = getNetworkCapacity(); this.theoreticalSpeed = theoreticalSpeed; this.speedSource = speedSource; - this.clientConnections = connections; + this.networkID = networkID; this.overstressed = overstressed; this.networkImpact = networkImpact; this.networkCapacity = networkCapacity; - boolean send = false; + boolean changed = initialConnectionsChanged; - if (prevOverstressed != overstressed || prevNetworkImpact != networkImpact || prevNetworkCapacity != networkCapacity) { + if (!kineticsInit || prevOverstressed != overstressed || prevNetworkImpact != networkImpact + || prevNetworkCapacity != networkCapacity) { onStressChanged(prevNetworkImpact, prevNetworkCapacity, prevOverstressed); - send = true; + changed = true; } - if (getSpeed() != prevSpeed) { + if (!kineticsInit || getSpeed() != prevSpeed) { onSpeedChanged(prevSpeed); - send = true; + changed = true; } + kineticsInit = true; if (level.isClientSide) return; - - if (!connections.equals(prevConnections)) - send = true; - if (!Objects.equal(speedSource, prevSpeedSource)) - send = true; - if (send) + if (changed || networkID != prevNetworkID || !Objects.equal(speedSource, prevSpeedSource)) sendData(); } - public boolean hasSource() { - return source != null; - } - - public boolean hasNetwork() { - return network != null; - } - public boolean isSpeedRequirementFulfilled() { BlockState state = getBlockState(); if (!(getBlockState().getBlock() instanceof IRotate)) @@ -299,8 +299,12 @@ public class KineticTileEntity extends SmartTileEntity } public static void switchToBlockState(Level world, BlockPos pos, BlockState state) { - if (!world.isClientSide) - world.setBlock(pos, state, 3); + if (!world.isClientSide) { + world.setBlockAndUpdate(pos, state); + if (world.getBlockEntity(pos) instanceof KineticTileEntity kte) { + kte.updateInitialConnections(state); + } + } } @Override @@ -341,16 +345,17 @@ public class KineticTileEntity extends SmartTileEntity @Override public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { boolean added = false; - float stressAtBase = getStressImpact(); - if (stressAtBase != 0 && StressImpact.isEnabled()) { + // stress impact info + float impact = getStressImpact(); + if (impact != 0 && StressImpact.isEnabled()) { tooltip.add(componentSpacing.plainCopy() .append(Lang.translate("gui.goggles.kinetic_stats"))); tooltip.add(componentSpacing.plainCopy() .append(Lang.translate("tooltip.stressImpact") .withStyle(ChatFormatting.GRAY))); - float stressTotal = stressAtBase * Math.abs(getTheoreticalSpeed()); + float stressTotal = impact * Math.abs(getTheoreticalSpeed()); tooltip.add(componentSpacing.plainCopy() .append(new TextComponent(" " + IHaveGoggleInformation.format(stressTotal)) @@ -363,8 +368,31 @@ public class KineticTileEntity extends SmartTileEntity added = true; } - return added; + // stress capacity info + float capacity = getStressCapacity(); + if (capacity != 0 && IRotate.StressImpact.isEnabled()) { + tooltip.add(componentSpacing.plainCopy().append(Lang.translate("gui.goggles.generator_stats"))); + tooltip.add(componentSpacing.plainCopy().append(Lang.translate("tooltip.capacityProvided").withStyle(ChatFormatting.GRAY))); + float speed = getTheoreticalSpeed(); + if (speed != getGeneratedSpeed() && speed != 0) + capacity *= getGeneratedSpeed() / speed; + + speed = Math.abs(speed); + float stressTotal = capacity * speed; + + tooltip.add( + componentSpacing.plainCopy() + .append(new TextComponent(" " + IHaveGoggleInformation.format(stressTotal)) + .append(Lang.translate("generic.unit.stress")) + .withStyle(ChatFormatting.AQUA)) + .append(" ") + .append(Lang.translate("gui.goggles.at_current_speed").withStyle(ChatFormatting.DARK_GRAY))); + + added = true; + } + + return added; } public void clearKineticInformation() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java index 425152021..2c5f0f476 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java @@ -98,7 +98,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer switch (state.getValue(AXIS)) { + case X -> state.setValue(AXIS, Axis.Z); + case Z -> state.setValue(AXIS, Axis.X); + default -> state; + }; + default -> state; + }; } public static Axis getPreferredAxis(BlockPlaceContext context) { - Axis prefferedAxis = null; + Axis preferredAxis = null; for (Direction side : Iterate.directions) { BlockState blockState = context.getLevel() .getBlockState(context.getClickedPos() .relative(side)); if (blockState.getBlock() instanceof IRotate) { - if (((IRotate) blockState.getBlock()).hasShaftTowards(context.getLevel(), context.getClickedPos() - .relative(side), blockState, side.getOpposite())) - if (prefferedAxis != null && prefferedAxis != side.getAxis()) { - prefferedAxis = null; + if (((IRotate) blockState.getBlock()).hasShaftTowards( + blockState, side.getOpposite(), context.getLevel(), context.getClickedPos())) + if (preferredAxis != null && preferredAxis != side.getAxis()) { + preferredAxis = null; break; } else { - prefferedAxis = side.getAxis(); + preferredAxis = side.getAxis(); } } } - return prefferedAxis; + return preferredAxis; } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/flwdata/KineticData.java b/src/main/java/com/simibubi/create/content/contraptions/base/flwdata/KineticData.java index 88f97c572..d7ad71116 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/flwdata/KineticData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/flwdata/KineticData.java @@ -39,11 +39,7 @@ public class KineticData extends BasicData { } public KineticData setColor(KineticTileEntity te) { - if (te.hasNetwork()) { - setColor(Color.generateFromLong(te.network)); - }else { - setColor(0xFF, 0xFF, 0xFF); - } + setColor(te.getNetworkID().map(Color::generateFromLong).orElse(Color.WHITE)); return this; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillBlock.java index a711b988c..7769540c4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillBlock.java @@ -17,7 +17,6 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; @@ -68,7 +67,7 @@ public class DrillBlock extends DirectionalKineticBlock implements ITE getTileEntityClass() { return HandCrankTileEntity.class; } - + @Override public BlockEntityType getTileEntityType() { return AllTileEntities.HAND_CRANK.get(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankTileEntity.java index 716523aa6..bc76446d7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankTileEntity.java @@ -2,7 +2,7 @@ package com.simibubi.create.content.contraptions.components.crank; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllSoundEvents; -import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.core.BlockPos; @@ -13,7 +13,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -public class HandCrankTileEntity extends GeneratingKineticTileEntity { +public class HandCrankTileEntity extends KineticTileEntity { public int inUse; public boolean backwards; @@ -25,23 +25,16 @@ public class HandCrankTileEntity extends GeneratingKineticTileEntity { } public void turn(boolean back) { - boolean update = false; - - if (getGeneratedSpeed() == 0 || back != backwards) - update = true; - inUse = 10; - this.backwards = back; - if (update && !level.isClientSide) - updateGeneratedRotation(); + backwards = back; } @Override public float getGeneratedSpeed() { + if (isRemoved()) return 0; Block block = getBlockState().getBlock(); - if (!(block instanceof HandCrankBlock)) + if (!(block instanceof HandCrankBlock crank)) return 0; - HandCrankBlock crank = (HandCrankBlock) block; int speed = (inUse == 0 ? 0 : backwards ? -1 : 1) * crank.getRotationSpeed(); return convertToDirection(speed, getBlockState().getValue(HandCrankBlock.FACING)); } @@ -66,12 +59,8 @@ public class HandCrankTileEntity extends GeneratingKineticTileEntity { chasingVelocity += ((actualSpeed * 10 / 3f) - chasingVelocity) * .25f; independentAngle += chasingVelocity; - if (inUse > 0) { + if (inUse > 0) inUse--; - - if (inUse == 0 && !level.isClientSide) - updateGeneratedRotation(); - } } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelBlock.java index 911391a56..2d53d5a5a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelBlock.java @@ -171,7 +171,7 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock implements ITE } @Override - public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) { + public boolean hasShaftTowards(BlockState state, Direction face) { return face.getAxis() == state.getValue(AXIS); } @@ -189,7 +189,7 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock implements ITE public Class getTileEntityClass() { return CrushingWheelTileEntity.class; } - + @Override public BlockEntityType getTileEntityType() { return AllTileEntities.CRUSHING_WHEEL.get(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java index 4efd7d263..5c485b150 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java @@ -13,7 +13,6 @@ import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; @@ -96,7 +95,7 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements ITE getTileEntityClass() { return EncasedFanTileEntity.class; } - + @Override public BlockEntityType getTileEntityType() { return AllTileEntities.ENCASED_FAN.get(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java index 87be978e4..884842b42 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java @@ -4,7 +4,7 @@ import javax.annotation.Nullable; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTags.AllBlockTags; -import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity; import com.simibubi.create.foundation.config.AllConfigs; @@ -20,7 +20,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; @MethodsReturnNonnullByDefault -public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements IAirCurrentSource { +public class EncasedFanTileEntity extends KineticTileEntity implements IAirCurrentSource { public AirCurrent airCurrent; protected int airCurrentUpdateCooldown; @@ -52,21 +52,21 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements super.write(compound, clientPacket); } - public float calculateAddedStressCapacity() { - //return lastCapacityProvided = (isGenerator ? super.calculateAddedStressCapacity() : 0); - return 0; - } - - public float calculateStressApplied() { - //return isGenerator ? 0 : super.calculateStressApplied(); - return 0; - } - @Override public float getGeneratedSpeed() { return isGenerator ? AllConfigs.SERVER.kinetics.generatingFanSpeed.get() : 0; } + @Override + public float getStressCapacity() { + return isGenerator ? super.getStressCapacity() : 0; + } + + @Override + public float getStressImpact() { + return isGenerator ? 0 : super.getStressImpact(); + } + public void queueGeneratorUpdate() { updateGenerator = true; } @@ -88,7 +88,6 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements if (shouldGenerate == isGenerator) return; isGenerator = shouldGenerate; - updateGeneratedRotation(); } public boolean blockBelowIsHot() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelBlock.java index 34ae99539..55eb1aa9f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelBlock.java @@ -16,7 +16,6 @@ import net.minecraft.world.InteractionResult; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; @@ -74,7 +73,7 @@ public class FlywheelBlock extends HorizontalKineticBlock implements ITE getTileEntityClass() { return SawTileEntity.class; } - + @Override public BlockEntityType getTileEntityType() { return AllTileEntities.SAW.get(); } - + @Override public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) { return false; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingBlock.java index 2f1c210e5..594c98e32 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingBlock.java @@ -2,12 +2,10 @@ package com.simibubi.create.content.contraptions.components.structureMovement.be import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock; -import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.context.UseOnContext; -import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -18,10 +16,10 @@ public abstract class BearingBlock extends DirectionalKineticBlock { } @Override - public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) { + public boolean hasShaftTowards(BlockState state, Direction face) { return face == state.getValue(FACING).getOpposite(); } - + @Override public Axis getRotationAxis(BlockState state) { return state.getValue(FACING).getAxis(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java index 1ff677797..c366fa305 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java @@ -77,10 +77,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity if (!level.isClientSide && assembleNextTick) { assembleNextTick = false; if (running) { - boolean canDisassemble = true; - if (theoreticalSpeed == 0 && (canDisassemble || hourHand == null || hourHand.getContraption() - .getBlocks() - .isEmpty())) { + if (getTheoreticalSpeed() == 0) { if (hourHand != null) hourHand.getContraption() .stop(level); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java index 865387e88..fa12f5993 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java @@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.be import java.util.List; import com.simibubi.create.AllSoundEvents; -import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity; @@ -25,7 +25,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; -public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity +public class MechanicalBearingTileEntity extends KineticTileEntity implements IBearingTileEntity, IDisplayAssemblyExceptions { protected ScrollOptionBehaviour movementMode; @@ -178,7 +178,6 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity running = true; angle = 0; sendData(); - updateGeneratedRotation(); } public void disassemble() { @@ -194,7 +193,6 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity movedContraption = null; running = false; - updateGeneratedRotation(); assembleNextTick = false; sendData(); } @@ -212,9 +210,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity if (running) { boolean canDisassemble = movementMode.get() == RotationMode.ROTATE_PLACE || (isNearInitialAngle() && movementMode.get() == RotationMode.ROTATE_PLACE_RETURNED); - if (theoreticalSpeed == 0 && (canDisassemble || movedContraption == null || movedContraption.getContraption() - .getBlocks() - .isEmpty())) { + if (getTheoreticalSpeed() == 0 && (canDisassemble || movedContraption == null + || movedContraption.getContraption().getBlocks().isEmpty())) { if (movedContraption != null) movedContraption.getContraption() .stop(level); @@ -222,7 +219,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity return; } } else { - if (theoreticalSpeed == 0 && !isWindmill()) + if (getTheoreticalSpeed() == 0 && !isWindmill()) return; assemble(); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/WindmillBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/WindmillBearingTileEntity.java index 33122a00d..ab3719344 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/WindmillBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/WindmillBearingTileEntity.java @@ -18,16 +18,38 @@ import net.minecraft.world.level.block.state.BlockState; public class WindmillBearingTileEntity extends MechanicalBearingTileEntity { protected ScrollOptionBehaviour movementDirection; - protected float lastGeneratedSpeed; + protected float generated; public WindmillBearingTileEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); } @Override - public void updateGeneratedRotation() { - super.updateGeneratedRotation(); - lastGeneratedSpeed = getGeneratedSpeed(); + public void initialize() { + updateGeneratedSpeed(); + super.initialize(); + } + + @Override + public void assemble() { + super.assemble(); + updateGeneratedSpeed(); + } + + @Override + public void disassemble() { + super.disassemble(); + updateGeneratedSpeed(); + } + + public void updateGeneratedSpeed() { + if (!running) { + generated = 0; + } else if (movedContraption != null) { + int sails = ((BearingContraption) movedContraption.getContraption()).getSailBlocks() + / AllConfigs.SERVER.kinetics.windmillSailsPerRPM.get(); + generated = Mth.clamp(sails, 1, 16) * getAngleSpeedDirection(); + } } @Override @@ -39,13 +61,7 @@ public class WindmillBearingTileEntity extends MechanicalBearingTileEntity { @Override public float getGeneratedSpeed() { - if (!running) - return 0; - if (movedContraption == null) - return lastGeneratedSpeed; - int sails = ((BearingContraption) movedContraption.getContraption()).getSailBlocks() - / AllConfigs.SERVER.kinetics.windmillSailsPerRPM.get(); - return Mth.clamp(sails, 1, 16) * getAngleSpeedDirection(); + return generated; } @Override @@ -60,14 +76,14 @@ public class WindmillBearingTileEntity extends MechanicalBearingTileEntity { @Override public void write(CompoundTag compound, boolean clientPacket) { - compound.putFloat("LastGenerated", lastGeneratedSpeed); + compound.putFloat("LastGenerated", generated); super.write(compound, clientPacket); } @Override protected void read(CompoundTag compound, boolean clientPacket) { if (!wasMoved) - lastGeneratedSpeed = compound.getFloat("LastGenerated"); + generated = compound.getFloat("LastGenerated"); super.read(compound, clientPacket); } @@ -86,7 +102,7 @@ public class WindmillBearingTileEntity extends MechanicalBearingTileEntity { if (!running) return; if (!level.isClientSide) - updateGeneratedRotation(); + updateGeneratedSpeed(); } @Override @@ -94,16 +110,14 @@ public class WindmillBearingTileEntity extends MechanicalBearingTileEntity { return true; } - static enum RotationDirection implements INamedIconOptions { + enum RotationDirection implements INamedIconOptions { - CLOCKWISE(AllIcons.I_REFRESH), COUNTER_CLOCKWISE(AllIcons.I_ROTATE_CCW), + CLOCKWISE(AllIcons.I_REFRESH), COUNTER_CLOCKWISE(AllIcons.I_ROTATE_CCW),; - ; + private final String translationKey; + private final AllIcons icon; - private String translationKey; - private AllIcons icon; - - private RotationDirection(AllIcons icon) { + RotationDirection(AllIcons icon) { this.icon = icon; translationKey = "generic." + Lang.asId(name()); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageBlock.java index 71ae146fc..5cc138012 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageBlock.java @@ -5,6 +5,8 @@ import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.relays.advanced.GantryShaftBlock; +import com.simibubi.create.content.contraptions.solver.AllConnections; +import com.simibubi.create.content.contraptions.solver.ConnectionsBuilder; import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.utility.Iterate; @@ -29,6 +31,15 @@ public class GantryCarriageBlock extends DirectionalAxisKineticBlock implements super(properties); } + @Override + public ConnectionsBuilder buildInitialConnections(ConnectionsBuilder builder, BlockState state) { + return super.buildInitialConnections(builder, state).withDirAxial( + AllConnections.DirAxial.GANTRY_PINION, + state.getValue(FACING), + state.getValue(AXIS_ALONG_FIRST_COORDINATE) + ); + } + @Override public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { Direction direction = state.getValue(FACING); @@ -59,7 +70,7 @@ public class GantryCarriageBlock extends DirectionalAxisKineticBlock implements return InteractionResult.PASS; if (player.getItemInHand(handIn) .isEmpty()) { - withTileEntityDo(worldIn, pos, te -> te.checkValidGantryShaft()); + withTileEntityDo(worldIn, pos, GantryCarriageTileEntity::checkValidGantryShaft); return InteractionResult.SUCCESS; } return InteractionResult.PASS; @@ -103,8 +114,7 @@ public class GantryCarriageBlock extends DirectionalAxisKineticBlock implements } public static boolean isValidGantryShaftAxis(BlockState pinionState, BlockState gantryState) { - return getValidGantryShaftAxis(pinionState) == gantryState.getValue(GantryShaftBlock.FACING) - .getAxis(); + return getValidGantryShaftAxis(pinionState) == gantryState.getValue(GantryShaftBlock.FACING).getAxis(); } public static Axis getValidGantryShaftAxis(BlockState state) { @@ -138,5 +148,5 @@ public class GantryCarriageBlock extends DirectionalAxisKineticBlock implements public BlockEntityType getTileEntityType() { return AllTileEntities.GANTRY_PINION.get(); } - + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageTileEntity.java index 63d27b6e5..0f8474247 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageTileEntity.java @@ -122,25 +122,6 @@ public class GantryCarriageTileEntity extends KineticTileEntity implements IDisp super.read(compound, clientPacket); } - public float propagateRotationTo(KineticTileEntity target, BlockState stateFrom, BlockState stateTo, BlockPos diff, - boolean connectedViaAxes, boolean connectedViaCogs) { - //float defaultModifier = - //super.propagateRotationTo(target, stateFrom, stateTo, diff, connectedViaAxes, connectedViaCogs); - float defaultModifier = 1; - - if (connectedViaAxes) - return defaultModifier; - if (!AllBlocks.GANTRY_SHAFT.has(stateTo)) - return defaultModifier; - if (!stateTo.getValue(GantryShaftBlock.POWERED)) - return defaultModifier; - - Direction direction = Direction.getNearest(diff.getX(), diff.getY(), diff.getZ()); - if (stateFrom.getValue(GantryCarriageBlock.FACING) != direction.getOpposite()) - return defaultModifier; - return getGantryPinionModifier(stateTo.getValue(GantryShaftBlock.FACING), stateFrom.getValue(GantryCarriageBlock.FACING)); - } - public static float getGantryPinionModifier(Direction shaft, Direction pinionDirection) { Axis shaftAxis = shaft.getAxis(); float directionModifier = shaft.getAxisDirection() diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java index 1fadd8a73..b08dc63d1 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java @@ -50,7 +50,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { if (!(level.getBlockState(worldPosition) .getBlock() instanceof PulleyBlock)) return; - if (theoreticalSpeed == 0) + if (getTheoreticalSpeed() == 0) return; int maxLength = AllConfigs.SERVER.kinetics.maxRopeLength.get(); int i = 1; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/turntable/TurntableBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/turntable/TurntableBlock.java index 5ddf1c8b9..f1d53e209 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/turntable/TurntableBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/turntable/TurntableBlock.java @@ -4,8 +4,6 @@ import com.simibubi.create.AllShapes; import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.base.KineticBlock; import com.simibubi.create.content.contraptions.base.KineticTileEntity; -import com.simibubi.create.content.contraptions.solver.AllConnections; -import com.simibubi.create.content.contraptions.solver.KineticConnections; import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.utility.VecHelper; @@ -18,7 +16,6 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; @@ -91,7 +88,7 @@ public class TurntableBlock extends KineticBlock implements ITE getTileEntityClass() { return TurntableTileEntity.class; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/waterwheel/WaterWheelBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/waterwheel/WaterWheelBlock.java index 6d4cf1533..583bc245f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/waterwheel/WaterWheelBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/waterwheel/WaterWheelBlock.java @@ -146,7 +146,7 @@ public class WaterWheelBlock extends DirectionalKineticBlock implements ITE flows; + private float generated; public WaterWheelTileEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); @@ -27,6 +28,12 @@ public class WaterWheelTileEntity extends GeneratingKineticTileEntity { setLazyTickRate(20); } + @Override + public void initialize() { + updateGeneratedSpeed(); + super.initialize(); + } + @Override protected void read(CompoundTag compound, boolean clientPacket) { super.read(compound, clientPacket); @@ -59,12 +66,15 @@ public class WaterWheelTileEntity extends GeneratingKineticTileEntity { @Override public float getGeneratedSpeed() { - float speed = 0; + return generated; + } + + public void updateGeneratedSpeed() { + generated = 0; for (Float f : flows.values()) - speed += f; - if (speed != 0) - speed += AllConfigs.SERVER.kinetics.waterWheelBaseSpeed.get() * Math.signum(speed); - return speed; + generated += f; + if (generated != 0) + generated += AllConfigs.SERVER.kinetics.waterWheelBaseSpeed.get() * Math.signum(generated); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpTileEntity.java index d6d010680..71708caae 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpTileEntity.java @@ -100,8 +100,8 @@ public class PumpTileEntity extends KineticTileEntity { if (previousSpeed == getSpeed()) return; - if (theoreticalSpeed != 0) - reversed = theoreticalSpeed < 0; + if (getTheoreticalSpeed() != 0) + reversed = getTheoreticalSpeed() < 0; if (level.isClientSide && !isVirtual()) return; diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/HosePulleyBlock.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/HosePulleyBlock.java index 982a3065b..ec426a969 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/HosePulleyBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/HosePulleyBlock.java @@ -44,7 +44,7 @@ public class HosePulleyBlock extends HorizontalKineticBlock implements ITE getTileEntityClass() { return HosePulleyTileEntity.class; } - + @Override public BlockEntityType getTileEntityType() { return AllTileEntities.HOSE_PULLEY.get(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java index bf5831763..32b05dd4a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java @@ -8,7 +8,6 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock; -import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; @@ -31,7 +30,6 @@ import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.entity.BlockEntity; @@ -229,9 +227,6 @@ public class GantryShaftBlock extends DirectionalKineticBlock implements ITE 0; - case SINGLE: - default: - return false; - } + return switch (blockState.getValue(GantryShaftBlock.PART)) { + case END -> speed < 0; + case MIDDLE -> speed != 0; + case START -> speed > 0; + default -> false; + }; } public float getPinionMovementSpeed() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlock.java index a77e3d3b6..7ca5f5d50 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlock.java @@ -11,6 +11,7 @@ import com.simibubi.create.content.contraptions.base.HorizontalAxisKineticBlock; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel; import com.simibubi.create.content.contraptions.solver.AllConnections; +import com.simibubi.create.content.contraptions.solver.ConnectionsBuilder; import com.simibubi.create.content.contraptions.solver.KineticConnections; import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.utility.placement.IPlacementHelper; @@ -46,8 +47,9 @@ public class SpeedControllerBlock extends HorizontalAxisKineticBlock implements } @Override - public KineticConnections getInitialConnections(BlockState state) { - return AllConnections.SPEED_CONTROLLER.apply(state.getValue(HORIZONTAL_AXIS)); + public ConnectionsBuilder buildInitialConnections(ConnectionsBuilder builder, BlockState state) { + return super.buildInitialConnections(builder, state) + .withAxial(AllConnections.Axial.SPEED_CONTROLLER_TOP, state.getValue(HORIZONTAL_AXIS)); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerTileEntity.java index 7abbfd87a..fd3cffca0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerTileEntity.java @@ -61,11 +61,13 @@ public class SpeedControllerTileEntity extends KineticTileEntity { } @Override - public void onUpdate(Level level, KineticSolver solver, KineticNode node) { + public void onKineticsTick(Level level, KineticSolver solver, KineticNode node) { BlockPos pos = node.getPos(), above = pos.above(); - if (solver.isStressOnlyConnected(pos, above)) { - solver.getNode(above).get().setController(node, KineticControllerSerial.SPEED_CONTROLLER_COG); - } + solver.getNode(above).ifPresent(to -> { + if (node.checkStressOnlyConnection(to)) { + to.setController(KineticControllerSerial.SPEED_CONTROLLER_COG); + } + }); } public void updateBracket() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/Instruction.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/Instruction.java index 9335285d1..5bb87387a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/Instruction.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/Instruction.java @@ -1,5 +1,6 @@ package com.simibubi.create.content.contraptions.relays.advanced.sequencer; +import java.util.Optional; import java.util.Vector; import com.simibubi.create.content.contraptions.base.KineticTileEntity; @@ -78,21 +79,11 @@ public class Instruction { return 0; } - int getSpeedModifier() { - switch (instruction) { - - case TURN_ANGLE: - case TURN_DISTANCE: - return speedModifier.value; - - case END: - case DELAY: - case AWAIT: - default: - break; - - } - return 0; + Optional getSpeedModifier() { + return switch (instruction) { + case TURN_ANGLE, TURN_DISTANCE -> Optional.of(speedModifier); + default -> Optional.empty(); + }; } OnIsPoweredResult onRedstonePulse() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/InstructionSpeedModifiers.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/InstructionSpeedModifiers.java index 4495a9d79..589021779 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/InstructionSpeedModifiers.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/InstructionSpeedModifiers.java @@ -18,12 +18,7 @@ public enum InstructionSpeedModifiers { int value; Component label; - private InstructionSpeedModifiers(int modifier, Component label) { - this.label = label; - translationKey = "gui.sequenced_gearshift.speed." + Lang.asId(name()); - value = modifier; - } - private InstructionSpeedModifiers(int modifier, String label) { + InstructionSpeedModifiers(int modifier, String label) { this.label = new TextComponent(label); translationKey = "gui.sequenced_gearshift.speed." + Lang.asId(name()); value = modifier; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java index e3ca38970..8f7f9285d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java @@ -5,8 +5,8 @@ import java.util.Random; import com.simibubi.create.AllItems; import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.base.HorizontalAxisKineticBlock; +import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticBlock; -import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock; import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.gui.ScreenOpener; @@ -38,6 +38,7 @@ import net.minecraftforge.fml.DistExecutor; public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implements ITE { public static final BooleanProperty VERTICAL = BooleanProperty.create("vertical"); + public static final BooleanProperty POSITIVE = BooleanProperty.create("positive"); public static final IntegerProperty STATE = IntegerProperty.create("state", 0, 5); public SequencedGearshiftBlock(Properties properties) { @@ -46,7 +47,7 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implemen @Override protected void createBlockStateDefinition(Builder builder) { - super.createBlockStateDefinition(builder.add(STATE, VERTICAL)); + super.createBlockStateDefinition(builder.add(STATE, VERTICAL, POSITIVE)); } @Override @@ -59,8 +60,7 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implemen boolean isMoving) { if (worldIn.isClientSide) return; - if (!worldIn.getBlockTicks() - .willTickThisTick(pos, this)) + if (!worldIn.getBlockTicks().willTickThisTick(pos, this)) worldIn.scheduleTick(pos, this, 0); } @@ -72,11 +72,10 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implemen } @Override - public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) { + public boolean hasShaftTowards(BlockState state, Direction face) { if (state.getValue(VERTICAL)) - return face.getAxis() - .isVertical(); - return super.hasShaftTowards(world, pos, state, face); + return face.getAxis().isVertical(); + return super.hasShaftTowards(state, face); } @Override @@ -85,9 +84,8 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implemen ItemStack held = player.getMainHandItem(); if (AllItems.WRENCH.isIn(held)) return InteractionResult.PASS; - if (held.getItem() instanceof BlockItem) { - BlockItem blockItem = (BlockItem) held.getItem(); - if (blockItem.getBlock() instanceof KineticBlock && hasShaftTowards(worldIn, pos, state, hit.getDirection())) + if (held.getItem() instanceof BlockItem blockItem) { + if (blockItem.getBlock() instanceof KineticBlock && hasShaftTowards(state, hit.getDirection(), worldIn, hit.getBlockPos())) return InteractionResult.PASS; } @@ -102,37 +100,56 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implemen ScreenOpener.open(new SequencedGearshiftScreen(te)); } + private static boolean sideFacesShaft(BlockPlaceContext context, Direction side) { + BlockPos pos = context.getClickedPos().relative(side); + BlockState state = context.getLevel().getBlockState(pos); + return state.getBlock() instanceof IRotate ir + && ir.hasShaftTowards(state, side.getOpposite(), context.getLevel(), pos); + } + @Override public BlockState getStateForPlacement(BlockPlaceContext context) { - Axis preferredAxis = RotatedPillarKineticBlock.getPreferredAxis(context); - if (preferredAxis != null && (context.getPlayer() == null || !context.getPlayer() - .isShiftKeyDown())) - return withAxis(preferredAxis, context); - return withAxis(context.getNearestLookingDirection() - .getAxis(), context); + Direction preferredFacing = null; + for (Direction dir : context.getNearestLookingDirections()) { + if (sideFacesShaft(context, dir.getOpposite())) { + preferredFacing = dir; + break; + } + } + + if (preferredFacing != null && (context.getPlayer() == null || !context.getPlayer().isShiftKeyDown())) + return withFacing(preferredFacing, context); + return withFacing(context.getNearestLookingDirection(), context); + } + + private BlockState withFacing(Direction dir, BlockPlaceContext context) { + Axis axis = dir.getAxis(); + BlockState state = defaultBlockState() + .setValue(VERTICAL, axis.isVertical()) + .setValue(POSITIVE, dir.getAxisDirection() == Direction.AxisDirection.POSITIVE); + if (axis.isVertical()) + return state.setValue(HORIZONTAL_AXIS, context.getHorizontalDirection().getAxis()); + return state.setValue(HORIZONTAL_AXIS, axis); + } + + public Direction getFacing(BlockState state) { + Direction.AxisDirection axisDir = state.getValue(POSITIVE) + ? Direction.AxisDirection.POSITIVE + : Direction.AxisDirection.NEGATIVE; + return Direction.fromAxisAndDirection(getRotationAxis(state), axisDir); } @Override public InteractionResult onWrenched(BlockState state, UseOnContext context) { BlockState newState = state; - if (context.getClickedFace() - .getAxis() != Axis.Y) - if (newState.getValue(HORIZONTAL_AXIS) != context.getClickedFace() - .getAxis()) + if (context.getClickedFace().getAxis() != Axis.Y) + if (newState.getValue(HORIZONTAL_AXIS) != context.getClickedFace().getAxis()) newState = newState.cycle(VERTICAL); return super.onWrenched(newState, context); } - private BlockState withAxis(Axis axis, BlockPlaceContext context) { - BlockState state = defaultBlockState().setValue(VERTICAL, axis.isVertical()); - if (axis.isVertical()) - return state.setValue(HORIZONTAL_AXIS, context.getHorizontalDirection() - .getAxis()); - return state.setValue(HORIZONTAL_AXIS, axis); - } - @Override public Axis getRotationAxis(BlockState state) { if (state.getValue(VERTICAL)) diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftTileEntity.java index ae1c36f48..13375f0a9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftTileEntity.java @@ -1,20 +1,19 @@ package com.simibubi.create.content.contraptions.relays.advanced.sequencer; +import java.util.Optional; import java.util.Vector; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.solver.AllConnections; +import com.simibubi.create.content.contraptions.solver.ConnectionsBuilder; import com.simibubi.create.content.contraptions.solver.KineticConnections; -import com.simibubi.create.content.contraptions.solver.KineticConnections.Entry; - import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class SequencedGearshiftTileEntity extends KineticTileEntity { @@ -47,7 +46,7 @@ public class SequencedGearshiftTileEntity extends KineticTileEntity { return; if (timer < currentInstructionDuration) { timer++; - currentInstructionProgress += getInstruction(currentInstruction).getTickProgress(theoreticalSpeed); + currentInstructionProgress += getInstruction(currentInstruction).getTickProgress(getTheoreticalSpeed()); return; } run(currentInstruction + 1); @@ -58,7 +57,7 @@ public class SequencedGearshiftTileEntity extends KineticTileEntity { super.onSpeedChanged(previousSpeed); if (isIdle()) return; - float currentSpeed = Math.abs(theoreticalSpeed); + float currentSpeed = Math.abs(getTheoreticalSpeed()); if (Math.abs(previousSpeed) == currentSpeed) return; Instruction instruction = getInstruction(currentInstruction); @@ -101,12 +100,8 @@ public class SequencedGearshiftTileEntity extends KineticTileEntity { return; poweredPreviously = true; - switch (instruction.onRedstonePulse()) { - case CONTINUE: + if (instruction.onRedstonePulse() == OnIsPoweredResult.CONTINUE) { run(currentInstruction + 1); - break; - default: - break; } } @@ -160,31 +155,31 @@ public class SequencedGearshiftTileEntity extends KineticTileEntity { @Override public KineticConnections getConnections() { - Direction.Axis axis = getBlockState().getValue(BlockStateProperties.HORIZONTAL_AXIS); + BlockState state = getBlockState(); + SequencedGearshiftBlock block = (SequencedGearshiftBlock) state.getBlock(); + Direction facing = block.getFacing(state); - if (isVirtual()) return AllConnections.FULL_SHAFT.apply(axis); + ConnectionsBuilder builder = ConnectionsBuilder.builder(); + if (isVirtual()) return builder.withFullShaft(facing.getAxis()).build(); - return getSpeedSource() - .map(p -> { - Direction dir = Direction.fromNormal(p.subtract(getBlockPos())); - float modifier = getModifier(); - if (modifier == 0 || isRemoved()) return AllConnections.HALF_SHAFT.apply(dir); + builder = builder.withHalfShaft(facing.getOpposite()); - Direction opp = dir.getOpposite(); - String from = AllConnections.type(AllConnections.TYPE_SHAFT, opp); - String to = AllConnections.type(AllConnections.TYPE_SHAFT, dir); - return new KineticConnections(new Entry(opp.getNormal(), from, to, modifier)) - .merge(AllConnections.HALF_SHAFT.apply(dir)); - }) - .orElse(AllConnections.FULL_SHAFT.apply(axis)); + Optional modifier = getModifier(); + if (modifier.isEmpty() || isRemoved()) return builder.build(); + + AllConnections.Shafts shaft = switch(modifier.get()) { + case FORWARD_FAST -> AllConnections.Shafts.SHAFT_X2; + case FORWARD -> AllConnections.Shafts.SHAFT; + case BACK -> AllConnections.Shafts.SHAFT_REV; + case BACK_FAST -> AllConnections.Shafts.SHAFT_REV_X2; + }; + return builder.withHalfShaft(shaft, facing).build(); } - public int getModifier() { - if (currentInstruction >= instructions.size()) - return 0; - return isIdle() ? 0 - : instructions.get(currentInstruction) - .getSpeedModifier(); + public Optional getModifier() { + if (currentInstruction >= instructions.size() || isIdle()) + return Optional.empty(); + return instructions.get(currentInstruction).getSpeedModifier(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltBlock.java index 0824c871d..b5e8bb1d2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltBlock.java @@ -5,6 +5,8 @@ import java.util.LinkedList; import java.util.List; import java.util.function.Consumer; +import net.minecraft.world.level.LevelReader; + import org.apache.commons.lang3.mutable.MutableBoolean; import com.simibubi.create.AllBlocks; @@ -52,7 +54,6 @@ import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.RenderShape; @@ -113,10 +114,11 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE AllConnections.HALF_SHAFT.apply(Direction.fromNormal(p.subtract(getBlockPos())))) - .orElse(AllConnections.FULL_SHAFT.apply(axis)); + ConnectionsBuilder builder = ConnectionsBuilder.builder(); + if (!state.getValue(BlockStateProperties.POWERED)) + return builder.withFullShaft(dir.getAxis()).build(); + return builder.withHalfShaft(dir.getOpposite()).build(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedBeltBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedBeltBlock.java index a4c585b9a..003622452 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedBeltBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedBeltBlock.java @@ -155,7 +155,7 @@ public class EncasedBeltBlock extends RotatedPillarKineticBlock implements ITE { rotatingModel = setup(getCogModel().createInstance()); Block block = blockState.getBlock(); - if (!(block instanceof IRotate)) + if (!(block instanceof IRotate def)) return; - IRotate def = (IRotate) block; rotatingTopShaft = Optional.empty(); rotatingBottomShaft = Optional.empty(); for (Direction d : Iterate.directionsInAxis(axis)) { - if (!def.hasShaftTowards(tile.getLevel(), tile.getBlockPos(), blockState, d)) + if (!def.hasShaftTowards(blockState, d, tile.getLevel(), tile.getBlockPos())) continue; RotatingData data = setup(getRotatingMaterial().getModel(AllBlockPartials.SHAFT_HALF, blockState, d) .createInstance()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedCogRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedCogRenderer.java index 0bb95a167..6084d32ac 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedCogRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedCogRenderer.java @@ -45,12 +45,11 @@ public class EncasedCogRenderer extends KineticTileEntityRenderer { BlockState blockState = te.getBlockState(); Block block = blockState.getBlock(); - if (!(block instanceof IRotate)) + if (!(block instanceof IRotate def)) return; - IRotate def = (IRotate) block; for (Direction d : Iterate.directionsInAxis(getRotationAxisOf(te))) { - if (!def.hasShaftTowards(te.getLevel(), te.getBlockPos(), blockState, d)) + if (!def.hasShaftTowards(blockState, d, te.getLevel(), te.getBlockPos())) continue; renderRotatingBuffer(te, CachedBufferer.partialFacing(AllBlockPartials.SHAFT_HALF, te.getBlockState(), d), ms, buffer.getBuffer(RenderType.solid()), light); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedCogwheelBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedCogwheelBlock.java index 264c42cf3..01f76f97d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedCogwheelBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedCogwheelBlock.java @@ -133,7 +133,7 @@ public class EncasedCogwheelBlock extends RotatedPillarKineticBlock } @Override - public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) { + public boolean hasShaftTowards(BlockState state, Direction face) { return face.getAxis() == state.getValue(AXIS) && state.getValue(face.getAxisDirection() == AxisDirection.POSITIVE ? TOP_SHAFT : BOTTOM_SHAFT); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/GearshiftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/GearshiftBlock.java index d2306e348..bc14914c7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/GearshiftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/GearshiftBlock.java @@ -1,25 +1,26 @@ package com.simibubi.create.content.contraptions.relays.encased; -import java.util.Random; - import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock; import com.simibubi.create.foundation.block.ITE; import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; +import net.minecraft.core.Direction; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition.Builder; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.ticks.TickPriority; +import net.minecraft.world.level.material.PushReaction; -public class GearshiftBlock extends AbstractEncasedShaftBlock implements ITE { +import javax.annotation.Nullable; + +public class GearshiftBlock extends RotatedPillarKineticBlock implements ITE { public static final BooleanProperty POWERED = BlockStateProperties.POWERED; @@ -36,8 +37,8 @@ public class GearshiftBlock extends AbstractEncasedShaftBlock implements ITE { keys = new ArrayList<>(2); - float speed = tile.getSpeed(); - Material rotatingMaterial = getRotatingMaterial(); - for (Direction dir : Iterate.directionsInAxis(getRotationAxis())) { + for (Direction dir : Iterate.directionsInAxis(getRotationAxis())) { Instancer half = rotatingMaterial.getModel(AllBlockPartials.SHAFT_HALF, blockState, dir); - float splitSpeed = speed * tile.getRotationSpeedModifier(dir); + float splitSpeed = tile.getShaftSpeed(dir); keys.add(setup(half.createInstance(), splitSpeed)); } @@ -46,8 +45,8 @@ public class SplitShaftInstance extends KineticTileInstance { Direction[] directions = Iterate.directionsInAxis(boxAxis); - for (int i : Iterate.zeroAndOne) { - updateRotation(keys.get(i), tile.getSpeed() * tile.getRotationSpeedModifier(directions[i])); + for (int i : Iterate.zeroAndOne) { + updateRotation(keys.get(i), tile.getShaftSpeed(directions[i])); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java index 946cd1770..330d97958 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java @@ -6,6 +6,7 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.content.contraptions.solver.KineticConnections; import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -41,12 +42,8 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer { continue; float offset = getRotationOffsetForPosition(te, pos, axis); - float angle = (time * te.getSpeed() * 3f / 10) % 360; - float modifier = 1; + float angle = (time * te.getShaftSpeed(direction) * 3f / 10) % 360; - modifier = te.getRotationSpeedModifier(direction); - - angle *= modifier; angle += offset; angle = angle / 180f * (float) Math.PI; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeBlock.java index 64f421053..c9b13ca31 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeBlock.java @@ -69,7 +69,7 @@ public class GaugeBlock extends DirectionalAxisKineticBlock implements ITE getTileEntityClass() { return GearboxTileEntity.class; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java index 8871111a8..ed4918360 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java @@ -12,7 +12,6 @@ import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.flwdata.RotatingData; import com.simibubi.create.foundation.utility.Iterate; -import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.block.state.properties.BlockStateProperties; @@ -20,7 +19,6 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class GearboxInstance extends KineticTileInstance { protected final EnumMap keys; - protected Direction sourceFacing; public GearboxInstance(MaterialManager modelManager, GearboxTileEntity tile) { super(modelManager, tile); @@ -31,7 +29,6 @@ public class GearboxInstance extends KineticTileInstance { int blockLight = world.getBrightness(LightLayer.BLOCK, pos); int skyLight = world.getBrightness(LightLayer.SKY, pos); - updateSourceFacing(); Material rotatingMaterial = getRotatingMaterial(); @@ -56,29 +53,11 @@ public class GearboxInstance extends KineticTileInstance { } private float getSpeed(Direction direction) { - float speed = tile.getSpeed(); - - if (speed != 0 && sourceFacing != null) { - if (sourceFacing.getAxis() == direction.getAxis()) - speed *= sourceFacing == direction ? 1 : -1; - else if (sourceFacing.getAxisDirection() == direction.getAxisDirection()) - speed *= -1; - } - return speed; - } - - protected void updateSourceFacing() { - if (tile.hasSource()) { - BlockPos source = tile.source.subtract(pos); - sourceFacing = Direction.getNearest(source.getX(), source.getY(), source.getZ()); - } else { - sourceFacing = null; - } + return tile.getShaftSpeed(direction); } @Override public void update() { - updateSourceFacing(); for (Map.Entry key : keys.entrySet()) { Direction direction = key.getKey(); Direction.Axis axis = direction.getAxis(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java index 56194ec81..6b3dc332b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java @@ -40,16 +40,7 @@ public class GearboxRenderer extends KineticTileEntityRenderer { SuperByteBuffer shaft = CachedBufferer.partialFacing(AllBlockPartials.SHAFT_HALF, te.getBlockState(), direction); float offset = getRotationOffsetForPosition(te, pos, axis); - float angle = (time * te.getSpeed() * 3f / 10) % 360; - - if (te.getSpeed() != 0 && te.hasSource()) { - BlockPos source = te.source.subtract(te.getBlockPos()); - Direction sourceFacing = Direction.getNearest(source.getX(), source.getY(), source.getZ()); - if (sourceFacing.getAxis() == direction.getAxis()) - angle *= sourceFacing == direction ? 1 : -1; - else if (sourceFacing.getAxisDirection() == direction.getAxisDirection()) - angle *= -1; - } + float angle = (time * te.getShaftSpeed(direction) * 3f / 10) % 360; angle += offset; angle = angle / 180f * (float) Math.PI; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearshiftTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearshiftTileEntity.java index 165b6e276..ab813d718 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearshiftTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearshiftTileEntity.java @@ -2,7 +2,9 @@ package com.simibubi.create.content.contraptions.relays.gearbox; import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.relays.encased.GearshiftBlock; import com.simibubi.create.content.contraptions.solver.AllConnections; +import com.simibubi.create.content.contraptions.solver.ConnectionsBuilder; import com.simibubi.create.content.contraptions.solver.KineticConnections; import net.minecraft.core.BlockPos; @@ -20,13 +22,15 @@ public class GearshiftTileEntity extends KineticTileEntity { @Override public KineticConnections getConnections() { BlockState state = getBlockState(); - Direction.Axis axis = state.getValue(BlockStateProperties.AXIS); + Direction dir = AllConnections.pos(state.getValue(GearshiftBlock.AXIS)); - if (!state.getValue(BlockStateProperties.POWERED)) return AllConnections.FULL_SHAFT.apply(axis); - - return getSpeedSource() - .map(p -> AllConnections.FULL_SHAFT_REVERSER.apply(Direction.fromNormal(p.subtract(getBlockPos())))) - .orElse(AllConnections.FULL_SHAFT.apply(axis)); + ConnectionsBuilder builder = ConnectionsBuilder.builder(); + if (!state.getValue(BlockStateProperties.POWERED)) + return builder.withFullShaft(dir.getAxis()).build(); + return builder + .withHalfShaft(AllConnections.Shafts.SHAFT_REV, dir) + .withHalfShaft(AllConnections.Shafts.SHAFT, dir.getOpposite()) + .build(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/VerticalGearboxItem.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/VerticalGearboxItem.java index 5b5a4761a..b76389eda 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/VerticalGearboxItem.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/VerticalGearboxItem.java @@ -4,6 +4,7 @@ import java.util.Map; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.base.IRotate; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.core.BlockPos; @@ -29,7 +30,7 @@ public class VerticalGearboxItem extends BlockItem { @Override public void fillItemCategory(CreativeModeTab p_150895_1_, NonNullList p_150895_2_) { } - + @Override public String getDescriptionId() { return "item.create.vertical_gearbox"; @@ -41,25 +42,26 @@ public class VerticalGearboxItem extends BlockItem { @Override protected boolean updateCustomBlockEntityTag(BlockPos pos, Level world, Player player, ItemStack stack, BlockState state) { - Axis prefferedAxis = null; + Axis preferredAxis = null; for (Direction side : Iterate.horizontalDirections) { BlockState blockState = world.getBlockState(pos.relative(side)); - if (blockState.getBlock() instanceof IRotate) { - if (((IRotate) blockState.getBlock()).hasShaftTowards(world, pos.relative(side), blockState, - side.getOpposite())) - if (prefferedAxis != null && prefferedAxis != side.getAxis()) { - prefferedAxis = null; + if (blockState.getBlock() instanceof IRotate ir) { + if (ir.hasShaftTowards(blockState, side.getOpposite(), world, pos.relative(side))) + if (preferredAxis != null && preferredAxis != side.getAxis()) { + preferredAxis = null; break; } else { - prefferedAxis = side.getAxis(); + preferredAxis = side.getAxis(); } } } - Axis axis = prefferedAxis == null ? player.getDirection() + Axis axis = preferredAxis == null ? player.getDirection() .getClockWise() - .getAxis() : prefferedAxis == Axis.X ? Axis.Z : Axis.X; - world.setBlockAndUpdate(pos, state.setValue(BlockStateProperties.AXIS, axis)); + .getAxis() : preferredAxis == Axis.X ? Axis.Z : Axis.X; + BlockState newState = state.setValue(BlockStateProperties.AXIS, axis); + KineticTileEntity.switchToBlockState(world, pos, newState); + return super.updateCustomBlockEntityTag(pos, world, player, stack, state); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/AllConnections.java b/src/main/java/com/simibubi/create/content/contraptions/solver/AllConnections.java index 97d3d4245..82f743721 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/solver/AllConnections.java +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/AllConnections.java @@ -1,13 +1,13 @@ package com.simibubi.create.content.contraptions.solver; +import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageTileEntity; import com.simibubi.create.foundation.utility.DirectionHelper; -import com.simibubi.create.foundation.utility.LazyMap; -import com.simibubi.create.content.contraptions.solver.KineticConnections.Entry; + +import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; import net.minecraft.core.Vec3i; -import net.minecraft.util.StringRepresentable; import java.util.LinkedList; import java.util.List; @@ -15,34 +15,250 @@ import java.util.Optional; public class AllConnections { - private static Direction pos(Axis axis) { + public static void register() { + Shafts.registerTypes(); + Directional.registerTypes(); + Axial.registerTypes(); + DirAxial.registerTypes(); + + Shafts.registerRatios(); + Directional.registerRatios(); + Axial.registerRatios(); + DirAxial.registerRatios(); + } + + private static record Entry(Vec3i offset, String to, float ratio) {} + + public enum Shafts { + SHAFT("shaft", 1), + SHAFT_REV("shaft_rev", -1), + SHAFT_X2("shaft_x2", 2), + SHAFT_REV_X2("shaft_rev_x2", -2); + + public final String prefix; + public final float ratio; + Shafts(String prefix, float ratio) { + this.prefix = prefix; + this.ratio = ratio; + } + + public String type(Direction dir) { + return prefix + "." + dir; + } + + public static void registerTypes() { + for (Shafts value : values()) { + for (Direction dir : Direction.values()) { + KineticConnectionsRegistry.registerConnectionType(value.type(dir)); + } + } + } + + public static void registerRatios() { + for (Shafts from : values()) { + for (Shafts to : values()) { + for (Direction dir : Direction.values()) { + KineticConnectionsRegistry.registerConnectionRatio( + KineticConnectionsRegistry.getConnectionType(from.type(dir)).get(), + KineticConnectionsRegistry.getConnectionType(to.type(dir.getOpposite())).get(), + dir.getNormal(), + from.ratio / to.ratio + ); + } + } + } + } + } + + public enum Directional { + GANTRY_RACK("gantry_rack") { + @Override + public List genConnections(Direction dir) { return List.of(); } + }; + + public final String prefix; + + Directional(String prefix) { + this.prefix = prefix; + } + + public abstract List genConnections(Direction dir); + + public String type(Direction dir) { + return prefix + "." + dir; + } + + public static void registerTypes() { + for (Directional value : values()) { + for (Direction dir : Direction.values()) { + KineticConnectionsRegistry.registerConnectionType(value.type(dir)); + } + } + } + + public static void registerRatios() { + for (Directional from : values()) { + for (Direction dir : Direction.values()) { + String fromType = from.type(dir); + from.genConnections(dir).forEach(entry -> KineticConnectionsRegistry.registerConnectionRatio( + KineticConnectionsRegistry.getConnectionType(fromType).get(), + KineticConnectionsRegistry.getConnectionType(entry.to).get(), + entry.offset, + entry.ratio + )); + } + } + } + } + + public enum Axial { + SMALL_COG("small_cog") { + @Override + public List genConnections(Axis axis) { + List out = new LinkedList<>(); + for (Direction cur : Iterate.directionsPerpendicularTo(axis)) { + Direction next = rot(cur, axis); + out.add(new Entry(cur.getNormal(), SMALL_COG.type(axis), -1)); + out.add(new Entry(cur.getNormal().relative(next), LARGE_COG.type(axis), -0.5f)); + } + return out; + } + }, + + LARGE_COG("large_cog") { + @Override + public List genConnections(Axis axis) { + List out = new LinkedList<>(); + for (Direction cur : Iterate.directionsPerpendicularTo(axis)) { + out.add(largeToLarge(cur.getNormal().relative(pos(axis)), axis, cur.getAxis())); + out.add(largeToLarge(cur.getNormal().relative(neg(axis)), axis, cur.getAxis())); + } + return out; + } + }, + + SPEED_CONTROLLER_TOP("speed_controller_top") { + @Override + public List genConnections(Axis axis) { + return oppAxis(axis) + .map(opp -> List.of(new Entry(Direction.UP.getNormal(), LARGE_COG.type(opp), 0))) + .orElseGet(List::of); + } + }; + + public final String prefix; + + Axial(String prefix) { + this.prefix = prefix; + } + + public abstract List genConnections(Axis axis); + + public String type(Axis axis) { + return prefix + "." + axis; + } + + public static void registerTypes() { + for (Axial value : values()) { + for (Axis axis : Axis.values()) { + KineticConnectionsRegistry.registerConnectionType(value.type(axis)); + } + } + } + + public static void registerRatios() { + for (Axial from : values()) { + for (Axis axis : Axis.values()) { + String fromType = from.type(axis); + from.genConnections(axis).forEach(entry -> KineticConnectionsRegistry.registerConnectionRatio( + KineticConnectionsRegistry.getConnectionType(fromType).get(), + KineticConnectionsRegistry.getConnectionType(entry.to).get(), + entry.offset, + entry.ratio + )); + } + } + } + } + + public enum DirAxial { + GANTRY_PINION("gantry_pinion") { + @Override + public List genConnections(Direction dir, boolean first) { + Axis shaftAxis = switch (dir.getAxis()) { + case X -> first ? Axis.Z : Axis.Y; + case Y -> first ? Axis.Z : Axis.X; + case Z -> first ? Axis.Y : Axis.X; + }; + + List out = new LinkedList<>(); + for (Direction shaftDir : Iterate.directionsInAxis(shaftAxis)) { + float ratio = GantryCarriageTileEntity.getGantryPinionModifier(shaftDir, dir); + out.add(new Entry(dir.getOpposite().getNormal(), Directional.GANTRY_RACK.type(shaftDir), ratio)); + } + return out; + } + }; + + public final String prefix; + + DirAxial(String prefix) { + this.prefix = prefix; + } + + public abstract List genConnections(Direction dir, boolean first); + + public String type(Direction dir, boolean first) { + return prefix + "." + dir + "_" + (first ? "0" : "1"); + } + + public static void registerTypes() { + for (DirAxial value : values()) { + for (Direction dir : Direction.values()) { + for (boolean first : Iterate.trueAndFalse) { + KineticConnectionsRegistry.registerConnectionType(value.type(dir, first)); + } + } + } + } + + public static void registerRatios() { + for (DirAxial from : values()) { + for (Direction dir : Direction.values()) { + for (boolean first : Iterate.trueAndFalse) { + String fromType = from.type(dir, first); + from.genConnections(dir, first).forEach(entry -> KineticConnectionsRegistry.registerConnectionRatio( + KineticConnectionsRegistry.getConnectionType(fromType).get(), + KineticConnectionsRegistry.getConnectionType(entry.to).get(), + entry.offset, + entry.ratio + )); + } + } + } + } + } + + public static Direction pos(Axis axis) { return Direction.get(Direction.AxisDirection.POSITIVE, axis); } - private static Direction neg(Axis axis) { + public static Direction neg(Axis axis) { return Direction.get(Direction.AxisDirection.NEGATIVE, axis); } - public static String type(String name, StringRepresentable ext) { - return name + "." + ext; + public static Direction rot(Direction dir, Axis axis) { + return DirectionHelper.rotateAround(dir, axis); } - public static final String - TYPE_SHAFT = "shaft", - TYPE_LARGE_COG = "large_cog", - TYPE_SMALL_COG = "small_cog", - TYPE_SPEED_CONTROLLER_TOP = "speed_controller_top"; - - private static Vec3i rhr(Vec3i vec) { - if (vec.getX() == 0) return new Vec3i(vec.getY(), vec.getZ(), 0); - if (vec.getY() == 0) return new Vec3i(vec.getZ(), vec.getX(), 0); - return new Vec3i(vec.getX(), vec.getY(), 0); + public static float perpendicularRatios(Vec3i diff, Axis from, Axis to) { + int fromDiff = from.choose(diff.getX(), diff.getY(), diff.getZ()); + int toDiff = to.choose(diff.getX(), diff.getY(), diff.getZ()); + return fromDiff * toDiff; } private static Entry largeToLarge(Vec3i diff, Axis from, Axis to) { - Vec3i rhr = rhr(diff); - float ratio = rhr.getX() == rhr.getY() ? 1 : rhr.getX(); - return new Entry(diff, type(TYPE_LARGE_COG, from), type(TYPE_LARGE_COG, to), ratio); + return new Entry(diff, Axial.LARGE_COG.type(to), perpendicularRatios(diff, from, to)); } private static Optional oppAxis(Axis axis) { @@ -53,69 +269,4 @@ public class AllConnections { }; } - - public static final KineticConnections EMPTY = new KineticConnections(); - - public static final LazyMap - HALF_SHAFT = new LazyMap<>(dir -> - new KineticConnections( - new Entry(dir.getNormal(), type(TYPE_SHAFT, dir), type(TYPE_SHAFT, dir.getOpposite())))), - - HALF_SHAFT_REVERSER = new LazyMap<>(dir -> - new KineticConnections( - new Entry(dir.getNormal(), type(TYPE_SHAFT, dir), type(TYPE_SHAFT, dir.getOpposite()), -1))), - - FULL_SHAFT_REVERSER = new LazyMap<>(dir -> - HALF_SHAFT.apply(dir).merge(HALF_SHAFT_REVERSER.apply(dir.getOpposite()))); - - public static final LazyMap - FULL_SHAFT = new LazyMap<>(axis -> HALF_SHAFT.apply(pos(axis)).merge(HALF_SHAFT.apply(neg(axis)))), - - LARGE_COG = new LazyMap<>(axis -> { - String large = type(TYPE_LARGE_COG, axis); - String small = type(TYPE_SMALL_COG, axis); - - List out = new LinkedList<>(); - Direction cur = DirectionHelper.getPositivePerpendicular(axis); - for (int i = 0; i < 4; i++) { - Direction next = DirectionHelper.rotateAround(cur, axis); - out.add(largeToLarge(cur.getNormal().relative(pos(axis)), axis, cur.getAxis())); - out.add(largeToLarge(cur.getNormal().relative(neg(axis)), axis, cur.getAxis())); - out.add(new Entry(cur.getNormal().relative(next), large, small, -2)); - cur = next; - } - - oppAxis(axis).ifPresent(opp -> { - String sc = type(TYPE_SPEED_CONTROLLER_TOP, opp); - out.add(new Entry(Direction.DOWN.getNormal(), large, sc).stressOnly()); - }); - return new KineticConnections(out); - }), - - SMALL_COG = new LazyMap<>(axis -> { - String large = type(TYPE_LARGE_COG, axis); - String small = type(TYPE_SMALL_COG, axis); - - List out = new LinkedList<>(); - Direction cur = DirectionHelper.getPositivePerpendicular(axis); - for (int i = 0; i < 4; i++) { - Direction next = DirectionHelper.rotateAround(cur, axis); - out.add(new Entry(cur.getNormal(), small, small, i < 2 ? -1 : 1)); - out.add(new Entry(cur.getNormal().relative(next), small, large)); - cur = next; - } - return new KineticConnections(out); - }), - - LARGE_COG_FULL_SHAFT = new LazyMap<>(axis -> LARGE_COG.apply(axis).merge(FULL_SHAFT.apply(axis))), - - SMALL_COG_FULL_SHAFT = new LazyMap<>(axis -> SMALL_COG.apply(axis).merge(FULL_SHAFT.apply(axis))), - - SPEED_CONTROLLER = new LazyMap<>(axis -> { - String sc = type(TYPE_SPEED_CONTROLLER_TOP, axis); - String large = type(TYPE_LARGE_COG, oppAxis(axis).get()); - Vec3i up = Direction.UP.getNormal(); - return new KineticConnections(new Entry(up, sc, large).stressOnly()).merge(FULL_SHAFT.apply(axis)); - }); - } diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/ConnectionsBuilder.java b/src/main/java/com/simibubi/create/content/contraptions/solver/ConnectionsBuilder.java new file mode 100644 index 000000000..e8903e4e6 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/ConnectionsBuilder.java @@ -0,0 +1,54 @@ +package com.simibubi.create.content.contraptions.solver; + +import net.minecraft.core.Direction; + +import java.util.HashSet; +import java.util.Set; + +public class ConnectionsBuilder { + private final Set connections = new HashSet<>(); + + public static ConnectionsBuilder builder() { + return new ConnectionsBuilder(); + } + + public KineticConnections build() { + return new KineticConnections(connections); + } + + public ConnectionsBuilder withHalfShaft(AllConnections.Shafts shaft, Direction dir) { + connections.add(KineticConnectionsRegistry.getConnectionType(shaft.type(dir)).get()); + return this; + } + + public ConnectionsBuilder withHalfShaft(Direction dir) { + return withHalfShaft(AllConnections.Shafts.SHAFT, dir); + } + + public ConnectionsBuilder withFullShaft(Direction.Axis axis) { + return this.withHalfShaft(AllConnections.pos(axis)).withHalfShaft(AllConnections.neg(axis)); + } + + public ConnectionsBuilder withDirectional(AllConnections.Directional directional, Direction dir) { + connections.add(KineticConnectionsRegistry.getConnectionType(directional.type(dir)).get()); + return this; + } + + public ConnectionsBuilder withAxial(AllConnections.Axial axial, Direction.Axis axis) { + connections.add(KineticConnectionsRegistry.getConnectionType(axial.type(axis)).get()); + return this; + } + + public ConnectionsBuilder withDirAxial(AllConnections.DirAxial dirAxial, Direction dir, boolean first) { + connections.add(KineticConnectionsRegistry.getConnectionType(dirAxial.type(dir, first)).get()); + return this; + } + + public ConnectionsBuilder withLargeCog(Direction.Axis axis) { + return withAxial(AllConnections.Axial.LARGE_COG, axis); + } + + public ConnectionsBuilder withSmallCog(Direction.Axis axis) { + return withAxial(AllConnections.Axial.SMALL_COG, axis); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/IKineticController.java b/src/main/java/com/simibubi/create/content/contraptions/solver/IKineticController.java index 874eef13c..6edd6659d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/solver/IKineticController.java +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/IKineticController.java @@ -4,10 +4,10 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.Level; public interface IKineticController { - default void onUpdate(Level level, KineticSolver solver, KineticNode node) { } + default void onKineticsTick(Level level, KineticSolver solver, KineticNode node) { } default KineticConnections getConnections() { - return AllConnections.EMPTY; + return KineticConnections.empty(); } default float getGeneratedSpeed() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnection.java b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnection.java new file mode 100644 index 000000000..7aaaa42a1 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnection.java @@ -0,0 +1,11 @@ +package com.simibubi.create.content.contraptions.solver; + +import net.minecraft.core.Vec3i; + +import java.util.Map; + +public record KineticConnection(String name) { + public Map> getRatios() { + return KineticConnectionsRegistry.getConnections(this); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnections.java b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnections.java index e3c4dd287..6ba1ba708 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnections.java +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnections.java @@ -1,106 +1,51 @@ package com.simibubi.create.content.contraptions.solver; -import com.simibubi.create.foundation.utility.NBTHelper; - +import net.minecraft.core.Direction; import net.minecraft.core.Vec3i; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; -import net.minecraft.util.Mth; - -import javax.annotation.Nullable; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; import java.util.stream.Stream; public class KineticConnections { + private final Set connections; - public static record Entry(Vec3i offset, Value value) { - public Entry(Vec3i offset, String from, String to, float ratio) { - this(offset, new Value(from, to, ratio)); - } - public Entry(Vec3i offset, String from, String to) { - this(offset, from, to, 1); - } - public Entry(Vec3i offset, String from) { - this(offset, from, from); - } - public Entry stressOnly() { - return new Entry(offset, new Value(value.from, value.to, 0)); - } - } - - public static record Value(String from, String to, float ratio) { - public boolean isStressOnly() { - return ratio == 0; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Value value = (Value) o; - return Float.compare(value.ratio, ratio) == 0 && from.equals(value.from) && to.equals(value.to); - } - - @Override - public int hashCode() { - return Objects.hash(from, to, ratio); - } - } - - private final Map connections; - - private KineticConnections(Map connections) { + public KineticConnections(Set connections) { this.connections = connections; } - public KineticConnections(Stream entries) { - this(entries.collect(Collectors.toMap(Entry::offset, Entry::value))); + public static KineticConnections empty() { + return new KineticConnections(Set.of()); } - public KineticConnections(Collection entries) { - this(entries.stream()); + public Stream stream() { + return connections.stream(); } - public KineticConnections(Entry... entries) { - this(Arrays.stream(entries)); + public boolean hasStressOnlyConnections() { + return connections.stream() + .flatMap(c -> c.getRatios().values().stream() + .flatMap(m -> m.values().stream())) + .anyMatch(r -> r == 0); } - public Set getDirections() { - return connections.keySet(); - } + public float getShaftSpeedModifier(Direction face) { + Vec3i offset = face.getNormal(); - public Optional checkConnection(Vec3i offset) { - Value value = connections.get(offset); - if (value == null) return Optional.empty(); - return Optional.of(value.ratio); - } + KineticConnection shaft = KineticConnectionsRegistry + .getConnectionType(AllConnections.Shafts.SHAFT.type(face.getOpposite())).get(); - private Optional checkConnection(KineticConnections to, Vec3i offset, boolean stressOnly) { - Value fromValue = connections.get(offset); - Value toValue = to.connections.get(offset.multiply(-1)); - if (fromValue == null || toValue == null) return Optional.empty(); - if (!fromValue.from.equals(toValue.to) || !fromValue.to.equals(toValue.from)) return Optional.empty(); - if (fromValue.isStressOnly() ^ toValue.isStressOnly()) return Optional.empty(); - if (fromValue.isStressOnly()) return stressOnly ? Optional.of(0f) : Optional.empty(); - return Optional.of(fromValue.ratio / toValue.ratio); - } - - public Optional checkConnection(KineticConnections to, Vec3i offset) { - return checkConnection(to, offset, false); - } - - public boolean checkStressOnlyConnection(KineticConnections to, Vec3i offset) { - return checkConnection(to, offset, true).isPresent(); + return stream() + .flatMap(c -> Optional.ofNullable(c.getRatios().get(offset)) + .flatMap(r -> Optional.ofNullable(r.get(shaft))) + .stream()) + .findFirst() + .orElse(0f); } @Override @@ -116,43 +61,20 @@ public class KineticConnections { return Objects.hash(connections); } - public KineticConnections merge(KineticConnections other) { - Map connectionsNew = new HashMap<>(); - connectionsNew.putAll(other.connections); - connectionsNew.putAll(connections); - return new KineticConnections(connectionsNew); - } - - public boolean hasStressOnlyConnections() { - return connections.values().stream().anyMatch(Value::isStressOnly); - } - public CompoundTag save(CompoundTag tag) { ListTag connectionsTags = new ListTag(); - for (Map.Entry entry : connections.entrySet()) { - CompoundTag entryTag = new CompoundTag(); - Value v = entry.getValue(); - entryTag.put("Off", NBTHelper.writeVec3i(entry.getKey())); - entryTag.putString("From", v.from()); - if (!v.to().equals(v.from())) - entryTag.putString("To", v.to()); - if (v.ratio() != 1) - entryTag.putFloat("Ratio", v.ratio()); - connectionsTags.add(entryTag); + for (KineticConnection connection : connections) { + connectionsTags.add(StringTag.valueOf(connection.name())); } tag.put("Connections", connectionsTags); return tag; } public static KineticConnections load(CompoundTag tag) { - Map connections = new HashMap<>(); - tag.getList("Connections", Tag.TAG_COMPOUND).forEach(c -> { - CompoundTag comp = (CompoundTag) c; - Vec3i offset = NBTHelper.readVec3i(comp.getList("Off", Tag.TAG_INT)); - String from = comp.getString("From"); - String to = comp.contains("To") ? comp.getString("To") : from; - float ratio = comp.contains("Ratio") ? comp.getFloat("Ratio") : 1; - connections.put(offset, new Value(from, to, ratio)); + Set connections = new HashSet<>(); + tag.getList("Connections", Tag.TAG_STRING).forEach(t -> { + KineticConnectionsRegistry.getConnectionType(t.getAsString()) + .ifPresent(connections::add); }); return new KineticConnections(connections); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnectionsRegistry.java b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnectionsRegistry.java new file mode 100644 index 000000000..882d8b682 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnectionsRegistry.java @@ -0,0 +1,46 @@ +package com.simibubi.create.content.contraptions.solver; + +import net.minecraft.core.Vec3i; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class KineticConnectionsRegistry { + private static final Map connectionTypes = new HashMap<>(); + private static final Map>> connectionRatios + = new HashMap<>(); + + public static KineticConnection registerConnectionType(String name) { + if (connectionTypes.containsKey(name)) + throw new IllegalStateException("connection type named \"" + name + "\" already exists"); + KineticConnection connection = new KineticConnection(name); + connectionTypes.put(name, connection); + return connection; + } + + public static Optional getConnectionType(String name) { + return Optional.ofNullable(connectionTypes.get(name)); + } + + public static void registerConnectionRatio(KineticConnection from, KineticConnection to, Vec3i offset, float ratio) { + Map fromMap = connectionRatios + .computeIfAbsent(from, $ -> new HashMap<>()) + .computeIfAbsent(offset, $ -> new HashMap<>()); + if (fromMap.containsKey(to)) return; + + Map toMap = connectionRatios + .computeIfAbsent(to, $ -> new HashMap<>()) + .computeIfAbsent(offset.multiply(-1), $ -> new HashMap<>()); + + fromMap.put(to, ratio); + toMap.put(from, ratio == 0 ? 0 : 1/ratio); + } + + public static Map> getConnections(KineticConnection from) { + return Optional.ofNullable(connectionRatios.get(from)) + .map(Collections::unmodifiableMap) + .orElseGet(Map::of); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticControllerSerial.java b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticControllerSerial.java index b068f4041..0a7e4c847 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticControllerSerial.java +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticControllerSerial.java @@ -27,10 +27,14 @@ public enum KineticControllerSerial { } @Override - public void onUpdate(Level level, KineticSolver solver, KineticNode node) { + public void onKineticsTick(Level level, KineticSolver solver, KineticNode node) { BlockPos below = node.getPos().below(); if (level.getBlockEntity(below) instanceof SpeedControllerTileEntity se) { targetSpeed = se.getTargetSpeed(); + } else if (generatedSpeed != 0) { + generatedSpeed = 0; + } else { + node.removeController(); } Optional seNode = solver.getNode(below); diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticNetwork.java b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticNetwork.java index a2b0f1a01..eea584570 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticNetwork.java +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticNetwork.java @@ -1,5 +1,6 @@ package com.simibubi.create.content.contraptions.solver; +import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.utility.Pair; @@ -18,6 +19,9 @@ import java.util.stream.Collectors; public class KineticNetwork { + private static long nextID = 1L; + public final long id; + private final Set members = new HashSet<>(); private final Set generators = new HashSet<>(); private final Set> conflictingCycles = new HashSet<>(); @@ -36,10 +40,14 @@ public class KineticNetwork { private final ResetableLazy totalStressCapacity = ResetableLazy.of(() -> (float) members.stream().mapToDouble(KineticNode::getStressCapacity).sum()); + private float latestSupernetworkStressImpact; + private float latestSupernetworkStressCapacity; + private boolean ticked; private final Set stressConnectors = new HashSet<>(); protected KineticNetwork(KineticNode root) { + id = nextID++; addMember(root); } @@ -150,11 +158,11 @@ public class KineticNetwork { } public float getTotalStressImpact() { - return totalStressImpact.get(); + return latestSupernetworkStressImpact; } public float getTotalStressCapacity() { - return totalStressCapacity.get(); + return latestSupernetworkStressCapacity; } public float getRootTheoreticalSpeed() { @@ -191,11 +199,16 @@ public class KineticNetwork { for (KineticNetwork cur : stressConnected) { cur.ticked = true; cur.checkForSpeedingNodes(popQueue::add); - stressImpact += cur.getTotalStressImpact(); - stressCapacity += cur.getTotalStressCapacity(); + stressImpact += cur.totalStressImpact.get(); + stressCapacity += cur.totalStressCapacity.get(); } - boolean nowOverstressed = stressImpact > stressCapacity; + for (KineticNetwork cur : stressConnected) { + cur.latestSupernetworkStressImpact = stressImpact; + cur.latestSupernetworkStressCapacity = stressCapacity; + } + + boolean nowOverstressed = stressImpact > stressCapacity && IRotate.StressImpact.isEnabled(); if (!nowOverstressed) { // we should only pop speeding nodes if the network isn't actually overstressed now popQueue.forEach(pop); diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticNode.java b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticNode.java index 872a8578b..96b1eb230 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticNode.java +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticNode.java @@ -5,16 +5,18 @@ import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.Pair; import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.util.Mth; -import net.minecraft.world.level.block.Block; import javax.annotation.Nullable; import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -28,7 +30,6 @@ public class KineticNode { private @Nullable IKineticController controller; private @Nullable KineticControllerSerial controllerType; - private @Nullable Set controlling; private @Nullable KineticNode parent; private @Nullable BlockPos speedSource; @@ -83,12 +84,15 @@ public class KineticNode { } tag.put("Connections", connections.save(new CompoundTag())); - tag.putFloat("Generated", generatedSpeed); - tag.putFloat("Capacity", stressCapacity); - tag.putFloat("Impact", stressImpact); - if (constantStress) { + if (generatedSpeed != 0) + tag.putFloat("Generated", generatedSpeed); + if (stressCapacity != 0) + tag.putFloat("Capacity", stressCapacity); + if (stressImpact != 0) + tag.putFloat("Impact", stressImpact); + if (constantStress) tag.putBoolean("ConstantStress", true); - } + return tag; } @@ -127,13 +131,10 @@ public class KineticNode { return Optional.empty(); } - public boolean setController(KineticNode source, KineticControllerSerial controller) { + public boolean setController(KineticControllerSerial controller) { if (this.controller != null) return false; this.controller = controller.init(this); this.controllerType = controller; - if (source.controlling == null) - source.controlling = new HashSet<>(); - source.controlling.add(pos); return true; } @@ -158,24 +159,38 @@ public class KineticNode { * @return a Stream containing a pair for each compatible connection with this node, where the first value is * the connecting node and the second value is the speed ratio of the connection */ - public Stream> getActiveConnections() { - return connections.getDirections().stream() - .map(d -> solver.getNode(pos.offset(d)) - .map(n -> connections.checkConnection(n.connections, d) - .map(r -> Pair.of(n, r)))) - .flatMap(Optional::stream) + private Stream> getAllActiveConnections() { + return connections.stream() + .flatMap(from -> from.getRatios().entrySet().stream() + .map(e -> { + Vec3i offset = e.getKey(); + return solver.getNode(pos.offset(offset)).flatMap(node -> { + Map ratios = e.getValue(); + return node.getConnections().stream() + .map(ratios::get) + .filter(Objects::nonNull) + .findFirst() + .map(r -> Pair.of(node, r)); + }); + }) + ) .flatMap(Optional::stream); } - public Iterable> getActiveConnectionsList() { - return getActiveConnections().collect(Collectors.toList()); + public Stream> getActiveConnections() { + return getAllActiveConnections().filter(p -> p.getSecond() != 0); } public Stream getActiveStressOnlyConnections() { - return connections.getDirections().stream() - .map(d -> solver.getNode(pos.offset(d)) - .filter(n -> connections.checkStressOnlyConnection(n.connections, d))) - .flatMap(Optional::stream); + return getAllActiveConnections().filter(p -> p.getSecond() == 0).map(Pair::getFirst); + } + + public Optional checkConnection(KineticNode to) { + return getActiveConnections().filter(p -> p.getFirst() == to).findAny().map(Pair::getSecond); + } + + public boolean checkStressOnlyConnection(KineticNode to) { + return getActiveStressOnlyConnections().anyMatch(n -> n == to); } public float getGeneratedSpeed() { @@ -298,7 +313,7 @@ public class KineticNode { while (!frontier.isEmpty()) { KineticNode cur = frontier.remove(0); - for (Pair pair : cur.getActiveConnectionsList()) { + for (Pair pair : cur.getActiveConnections().collect(Collectors.toList())) { KineticNode next = pair.getFirst(); float ratio = pair.getSecond(); @@ -334,12 +349,6 @@ public class KineticNode { .map(Pair::getFirst) .filter(n -> n.parent == this) .forEach(KineticNode::rerootHere); - if (controlling != null) { - controlling.stream() - .map(solver::getNode) - .flatMap(Optional::stream) - .forEach(KineticNode::removeController); - } } private void rerootHere() { @@ -361,7 +370,7 @@ public class KineticNode { protected void flushChanges() { if (entity != null) { - entity.updateFromSolver(getTheoreticalSpeed(), getSpeedSource(), getConnections(), + entity.updateFromSolver(getTheoreticalSpeed(), getSpeedSource(), network.id, network.isOverstressed(), network.getTotalStressImpact(), network.getTotalStressCapacity()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticSolver.java b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticSolver.java index 93a930e0e..48970c62a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticSolver.java +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticSolver.java @@ -7,25 +7,19 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; import com.simibubi.create.content.contraptions.base.KineticTileEntity; -import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.WorldAttached; import net.minecraft.core.BlockPos; -import net.minecraft.core.Vec3i; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.saveddata.SavedData; -import org.checkerframework.checker.units.qual.C; import org.jetbrains.annotations.NotNull; public class KineticSolver extends SavedData { @@ -162,7 +156,7 @@ public class KineticSolver extends SavedData { Set popQueue = new HashSet<>(); Set regenQueue = new HashSet<>(); for (KineticNode node : nodes.values()) { - node.getController().ifPresent(c -> c.onUpdate(level, this, node)); + node.getController().ifPresent(c -> c.onKineticsTick(level, this, node)); switch (node.onUpdated()) { case NEEDS_POP -> popQueue.add(node); case NEEDS_REGEN -> regenQueue.add(node); @@ -188,19 +182,4 @@ public class KineticSolver extends SavedData { } } } - - public Optional isConnected(BlockPos from, BlockPos to) { - return getNode(from).flatMap(fromNode -> - getNode(to).flatMap(toNode -> - fromNode.getConnections() - .checkConnection(toNode.getConnections(), to.subtract(from)))); - } - - public boolean isStressOnlyConnected(BlockPos from, BlockPos to) { - return getNode(from).flatMap(fromNode -> - getNode(to).map(toNode -> - fromNode.getConnections() - .checkStressOnlyConnection(toNode.getConnections(), to.subtract(from))) - ).orElse(false); - } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/wrench/IWrenchable.java b/src/main/java/com/simibubi/create/content/contraptions/wrench/IWrenchable.java index dc2a85735..530368ccd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/wrench/IWrenchable.java +++ b/src/main/java/com/simibubi/create/content/contraptions/wrench/IWrenchable.java @@ -4,7 +4,6 @@ import com.simibubi.create.AllSoundEvents; import com.simibubi.create.Create; import com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock; -import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; import com.simibubi.create.content.contraptions.base.HorizontalAxisKineticBlock; import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock; import com.simibubi.create.content.contraptions.base.KineticTileEntity; @@ -34,12 +33,6 @@ public interface IWrenchable { KineticTileEntity.switchToBlockState(world, context.getClickedPos(), updateAfterWrenched(rotated, context)); - BlockEntity te = context.getLevel() - .getBlockEntity(context.getClickedPos()); - if (te instanceof GeneratingKineticTileEntity) { - ((GeneratingKineticTileEntity) te).reActivateSource = true; - } - if (world.getBlockState(context.getClickedPos()) != state) playRotateSound(world, context.getClickedPos()); diff --git a/src/main/java/com/simibubi/create/content/curiosities/armor/CopperBacktankBlock.java b/src/main/java/com/simibubi/create/content/curiosities/armor/CopperBacktankBlock.java index e2eda105f..a3111d5ba 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/armor/CopperBacktankBlock.java +++ b/src/main/java/com/simibubi/create/content/curiosities/armor/CopperBacktankBlock.java @@ -29,7 +29,6 @@ import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.SimpleWaterloggedBlock; import net.minecraft.world.level.block.entity.BlockEntityType; @@ -63,12 +62,12 @@ public class CopperBacktankBlock extends HorizontalKineticBlock builder.add(BlockStateProperties.WATERLOGGED); super.createBlockStateDefinition(builder); } - + @Override public boolean hasAnalogOutputSignal(BlockState p_149740_1_) { return true; } - + @Override public int getAnalogOutputSignal(BlockState p_180641_1_, Level world, BlockPos pos) { return getTileEntityOptional(world, pos).map(CopperBacktankTileEntity::getComparatorOutput) @@ -78,7 +77,7 @@ public class CopperBacktankBlock extends HorizontalKineticBlock @Override public BlockState updateShape(BlockState state, Direction direction, BlockState neighbourState, LevelAccessor world, BlockPos pos, BlockPos neighbourPos) { - if (state.getValue(BlockStateProperties.WATERLOGGED)) + if (state.getValue(BlockStateProperties.WATERLOGGED)) world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); return state; } @@ -92,7 +91,7 @@ public class CopperBacktankBlock extends HorizontalKineticBlock } @Override - public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) { + public boolean hasShaftTowards(BlockState state, Direction face) { return face == Direction.UP; } @@ -177,7 +176,7 @@ public class CopperBacktankBlock extends HorizontalKineticBlock public Class getTileEntityClass() { return CopperBacktankTileEntity.class; } - + @Override public BlockEntityType getTileEntityType() { return AllTileEntities.COPPER_BACKTANK.get(); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorBlock.java index 875d6462c..ae73ee8fd 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorBlock.java @@ -139,7 +139,7 @@ public class EjectorBlock extends HorizontalKineticBlock implements ITE { + if (dir != WEST && dir != EAST) { + return rotateX(dir); + } + return dir; } - - return dir; - case Y: - if (dir != UP && dir != DOWN) { - return dir.getClockWise(); + case Y -> { + if (dir != UP && dir != DOWN) { + return dir.getClockWise(); + } + return dir; } - - return dir; - case Z: - if (dir != NORTH && dir != SOUTH) { - return rotateZ(dir); + case Z -> { + if (dir != NORTH && dir != SOUTH) { + return rotateZ(dir); + } + return dir; } - - return dir; - default: - throw new IllegalStateException("Unable to get CW facing for axis " + axis); + default -> throw new IllegalStateException("Unable to get CW facing for axis " + axis); } } public static Direction rotateX(Direction dir) { - switch (dir) { - case NORTH: - return DOWN; - case EAST: - case WEST: - default: - throw new IllegalStateException("Unable to get X-rotated facing of " + dir); - case SOUTH: - return UP; - case UP: - return NORTH; - case DOWN: - return SOUTH; - } + return switch (dir) { + case NORTH -> DOWN; + case SOUTH -> UP; + case UP -> NORTH; + case DOWN -> SOUTH; + default -> throw new IllegalStateException("Unable to get X-rotated facing of " + dir); + }; } public static Direction rotateZ(Direction dir) { - switch (dir) { - case EAST: - return DOWN; - case SOUTH: - default: - throw new IllegalStateException("Unable to get Z-rotated facing of " + dir); - case WEST: - return UP; - case UP: - return EAST; - case DOWN: - return WEST; - } + return switch (dir) { + case EAST -> DOWN; + case WEST -> UP; + case UP -> EAST; + case DOWN -> WEST; + default -> throw new IllegalStateException("Unable to get Z-rotated facing of " + dir); + }; } public static Direction getPositivePerpendicular(Axis horizontalAxis) { diff --git a/src/main/java/com/simibubi/create/foundation/utility/Iterate.java b/src/main/java/com/simibubi/create/foundation/utility/Iterate.java index e8e541aa1..124d39602 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/Iterate.java +++ b/src/main/java/com/simibubi/create/foundation/utility/Iterate.java @@ -27,15 +27,19 @@ public class Iterate { } public static Direction[] directionsInAxis(Axis axis) { - switch (axis) { - case X: - return new Direction[] { Direction.EAST, Direction.WEST }; - case Y: - return new Direction[] { Direction.UP, Direction.DOWN }; - default: - case Z: - return new Direction[] { Direction.SOUTH, Direction.NORTH }; - } + return switch (axis) { + case X -> new Direction[]{Direction.EAST, Direction.WEST}; + case Y -> new Direction[]{Direction.UP, Direction.DOWN}; + case Z -> new Direction[]{Direction.SOUTH, Direction.NORTH}; + }; + } + + public static Direction[] directionsPerpendicularTo(Axis axis) { + return switch (axis) { + case X -> new Direction[]{Direction.SOUTH, Direction.DOWN, Direction.NORTH, Direction.UP}; + case Y -> new Direction[]{Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.NORTH}; + case Z -> new Direction[]{Direction.EAST, Direction.UP, Direction.WEST, Direction.DOWN}; + }; } public static List hereAndBelow(BlockPos pos) {