From b89db104b8226bfe98faed0c4fd225a20277ec3b Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Fri, 6 Mar 2020 17:22:02 +0100 Subject: [PATCH] Rotation validation - Contraptions can no longer speed up themselves when connected in a loop - Components now validate from time to time if they still have a source - Some minor refactoring in KineticTileEntity - Empty networks are now being removed from the network space (fixes memory leak) - Waterwheels no longer differentiate between a slight side-ways flow and a straight flow of water --- .../com/simibubi/create/config/CKinetics.java | 2 + .../modules/contraptions/KineticNetwork.java | 23 +- .../contraptions/RotationPropagator.java | 96 ++--- .../contraptions/TorquePropagator.java | 19 +- .../base/GeneratingKineticTileEntity.java | 131 ++++--- .../contraptions/base/KineticBlock.java | 2 +- .../base/KineticEffectHandler.java | 116 ++++++ .../contraptions/base/KineticTileEntity.java | 329 +++++++----------- .../base/KineticTileEntityRenderer.java | 17 +- .../deployer/DeployerTileEntityRenderer.java | 2 +- .../contraptions/components/saw/SawBlock.java | 2 +- .../waterwheel/WaterWheelBlock.java | 9 +- .../advanced/SpeedControllerTileEntity.java | 9 +- .../contraptions/relays/belt/BeltBlock.java | 4 +- .../relays/belt/BeltConnectorItem.java | 4 +- .../DirectionalShaftHalvesTileEntity.java | 20 ++ .../relays/encased/SplitShaftTileEntity.java | 4 +- .../gauge/GaugeInformationRenderer.java | 26 +- .../relays/gauge/StressGaugeTileEntity.java | 8 + .../relays/gearbox/GearboxTileEntity.java | 4 +- 20 files changed, 460 insertions(+), 367 deletions(-) create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/base/KineticEffectHandler.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/relays/encased/DirectionalShaftHalvesTileEntity.java diff --git a/src/main/java/com/simibubi/create/config/CKinetics.java b/src/main/java/com/simibubi/create/config/CKinetics.java index 1b7a77325..da34eb94d 100644 --- a/src/main/java/com/simibubi/create/config/CKinetics.java +++ b/src/main/java/com/simibubi/create/config/CKinetics.java @@ -10,6 +10,7 @@ public class CKinetics extends ConfigBase { public ConfigInt maxRotationSpeed = i(256, 64, "maxRotationSpeed", Comments.rpm, Comments.maxRotationSpeed); public ConfigEnum ignoreDeployerAttacks = e(DeployerAggroSetting.CREEPERS, "ignoreDeployerAttacks", Comments.ignoreDeployerAttacks); + public ConfigInt kineticValidationFrequency = i(60, 5, "kineticValidationFrequency", Comments.kineticValidationFrequency); public ConfigGroup fan = group(0, "encasedFan", "Encased Fan"); public ConfigInt fanPushDistance = i(20, 5, "fanPushDistance", Comments.fanPushDistance); @@ -71,6 +72,7 @@ public class CKinetics extends ConfigBase { static String ignoreDeployerAttacks = "Select what mobs should ignore Deployers when attacked by them."; static String waterWheelSpeed = "Rotation speed gained by a water wheel for each side with running water. (halved if not against blades)"; static String disableStress = "Disable the Stress mechanic altogether."; + static String kineticValidationFrequency = "Game ticks between Kinetic Blocks checking whether their source is still valid."; } public static enum DeployerAggroSetting { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java b/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java index 0e2a39c8d..07195fb7f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java @@ -25,9 +25,9 @@ public class KineticNetwork { members = new HashMap<>(); } - public void initFromTE(KineticTileEntity te) { - unloadedStressCapacity = te.maxStress; - unloadedStress = te.currentStress; + public void initFromTE(float maxStress, float currentStress) { + unloadedStressCapacity = maxStress; + unloadedStress = currentStress; initialized = true; updateStress(); updateStressCapacity(); @@ -42,16 +42,13 @@ public class KineticNetwork { sources.put(te, capacity); } float stressApplied = te.getStressApplied(); - unloadedStress -= stressApplied * getStressMultiplierForSpeed(te.speed); + unloadedStress -= stressApplied * getStressMultiplierForSpeed(te.getTheoreticalSpeed()); members.put(te, stressApplied); } public void add(KineticTileEntity te) { if (members.containsKey(te)) return; - -// Debug.debugChatAndShowStack(te.getType().getRegistryName().getPath() + " added to Network", 5); - if (te.isSource()) { sources.put(te, te.getAddedStressCapacity()); updateStressCapacity(); @@ -75,9 +72,6 @@ public class KineticNetwork { public void remove(KineticTileEntity te) { if (!members.containsKey(te)) return; - -// Debug.debugChat(te.getType().getRegistryName().getPath() + " removed from Network"); - if (te.isSource()) { sources.remove(te); updateStressCapacity(); @@ -86,6 +80,9 @@ public class KineticNetwork { members.remove(te); updateStress(); sync(); + + if (members.isEmpty()) + TorquePropagator.networks.get(te.getWorld()).remove(this.id); } public void sync() { @@ -101,21 +98,17 @@ public class KineticNetwork { if (maxStress != newMaxStress) { maxStress = newMaxStress; sync(); -// Debug.debugChatAndShowStack("Current Stress level: " + currentStress + "/" + maxStress, 5); } - } public void updateStress() { float presentStress = 0; - for (KineticTileEntity te : members.keySet()) - presentStress += members.get(te) * getStressMultiplierForSpeed(te.speed); + presentStress += members.get(te) * getStressMultiplierForSpeed(te.getTheoreticalSpeed()); float newStress = presentStress + unloadedStress; if (currentStress != newStress) { currentStress = newStress; sync(); -// Debug.debugChatAndShowStack("Current Stress level: " + currentStress + "/" + maxStress, 5); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java index 52199ded6..ed690cc4e 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java @@ -14,6 +14,7 @@ import com.simibubi.create.modules.contraptions.base.IRotate; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.relays.advanced.SpeedControllerTileEntity; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; +import com.simibubi.create.modules.contraptions.relays.encased.DirectionalShaftHalvesTileEntity; import com.simibubi.create.modules.contraptions.relays.encased.EncasedBeltBlock; import com.simibubi.create.modules.contraptions.relays.encased.SplitShaftTileEntity; import com.simibubi.create.modules.contraptions.relays.gearbox.GearboxTileEntity; @@ -52,9 +53,9 @@ public class RotationPropagator { if (axis.getCoordinate(diff.getX(), diff.getY(), diff.getZ()) != 0) alignedAxes = false; - boolean connectedByAxis = alignedAxes - && definitionFrom.hasShaftTowards(world, from.getPos(), stateFrom, direction) - && definitionTo.hasShaftTowards(world, to.getPos(), stateTo, direction.getOpposite()); + boolean connectedByAxis = + alignedAxes && definitionFrom.hasShaftTowards(world, from.getPos(), stateFrom, direction) + && definitionTo.hasShaftTowards(world, to.getPos(), stateTo, direction.getOpposite()); boolean connectedByGears = definitionFrom.hasCogsTowards(world, from.getPos(), stateFrom, direction) && definitionTo.hasCogsTowards(world, to.getPos(), stateTo, direction.getOpposite()); @@ -130,9 +131,9 @@ public class RotationPropagator { } private static float getAxisModifier(KineticTileEntity te, Direction direction) { - if (!te.hasSource()) + if (!te.hasSource() || !(te instanceof DirectionalShaftHalvesTileEntity)) return 1; - Direction source = te.getSourceFacing(); + Direction source = ((DirectionalShaftHalvesTileEntity) te).getSourceFacing(); if (te instanceof GearboxTileEntity) return direction.getAxis() == source.getAxis() ? direction == source ? 1 : -1 @@ -180,7 +181,7 @@ public class RotationPropagator { return; if (!worldIn.isBlockPresent(pos)) return; - if (addedTE.speed != 0) { + if (addedTE.getTheoreticalSpeed() != 0) { propagateNewSource(addedTE); return; } @@ -188,16 +189,17 @@ public class RotationPropagator { for (KineticTileEntity neighbourTE : getConnectedNeighbours(addedTE)) { final float speedModifier = getRotationSpeedModifier(neighbourTE, addedTE); - if (neighbourTE.speed == 0) + float neighbourSpeed = neighbourTE.getTheoreticalSpeed(); + if (neighbourSpeed == 0) continue; if (neighbourTE.hasSource() && neighbourTE.getSource().equals(addedTE.getPos())) { - addedTE.setSpeed(neighbourTE.speed * speedModifier); + addedTE.setSpeed(neighbourSpeed * speedModifier); addedTE.onSpeedChanged(0); addedTE.sendData(); continue; } - addedTE.setSpeed(neighbourTE.speed * speedModifier); + addedTE.setSpeed(neighbourSpeed * speedModifier); addedTE.setSource(neighbourTE.getPos()); addedTE.onSpeedChanged(0); addedTE.sendData(); @@ -209,23 +211,25 @@ public class RotationPropagator { /** * Search for sourceless networks attached to the given entity and update them. * - * @param updateTE + * @param currentTE */ - private static void propagateNewSource(KineticTileEntity updateTE) { - BlockPos pos = updateTE.getPos(); - World world = updateTE.getWorld(); + private static void propagateNewSource(KineticTileEntity currentTE) { + BlockPos pos = currentTE.getPos(); + World world = currentTE.getWorld(); - for (KineticTileEntity neighbourTE : getConnectedNeighbours(updateTE)) { - float modFromTo = getRotationSpeedModifier(updateTE, neighbourTE); - float modToFrom = getRotationSpeedModifier(neighbourTE, updateTE); - final float newSpeed = updateTE.speed * modFromTo; - float oppositeSpeed = neighbourTE.speed * modToFrom; + for (KineticTileEntity neighbourTE : getConnectedNeighbours(currentTE)) { + float modFromTo = getRotationSpeedModifier(currentTE, neighbourTE); + float modToFrom = getRotationSpeedModifier(neighbourTE, currentTE); + float speedOfCurrent = currentTE.getTheoreticalSpeed(); + float speedOfNeighbour = neighbourTE.getTheoreticalSpeed(); + float newSpeed = speedOfCurrent * modFromTo; + float oppositeSpeed = speedOfNeighbour * modToFrom; - boolean incompatible = Math.signum(newSpeed) != Math.signum(neighbourTE.speed) - && (newSpeed != 0 && neighbourTE.speed != 0); + boolean incompatible = + Math.signum(newSpeed) != Math.signum(speedOfNeighbour) && (newSpeed != 0 && speedOfNeighbour != 0); boolean tooFast = Math.abs(newSpeed) > AllConfigs.SERVER.kinetics.maxRotationSpeed.get(); - boolean speedChangedTooOften = updateTE.speedChangeCounter > MAX_FLICKER_SCORE; + boolean speedChangedTooOften = currentTE.getFlickerScore() > MAX_FLICKER_SCORE; if (tooFast || speedChangedTooOften) { world.destroyBlock(pos, true); return; @@ -238,43 +242,45 @@ public class RotationPropagator { } else { // Same direction: overpower the slower speed - if (Math.abs(oppositeSpeed) > Math.abs(updateTE.speed)) { + if (Math.abs(oppositeSpeed) > Math.abs(speedOfCurrent)) { // Neighbour faster, overpower the incoming tree - updateTE.setSource(neighbourTE.getPos()); - float prevSpeed = updateTE.getSpeed(); - updateTE.setSpeed(neighbourTE.speed * getRotationSpeedModifier(neighbourTE, updateTE)); - updateTE.onSpeedChanged(prevSpeed); - updateTE.sendData(); + currentTE.setSource(neighbourTE.getPos()); + float prevSpeed = currentTE.getSpeed(); + currentTE.setSpeed(speedOfNeighbour * getRotationSpeedModifier(neighbourTE, currentTE)); + currentTE.onSpeedChanged(prevSpeed); + currentTE.sendData(); - propagateNewSource(updateTE); + propagateNewSource(currentTE); return; } - if (Math.abs(newSpeed) >= Math.abs(neighbourTE.speed)) { - if (Math.abs(newSpeed) > Math.abs(neighbourTE.speed) || updateTE.newNetworkID != null - && !updateTE.newNetworkID.equals(neighbourTE.newNetworkID)) { - // Current faster, overpower the neighbours' tree - if (updateTE.hasSource() && updateTE.getSource().equals(neighbourTE.getPos())) { - updateTE.removeSource(); - } - - neighbourTE.setSource(updateTE.getPos()); - float prevSpeed = neighbourTE.getSpeed(); - neighbourTE.setSpeed(updateTE.speed * getRotationSpeedModifier(updateTE, neighbourTE)); - neighbourTE.onSpeedChanged(prevSpeed); - neighbourTE.sendData(); - propagateNewSource(neighbourTE); + // Current faster, overpower the neighbours' tree + if (Math.abs(newSpeed) >= Math.abs(speedOfNeighbour)) { + if (!currentTE.canOverPower(neighbourTE)) { + if (Math.abs(newSpeed) > Math.abs(speedOfNeighbour)) + world.destroyBlock(pos, true); + continue; } + + if (currentTE.hasSource() && currentTE.getSource().equals(neighbourTE.getPos())) + currentTE.removeSource(); + + neighbourTE.setSource(currentTE.getPos()); + float prevSpeed = neighbourTE.getSpeed(); + neighbourTE.setSpeed(speedOfCurrent * getRotationSpeedModifier(currentTE, neighbourTE)); + neighbourTE.onSpeedChanged(prevSpeed); + neighbourTE.sendData(); + propagateNewSource(neighbourTE); continue; } } - if (neighbourTE.speed == newSpeed) + if (neighbourTE.getTheoreticalSpeed() == newSpeed) continue; float prevSpeed = neighbourTE.getSpeed(); neighbourTE.setSpeed(newSpeed); - neighbourTE.setSource(updateTE.getPos()); + neighbourTE.setSource(currentTE.getPos()); neighbourTE.onSpeedChanged(prevSpeed); neighbourTE.sendData(); propagateNewSource(neighbourTE); @@ -294,7 +300,7 @@ public class RotationPropagator { return; if (removedTE == null) return; - if (removedTE.speed == 0) + if (removedTE.getTheoreticalSpeed() == 0) return; for (BlockPos neighbourPos : getPotentialNeighbourLocations(removedTE)) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/TorquePropagator.java b/src/main/java/com/simibubi/create/modules/contraptions/TorquePropagator.java index 3305b659c..7d8db5e48 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/TorquePropagator.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/TorquePropagator.java @@ -27,22 +27,15 @@ public class TorquePropagator { UUID id = te.getNetworkID(); KineticNetwork network; Map map = networks.get(te.getWorld()); - if (id == null) { + if (id == null) + return null; + + if (!map.containsKey(id)) { network = new KineticNetwork(); - -// Debug.debugChatAndShowStack(te.getType().getRegistryName().getPath() + " created new Network", 5); - - te.newNetworkID = network.id; - te.updateNetwork = true; + network.id = te.getNetworkID(); map.put(id, network); - } else { - if (!map.containsKey(id)) { - network = new KineticNetwork(); - network.id = te.getNetworkID(); - map.put(id, network); - } - network = map.get(id); } + network = map.get(id); return network; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java index 199a3060a..d41c85e4b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java @@ -1,14 +1,17 @@ package com.simibubi.create.modules.contraptions.base; -import java.util.Optional; import java.util.UUID; +import com.simibubi.create.modules.contraptions.KineticNetwork; import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel; import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.math.BlockPos; public abstract class GeneratingKineticTileEntity extends KineticTileEntity { + public boolean reActivateSource; + public GeneratingKineticTileEntity(TileEntityType typeIn) { super(typeIn); } @@ -18,68 +21,108 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity { } @Override - public void reActivateSource() { - updateGeneratedRotation(); + public void removeSource() { + if (hasSource() && isSource()) + reActivateSource = true; + super.removeSource(); + } + + @Override + public void setSource(BlockPos source) { + super.setSource(source); + KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source); + if (reActivateSource && sourceTe != null && Math.abs(sourceTe.getSpeed()) >= Math.abs(getGeneratedSpeed())) + reActivateSource = false; + } + + @Override + public void tick() { + super.tick(); + if (reActivateSource) { + updateGeneratedRotation(); + reActivateSource = false; + } } public void updateGeneratedRotation() { float speed = getGeneratedSpeed(); float prevSpeed = this.speed; - if (this.speed != speed) { + if (world.isRemote) + return; - if (!world.isRemote) { + if (prevSpeed != speed) { + if (!hasSource()) { SpeedLevel levelBefore = SpeedLevel.of(this.speed); SpeedLevel levelafter = SpeedLevel.of(speed); if (levelBefore != levelafter) - queueRotationIndicators(); + effects.queueRotationIndicators(); } - if (speed == 0) { - if (hasSource()) - notifyStressCapacityChange(0); - else { - detachKinetics(); - setSpeed(speed); - newNetworkID = null; - updateNetwork = true; - } - } else if (this.speed == 0) { - setSpeed(speed); - newNetworkID = UUID.randomUUID(); - updateNetwork = true; - attachKinetics(); - } else { - if (hasSource()) { - if (Math.abs(this.speed) >= Math.abs(speed)) { - if (Math.signum(this.speed) == Math.signum(speed)) - notifyStressCapacityChange(getAddedStressCapacity()); - else - world.destroyBlock(pos, true); - } else { - detachKinetics(); - setSpeed(speed); - source = Optional.empty(); - newNetworkID = UUID.randomUUID(); - updateNetwork = true; - attachKinetics(); - } - } else { - detachKinetics(); - setSpeed(speed); - attachKinetics(); - } - } + applyNewSpeed(prevSpeed, speed); } if (hasNetwork() && speed != 0) { - getNetwork().updateCapacityFor(this, getAddedStressCapacity()); - getNetwork().updateStressCapacity(); - getNetwork().updateStress(); + KineticNetwork network = getNetwork(); + network.updateCapacityFor(this, getAddedStressCapacity()); + network.updateStress(); } onSpeedChanged(prevSpeed); sendData(); } + public void applyNewSpeed(float prevSpeed, float speed) { + + // Speed changed to 0 + if (speed == 0) { + if (hasSource() && hasNetwork()) { + getNetwork().updateCapacityFor(this, 0); + return; + } + detachKinetics(); + setSpeed(speed); + newNetworkID = null; + updateNetwork = true; + return; + } + + // Now turning - create a new Network + if (prevSpeed == 0) { + setSpeed(speed); + newNetworkID = UUID.randomUUID(); + updateNetwork = true; + attachKinetics(); + return; + } + + // Change speed when overpowered by other generator + if (hasSource() && hasNetwork()) { + + // Staying below Overpowered speed + if (Math.abs(prevSpeed) >= Math.abs(speed)) { + if (Math.signum(prevSpeed) != Math.signum(speed)) { + world.destroyBlock(pos, true); + return; + } + getNetwork().updateCapacityFor(this, getAddedStressCapacity()); + return; + } + + // Faster than attached network -> become the new source + detachKinetics(); + setSpeed(speed); + source = null; + newNetworkID = UUID.randomUUID(); + updateNetwork = true; + attachKinetics(); + return; + } + + // Reapply source + detachKinetics(); + setSpeed(speed); + attachKinetics(); + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java index 4fe29a070..ff6fbcd80 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java @@ -112,7 +112,7 @@ public abstract class KineticBlock extends Block implements IRotate { return; KineticTileEntity kte = (KineticTileEntity) tileEntity; - kte.queueRotationIndicators(); + kte.effects.queueRotationIndicators(); } public float getParticleTargetRadius() { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticEffectHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticEffectHandler.java new file mode 100644 index 000000000..bbb3d3c71 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticEffectHandler.java @@ -0,0 +1,116 @@ +package com.simibubi.create.modules.contraptions.base; + +import java.util.Random; + +import com.simibubi.create.foundation.advancement.AllTriggers; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel; +import com.simibubi.create.modules.contraptions.particle.RotationIndicatorParticleData; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.particles.IParticleData; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; + +public class KineticEffectHandler { + + int overStressedTime; + float overStressedEffect; + int particleSpawnCountdown; + KineticTileEntity kte; + + public KineticEffectHandler(KineticTileEntity kte) { + this.kte = kte; + } + + public void tick() { + World world = kte.getWorld(); + + if (world.isRemote) { + if (overStressedTime > 0) + if (--overStressedTime == 0) + if (kte.overStressed) { + overStressedEffect = 1; + spawnEffect(ParticleTypes.SMOKE, 0.2f, 5); + } else { + overStressedEffect = -1; + spawnEffect(ParticleTypes.CLOUD, .075f, 2); + } + + if (overStressedEffect != 0) { + overStressedEffect -= overStressedEffect * .1f; + if (Math.abs(overStressedEffect) < 1 / 128f) + overStressedEffect = 0; + } + + } else if (particleSpawnCountdown > 0) { + if (--particleSpawnCountdown == 0) + spawnRotationIndicators(); + } + } + + public void queueRotationIndicators() { + particleSpawnCountdown = 2; + } + + public void spawnEffect(IParticleData particle, float maxMotion, int amount) { + World world = kte.getWorld(); + if (world == null) + return; + if (!world.isRemote) + return; + Random r = world.rand; + for (int i = 0; i < amount; i++) { + Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, r, maxMotion); + Vec3d position = VecHelper.getCenterOf(kte.getPos()); + world.addParticle(particle, position.x, position.y, position.z, motion.x, motion.y, motion.z); + } + } + + public void spawnRotationIndicators() { + float speed = kte.getSpeed(); + if (speed == 0) + return; + + BlockState state = kte.getBlockState(); + Block block = state.getBlock(); + if (!(block instanceof KineticBlock)) + return; + + KineticBlock kb = (KineticBlock) block; + float radius1 = kb.getParticleInitialRadius(); + float radius2 = kb.getParticleTargetRadius(); + + Axis axis = kb.getRotationAxis(state); + BlockPos pos = kte.getPos(); + World world = kte.getWorld(); + if (axis == null) + return; + if (world == null) + return; + + char axisChar = axis.name().charAt(0); + Vec3d vec = VecHelper.getCenterOf(pos); + SpeedLevel speedLevel = SpeedLevel.of(speed); + int color = speedLevel.getColor(); + int particleSpeed = speedLevel.getParticleSpeed(); + particleSpeed *= Math.signum(speed); + + if (world instanceof ServerWorld) { + AllTriggers.triggerForNearbyPlayers(AllTriggers.ROTATION, world, pos, 5); + RotationIndicatorParticleData particleData = + new RotationIndicatorParticleData(color, particleSpeed, radius1, radius2, 10, axisChar); + ((ServerWorld) world).spawnParticle(particleData, vec.x, vec.y, vec.z, 20, 0, 0, 0, 1); + } + } + + public void triggerOverStressedEffect() { + overStressedTime = overStressedTime == 0 ? 2 : 0; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java index 4184e508a..9712edc14 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java @@ -1,12 +1,7 @@ package com.simibubi.create.modules.contraptions.base; -import static net.minecraft.util.text.TextFormatting.GREEN; -import static net.minecraft.util.text.TextFormatting.WHITE; - import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.Random; import java.util.UUID; import com.simibubi.create.Create; @@ -14,60 +9,113 @@ import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; -import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.KineticNetwork; import com.simibubi.create.modules.contraptions.RotationPropagator; import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel; import com.simibubi.create.modules.contraptions.base.IRotate.StressImpact; -import com.simibubi.create.modules.contraptions.particle.RotationIndicatorParticleData; -import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.NBTUtil; -import net.minecraft.particles.IParticleData; -import net.minecraft.particles.ParticleTypes; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntityType; -import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.ForgeConfigSpec.ConfigValue; public abstract class KineticTileEntity extends SmartTileEntity implements ITickableTileEntity { - int particleSpawnCountdown; + protected UUID networkID; + protected UUID newNetworkID; + protected float maxStress; + protected float currentStress; + protected boolean updateNetwork; - // Speed related - public float speed; - protected Optional source; - public boolean reActivateSource; - public int speedChangeCounter; - - // Torque related - public float maxStress; - public float currentStress; + protected KineticEffectHandler effects; + protected BlockPos source; + protected float speed; protected boolean overStressed; - public UUID networkID; - public UUID newNetworkID; - public boolean updateNetwork; protected boolean initNetwork; - // Client - int overStressedTime; - float overStressedEffect; + private int flickerTally; + private int validationCountdown; public KineticTileEntity(TileEntityType typeIn) { super(typeIn); - speed = 0; - source = Optional.empty(); + effects = new KineticEffectHandler(this); } @Override - public void addBehaviours(List behaviours) { + public void tick() { + super.tick(); + effects.tick(); + + if (world.isRemote) + return; + + if (validationCountdown-- <= 0) { + validationCountdown = AllConfigs.SERVER.kinetics.kineticValidationFrequency.get(); + validateKinetics(); + } + + if (getFlickerScore() > 0) + flickerTally = getFlickerScore() - 1; + + if (initNetwork) { + initNetwork = false; + + KineticNetwork network = getNetwork(); + if (!network.initialized) + network.initFromTE(maxStress, currentStress); + network.addSilently(this); + } + + if (updateNetwork) { + updateNetwork = false; + + if (hasNetwork() && !networkID.equals(newNetworkID)) { + getNetwork().remove(this); + networkID = null; + maxStress = currentStress = 0; + overStressed = false; + } + + if (newNetworkID != null) { + networkID = newNetworkID; + KineticNetwork network = getNetwork(); + network.initialized = true; + network.add(this); + } + + sendData(); + } + } + + private void validateKinetics() { + if (hasSource()) { + if (!world.isBlockPresent(source)) + return; + + KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source); + if (sourceTe == null || sourceTe.speed == 0) { + removeSource(); + detachKinetics(); + return; + } + + if (hasNetwork() && maxStress == 0) { + for (KineticTileEntity kineticTileEntity : getNetwork().members.keySet()) + kineticTileEntity.removeSource(); + return; + } + + return; + } + + if (speed != 0) { + if (getGeneratedSpeed() == 0) + setSpeed(0); + } } public void sync(float maxStress, float currentStress) { @@ -100,46 +148,35 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick return stressEntries.get(path).get().floatValue(); } - protected void notifyStressChange(float stress) { - getNetwork().updateStressFor(this, stress); - } - - @Override - public boolean hasFastRenderer() { - return true; - } - public void onSpeedChanged(float previousSpeed) { boolean fromOrToZero = (previousSpeed == 0) != (getSpeed() == 0); boolean directionSwap = !fromOrToZero && Math.signum(previousSpeed) != Math.signum(getSpeed()); if (fromOrToZero || directionSwap) { - speedChangeCounter += 5; + flickerTally = getFlickerScore() + 5; } } @Override public void remove() { - if (world.isRemote) { - super.remove(); - return; + if (!world.isRemote) { + if (hasNetwork()) + getNetwork().remove(this); + detachKinetics(); } - if (hasNetwork()) { - getNetwork().remove(this); - } - RotationPropagator.handleRemoved(getWorld(), getPos(), this); super.remove(); } @Override public CompoundNBT write(CompoundNBT compound) { compound.putFloat("Speed", speed); + if (hasSource()) - compound.put("Source", NBTUtil.writeBlockPos(getSource())); + compound.put("Source", NBTUtil.writeBlockPos(source)); if (hasNetwork()) { compound.putFloat("MaxStress", maxStress); compound.putFloat("Stress", currentStress); - compound.put("Id", NBTUtil.writeUniqueId(getNetworkID())); + compound.put("Id", NBTUtil.writeUniqueId(networkID)); } return super.write(compound); @@ -147,23 +184,21 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick @Override public void read(CompoundNBT compound) { - setSpeed(compound.getFloat("Speed")); - setSource(null); - if (compound.contains("Source")) { - CompoundNBT tagSource = compound.getCompound("Source"); - setSource(NBTUtil.readBlockPos(tagSource)); - } + speed = compound.getFloat("Speed"); + source = null; + networkID = newNetworkID = null; + overStressed = false; + + if (compound.contains("Source")) + source = NBTUtil.readBlockPos(compound.getCompound("Source")); if (compound.contains("Id")) { maxStress = compound.getFloat("MaxStress"); currentStress = compound.getFloat("Stress"); overStressed = maxStress < currentStress && StressImpact.isEnabled(); - setNetworkID(NBTUtil.readUniqueId(compound.getCompound("Id"))); + networkID = NBTUtil.readUniqueId(compound.getCompound("Id")); newNetworkID = networkID; initNetwork = true; - } else { - networkID = newNetworkID = null; - overStressed = false; } super.read(compound); @@ -174,7 +209,7 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick boolean overStressedBefore = overStressed; super.readClientUpdate(tag); if (overStressedBefore != overStressed && speed != 0) - overStressedTime = overStressedTime == 0 ? 2 : 0; + effects.triggerOverStressedEffect(); } public boolean isSource() { @@ -184,6 +219,10 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick public float getSpeed() { if (overStressed) return 0; + return getTheoreticalSpeed(); + } + + public float getTheoreticalSpeed() { return speed; } @@ -196,31 +235,22 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick } public boolean hasSource() { - return source.isPresent(); + return source != null; } public BlockPos getSource() { - return source.get(); - } - - public Direction getSourceFacing() { - BlockPos source = getSource().subtract(getPos()); - return Direction.getFacingFromVector(source.getX(), source.getY(), source.getZ()); + return source; } public void setSource(BlockPos source) { - this.source = Optional.ofNullable(source); - + this.source = source; if (world == null || world.isRemote) return; - if (source == null) - return; - KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source); - if (sourceTe == null) - return; - if (reActivateSource && Math.abs(sourceTe.getSpeed()) >= Math.abs(getGeneratedSpeed())) { - reActivateSource = false; + KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source); + if (sourceTe == null) { + removeSource(); + return; } newNetworkID = sourceTe.newNetworkID; @@ -228,10 +258,7 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick } public void removeSource() { - if (hasSource() && isSource()) - reActivateSource = true; - - this.source = Optional.empty(); + source = null; newNetworkID = null; updateNetwork = true; float prevSpeed = getSpeed(); @@ -247,10 +274,8 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick return networkID != null; } - public void applyNewSpeed(float speed) { - detachKinetics(); - this.speed = speed; - attachKinetics(); + public boolean canOverPower(KineticTileEntity other) { + return newNetworkID != null && !newNetworkID.equals(other.newNetworkID); } public void attachKinetics() { @@ -269,79 +294,6 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick this.networkID = networkID; } - /** - * Callback for source blocks to re-apply their speed when an overpowering - * source is removed - */ - public void reActivateSource() { - - } - - @Override - public void tick() { - super.tick(); - - if (world.isRemote) { - if (overStressedTime > 0) - if (--overStressedTime == 0) - if (overStressed) { - overStressedEffect = 1; - spawnEffect(ParticleTypes.SMOKE, 0.2f, 5); - } else { - overStressedEffect = -1; - spawnEffect(ParticleTypes.CLOUD, .075f, 2); - } - - if (overStressedEffect != 0) { - overStressedEffect -= overStressedEffect * .1f; - if (Math.abs(overStressedEffect) < 1 / 128f) - overStressedEffect = 0; - } - return; - } - - if (speedChangeCounter > 0) - speedChangeCounter--; - - if (particleSpawnCountdown > 0) - if (--particleSpawnCountdown == 0) - spawnRotationIndicators(); - - if (initNetwork) { - initNetwork = false; - - KineticNetwork network = getNetwork(); - if (!network.initialized) - network.initFromTE(this); - network.addSilently(this); - } - - if (updateNetwork) { - updateNetwork = false; - - if (hasNetwork() && !networkID.equals(newNetworkID)) { - getNetwork().remove(this); - networkID = null; - maxStress = currentStress = 0; - overStressed = false; - } - - if (newNetworkID != null) { - networkID = newNetworkID; - KineticNetwork network = getNetwork(); - network.initialized = true; - network.add(this); - } - - sendData(); - } - - if (reActivateSource) { - reActivateSource(); - reActivateSource = false; - } - } - public boolean isSpeedRequirementFulfilled() { BlockState state = getBlockState(); if (!(getBlockState().getBlock() instanceof IRotate)) @@ -357,60 +309,17 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick return true; } - public void addDebugInformation(List lines) { - lines.add("Speed: " + GREEN + speed); - lines.add("Cost: " + GREEN + getStressApplied() + WHITE + "/" + GREEN + getAddedStressCapacity()); - lines.add("Stress: " + GREEN + currentStress + WHITE + "/" + GREEN + maxStress); + @Override + public void addBehaviours(List behaviours) { } - public void queueRotationIndicators() { - // wait a few ticks for network jamming etc - particleSpawnCountdown = 2; + @Override + public boolean hasFastRenderer() { + return true; } - protected void spawnEffect(IParticleData particle, float maxMotion, int amount) { - if (!hasWorld()) - return; - if (!world.isRemote) - return; - Random r = getWorld().rand; - for (int i = 0; i < amount; i++) { - Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, r, maxMotion); - Vec3d position = VecHelper.getCenterOf(pos); - this.getWorld().addParticle(particle, position.x, position.y, position.z, motion.x, motion.y, motion.z); - } - } - - protected void spawnRotationIndicators() { - if (getSpeed() == 0) - return; - - BlockState state = getBlockState(); - Block block = state.getBlock(); - if (!(block instanceof KineticBlock)) - return; - - KineticBlock kb = (KineticBlock) block; - float radius1 = kb.getParticleInitialRadius(); - float radius2 = kb.getParticleTargetRadius(); - - Axis axis = kb.getRotationAxis(state); - if (axis == null) - return; - char axisChar = axis.name().charAt(0); - Vec3d vec = VecHelper.getCenterOf(pos); - - SpeedLevel speedLevel = SpeedLevel.of(getSpeed()); - int color = speedLevel.getColor(); - int particleSpeed = speedLevel.getParticleSpeed(); - particleSpeed *= Math.signum(getSpeed()); - - if (getWorld() instanceof ServerWorld) { - AllTriggers.triggerForNearbyPlayers(AllTriggers.ROTATION, world, pos, 5); - RotationIndicatorParticleData particleData = - new RotationIndicatorParticleData(color, particleSpeed, radius1, radius2, 10, axisChar); - ((ServerWorld) getWorld()).spawnParticle(particleData, vec.x, vec.y, vec.z, 20, 0, 0, 0, 1); - } + public int getFlickerScore() { + return flickerTally; } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java index 99a637713..822d3f176 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java @@ -24,8 +24,8 @@ public class KineticTileEntityRenderer extends SafeTileEntityRendererFast 0) - buffer.color(ColorHelper.mixColors(white, 0xFF0000, te.overStressedEffect)); + float overStressedEffect = te.effects.overStressedEffect; + if (overStressedEffect != 0) + if (overStressedEffect > 0) + buffer.color(ColorHelper.mixColors(white, 0xFF0000, overStressedEffect)); else - buffer.color(ColorHelper.mixColors(white, 0x00FFBB, -te.overStressedEffect)); + buffer.color(ColorHelper.mixColors(white, 0x00FFBB, -overStressedEffect)); else buffer.color(white); } @@ -97,5 +98,5 @@ public class KineticTileEntityRenderer extends SafeTileEntityRendererFast { if (te.getSpeed() == 0) return; - entityIn.attackEntityFrom(damageSourceSaw, MathHelper.clamp(Math.abs(te.speed / 512f) + 1, 0, 20)); + entityIn.attackEntityFrom(damageSourceSaw, MathHelper.clamp(Math.abs(te.getSpeed() / 512f) + 1, 0, 20)); }); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/waterwheel/WaterWheelBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/waterwheel/WaterWheelBlock.java index 61c56fcf4..fcbb899d8 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/waterwheel/WaterWheelBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/waterwheel/WaterWheelBlock.java @@ -68,7 +68,7 @@ public class WaterWheelBlock extends HorizontalKineticBlock { public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { updateAllSides(state, worldIn, pos); } - + public void updateAllSides(BlockState state, World worldIn, BlockPos pos) { for (Direction d : Direction.values()) updateFlowAt(state, worldIn, pos, d); @@ -88,7 +88,8 @@ public class WaterWheelBlock extends HorizontalKineticBlock { flowVec = flowVec.scale(f.getAxisDirection().getOffset()); boolean clockwise = wf.getAxisDirection() == AxisDirection.POSITIVE; - int clockwiseMultiplier = 2; + int clockwiseMultiplier = 2; + flowVec = new Vec3d(Math.signum(flowVec.x), Math.signum(flowVec.y), Math.signum(flowVec.z)); if (wf.getAxis() == Axis.Z) { if (f.getAxis() == Axis.Y) @@ -149,10 +150,10 @@ public class WaterWheelBlock extends HorizontalKineticBlock { public float getParticleInitialRadius() { return 1f; } - + @Override public boolean hideStressImpact() { return true; } - + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/SpeedControllerTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/SpeedControllerTileEntity.java index d67bf4d6d..f2074d455 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/SpeedControllerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/SpeedControllerTileEntity.java @@ -65,12 +65,13 @@ public class SpeedControllerTileEntity extends KineticTileEntity { if (targetSpeed == 0) return 0; - if (targetingController && cogWheel.speed == 0) + float wheelSpeed = cogWheel.getTheoreticalSpeed(); + if (targetingController && wheelSpeed == 0) return 1; if (!speedController.hasSource()) { if (targetingController) - return targetSpeed / cogWheel.speed; + return targetSpeed / wheelSpeed; return 1; } @@ -78,8 +79,8 @@ public class SpeedControllerTileEntity extends KineticTileEntity { if (wheelPowersController) { if (targetingController) - return targetSpeed / cogWheel.speed; - return cogWheel.speed / targetSpeed; + return targetSpeed / wheelSpeed; + return wheelSpeed / targetSpeed; } if (targetingController) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java index e3f9140e3..c6610426a 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java @@ -347,7 +347,7 @@ public class BeltBlock extends HorizontalKineticBlock implements IHaveNoBlockIte return; BeltTileEntity beltEntity = (BeltTileEntity) tileEntity; BlockPos controller = beltEntity.getController(); - beltEntity.setSource(null); + beltEntity.removeSource(); beltEntity.remove(); int limit = 1000; @@ -368,7 +368,7 @@ public class BeltBlock extends HorizontalKineticBlock implements IHaveNoBlockIte inv.eject(stack); } - te.setSource(null); + te.removeSource(); te.remove(); if (destroyedBlock.get(CASING)) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltConnectorItem.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltConnectorItem.java index 6bba3385b..b972397ce 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltConnectorItem.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltConnectorItem.java @@ -194,8 +194,8 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther { if (axis != world.getBlockState(second).get(BlockStateProperties.AXIS)) return false; - float speed1 = ((KineticTileEntity) world.getTileEntity(first)).speed; - float speed2 = ((KineticTileEntity) world.getTileEntity(second)).speed; + float speed1 = ((KineticTileEntity) world.getTileEntity(first)).getTheoreticalSpeed(); + float speed2 = ((KineticTileEntity) world.getTileEntity(second)).getTheoreticalSpeed(); if (Math.signum(speed1) != Math.signum(speed2) && speed1 != 0 && speed2 != 0) return false; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/DirectionalShaftHalvesTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/DirectionalShaftHalvesTileEntity.java new file mode 100644 index 000000000..005159c40 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/DirectionalShaftHalvesTileEntity.java @@ -0,0 +1,20 @@ +package com.simibubi.create.modules.contraptions.relays.encased; + +import com.simibubi.create.modules.contraptions.base.KineticTileEntity; + +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; + +public class DirectionalShaftHalvesTileEntity extends KineticTileEntity { + + public DirectionalShaftHalvesTileEntity(TileEntityType typeIn) { + super(typeIn); + } + + public Direction getSourceFacing() { + BlockPos source = getSource().subtract(getPos()); + return Direction.getFacingFromVector(source.getX(), source.getY(), source.getZ()); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/SplitShaftTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/SplitShaftTileEntity.java index e3fd8e2b3..ed0a4cabc 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/SplitShaftTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/SplitShaftTileEntity.java @@ -1,11 +1,9 @@ package com.simibubi.create.modules.contraptions.relays.encased; -import com.simibubi.create.modules.contraptions.base.KineticTileEntity; - import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; -public abstract class SplitShaftTileEntity extends KineticTileEntity { +public abstract class SplitShaftTileEntity extends DirectionalShaftHalvesTileEntity { public SplitShaftTileEntity(TileEntityType typeIn) { super(typeIn); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/GaugeInformationRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/GaugeInformationRenderer.java index c61856a1e..6304d6757 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/GaugeInformationRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/GaugeInformationRenderer.java @@ -133,13 +133,14 @@ public class GaugeInformationRenderer { String _generatorStatsTitle = Lang.translate("gui.goggles.generator_stats"); String _capacityProvided = Lang.translate("tooltip.capacityProvided"); - if (te.speed != te.getGeneratedSpeed() && te.speed != 0) - addedStressCapacity *= (te.getGeneratedSpeed() / te.speed); + float speed = te.getTheoreticalSpeed(); + if (speed != te.getGeneratedSpeed() && speed != 0) + addedStressCapacity *= (te.getGeneratedSpeed() / speed); tooltip.add(spacing + _generatorStatsTitle); tooltip.add(spacing + GRAY + _capacityProvided); - float actualSpeed = Math.abs(te.speed); + float actualSpeed = Math.abs(speed); float relativeCap = 0; if (actualSpeed != 0) relativeCap = addedStressCapacity * actualSpeed; @@ -176,8 +177,8 @@ public class GaugeInformationRenderer { } StressGaugeTileEntity stressGauge = (StressGaugeTileEntity) te; List stressLevels = Lang.translatedOptions("tooltip.stressImpact", "low", "medium", "high"); - double stress = stressGauge.currentStress; - double cap = stressGauge.maxStress; + double stress = stressGauge.getNetworkStress(); + double cap = stressGauge.getNetworkCapacity(); double relStress = stress / (cap == 0 ? 1 : cap); StressImpact impactId = relStress > 1 ? null : (relStress > .75f) ? StressImpact.HIGH @@ -199,17 +200,17 @@ public class GaugeInformationRenderer { level += " (" + (int) (relStress * 100) + "%)"; - float actualSpeed = stressGauge.speed; - if (actualSpeed == 0) + float theoreticalSpeed = stressGauge.getTheoreticalSpeed(); + if (theoreticalSpeed == 0) level = DARK_GRAY + ItemDescription.makeProgressBar(3, -1) + _noRotation; tooltip.add(spacing + GRAY + _stressGaugeTitle); tooltip.add(spacing + level); - if (actualSpeed != 0) { + if (theoreticalSpeed != 0) { tooltip.add(spacing + GRAY + _capacity); - String capacity = color + "" + format((cap - stress) / Math.abs(actualSpeed)) + _stressUnit + " " + String capacity = color + "" + format((cap - stress) / Math.abs(theoreticalSpeed)) + _stressUnit + " " + DARK_GRAY + _atCurrentSpeed; String capacityAtBase = GRAY + "" + format(cap - stress) + _stressUnit + " " + DARK_GRAY + _baseValue; tooltip.add(spacing + " " + capacity); @@ -221,9 +222,10 @@ public class GaugeInformationRenderer { if (!(te instanceof SpeedGaugeTileEntity)) return; SpeedGaugeTileEntity speedGauge = (SpeedGaugeTileEntity) te; - boolean overstressed = speedGauge.currentStress > speedGauge.maxStress && speedGauge.speed != 0; + float speed = speedGauge.getTheoreticalSpeed(); + boolean overstressed = speedGauge.getSpeed() == 0 && speed != 0; - SpeedLevel speedLevel = SpeedLevel.of(speedGauge.speed); + SpeedLevel speedLevel = SpeedLevel.of(speed); String color = speedLevel.getTextColor() + ""; if (overstressed) color = DARK_GRAY + "" + TextFormatting.STRIKETHROUGH; @@ -232,7 +234,7 @@ public class GaugeInformationRenderer { int index = speedLevel.ordinal(); String level = color + ItemDescription.makeProgressBar(3, index) + (speedLevel != SpeedLevel.NONE ? speedLevels.get(index) : ""); - level += " (" + format(Math.abs(speedGauge.speed)) + "" + _rpmUnit + ") "; + level += " (" + format(Math.abs(speed)) + "" + _rpmUnit + ") "; tooltip.add(spacing + GRAY + _speedGaugeTitle); tooltip.add(spacing + level); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/StressGaugeTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/StressGaugeTileEntity.java index 51f0bdb44..fac69932c 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/StressGaugeTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/StressGaugeTileEntity.java @@ -43,5 +43,13 @@ public class StressGaugeTileEntity extends GaugeTileEntity { else sync(maxStress, currentStress); } + + public float getNetworkStress() { + return currentStress; + } + + public float getNetworkCapacity() { + return maxStress; + } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/gearbox/GearboxTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/gearbox/GearboxTileEntity.java index 37a7f5823..8ec0d84de 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/gearbox/GearboxTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/gearbox/GearboxTileEntity.java @@ -1,9 +1,9 @@ package com.simibubi.create.modules.contraptions.relays.gearbox; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.modules.contraptions.relays.encased.DirectionalShaftHalvesTileEntity; -public class GearboxTileEntity extends KineticTileEntity { +public class GearboxTileEntity extends DirectionalShaftHalvesTileEntity { public GearboxTileEntity() { super(AllTileEntities.GEARBOX.type);