diff --git a/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java b/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java index ee2f195e2..a16b143f3 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java @@ -62,11 +62,15 @@ public class ColorHelper { int b = color & 0xFF; return new Vec3d(r, g, b).scale(1 / 256d); } - + public static int colorFromUUID(UUID uuid) { if (uuid == null) return 0x333333; - int rainbowColor = ColorHelper.rainbowColor((int) uuid.getLeastSignificantBits()); + return colorFromLong(uuid.getLeastSignificantBits()); + } + + public static int colorFromLong(long l) { + int rainbowColor = ColorHelper.rainbowColor(String.valueOf(l).hashCode()); return ColorHelper.mixColors(rainbowColor, 0xFFFFFF, .5f); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/KineticDebugger.java b/src/main/java/com/simibubi/create/modules/contraptions/KineticDebugger.java index 54bfd52d8..683895639 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/KineticDebugger.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/KineticDebugger.java @@ -25,7 +25,7 @@ public class KineticDebugger { return; World world = Minecraft.getInstance().world; - BlockPos toOutline = te.hasSource() ? te.getSource() : te.getPos(); + BlockPos toOutline = te.hasSource() ? te.source : te.getPos(); VoxelShape shape = world.getBlockState(toOutline).getShape(world, toOutline); TessellatorHelper.prepareForDrawing(); 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 07195fb7f..9d9b85679 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java @@ -2,35 +2,32 @@ package com.simibubi.create.modules.contraptions; import java.util.HashMap; import java.util.Map; -import java.util.UUID; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; public class KineticNetwork { - public UUID id; + public Long id; public boolean initialized; - - private float maxStress; - private float currentStress; - - private float unloadedStressCapacity; - private float unloadedStress; public Map sources; public Map members; + private float currentCapacity; + private float currentStress; + private float unloadedCapacity; + private float unloadedStress; + public KineticNetwork() { - id = UUID.randomUUID(); sources = new HashMap<>(); members = new HashMap<>(); } public void initFromTE(float maxStress, float currentStress) { - unloadedStressCapacity = maxStress; + unloadedCapacity = maxStress; unloadedStress = currentStress; initialized = true; updateStress(); - updateStressCapacity(); + updateCapacity(); } public void addSilently(KineticTileEntity te) { @@ -38,7 +35,7 @@ public class KineticNetwork { return; if (te.isSource()) { float capacity = te.getAddedStressCapacity(); - unloadedStressCapacity -= capacity * getStressMultiplierForSpeed(te.getGeneratedSpeed()); + unloadedCapacity -= capacity * getStressMultiplierForSpeed(te.getGeneratedSpeed()); sources.put(te, capacity); } float stressApplied = te.getStressApplied(); @@ -49,19 +46,16 @@ public class KineticNetwork { public void add(KineticTileEntity te) { if (members.containsKey(te)) return; - if (te.isSource()) { + if (te.isSource()) sources.put(te, te.getAddedStressCapacity()); - updateStressCapacity(); - } - members.put(te, te.getStressApplied()); - updateStress(); - sync(); + te.updateStressFromNetwork(currentCapacity, currentStress); + te.networkDirty = true; } public void updateCapacityFor(KineticTileEntity te, float capacity) { sources.put(te, capacity); - updateStressCapacity(); + updateCapacity(); } public void updateStressFor(KineticTileEntity te, float stress) { @@ -72,46 +66,66 @@ public class KineticNetwork { public void remove(KineticTileEntity te) { if (!members.containsKey(te)) return; - if (te.isSource()) { + if (te.isSource()) sources.remove(te); - updateStressCapacity(); + members.remove(te); + te.updateStressFromNetwork(0, 0); + + if (members.isEmpty()) { + TorquePropagator.networks.get(te.getWorld()).remove(this.id); + return; } - members.remove(te); - updateStress(); - sync(); - - if (members.isEmpty()) - TorquePropagator.networks.get(te.getWorld()).remove(this.id); + members.keySet().stream().findFirst().map(member -> member.networkDirty = true); } public void sync() { for (KineticTileEntity te : members.keySet()) - te.sync(maxStress, currentStress); + te.updateStressFromNetwork(currentCapacity, currentStress); } - public void updateStressCapacity() { - float presentCapacity = 0; - for (KineticTileEntity te : sources.keySet()) - presentCapacity += sources.get(te) * getStressMultiplierForSpeed(te.getGeneratedSpeed()); - float newMaxStress = presentCapacity + unloadedStressCapacity; - if (maxStress != newMaxStress) { - maxStress = newMaxStress; + public void updateCapacity() { + float newMaxStress = calculateCapacity(); + if (currentCapacity != newMaxStress) { + currentCapacity = newMaxStress; sync(); } } public void updateStress() { - float presentStress = 0; - for (KineticTileEntity te : members.keySet()) - presentStress += members.get(te) * getStressMultiplierForSpeed(te.getTheoreticalSpeed()); - float newStress = presentStress + unloadedStress; + float newStress = calculateStress(); if (currentStress != newStress) { currentStress = newStress; sync(); } } + public void updateNetwork() { + float newStress = calculateStress(); + float newMaxStress = calculateCapacity(); + if (currentStress != newStress || currentCapacity != newMaxStress) { + currentStress = newStress; + currentCapacity = newMaxStress; + sync(); + } + } + + public float calculateCapacity() { + float presentCapacity = 0; + for (KineticTileEntity te : sources.keySet()) + presentCapacity += sources.get(te) * getStressMultiplierForSpeed(te.getGeneratedSpeed()); + float newMaxStress = presentCapacity + unloadedCapacity; + return newMaxStress; + } + + public float calculateStress() { + float presentStress = 0; + for (KineticTileEntity te : members.keySet()) + presentStress += members.get(te) * getStressMultiplierForSpeed(te.getTheoreticalSpeed()); + float newStress = presentStress + unloadedStress; + return newStress; + } + private float getStressMultiplierForSpeed(float speed) { return Math.abs(speed); } 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 ed690cc4e..7afedea6f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java @@ -192,7 +192,7 @@ public class RotationPropagator { float neighbourSpeed = neighbourTE.getTheoreticalSpeed(); if (neighbourSpeed == 0) continue; - if (neighbourTE.hasSource() && neighbourTE.getSource().equals(addedTE.getPos())) { + if (neighbourTE.hasSource() && neighbourTE.source.equals(addedTE.getPos())) { addedTE.setSpeed(neighbourSpeed * speedModifier); addedTE.onSpeedChanged(0); addedTE.sendData(); @@ -235,18 +235,19 @@ public class RotationPropagator { return; } + // Opposite directions if (incompatible) { - // Opposite directions world.destroyBlock(pos, true); return; - } else { // Same direction: overpower the slower speed + } else { + + // Neighbour faster, overpower the incoming tree if (Math.abs(oppositeSpeed) > Math.abs(speedOfCurrent)) { - // Neighbour faster, overpower the incoming tree - currentTE.setSource(neighbourTE.getPos()); float prevSpeed = currentTE.getSpeed(); currentTE.setSpeed(speedOfNeighbour * getRotationSpeedModifier(neighbourTE, currentTE)); + currentTE.setSource(neighbourTE.getPos()); currentTE.onSpeedChanged(prevSpeed); currentTE.sendData(); @@ -256,18 +257,20 @@ public class RotationPropagator { // Current faster, overpower the neighbours' tree if (Math.abs(newSpeed) >= Math.abs(speedOfNeighbour)) { - if (!currentTE.canOverPower(neighbourTE)) { + + // Do not overpower you own network -> cycle + if (!currentTE.hasNetwork() || currentTE.network.equals(neighbourTE.network)) { if (Math.abs(newSpeed) > Math.abs(speedOfNeighbour)) world.destroyBlock(pos, true); continue; } - - if (currentTE.hasSource() && currentTE.getSource().equals(neighbourTE.getPos())) + + if (currentTE.hasSource() && currentTE.source.equals(neighbourTE.getPos())) currentTE.removeSource(); - neighbourTE.setSource(currentTE.getPos()); float prevSpeed = neighbourTE.getSpeed(); neighbourTE.setSpeed(speedOfCurrent * getRotationSpeedModifier(currentTE, neighbourTE)); + neighbourTE.setSource(currentTE.getPos()); neighbourTE.onSpeedChanged(prevSpeed); neighbourTE.sendData(); propagateNewSource(neighbourTE); @@ -309,7 +312,7 @@ public class RotationPropagator { continue; final KineticTileEntity neighbourTE = (KineticTileEntity) worldIn.getTileEntity(neighbourPos); - if (!neighbourTE.hasSource() || !neighbourTE.getSource().equals(pos)) + if (!neighbourTE.hasSource() || !neighbourTE.source.equals(pos)) continue; propagateMissingSource(neighbourTE); @@ -329,7 +332,7 @@ public class RotationPropagator { List potentialNewSources = new LinkedList<>(); List frontier = new LinkedList<>(); frontier.add(updateTE.getPos()); - BlockPos missingSource = updateTE.hasSource() ? updateTE.getSource() : null; + BlockPos missingSource = updateTE.hasSource() ? updateTE.source : null; while (!frontier.isEmpty()) { final BlockPos pos = frontier.remove(0); @@ -344,7 +347,7 @@ public class RotationPropagator { if (!neighbourTE.hasSource()) continue; - if (!neighbourTE.getSource().equals(pos)) { + if (!neighbourTE.source.equals(pos)) { potentialNewSources.add(neighbourTE); continue; } 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 7d8db5e48..3e83ab772 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/TorquePropagator.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/TorquePropagator.java @@ -2,7 +2,6 @@ package com.simibubi.create.modules.contraptions; import java.util.HashMap; import java.util.Map; -import java.util.UUID; import com.simibubi.create.Create; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; @@ -11,7 +10,7 @@ import net.minecraft.world.IWorld; public class TorquePropagator { - static Map> networks = new HashMap<>(); + static Map> networks = new HashMap<>(); public void onLoadWorld(IWorld world) { networks.put(world, new HashMap<>()); @@ -24,15 +23,15 @@ public class TorquePropagator { } public KineticNetwork getNetworkFor(KineticTileEntity te) { - UUID id = te.getNetworkID(); + Long id = te.network; KineticNetwork network; - Map map = networks.get(te.getWorld()); + Map map = networks.get(te.getWorld()); if (id == null) return null; if (!map.containsKey(id)) { network = new KineticNetwork(); - network.id = te.getNetworkID(); + network.id = te.network; map.put(id, network); } network = map.get(id); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/DirectionalAxisKineticBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/base/DirectionalAxisKineticBlock.java index 16bba1fbb..1b59c7226 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/DirectionalAxisKineticBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/DirectionalAxisKineticBlock.java @@ -90,13 +90,7 @@ public abstract class DirectionalAxisKineticBlock extends DirectionalKineticBloc World world = context.getWorld(); Direction face = context.getFace(); if ((turnBackOnWrenched() ? face.getOpposite() : face) == state.get(FACING)) { - if (!world.isRemote) { - BlockPos pos = context.getPos(); - world.removeTileEntity(pos); - world.setBlockState(pos, state.cycle(AXIS_ALONG_FIRST_COORDINATE), 3); - KineticTileEntity tileEntity = (KineticTileEntity) world.getTileEntity(pos); - tileEntity.attachKinetics(); - } + KineticTileEntity.switchToBlockState(world, context.getPos(), state.cycle(AXIS_ALONG_FIRST_COORDINATE)); return ActionResultType.SUCCESS; } return super.onWrenched(state, context); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/DirectionalKineticBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/base/DirectionalKineticBlock.java index 6e1f816b8..6edcd6c93 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/DirectionalKineticBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/DirectionalKineticBlock.java @@ -11,7 +11,6 @@ import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Mirror; import net.minecraft.util.Rotation; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public abstract class DirectionalKineticBlock extends KineticBlock { @@ -56,14 +55,7 @@ public abstract class DirectionalKineticBlock extends KineticBlock { BlockState with = state.with(FACING, facing); if (!with.isValidPosition(world, context.getPos())) return ActionResultType.PASS; - - if (!world.isRemote) { - BlockPos pos = context.getPos(); - world.removeTileEntity(pos); - world.setBlockState(pos, with, 3); - KineticTileEntity tileEntity = (KineticTileEntity) world.getTileEntity(pos); - tileEntity.attachKinetics(); - } + KineticTileEntity.switchToBlockState(world, context.getPos(), with); return ActionResultType.SUCCESS; } 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 d41c85e4b..64d937b9b 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,7 +1,5 @@ package com.simibubi.create.modules.contraptions.base; -import java.util.UUID; - import com.simibubi.create.modules.contraptions.KineticNetwork; import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel; @@ -17,7 +15,7 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity { } protected void notifyStressCapacityChange(float capacity) { - getNetwork().updateCapacityFor(this, capacity); + getOrCreateNetwork().updateCapacityFor(this, capacity); } @Override @@ -63,8 +61,9 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity { } if (hasNetwork() && speed != 0) { - KineticNetwork network = getNetwork(); - network.updateCapacityFor(this, getAddedStressCapacity()); + KineticNetwork network = getOrCreateNetwork(); + notifyStressCapacityChange(getAddedStressCapacity()); + getOrCreateNetwork().updateStressFor(this, getStressApplied()); network.updateStress(); } @@ -76,36 +75,32 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity { // Speed changed to 0 if (speed == 0) { - if (hasSource() && hasNetwork()) { - getNetwork().updateCapacityFor(this, 0); + if (hasSource()) { + notifyStressCapacityChange(0); + getOrCreateNetwork().updateStressFor(this, getStressApplied()); return; } detachKinetics(); - setSpeed(speed); - newNetworkID = null; - updateNetwork = true; + setSpeed(0); + setNetwork(null); return; } // Now turning - create a new Network if (prevSpeed == 0) { setSpeed(speed); - newNetworkID = UUID.randomUUID(); - updateNetwork = true; + setNetwork(createNetworkId()); attachKinetics(); return; } // Change speed when overpowered by other generator - if (hasSource() && hasNetwork()) { + if (hasSource()) { // Staying below Overpowered speed if (Math.abs(prevSpeed) >= Math.abs(speed)) { - if (Math.signum(prevSpeed) != Math.signum(speed)) { + if (Math.signum(prevSpeed) != Math.signum(speed)) world.destroyBlock(pos, true); - return; - } - getNetwork().updateCapacityFor(this, getAddedStressCapacity()); return; } @@ -113,8 +108,7 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity { detachKinetics(); setSpeed(speed); source = null; - newNetworkID = UUID.randomUUID(); - updateNetwork = true; + setNetwork(createNetworkId()); attachKinetics(); return; } @@ -125,4 +119,8 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity { attachKinetics(); } + public Long createNetworkId() { + return pos.toLong(); + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java index 921edff95..939a2b83b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java @@ -1,7 +1,5 @@ package com.simibubi.create.modules.contraptions.base; -import com.simibubi.create.modules.contraptions.RotationPropagator; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.item.BlockItemUseContext; @@ -79,16 +77,7 @@ public abstract class HorizontalAxisKineticBlock extends KineticBlock { World world = context.getWorld(); if (facing.getAxis() == state.get(HORIZONTAL_AXIS)) return ActionResultType.PASS; - if (!world.isRemote) { - BlockPos pos = context.getPos(); - KineticTileEntity tileEntity = (KineticTileEntity) world.getTileEntity(pos); - if (tileEntity.hasNetwork()) - tileEntity.getNetwork().remove(tileEntity); - RotationPropagator.handleRemoved(world, pos, tileEntity); - tileEntity.removeSource(); - world.setBlockState(pos, state.cycle(HORIZONTAL_AXIS), 3); - tileEntity.attachKinetics(); - } + KineticTileEntity.switchToBlockState(world, context.getPos(), state.cycle(HORIZONTAL_AXIS)); return ActionResultType.SUCCESS; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalKineticBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalKineticBlock.java index 538dbdd77..fbe62e2f5 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalKineticBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalKineticBlock.java @@ -11,7 +11,6 @@ import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Mirror; import net.minecraft.util.Rotation; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public abstract class HorizontalKineticBlock extends KineticBlock { @@ -61,13 +60,7 @@ public abstract class HorizontalKineticBlock extends KineticBlock { World world = context.getWorld(); if (facing == state.get(HORIZONTAL_FACING)) return ActionResultType.PASS; - if (!world.isRemote) { - BlockPos pos = context.getPos(); - world.removeTileEntity(pos); - world.setBlockState(pos, state.with(HORIZONTAL_FACING, facing), 3); - KineticTileEntity tileEntity = (KineticTileEntity) world.getTileEntity(pos); - tileEntity.attachKinetics(); - } + KineticTileEntity.switchToBlockState(world, context.getPos(), state.with(HORIZONTAL_FACING, facing)); return ActionResultType.SUCCESS; } 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 ff6fbcd80..215172baa 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 @@ -27,7 +27,7 @@ public abstract class KineticBlock extends Block implements IRotate { public KineticBlock(Properties properties) { super(properties); } - + @Override public ToolType getHarvestTool(BlockState state) { return null; @@ -38,10 +38,10 @@ public abstract class KineticBlock extends Block implements IRotate { for (ToolType toolType : player.getHeldItemMainhand().getToolTypes()) { if (isToolEffective(state, toolType)) return true; - } + } return super.canHarvestBlock(state, world, pos, player); } - + @Override public boolean isToolEffective(BlockState state, ToolType tool) { return tool == ToolType.AXE || tool == ToolType.PICKAXE; @@ -79,6 +79,20 @@ public abstract class KineticBlock extends Block implements IRotate { @Override public abstract TileEntity createTileEntity(BlockState state, IBlockReader world); + @Override + public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { + if (isMoving) { + KineticTileEntity tileEntity = (KineticTileEntity) worldIn.getTileEntity(pos); + if (tileEntity == null) + return; + if (worldIn.isRemote()) + return; + tileEntity.network = null; + tileEntity.source = null; + tileEntity.speed = 0; + } + } + @SuppressWarnings("deprecation") @Override public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) { 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 9712edc14..6e547118c 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 @@ -2,7 +2,8 @@ package com.simibubi.create.modules.contraptions.base; import java.util.List; import java.util.Map; -import java.util.UUID; + +import javax.annotation.Nullable; import com.simibubi.create.Create; import com.simibubi.create.config.AllConfigs; @@ -18,24 +19,24 @@ import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.NBTUtil; import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import net.minecraftforge.common.ForgeConfigSpec.ConfigValue; public abstract class KineticTileEntity extends SmartTileEntity implements ITickableTileEntity { - protected UUID networkID; - protected UUID newNetworkID; - protected float maxStress; - protected float currentStress; - protected boolean updateNetwork; + public @Nullable Long network; + public @Nullable BlockPos source; + public boolean networkDirty; protected KineticEffectHandler effects; - protected BlockPos source; protected float speed; + protected float capacity; + protected float stress; protected boolean overStressed; - protected boolean initNetwork; private int flickerTally; private int validationCountdown; @@ -45,6 +46,18 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick effects = new KineticEffectHandler(this); } + @Override + public void initialize() { + super.initialize(); + if (!hasNetwork()) + return; + + KineticNetwork network = getOrCreateNetwork(); + if (!network.initialized) + network.initFromTE(capacity, stress); + network.addSilently(this); + } + @Override public void tick() { super.tick(); @@ -61,33 +74,10 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick 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(); + if (networkDirty) { + if (hasNetwork()) + getOrCreateNetwork().updateNetwork(); + networkDirty = false; } } @@ -103,25 +93,21 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick return; } - if (hasNetwork() && maxStress == 0) { - for (KineticTileEntity kineticTileEntity : getNetwork().members.keySet()) - kineticTileEntity.removeSource(); - return; - } - return; } if (speed != 0) { if (getGeneratedSpeed() == 0) - setSpeed(0); + speed = 0; } } - public void sync(float maxStress, float currentStress) { - this.maxStress = maxStress; - this.currentStress = currentStress; + public void updateStressFromNetwork(float maxStress, float currentStress) { + networkDirty = false; + this.capacity = maxStress; + this.stress = currentStress; boolean overStressed = maxStress < currentStress && StressImpact.isEnabled(); + if (overStressed != this.overStressed) { if (speed != 0 && overStressed) AllTriggers.triggerForNearbyPlayers(AllTriggers.OVERSTRESSED, world, pos, 8); @@ -160,7 +146,7 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick public void remove() { if (!world.isRemote) { if (hasNetwork()) - getNetwork().remove(this); + getOrCreateNetwork().remove(this); detachKinetics(); } super.remove(); @@ -174,9 +160,11 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick compound.put("Source", NBTUtil.writeBlockPos(source)); if (hasNetwork()) { - compound.putFloat("MaxStress", maxStress); - compound.putFloat("Stress", currentStress); - compound.put("Id", NBTUtil.writeUniqueId(networkID)); + CompoundNBT networkTag = new CompoundNBT(); + networkTag.putLong("Id", network); + networkTag.putFloat("Stress", stress); + networkTag.putFloat("Capacity", capacity); + compound.put("Network", networkTag); } return super.write(compound); @@ -185,20 +173,22 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick @Override public void read(CompoundNBT compound) { speed = compound.getFloat("Speed"); + source = null; - networkID = newNetworkID = null; + network = null; overStressed = false; + stress = 0; + capacity = 0; 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(); - networkID = NBTUtil.readUniqueId(compound.getCompound("Id")); - newNetworkID = networkID; - initNetwork = true; + if (compound.contains("Network")) { + CompoundNBT networkTag = compound.getCompound("Network"); + network = networkTag.getLong("Id"); + stress = networkTag.getFloat("Stress"); + capacity = networkTag.getFloat("Capacity"); + overStressed = capacity < stress && StressImpact.isEnabled(); } super.read(compound); @@ -212,6 +202,10 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick effects.triggerOverStressedEffect(); } + public float getGeneratedSpeed() { + return 0; + } + public boolean isSource() { return getGeneratedSpeed() != 0; } @@ -226,10 +220,6 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick return speed; } - public float getGeneratedSpeed() { - return 0; - } - public void setSpeed(float speed) { this.speed = speed; } @@ -238,10 +228,6 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick return source != null; } - public BlockPos getSource() { - return source; - } - public void setSource(BlockPos source) { this.source = source; if (world == null || world.isRemote) @@ -253,29 +239,42 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick return; } - newNetworkID = sourceTe.newNetworkID; - updateNetwork = true; + setNetwork(sourceTe.network); } public void removeSource() { - source = null; - newNetworkID = null; - updateNetwork = true; float prevSpeed = getSpeed(); - setSpeed(0); + + speed = 0; + source = null; + setNetwork(null); + onSpeedChanged(prevSpeed); } - public KineticNetwork getNetwork() { + public void setNetwork(@Nullable Long networkIn) { + if (network == networkIn) + return; + if (network != null) + getOrCreateNetwork().remove(this); + + network = networkIn; + + if (networkIn == null) + return; + + network = networkIn; + KineticNetwork network = getOrCreateNetwork(); + network.initialized = true; + network.add(this); + } + + public KineticNetwork getOrCreateNetwork() { return Create.torquePropagator.getNetworkFor(this); } public boolean hasNetwork() { - return networkID != null; - } - - public boolean canOverPower(KineticTileEntity other) { - return newNetworkID != null && !newNetworkID.equals(other.newNetworkID); + return network != null; } public void attachKinetics() { @@ -286,14 +285,6 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick RotationPropagator.handleRemoved(world, pos, this); } - public UUID getNetworkID() { - return networkID; - } - - public void setNetworkID(UUID networkID) { - this.networkID = networkID; - } - public boolean isSpeedRequirementFulfilled() { BlockState state = getBlockState(); if (!(getBlockState().getBlock() instanceof IRotate)) @@ -309,6 +300,21 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick return true; } + public static void switchToBlockState(World world, BlockPos pos, BlockState state) { + if (world.isRemote) + return; + TileEntity tileEntityIn = world.getTileEntity(pos); + if (!(tileEntityIn instanceof KineticTileEntity)) + return; + KineticTileEntity tileEntity = (KineticTileEntity) tileEntityIn; + if (tileEntity.hasNetwork()) + tileEntity.getOrCreateNetwork().remove(tileEntity); + tileEntity.detachKinetics(); + tileEntity.removeSource(); + world.setBlockState(pos, state, 3); + tileEntity.attachKinetics(); + } + @Override public void addBehaviours(List behaviours) { } 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 822d3f176..fc111c54b 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 @@ -63,10 +63,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRendererFast list = storage.values().stream().map(MountedStorage::getItemHandler) - .collect(Collectors.toList()); + List list = + storage.values().stream().map(MountedStorage::getItemHandler).collect(Collectors.toList()); inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); } @@ -251,8 +252,8 @@ public abstract class Contraption { CompoundNBT comp = (CompoundNBT) c; storage.put(NBTUtil.readBlockPos(comp.getCompound("Pos")), new MountedStorage(comp.getCompound("Data"))); }); - List list = storage.values().stream().map(MountedStorage::getItemHandler) - .collect(Collectors.toList()); + List list = + storage.values().stream().map(MountedStorage::getItemHandler).collect(Collectors.toList()); inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); if (nbt.contains("BoundsFront")) @@ -358,6 +359,15 @@ public abstract class Contraption { block.nbt.putInt("y", targetPos.getY()); block.nbt.putInt("z", targetPos.getZ()); tileEntity.read(block.nbt); + + if (tileEntity instanceof KineticTileEntity) { + KineticTileEntity kineticTileEntity = (KineticTileEntity) tileEntity; + kineticTileEntity.source = null; + kineticTileEntity.setSpeed(0); + kineticTileEntity.network = null; + kineticTileEntity.attachKinetics(); + } + if (storage.containsKey(block.pos)) { MountedStorage mountedStorage = storage.get(block.pos); if (mountedStorage.isWorking()) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java index 9a78be26e..aa40d7e57 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java @@ -165,7 +165,6 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp running = true; angle = 0; sendData(); - updateGeneratedRotation(); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java index bdaae3965..1c5a47370 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java @@ -226,10 +226,13 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme } protected void applyContraptionMotion() { - if (movedContraption.isStalled()) + if (movedContraption == null) + return; + if (movedContraption.isStalled()) { movedContraption.setContraptionMotion(Vec3d.ZERO); - else - movedContraption.setContraptionMotion(getMotionVector()); + return; + } + movedContraption.setContraptionMotion(getMotionVector()); } protected void applyContraptionPosition() { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerBlock.java index ef2617b3e..aed3fa16d 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerBlock.java @@ -44,7 +44,7 @@ public class DeployerBlock extends DirectionalAxisKineticBlock @Override public PushReaction getPushReaction(BlockState state) { - return PushReaction.PUSH_ONLY; + return PushReaction.NORMAL; } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java index bcdabadbe..8f9f23a5a 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java @@ -153,6 +153,8 @@ public class DeployerHandler { RayTraceContext rayTraceContext = new RayTraceContext(rayOrigin, rayTarget, BlockMode.OUTLINE, FluidMode.NONE, player); BlockRayTraceResult result = world.rayTraceBlocks(rayTraceContext); + if (result.getPos() != clickedPos) + result = new BlockRayTraceResult(result.getHitVec(), result.getFace(), clickedPos, result.isInside()); BlockState clickedState = world.getBlockState(clickedPos); Direction face = result.getFace(); if (face == null) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java index 9a8c64649..6a1ad4489 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java @@ -272,8 +272,7 @@ public class DeployerTileEntity extends KineticTileEntity { continue; if (list == inv.mainInventory && i == inv.currentItem && filtering.test(itemstack)) - if (itemstack.getCount() == 1) - continue; + continue; itemstack = insert(itemstack, false); if (!itemstack.isEmpty()) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java index 7d8424f46..9fadca26d 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java @@ -1,7 +1,6 @@ package com.simibubi.create.modules.contraptions.components.motor; import java.util.List; -import java.util.UUID; import com.simibubi.create.AllTileEntities; import com.simibubi.create.config.AllConfigs; @@ -19,9 +18,6 @@ public class MotorTileEntity extends GeneratingKineticTileEntity { public MotorTileEntity() { super(AllTileEntities.MOTOR.type); - updateNetwork = true; - newNetworkID = UUID.randomUUID(); - speed = DEFAULT_SPEED; } @Override @@ -42,6 +38,13 @@ public class MotorTileEntity extends GeneratingKineticTileEntity { behaviours.add(generatedSpeed); } + @Override + public void initialize() { + super.initialize(); + if (!hasSource()) + updateGeneratedRotation(); + } + @Override public float getGeneratedSpeed() { return generatedSpeed.getValue(); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawBlock.java index 27679df3e..afede2d81 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawBlock.java @@ -102,7 +102,7 @@ public class SawBlock extends DirectionalAxisKineticBlock implements IWithTileEn @Override public PushReaction getPushReaction(BlockState state) { - return PushReaction.PUSH_ONLY; + return PushReaction.NORMAL; } public static boolean isHorizontal(BlockState state) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/waterwheel/WaterWheelTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/waterwheel/WaterWheelTileEntity.java index 9268480fa..ffe000e97 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/waterwheel/WaterWheelTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/waterwheel/WaterWheelTileEntity.java @@ -50,6 +50,7 @@ public class WaterWheelTileEntity extends GeneratingKineticTileEntity { public void setFlow(Direction direction, float speed) { flows.put(direction, speed); + markDirty(); } @Override 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 f2074d455..c0a7fda31 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 @@ -44,7 +44,7 @@ public class SpeedControllerTileEntity extends KineticTileEntity { private void updateTargetRotation() { if (hasNetwork()) - getNetwork().remove(this); + getOrCreateNetwork().remove(this); RotationPropagator.handleRemoved(world, pos, this); removeSource(); attachKinetics(); @@ -75,7 +75,7 @@ public class SpeedControllerTileEntity extends KineticTileEntity { return 1; } - boolean wheelPowersController = speedController.getSource().equals(cogWheel.getPos()); + boolean wheelPowersController = speedController.source.equals(cogWheel.getPos()); if (wheelPowersController) { 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 c6610426a..c044405ee 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,6 @@ public class BeltBlock extends HorizontalKineticBlock implements IHaveNoBlockIte return; BeltTileEntity beltEntity = (BeltTileEntity) tileEntity; BlockPos controller = beltEntity.getController(); - beltEntity.removeSource(); beltEntity.remove(); int limit = 1000; @@ -368,7 +367,6 @@ public class BeltBlock extends HorizontalKineticBlock implements IHaveNoBlockIte inv.eject(stack); } - te.removeSource(); te.remove(); if (destroyedBlock.get(CASING)) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/elementary/ShaftBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/elementary/ShaftBlock.java index bfac13f95..e0fbb59a4 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/elementary/ShaftBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/elementary/ShaftBlock.java @@ -5,6 +5,7 @@ import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock; import net.minecraft.block.BlockState; +import net.minecraft.block.material.PushReaction; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; @@ -22,6 +23,11 @@ public class ShaftBlock extends RotatedPillarKineticBlock { public ShaftBlock(Properties properties) { super(properties); } + + @Override + public PushReaction getPushReaction(BlockState state) { + return PushReaction.NORMAL; + } @Override public TileEntity createTileEntity(BlockState state, IBlockReader world) { 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 index 005159c40..cc904a43e 100644 --- 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 @@ -7,14 +7,14 @@ 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()); + BlockPos localSource = source.subtract(getPos()); + return Direction.getFacingFromVector(localSource.getX(), localSource.getY(), localSource.getZ()); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/EncasedBeltBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/EncasedBeltBlock.java index 727d5c61a..385159da0 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/EncasedBeltBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/EncasedBeltBlock.java @@ -8,6 +8,7 @@ import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.block.material.PushReaction; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemUseContext; import net.minecraft.state.BooleanProperty; @@ -40,6 +41,11 @@ public class EncasedBeltBlock extends RotatedPillarKineticBlock { return false; } + @Override + public PushReaction getPushReaction(BlockState state) { + return PushReaction.NORMAL; + } + @Override protected void fillStateContainer(Builder builder) { super.fillStateContainer(builder.add(PART, CONNECTED_ALONG_FIRST_COORDINATE)); 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 fac69932c..bf12b0543 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 @@ -11,8 +11,8 @@ public class StressGaugeTileEntity extends GaugeTileEntity { } @Override - public void sync(float maxStress, float currentStress) { - super.sync(maxStress, currentStress); + public void updateStressFromNetwork(float maxStress, float currentStress) { + super.updateStressFromNetwork(maxStress, currentStress); if (!StressImpact.isEnabled()) dialTarget = 0; @@ -41,15 +41,15 @@ public class StressGaugeTileEntity extends GaugeTileEntity { if (getSpeed() == 0) dialTarget = 0; else - sync(maxStress, currentStress); + updateStressFromNetwork(capacity, stress); } public float getNetworkStress() { - return currentStress; + return stress; } public float getNetworkCapacity() { - return maxStress; + return capacity; } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/gearbox/GearboxTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/gearbox/GearboxTileEntityRenderer.java index b3b1be8fa..36f189084 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/gearbox/GearboxTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/gearbox/GearboxTileEntityRenderer.java @@ -31,7 +31,7 @@ public class GearboxTileEntityRenderer extends KineticTileEntityRenderer { float angle = (time * te.getSpeed() * 3f / 10) % 360; if (te.getSpeed() != 0 && te.hasSource()) { - BlockPos source = te.getSource().subtract(te.getPos()); + BlockPos source = te.source.subtract(te.getPos()); Direction sourceFacing = Direction.getFacingFromVector(source.getX(), source.getY(), source.getZ()); if (sourceFacing.getAxis() == direction.getAxis()) angle *= sourceFacing == direction ? 1 : -1;