From 3b78ad4da50ebd69fc96a37d4f13a2f84d6f5ad0 Mon Sep 17 00:00:00 2001 From: reidbhuntley Date: Sun, 2 Jan 2022 16:00:44 -0500 Subject: [PATCH] Preparing for The Port --- .../contraptions/RotationPropagator.java | 442 ------------------ .../base/KineticEffectHandler.java | 2 +- .../contraptions/base/KineticTileEntity.java | 118 ++--- .../flywheel/FlywheelTileEntity.java | 2 +- .../structureMovement/Contraption.java | 8 +- .../bearing/ClockworkBearingTileEntity.java | 2 +- .../bearing/MechanicalBearingTileEntity.java | 4 +- .../pulley/PulleyTileEntity.java | 2 +- .../contraptions/fluids/PumpTileEntity.java | 6 +- .../advanced/SpeedControllerTileEntity.java | 9 +- .../SequencedGearshiftTileEntity.java | 4 +- .../relays/encased/GearshiftBlock.java | 7 +- .../relays/gauge/SpeedGaugeTileEntity.java | 2 +- .../relays/gauge/StressGaugeTileEntity.java | 2 +- .../contraptions/solver/KineticNetwork.java | 15 +- .../contraptions/solver/KineticNode.java | 26 +- 16 files changed, 70 insertions(+), 581 deletions(-) delete mode 100644 src/main/java/com/simibubi/create/content/contraptions/RotationPropagator.java diff --git a/src/main/java/com/simibubi/create/content/contraptions/RotationPropagator.java b/src/main/java/com/simibubi/create/content/contraptions/RotationPropagator.java deleted file mode 100644 index 1d94ebf23..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/RotationPropagator.java +++ /dev/null @@ -1,442 +0,0 @@ -package com.simibubi.create.content.contraptions; - -import static net.minecraft.world.level.block.state.properties.BlockStateProperties.AXIS; - -import java.util.LinkedList; -import java.util.List; - -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.content.contraptions.relays.advanced.SpeedControllerBlock; -import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerTileEntity; -import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; -import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel; -import com.simibubi.create.content.contraptions.relays.encased.DirectionalShaftHalvesTileEntity; -import com.simibubi.create.content.contraptions.relays.encased.EncasedBeltBlock; -import com.simibubi.create.content.contraptions.relays.encased.SplitShaftTileEntity; -import com.simibubi.create.content.contraptions.relays.gearbox.GearboxTileEntity; -import com.simibubi.create.foundation.config.AllConfigs; -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.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; - - -public class RotationPropagator { - - private static final int MAX_FLICKER_SCORE = 128; - - /** - * Determines the change in rotation between two attached kinetic entities. For - * instance, an axis connection returns 1 while a 1-to-1 gear connection - * reverses the rotation and therefore returns -1. - * - * @param from - * @param to - * @return - */ - private static float getRotationSpeedModifier(KineticTileEntity from, KineticTileEntity to) { - final BlockState stateFrom = from.getBlockState(); - final BlockState stateTo = to.getBlockState(); - - Block fromBlock = stateFrom.getBlock(); - Block toBlock = stateTo.getBlock(); - if (!(fromBlock instanceof IRotate && toBlock instanceof IRotate)) - return 0; - - final IRotate definitionFrom = (IRotate) fromBlock; - final IRotate definitionTo = (IRotate) toBlock; - final BlockPos diff = to.getBlockPos() - .subtract(from.getBlockPos()); - final Direction direction = Direction.getNearest(diff.getX(), diff.getY(), diff.getZ()); - final Level world = from.getLevel(); - - boolean alignedAxes = true; - for (Axis axis : Axis.values()) - if (axis != direction.getAxis()) - if (axis.choose(diff.getX(), diff.getY(), diff.getZ()) != 0) - alignedAxes = false; - - boolean connectedByAxis = - alignedAxes && definitionFrom.hasShaftTowards(world, from.getBlockPos(), stateFrom, direction) - && definitionTo.hasShaftTowards(world, to.getBlockPos(), stateTo, direction.getOpposite()); - - boolean connectedByGears = ICogWheel.isSmallCog(stateFrom) - && ICogWheel.isSmallCog(stateTo); - - float custom = from.propagateRotationTo(to, stateFrom, stateTo, diff, connectedByAxis, connectedByGears); - if (custom != 0) - return custom; - - // Axis <-> Axis - if (connectedByAxis) { - float axisModifier = getAxisModifier(to, direction.getOpposite()); - if (axisModifier != 0) - axisModifier = 1 / axisModifier; - return getAxisModifier(from, direction) * axisModifier; - } - - // Attached Encased Belts - if (fromBlock instanceof EncasedBeltBlock && toBlock instanceof EncasedBeltBlock) { - boolean connected = EncasedBeltBlock.areBlocksConnected(stateFrom, stateTo, direction); - return connected ? EncasedBeltBlock.getRotationSpeedModifier(from, to) : 0; - } - - // Large Gear <-> Large Gear - if (isLargeToLargeGear(stateFrom, stateTo, diff)) { - Axis sourceAxis = stateFrom.getValue(AXIS); - Axis targetAxis = stateTo.getValue(AXIS); - int sourceAxisDiff = sourceAxis.choose(diff.getX(), diff.getY(), diff.getZ()); - int targetAxisDiff = targetAxis.choose(diff.getX(), diff.getY(), diff.getZ()); - - return sourceAxisDiff > 0 ^ targetAxisDiff > 0 ? -1 : 1; - } - - // Gear <-> Large Gear - if (ICogWheel.isLargeCog(stateFrom) && ICogWheel.isSmallCog(stateTo)) - if (isLargeToSmallCog(stateFrom, stateTo, definitionTo, diff)) - return -2f; - if (ICogWheel.isLargeCog(stateTo) && ICogWheel.isSmallCog(stateFrom)) - if (isLargeToSmallCog(stateTo, stateFrom, definitionFrom, diff)) - return -.5f; - - // Gear <-> Gear - if (connectedByGears) { - if (diff.distManhattan(BlockPos.ZERO) != 1) - return 0; - if (ICogWheel.isLargeCog(stateTo)) - return 0; - if (direction.getAxis() == definitionFrom.getRotationAxis(stateFrom)) - return 0; - if (definitionFrom.getRotationAxis(stateFrom) == definitionTo.getRotationAxis(stateTo)) - return -1; - } - - return 0; - } - - private static float getConveyedSpeed(KineticTileEntity from, KineticTileEntity to) { - final BlockState stateFrom = from.getBlockState(); - final BlockState stateTo = to.getBlockState(); - - // Rotation Speed Controller <-> Large Gear - if (isLargeCogToSpeedController(stateFrom, stateTo, to.getBlockPos() - .subtract(from.getBlockPos()))) - return SpeedControllerTileEntity.getConveyedSpeed(from, to, true); - if (isLargeCogToSpeedController(stateTo, stateFrom, from.getBlockPos() - .subtract(to.getBlockPos()))) - return SpeedControllerTileEntity.getConveyedSpeed(to, from, false); - - float rotationSpeedModifier = getRotationSpeedModifier(from, to); - return from.getTheoreticalSpeed() * rotationSpeedModifier; - } - - private static boolean isLargeToLargeGear(BlockState from, BlockState to, BlockPos diff) { - if (!ICogWheel.isLargeCog(from) || !ICogWheel.isLargeCog(to)) - return false; - Axis fromAxis = from.getValue(AXIS); - Axis toAxis = to.getValue(AXIS); - if (fromAxis == toAxis) - return false; - for (Axis axis : Axis.values()) { - int axisDiff = axis.choose(diff.getX(), diff.getY(), diff.getZ()); - if (axis == fromAxis || axis == toAxis) { - if (axisDiff == 0) - return false; - - } else if (axisDiff != 0) - return false; - } - return true; - } - - private static float getAxisModifier(KineticTileEntity te, Direction direction) { - if (!(te.hasSource()||te.isSource()) || !(te instanceof DirectionalShaftHalvesTileEntity)) - return 1; - Direction source = ((DirectionalShaftHalvesTileEntity) te).getSourceFacing(); - - if (te instanceof GearboxTileEntity) - return direction.getAxis() == source.getAxis() ? direction == source ? 1 : -1 - : direction.getAxisDirection() == source.getAxisDirection() ? -1 : 1; - - if (te instanceof SplitShaftTileEntity) - return ((SplitShaftTileEntity) te).getRotationSpeedModifier(direction); - - return 1; - } - - private static boolean isLargeToSmallCog(BlockState from, BlockState to, IRotate defTo, BlockPos diff) { - Axis axisFrom = from.getValue(AXIS); - if (axisFrom != defTo.getRotationAxis(to)) - return false; - if (axisFrom.choose(diff.getX(), diff.getY(), diff.getZ()) != 0) - return false; - for (Axis axis : Axis.values()) { - if (axis == axisFrom) - continue; - if (Math.abs(axis.choose(diff.getX(), diff.getY(), diff.getZ())) != 1) - return false; - } - return true; - } - - private static boolean isLargeCogToSpeedController(BlockState from, BlockState to, BlockPos diff) { - if (!ICogWheel.isLargeCog(from) || !AllBlocks.ROTATION_SPEED_CONTROLLER.has(to)) - return false; - if (!diff.equals(BlockPos.ZERO.below())) - return false; - Axis axis = from.getValue(CogWheelBlock.AXIS); - if (axis.isVertical()) - return false; - if (to.getValue(SpeedControllerBlock.HORIZONTAL_AXIS) == axis) - return false; - return true; - } - - /** - * Insert the added position to the kinetic network. - * - * @param worldIn - * @param pos - */ - public static void handleAdded(Level worldIn, BlockPos pos, KineticTileEntity addedTE) { -// if (worldIn.isClientSide) -// return; -// if (!worldIn.isLoaded(pos)) -// return; -// propagateNewSource(addedTE); - } - - /** - * Search for sourceless networks attached to the given entity and update them. - * - * @param currentTE - */ - private static void propagateNewSource(KineticTileEntity currentTE) { - BlockPos pos = currentTE.getBlockPos(); - Level world = currentTE.getLevel(); - - for (KineticTileEntity neighbourTE : getConnectedNeighbours(currentTE)) { - float speedOfCurrent = currentTE.getTheoreticalSpeed(); - float speedOfNeighbour = neighbourTE.getTheoreticalSpeed(); - float newSpeed = getConveyedSpeed(currentTE, neighbourTE); - float oppositeSpeed = getConveyedSpeed(neighbourTE, currentTE); - - if (newSpeed == 0 && oppositeSpeed == 0) - continue; - - boolean incompatible = - Math.signum(newSpeed) != Math.signum(speedOfNeighbour) && (newSpeed != 0 && speedOfNeighbour != 0); - - boolean tooFast = Math.abs(newSpeed) > AllConfigs.SERVER.kinetics.maxRotationSpeed.get(); - boolean speedChangedTooOften = currentTE.getFlickerScore() > MAX_FLICKER_SCORE; - if (tooFast || speedChangedTooOften) { - world.destroyBlock(pos, true); - return; - } - - // Opposite directions - if (incompatible) { - world.destroyBlock(pos, true); - return; - - // Same direction: overpower the slower speed - } else { - - // Neighbour faster, overpower the incoming tree - if (Math.abs(oppositeSpeed) > Math.abs(speedOfCurrent)) { - float prevSpeed = currentTE.getSpeed(); - currentTE.setSource(neighbourTE.getBlockPos()); - currentTE.setSpeed(getConveyedSpeed(neighbourTE, currentTE)); - currentTE.onSpeedChanged(prevSpeed); - currentTE.sendData(); - - propagateNewSource(currentTE); - return; - } - - // Current faster, overpower the neighbours' tree - if (Math.abs(newSpeed) >= Math.abs(speedOfNeighbour)) { - - // Do not overpower you own network -> cycle - if (!currentTE.hasNetwork() || currentTE.network.equals(neighbourTE.network)) { - float epsilon = Math.abs(speedOfNeighbour) / 256f / 256f; - if (Math.abs(newSpeed) > Math.abs(speedOfNeighbour) + epsilon) - world.destroyBlock(pos, true); - continue; - } - - if (currentTE.hasSource() && currentTE.source.equals(neighbourTE.getBlockPos())) - currentTE.removeSource(); - - float prevSpeed = neighbourTE.getSpeed(); - neighbourTE.setSource(currentTE.getBlockPos()); - neighbourTE.setSpeed(getConveyedSpeed(currentTE, neighbourTE)); - neighbourTE.onSpeedChanged(prevSpeed); - neighbourTE.sendData(); - propagateNewSource(neighbourTE); - continue; - } - } - - if (neighbourTE.getTheoreticalSpeed() == newSpeed) - continue; - - float prevSpeed = neighbourTE.getSpeed(); - neighbourTE.setSpeed(newSpeed); - neighbourTE.setSource(currentTE.getBlockPos()); - neighbourTE.onSpeedChanged(prevSpeed); - neighbourTE.sendData(); - propagateNewSource(neighbourTE); - - } - } - - /** - * Remove the given entity from the network. - * - * @param worldIn - * @param pos - * @param removedTE - */ - public static void handleRemoved(Level worldIn, BlockPos pos, KineticTileEntity removedTE) { - if (worldIn.isClientSide) - return; - if (removedTE == null) - return; - if (removedTE.getTheoreticalSpeed() == 0) - return; - - for (BlockPos neighbourPos : getPotentialNeighbourLocations(removedTE)) { - BlockState neighbourState = worldIn.getBlockState(neighbourPos); - if (!(neighbourState.getBlock() instanceof IRotate)) - continue; - BlockEntity tileEntity = worldIn.getBlockEntity(neighbourPos); - if (!(tileEntity instanceof KineticTileEntity)) - continue; - - final KineticTileEntity neighbourTE = (KineticTileEntity) tileEntity; - if (!neighbourTE.hasSource() || !neighbourTE.source.equals(pos)) - continue; - - propagateMissingSource(neighbourTE); - } - - } - - /** - * Clear the entire subnetwork depending on the given entity and find a new - * source - * - * @param updateTE - */ - private static void propagateMissingSource(KineticTileEntity updateTE) { - final Level world = updateTE.getLevel(); - - List potentialNewSources = new LinkedList<>(); - List frontier = new LinkedList<>(); - frontier.add(updateTE.getBlockPos()); - BlockPos missingSource = updateTE.hasSource() ? updateTE.source : null; - - while (!frontier.isEmpty()) { - final BlockPos pos = frontier.remove(0); - BlockEntity tileEntity = world.getBlockEntity(pos); - if (!(tileEntity instanceof KineticTileEntity)) - continue; - final KineticTileEntity currentTE = (KineticTileEntity) tileEntity; - - currentTE.removeSource(); - currentTE.sendData(); - - for (KineticTileEntity neighbourTE : getConnectedNeighbours(currentTE)) { - if (neighbourTE.getBlockPos() - .equals(missingSource)) - continue; - if (!neighbourTE.hasSource()) - continue; - - if (!neighbourTE.source.equals(pos)) { - potentialNewSources.add(neighbourTE); - continue; - } - - if (neighbourTE.isSource()) - potentialNewSources.add(neighbourTE); - - frontier.add(neighbourTE.getBlockPos()); - } - } - - for (KineticTileEntity newSource : potentialNewSources) { - if (newSource.hasSource() || newSource.isSource()) { - propagateNewSource(newSource); - return; - } - } - } - - private static KineticTileEntity findConnectedNeighbour(KineticTileEntity currentTE, BlockPos neighbourPos) { - BlockState neighbourState = currentTE.getLevel() - .getBlockState(neighbourPos); - if (!(neighbourState.getBlock() instanceof IRotate)) - return null; - if (!neighbourState.hasBlockEntity()) - return null; - BlockEntity neighbourTE = currentTE.getLevel() - .getBlockEntity(neighbourPos); - if (!(neighbourTE instanceof KineticTileEntity)) - return null; - KineticTileEntity neighbourKTE = (KineticTileEntity) neighbourTE; - if (!(neighbourKTE.getBlockState() - .getBlock() instanceof IRotate)) - return null; - if (!isConnected(currentTE, neighbourKTE) && !isConnected(neighbourKTE, currentTE)) - return null; - return neighbourKTE; - } - - public static boolean isConnected(KineticTileEntity from, KineticTileEntity to) { - final BlockState stateFrom = from.getBlockState(); - final BlockState stateTo = to.getBlockState(); - return isLargeCogToSpeedController(stateFrom, stateTo, to.getBlockPos() - .subtract(from.getBlockPos())) || getRotationSpeedModifier(from, to) != 0 - || from.isCustomConnection(to, stateFrom, stateTo); - } - - private static List getConnectedNeighbours(KineticTileEntity te) { - List neighbours = new LinkedList<>(); - for (BlockPos neighbourPos : getPotentialNeighbourLocations(te)) { - final KineticTileEntity neighbourTE = findConnectedNeighbour(te, neighbourPos); - if (neighbourTE == null) - continue; - - neighbours.add(neighbourTE); - } - return neighbours; - } - - private static List getPotentialNeighbourLocations(KineticTileEntity te) { - List neighbours = new LinkedList<>(); - - if (!te.getLevel() - .isAreaLoaded(te.getBlockPos(), 1)) - return neighbours; - - for (Direction facing : Iterate.directions) - neighbours.add(te.getBlockPos() - .relative(facing)); - - BlockState blockState = te.getBlockState(); - if (!(blockState.getBlock() instanceof IRotate)) - return neighbours; - IRotate block = (IRotate) blockState.getBlock(); - return te.addPropagationLocations(block, blockState, neighbours); - } - -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticEffectHandler.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticEffectHandler.java index 170738eb1..b157787cf 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticEffectHandler.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticEffectHandler.java @@ -34,7 +34,7 @@ public class KineticEffectHandler { if (world.isClientSide) { if (overStressedTime > 0) if (--overStressedTime == 0) - if (kte.isOverStressed()) { + if (kte.isOverstressed()) { overStressedEffect = 1; spawnEffect(ParticleTypes.SMOKE, 0.2f, 5); } else { 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 13e82f913..74820857d 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 @@ -56,10 +56,10 @@ public class KineticTileEntity extends SmartTileEntity public @Nullable BlockPos source = null; protected KineticEffectHandler effects; - protected float speed; + protected float theoreticalSpeed; protected float capacity; protected float stress; - protected boolean overStressed; + protected boolean overstressed; protected boolean wasMoved; private int flickerTally; @@ -224,76 +224,28 @@ public class KineticTileEntity extends SmartTileEntity flickerTally = getFlickerScore() + 5; } - @Override - public void setRemoved() { - super.setRemoved(); + public void onOverstressedChanged(boolean previousOverstressed) { + if (isOverstressed()) + effects.triggerOverStressedEffect(); } @Override protected void write(CompoundTag compound, boolean clientPacket) { - compound.putFloat("Speed", speed); - -// if (needsSpeedUpdate()) -// compound.putBoolean("NeedsSpeedUpdate", true); -// -// if (hasSource()) -// compound.put("Source", NbtUtils.writeBlockPos(source)); - -// if (hasNetwork()) { -// CompoundTag networkTag = new CompoundTag(); -// //networkTag.putLong("Id", this.network); -// networkTag.putFloat("Stress", stress); -// networkTag.putFloat("Capacity", capacity); -// networkTag.putInt("Size", networkSize); -// -// if (lastStressApplied != 0) -// networkTag.putFloat("AddedStress", lastStressApplied); -// if (lastCapacityProvided != 0) -// networkTag.putFloat("AddedCapacity", lastCapacityProvided); -// -// compound.put("Network", networkTag); -// } + if (clientPacket) { + compound.putFloat("Speed", theoreticalSpeed); + compound.putBoolean("Overstressed", overstressed); + } super.write(compound, clientPacket); } -// public boolean needsSpeedUpdate() { -// return updateSpeed; -// } - @Override protected void read(CompoundTag compound, boolean clientPacket) { - //boolean overStressedBefore = overStressed; - //clearKineticInformation(); - - // DO NOT READ kinetic information when placed after movement - //if (wasMoved) { - // super.read(compound, clientPacket); - // return; - //} - if (clientPacket) - speed = compound.getFloat("Speed"); - -// if (compound.contains("Source")) -// source = NbtUtils.readBlockPos(compound.getCompound("Source")); - -// if (compound.contains("Network")) { -// CompoundTag networkTag = compound.getCompound("Network"); -// network = networkTag.getLong("Id"); -// stress = networkTag.getFloat("Stress"); -// capacity = networkTag.getFloat("Capacity"); -// networkSize = networkTag.getInt("Size"); -// lastStressApplied = networkTag.getFloat("AddedStress"); -// lastCapacityProvided = networkTag.getFloat("AddedCapacity"); -// overStressed = capacity < stress && StressImpact.isEnabled(); -// } + updateFromSolver(compound.getFloat("Speed"), compound.getBoolean("Overstressed")); super.read(compound, clientPacket); -// if (clientPacket && overStressedBefore != overStressed && speed != 0) -// effects.triggerOverStressedEffect(); - if (clientPacket) DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> InstancedRenderDispatcher.enqueueUpdate(this)); } @@ -304,20 +256,34 @@ public class KineticTileEntity extends SmartTileEntity } public float getSpeed() { - if (overStressed) - return 0; + if (overstressed) return 0; return getTheoreticalSpeed(); } public float getTheoreticalSpeed() { - return speed; + return theoreticalSpeed; } - public void setSpeed(float speed) { - float prevSpeed = this.speed; - this.speed = speed; - onSpeedChanged(prevSpeed); - sendData(); + public void updateFromSolver(float theoreticalSpeed, boolean overstressed) { + float prevSpeed = getSpeed(); + boolean send = false; + + if (this.theoreticalSpeed != theoreticalSpeed) { + this.theoreticalSpeed = theoreticalSpeed; + send = true; + } + + if (this.overstressed != overstressed) { + this.overstressed = overstressed; + onOverstressedChanged(!overstressed); + send = true; + } + + if (getSpeed() != prevSpeed) + onSpeedChanged(prevSpeed); + + if (send) + sendData(); } public boolean hasSource() { @@ -409,16 +375,6 @@ public class KineticTileEntity extends SmartTileEntity return; } -// KineticTileEntity tileEntity = (KineticTileEntity) tileEntityIn; -// if (state.getBlock() instanceof KineticBlock -// && !((KineticBlock) state.getBlock()).areStatesKineticallyEquivalent(currentState, state)) { -// if (tileEntity.hasNetwork()) -// tileEntity.getOrCreateNetwork() -// .remove(tileEntity); -// tileEntity.detachKinetics(); -// tileEntity.removeSource(); -// } - world.setBlock(pos, state, 3); } @@ -429,7 +385,7 @@ public class KineticTileEntity extends SmartTileEntity public boolean addToTooltip(List tooltip, boolean isPlayerSneaking) { boolean notFastEnough = !isSpeedRequirementFulfilled() && getSpeed() != 0; - if (overStressed && AllConfigs.CLIENT.enableOverstressedTooltip.get()) { + if (overstressed && AllConfigs.CLIENT.enableOverstressedTooltip.get()) { tooltip.add(componentSpacing.plainCopy() .append(Lang.translate("gui.stressometer.overstressed") .withStyle(GOLD))); @@ -487,8 +443,8 @@ public class KineticTileEntity extends SmartTileEntity } public void clearKineticInformation() { - speed = 0; - overStressed = false; + theoreticalSpeed = 0; + overstressed = false; stress = 0; capacity = 0; lastStressApplied = 0; @@ -515,8 +471,8 @@ public class KineticTileEntity extends SmartTileEntity return speed * 3 / 10f; } - public boolean isOverStressed() { - return overStressed; + public boolean isOverstressed() { + return overstressed; } // Custom Propagation diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java index 78a48627a..f27c0ad77 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java @@ -78,7 +78,7 @@ public class FlywheelTileEntity extends GeneratingKineticTileEntity { super.tick(); if (level.isClientSide) { - float targetSpeed = isVirtual() ? speed : getGeneratedSpeed(); + float targetSpeed = isVirtual() ? theoreticalSpeed : getGeneratedSpeed(); visualSpeed.target(targetSpeed); visualSpeed.tick(); angle += visualSpeed.value * 3 / 10f; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 66ad205e5..fb94d1d48 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -874,9 +874,9 @@ public abstract class Contraption { } ListTag paletteNBT = new ListTag(); - for(int i = 0; i < palette.getSize(); ++i) + for(int i = 0; i < palette.getSize(); ++i) paletteNBT.add(NbtUtils.writeBlockState(palette.values.byId(i))); - + compound.put("Palette", paletteNBT); compound.put("BlockList", blockList); @@ -891,7 +891,7 @@ public abstract class Contraption { palette = new HashMapPalette<>(GameData.getBlockStateIDMap(), 16, (i, s) -> { throw new IllegalStateException("Palette Map index exceeded maximum"); }); - + ListTag list = c.getList("Palette", 10); palette.values.clear(); for (int i = 0; i < list.size(); ++i) @@ -926,8 +926,6 @@ public abstract class Contraption { if (te == null) return; te.setLevel(world); - if (te instanceof KineticTileEntity) - ((KineticTileEntity) te).setSpeed(0); te.getBlockState(); if (movementBehaviour == null || !movementBehaviour.hasSpecialInstancedRendering()) 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 633495afc..1ff677797 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 @@ -78,7 +78,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity assembleNextTick = false; if (running) { boolean canDisassemble = true; - if (speed == 0 && (canDisassemble || hourHand == null || hourHand.getContraption() + if (theoreticalSpeed == 0 && (canDisassemble || hourHand == null || hourHand.getContraption() .getBlocks() .isEmpty())) { if (hourHand != null) 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 19d35104a..865387e88 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 @@ -212,7 +212,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity if (running) { boolean canDisassemble = movementMode.get() == RotationMode.ROTATE_PLACE || (isNearInitialAngle() && movementMode.get() == RotationMode.ROTATE_PLACE_RETURNED); - if (speed == 0 && (canDisassemble || movedContraption == null || movedContraption.getContraption() + if (theoreticalSpeed == 0 && (canDisassemble || movedContraption == null || movedContraption.getContraption() .getBlocks() .isEmpty())) { if (movedContraption != null) @@ -222,7 +222,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity return; } } else { - if (speed == 0 && !isWindmill()) + if (theoreticalSpeed == 0 && !isWindmill()) return; assemble(); } 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 265aad167..1fadd8a73 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 (speed == 0) + if (theoreticalSpeed == 0) return; int maxLength = AllConfigs.SERVER.kinetics.maxRopeLength.get(); int i = 1; 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 f8df35193..d6d010680 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 @@ -74,7 +74,7 @@ public class PumpTileEntity extends KineticTileEntity { if (!isVirtual()) return; } - + // if (pressureUpdate) // updatePressureChange(); @@ -100,8 +100,8 @@ public class PumpTileEntity extends KineticTileEntity { if (previousSpeed == getSpeed()) return; - if (speed != 0) - reversed = speed < 0; + if (theoreticalSpeed != 0) + reversed = theoreticalSpeed < 0; if (level.isClientSide && !isVirtual()) return; 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 3ec3b7dfc..33a617bd5 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 @@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.relays.advanced; import java.util.List; -import com.simibubi.create.content.contraptions.RotationPropagator; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.components.motor.CreativeMotorTileEntity; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; @@ -15,7 +14,6 @@ import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueBehaviour; import com.simibubi.create.foundation.utility.Lang; -import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.core.BlockPos; @@ -64,9 +62,10 @@ public class SpeedControllerTileEntity extends KineticTileEntity { @Override public void onUpdate(Level level, KineticSolver solver, KineticNode node) { - solver.getNode(node.getPos().above()) - .filter(n -> node.getActiveStressOnlyConnections().anyMatch(m -> m == n)) - .ifPresent(n -> n.setController(node, KineticControllerSerial.SPEED_CONTROLLER_COG)); + BlockPos above = node.getPos().above(); + if (isStressOnlyConnected(above)) { + solver.getNode(above).get().setController(node, KineticControllerSerial.SPEED_CONTROLLER_COG); + } } public static float getConveyedSpeed(KineticTileEntity cogWheel, KineticTileEntity speedControllerIn, 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 9c595af72..7a39a27f9 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 @@ -42,7 +42,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity { return; if (timer < currentInstructionDuration) { timer++; - currentInstructionProgress += getInstruction(currentInstruction).getTickProgress(speed); + currentInstructionProgress += getInstruction(currentInstruction).getTickProgress(theoreticalSpeed); return; } run(currentInstruction + 1); @@ -53,7 +53,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity { super.onSpeedChanged(previousSpeed); if (isIdle()) return; - float currentSpeed = Math.abs(speed); + float currentSpeed = Math.abs(theoreticalSpeed); if (Math.abs(previousSpeed) == currentSpeed) return; Instruction instruction = getInstruction(currentInstruction); 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 099d2c3f8..7338c0666 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 @@ -3,7 +3,6 @@ package com.simibubi.create.content.contraptions.relays.encased; import java.util.Random; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.content.contraptions.RotationPropagator; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.block.ITE; @@ -58,7 +57,7 @@ public class GearshiftBlock extends AbstractEncasedShaftBlock implements ITE getTileEntityClass() { return SplitShaftTileEntity.class; } - + @Override public BlockEntityType getTileEntityType() { return AllTileEntities.GEARSHIFT.get(); @@ -68,7 +67,7 @@ public class GearshiftBlock extends AbstractEncasedShaftBlock implements ITE onSpeeding, boolean followSource) { + float max = AllConfigs.SERVER.kinetics.maxRotationSpeed.get(); + // update node speeds in a breadth-first order, checking for speeding nodes along the way Set visited = new HashSet<>(); List frontier = new LinkedList<>(); @@ -258,7 +259,7 @@ public class KineticNetwork { if (!members.contains(cur) || visited.contains(cur)) continue; visited.add(cur); - if (cur.tryUpdateSpeed().isOk()) { + if (Math.abs(cur.getSpeed()) <= max) { cur.getActiveConnections() .map(Pair::getFirst) .filter(n -> !followSource || n.getSource() == cur) 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 e44c6c9fa..7a5df1b58 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 @@ -32,8 +32,6 @@ public class KineticNode { private @Nullable KineticNode source; private KineticNetwork network; private float speedRatio = 1; - private float speedCur; - private float speedNext; private final BlockPos pos; private final KineticConnections connections; @@ -114,8 +112,6 @@ public class KineticNode { protected void onLoaded(KineticTileEntity entity) { this.entity = entity; network.onMemberLoaded(this); - if (speedCur != 0) - entity.setSpeed(speedCur); } protected void onUnloaded() { @@ -344,27 +340,9 @@ public class KineticNode { propagateSource(); } - /** - * Updates the speed of this node based on its network's root speed and its own speed ratio. - * @return CONTRADICTION if the node's new speed exceeds the maximum value, and OK otherwise - */ - protected SolveResult tryUpdateSpeed() { - speedNext = getSpeed(); - if (Math.abs(speedNext) > AllConfigs.SERVER.kinetics.maxRotationSpeed.get()) - return SolveResult.CONTRADICTION; - return SolveResult.OK; - } - - protected void stop() { - speedNext = 0; - } - protected void flushChangedSpeed() { - if (speedCur != speedNext) { - speedCur = speedNext; - if (entity != null) { - entity.setSpeed(speedCur); - } + if (entity != null) { + entity.updateFromSolver(getTheoreticalSpeed(), network.isOverstressed()); } }