Optimizing and Stabilizing Kinetic Networks

- Kinetic components can no longer overpower components of their own network, fixes speed-up cycles in certain arrangements
- Kinetic networks are now identified by the packed block position of the source
- Networks now get assigned to tileentities within the tick of them changing, fixes late overstress callbacks messing with some components
- Wrench now keeps the instance of kinetic TEs intact when rotating their blocks, it only updates their kinetic connections
- Kinetic blocks no longer carry over their rotation and source information when moved by pistons or rotated by bearings
- Fixed crash when pulley retracts without an attached structure
- Deployers now hold onto their stack of items if they match the filter
- Fixed Deployers duplicating activated blocks when not facing an axis-aligned direction
- Fixed belts not properly re-attaching the shafts left behind when destroyed
This commit is contained in:
simibubi 2020-03-06 23:25:13 +01:00
parent b89db104b8
commit ea5c77b2b2
31 changed files with 267 additions and 244 deletions

View file

@ -66,7 +66,11 @@ public class ColorHelper {
public static int colorFromUUID(UUID uuid) { public static int colorFromUUID(UUID uuid) {
if (uuid == null) if (uuid == null)
return 0x333333; 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); return ColorHelper.mixColors(rainbowColor, 0xFFFFFF, .5f);
} }

View file

@ -25,7 +25,7 @@ public class KineticDebugger {
return; return;
World world = Minecraft.getInstance().world; 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); VoxelShape shape = world.getBlockState(toOutline).getShape(world, toOutline);
TessellatorHelper.prepareForDrawing(); TessellatorHelper.prepareForDrawing();

View file

@ -2,35 +2,32 @@ package com.simibubi.create.modules.contraptions;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class KineticNetwork { public class KineticNetwork {
public UUID id; public Long id;
public boolean initialized; public boolean initialized;
private float maxStress;
private float currentStress;
private float unloadedStressCapacity;
private float unloadedStress;
public Map<KineticTileEntity, Float> sources; public Map<KineticTileEntity, Float> sources;
public Map<KineticTileEntity, Float> members; public Map<KineticTileEntity, Float> members;
private float currentCapacity;
private float currentStress;
private float unloadedCapacity;
private float unloadedStress;
public KineticNetwork() { public KineticNetwork() {
id = UUID.randomUUID();
sources = new HashMap<>(); sources = new HashMap<>();
members = new HashMap<>(); members = new HashMap<>();
} }
public void initFromTE(float maxStress, float currentStress) { public void initFromTE(float maxStress, float currentStress) {
unloadedStressCapacity = maxStress; unloadedCapacity = maxStress;
unloadedStress = currentStress; unloadedStress = currentStress;
initialized = true; initialized = true;
updateStress(); updateStress();
updateStressCapacity(); updateCapacity();
} }
public void addSilently(KineticTileEntity te) { public void addSilently(KineticTileEntity te) {
@ -38,7 +35,7 @@ public class KineticNetwork {
return; return;
if (te.isSource()) { if (te.isSource()) {
float capacity = te.getAddedStressCapacity(); float capacity = te.getAddedStressCapacity();
unloadedStressCapacity -= capacity * getStressMultiplierForSpeed(te.getGeneratedSpeed()); unloadedCapacity -= capacity * getStressMultiplierForSpeed(te.getGeneratedSpeed());
sources.put(te, capacity); sources.put(te, capacity);
} }
float stressApplied = te.getStressApplied(); float stressApplied = te.getStressApplied();
@ -49,19 +46,16 @@ public class KineticNetwork {
public void add(KineticTileEntity te) { public void add(KineticTileEntity te) {
if (members.containsKey(te)) if (members.containsKey(te))
return; return;
if (te.isSource()) { if (te.isSource())
sources.put(te, te.getAddedStressCapacity()); sources.put(te, te.getAddedStressCapacity());
updateStressCapacity();
}
members.put(te, te.getStressApplied()); members.put(te, te.getStressApplied());
updateStress(); te.updateStressFromNetwork(currentCapacity, currentStress);
sync(); te.networkDirty = true;
} }
public void updateCapacityFor(KineticTileEntity te, float capacity) { public void updateCapacityFor(KineticTileEntity te, float capacity) {
sources.put(te, capacity); sources.put(te, capacity);
updateStressCapacity(); updateCapacity();
} }
public void updateStressFor(KineticTileEntity te, float stress) { public void updateStressFor(KineticTileEntity te, float stress) {
@ -72,46 +66,66 @@ public class KineticNetwork {
public void remove(KineticTileEntity te) { public void remove(KineticTileEntity te) {
if (!members.containsKey(te)) if (!members.containsKey(te))
return; return;
if (te.isSource()) { if (te.isSource())
sources.remove(te); 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); members.keySet().stream().findFirst().map(member -> member.networkDirty = true);
updateStress();
sync();
if (members.isEmpty())
TorquePropagator.networks.get(te.getWorld()).remove(this.id);
} }
public void sync() { public void sync() {
for (KineticTileEntity te : members.keySet()) for (KineticTileEntity te : members.keySet())
te.sync(maxStress, currentStress); te.updateStressFromNetwork(currentCapacity, currentStress);
} }
public void updateStressCapacity() { public void updateCapacity() {
float presentCapacity = 0; float newMaxStress = calculateCapacity();
for (KineticTileEntity te : sources.keySet()) if (currentCapacity != newMaxStress) {
presentCapacity += sources.get(te) * getStressMultiplierForSpeed(te.getGeneratedSpeed()); currentCapacity = newMaxStress;
float newMaxStress = presentCapacity + unloadedStressCapacity;
if (maxStress != newMaxStress) {
maxStress = newMaxStress;
sync(); sync();
} }
} }
public void updateStress() { public void updateStress() {
float presentStress = 0; float newStress = calculateStress();
for (KineticTileEntity te : members.keySet())
presentStress += members.get(te) * getStressMultiplierForSpeed(te.getTheoreticalSpeed());
float newStress = presentStress + unloadedStress;
if (currentStress != newStress) { if (currentStress != newStress) {
currentStress = newStress; currentStress = newStress;
sync(); 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) { private float getStressMultiplierForSpeed(float speed) {
return Math.abs(speed); return Math.abs(speed);
} }

View file

@ -192,7 +192,7 @@ public class RotationPropagator {
float neighbourSpeed = neighbourTE.getTheoreticalSpeed(); float neighbourSpeed = neighbourTE.getTheoreticalSpeed();
if (neighbourSpeed == 0) if (neighbourSpeed == 0)
continue; continue;
if (neighbourTE.hasSource() && neighbourTE.getSource().equals(addedTE.getPos())) { if (neighbourTE.hasSource() && neighbourTE.source.equals(addedTE.getPos())) {
addedTE.setSpeed(neighbourSpeed * speedModifier); addedTE.setSpeed(neighbourSpeed * speedModifier);
addedTE.onSpeedChanged(0); addedTE.onSpeedChanged(0);
addedTE.sendData(); addedTE.sendData();
@ -235,18 +235,19 @@ public class RotationPropagator {
return; return;
} }
if (incompatible) {
// Opposite directions // Opposite directions
if (incompatible) {
world.destroyBlock(pos, true); world.destroyBlock(pos, true);
return; return;
} else {
// Same direction: overpower the slower speed // Same direction: overpower the slower speed
if (Math.abs(oppositeSpeed) > Math.abs(speedOfCurrent)) { } else {
// Neighbour faster, overpower the incoming tree // Neighbour faster, overpower the incoming tree
currentTE.setSource(neighbourTE.getPos()); if (Math.abs(oppositeSpeed) > Math.abs(speedOfCurrent)) {
float prevSpeed = currentTE.getSpeed(); float prevSpeed = currentTE.getSpeed();
currentTE.setSpeed(speedOfNeighbour * getRotationSpeedModifier(neighbourTE, currentTE)); currentTE.setSpeed(speedOfNeighbour * getRotationSpeedModifier(neighbourTE, currentTE));
currentTE.setSource(neighbourTE.getPos());
currentTE.onSpeedChanged(prevSpeed); currentTE.onSpeedChanged(prevSpeed);
currentTE.sendData(); currentTE.sendData();
@ -256,18 +257,20 @@ public class RotationPropagator {
// Current faster, overpower the neighbours' tree // Current faster, overpower the neighbours' tree
if (Math.abs(newSpeed) >= Math.abs(speedOfNeighbour)) { 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)) if (Math.abs(newSpeed) > Math.abs(speedOfNeighbour))
world.destroyBlock(pos, true); world.destroyBlock(pos, true);
continue; continue;
} }
if (currentTE.hasSource() && currentTE.getSource().equals(neighbourTE.getPos())) if (currentTE.hasSource() && currentTE.source.equals(neighbourTE.getPos()))
currentTE.removeSource(); currentTE.removeSource();
neighbourTE.setSource(currentTE.getPos());
float prevSpeed = neighbourTE.getSpeed(); float prevSpeed = neighbourTE.getSpeed();
neighbourTE.setSpeed(speedOfCurrent * getRotationSpeedModifier(currentTE, neighbourTE)); neighbourTE.setSpeed(speedOfCurrent * getRotationSpeedModifier(currentTE, neighbourTE));
neighbourTE.setSource(currentTE.getPos());
neighbourTE.onSpeedChanged(prevSpeed); neighbourTE.onSpeedChanged(prevSpeed);
neighbourTE.sendData(); neighbourTE.sendData();
propagateNewSource(neighbourTE); propagateNewSource(neighbourTE);
@ -309,7 +312,7 @@ public class RotationPropagator {
continue; continue;
final KineticTileEntity neighbourTE = (KineticTileEntity) worldIn.getTileEntity(neighbourPos); final KineticTileEntity neighbourTE = (KineticTileEntity) worldIn.getTileEntity(neighbourPos);
if (!neighbourTE.hasSource() || !neighbourTE.getSource().equals(pos)) if (!neighbourTE.hasSource() || !neighbourTE.source.equals(pos))
continue; continue;
propagateMissingSource(neighbourTE); propagateMissingSource(neighbourTE);
@ -329,7 +332,7 @@ public class RotationPropagator {
List<KineticTileEntity> potentialNewSources = new LinkedList<>(); List<KineticTileEntity> potentialNewSources = new LinkedList<>();
List<BlockPos> frontier = new LinkedList<>(); List<BlockPos> frontier = new LinkedList<>();
frontier.add(updateTE.getPos()); frontier.add(updateTE.getPos());
BlockPos missingSource = updateTE.hasSource() ? updateTE.getSource() : null; BlockPos missingSource = updateTE.hasSource() ? updateTE.source : null;
while (!frontier.isEmpty()) { while (!frontier.isEmpty()) {
final BlockPos pos = frontier.remove(0); final BlockPos pos = frontier.remove(0);
@ -344,7 +347,7 @@ public class RotationPropagator {
if (!neighbourTE.hasSource()) if (!neighbourTE.hasSource())
continue; continue;
if (!neighbourTE.getSource().equals(pos)) { if (!neighbourTE.source.equals(pos)) {
potentialNewSources.add(neighbourTE); potentialNewSources.add(neighbourTE);
continue; continue;
} }

View file

@ -2,7 +2,6 @@ package com.simibubi.create.modules.contraptions;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
@ -11,7 +10,7 @@ import net.minecraft.world.IWorld;
public class TorquePropagator { public class TorquePropagator {
static Map<IWorld, Map<UUID, KineticNetwork>> networks = new HashMap<>(); static Map<IWorld, Map<Long, KineticNetwork>> networks = new HashMap<>();
public void onLoadWorld(IWorld world) { public void onLoadWorld(IWorld world) {
networks.put(world, new HashMap<>()); networks.put(world, new HashMap<>());
@ -24,15 +23,15 @@ public class TorquePropagator {
} }
public KineticNetwork getNetworkFor(KineticTileEntity te) { public KineticNetwork getNetworkFor(KineticTileEntity te) {
UUID id = te.getNetworkID(); Long id = te.network;
KineticNetwork network; KineticNetwork network;
Map<UUID, KineticNetwork> map = networks.get(te.getWorld()); Map<Long, KineticNetwork> map = networks.get(te.getWorld());
if (id == null) if (id == null)
return null; return null;
if (!map.containsKey(id)) { if (!map.containsKey(id)) {
network = new KineticNetwork(); network = new KineticNetwork();
network.id = te.getNetworkID(); network.id = te.network;
map.put(id, network); map.put(id, network);
} }
network = map.get(id); network = map.get(id);

View file

@ -90,13 +90,7 @@ public abstract class DirectionalAxisKineticBlock extends DirectionalKineticBloc
World world = context.getWorld(); World world = context.getWorld();
Direction face = context.getFace(); Direction face = context.getFace();
if ((turnBackOnWrenched() ? face.getOpposite() : face) == state.get(FACING)) { if ((turnBackOnWrenched() ? face.getOpposite() : face) == state.get(FACING)) {
if (!world.isRemote) { KineticTileEntity.switchToBlockState(world, context.getPos(), state.cycle(AXIS_ALONG_FIRST_COORDINATE));
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();
}
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }
return super.onWrenched(state, context); return super.onWrenched(state, context);

View file

@ -11,7 +11,6 @@ import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Mirror; import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation; import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
public abstract class DirectionalKineticBlock extends KineticBlock { public abstract class DirectionalKineticBlock extends KineticBlock {
@ -56,14 +55,7 @@ public abstract class DirectionalKineticBlock extends KineticBlock {
BlockState with = state.with(FACING, facing); BlockState with = state.with(FACING, facing);
if (!with.isValidPosition(world, context.getPos())) if (!with.isValidPosition(world, context.getPos()))
return ActionResultType.PASS; return ActionResultType.PASS;
KineticTileEntity.switchToBlockState(world, context.getPos(), with);
if (!world.isRemote) {
BlockPos pos = context.getPos();
world.removeTileEntity(pos);
world.setBlockState(pos, with, 3);
KineticTileEntity tileEntity = (KineticTileEntity) world.getTileEntity(pos);
tileEntity.attachKinetics();
}
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }

View file

@ -1,7 +1,5 @@
package com.simibubi.create.modules.contraptions.base; package com.simibubi.create.modules.contraptions.base;
import java.util.UUID;
import com.simibubi.create.modules.contraptions.KineticNetwork; import com.simibubi.create.modules.contraptions.KineticNetwork;
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel; import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel;
@ -17,7 +15,7 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
} }
protected void notifyStressCapacityChange(float capacity) { protected void notifyStressCapacityChange(float capacity) {
getNetwork().updateCapacityFor(this, capacity); getOrCreateNetwork().updateCapacityFor(this, capacity);
} }
@Override @Override
@ -63,8 +61,9 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
} }
if (hasNetwork() && speed != 0) { if (hasNetwork() && speed != 0) {
KineticNetwork network = getNetwork(); KineticNetwork network = getOrCreateNetwork();
network.updateCapacityFor(this, getAddedStressCapacity()); notifyStressCapacityChange(getAddedStressCapacity());
getOrCreateNetwork().updateStressFor(this, getStressApplied());
network.updateStress(); network.updateStress();
} }
@ -76,45 +75,40 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
// Speed changed to 0 // Speed changed to 0
if (speed == 0) { if (speed == 0) {
if (hasSource() && hasNetwork()) { if (hasSource()) {
getNetwork().updateCapacityFor(this, 0); notifyStressCapacityChange(0);
getOrCreateNetwork().updateStressFor(this, getStressApplied());
return; return;
} }
detachKinetics(); detachKinetics();
setSpeed(speed); setSpeed(0);
newNetworkID = null; setNetwork(null);
updateNetwork = true;
return; return;
} }
// Now turning - create a new Network // Now turning - create a new Network
if (prevSpeed == 0) { if (prevSpeed == 0) {
setSpeed(speed); setSpeed(speed);
newNetworkID = UUID.randomUUID(); setNetwork(createNetworkId());
updateNetwork = true;
attachKinetics(); attachKinetics();
return; return;
} }
// Change speed when overpowered by other generator // Change speed when overpowered by other generator
if (hasSource() && hasNetwork()) { if (hasSource()) {
// Staying below Overpowered speed // Staying below Overpowered speed
if (Math.abs(prevSpeed) >= Math.abs(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); world.destroyBlock(pos, true);
return; return;
} }
getNetwork().updateCapacityFor(this, getAddedStressCapacity());
return;
}
// Faster than attached network -> become the new source // Faster than attached network -> become the new source
detachKinetics(); detachKinetics();
setSpeed(speed); setSpeed(speed);
source = null; source = null;
newNetworkID = UUID.randomUUID(); setNetwork(createNetworkId());
updateNetwork = true;
attachKinetics(); attachKinetics();
return; return;
} }
@ -125,4 +119,8 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
attachKinetics(); attachKinetics();
} }
public Long createNetworkId() {
return pos.toLong();
}
} }

View file

@ -1,7 +1,5 @@
package com.simibubi.create.modules.contraptions.base; package com.simibubi.create.modules.contraptions.base;
import com.simibubi.create.modules.contraptions.RotationPropagator;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
@ -79,16 +77,7 @@ public abstract class HorizontalAxisKineticBlock extends KineticBlock {
World world = context.getWorld(); World world = context.getWorld();
if (facing.getAxis() == state.get(HORIZONTAL_AXIS)) if (facing.getAxis() == state.get(HORIZONTAL_AXIS))
return ActionResultType.PASS; return ActionResultType.PASS;
if (!world.isRemote) { KineticTileEntity.switchToBlockState(world, context.getPos(), state.cycle(HORIZONTAL_AXIS));
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();
}
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }

View file

@ -11,7 +11,6 @@ import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Mirror; import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation; import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
public abstract class HorizontalKineticBlock extends KineticBlock { public abstract class HorizontalKineticBlock extends KineticBlock {
@ -61,13 +60,7 @@ public abstract class HorizontalKineticBlock extends KineticBlock {
World world = context.getWorld(); World world = context.getWorld();
if (facing == state.get(HORIZONTAL_FACING)) if (facing == state.get(HORIZONTAL_FACING))
return ActionResultType.PASS; return ActionResultType.PASS;
if (!world.isRemote) { KineticTileEntity.switchToBlockState(world, context.getPos(), state.with(HORIZONTAL_FACING, facing));
BlockPos pos = context.getPos();
world.removeTileEntity(pos);
world.setBlockState(pos, state.with(HORIZONTAL_FACING, facing), 3);
KineticTileEntity tileEntity = (KineticTileEntity) world.getTileEntity(pos);
tileEntity.attachKinetics();
}
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }

View file

@ -79,6 +79,20 @@ public abstract class KineticBlock extends Block implements IRotate {
@Override @Override
public abstract TileEntity createTileEntity(BlockState state, IBlockReader world); 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") @SuppressWarnings("deprecation")
@Override @Override
public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) { public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) {

View file

@ -2,7 +2,8 @@ package com.simibubi.create.modules.contraptions.base;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import javax.annotation.Nullable;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.config.AllConfigs; import com.simibubi.create.config.AllConfigs;
@ -18,24 +19,24 @@ import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue; import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
public abstract class KineticTileEntity extends SmartTileEntity implements ITickableTileEntity { public abstract class KineticTileEntity extends SmartTileEntity implements ITickableTileEntity {
protected UUID networkID; public @Nullable Long network;
protected UUID newNetworkID; public @Nullable BlockPos source;
protected float maxStress; public boolean networkDirty;
protected float currentStress;
protected boolean updateNetwork;
protected KineticEffectHandler effects; protected KineticEffectHandler effects;
protected BlockPos source;
protected float speed; protected float speed;
protected float capacity;
protected float stress;
protected boolean overStressed; protected boolean overStressed;
protected boolean initNetwork;
private int flickerTally; private int flickerTally;
private int validationCountdown; private int validationCountdown;
@ -45,6 +46,18 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
effects = new KineticEffectHandler(this); 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 @Override
public void tick() { public void tick() {
super.tick(); super.tick();
@ -61,33 +74,10 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
if (getFlickerScore() > 0) if (getFlickerScore() > 0)
flickerTally = getFlickerScore() - 1; flickerTally = getFlickerScore() - 1;
if (initNetwork) { if (networkDirty) {
initNetwork = false; if (hasNetwork())
getOrCreateNetwork().updateNetwork();
KineticNetwork network = getNetwork(); networkDirty = false;
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();
} }
} }
@ -103,25 +93,21 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
return; return;
} }
if (hasNetwork() && maxStress == 0) {
for (KineticTileEntity kineticTileEntity : getNetwork().members.keySet())
kineticTileEntity.removeSource();
return;
}
return; return;
} }
if (speed != 0) { if (speed != 0) {
if (getGeneratedSpeed() == 0) if (getGeneratedSpeed() == 0)
setSpeed(0); speed = 0;
} }
} }
public void sync(float maxStress, float currentStress) { public void updateStressFromNetwork(float maxStress, float currentStress) {
this.maxStress = maxStress; networkDirty = false;
this.currentStress = currentStress; this.capacity = maxStress;
this.stress = currentStress;
boolean overStressed = maxStress < currentStress && StressImpact.isEnabled(); boolean overStressed = maxStress < currentStress && StressImpact.isEnabled();
if (overStressed != this.overStressed) { if (overStressed != this.overStressed) {
if (speed != 0 && overStressed) if (speed != 0 && overStressed)
AllTriggers.triggerForNearbyPlayers(AllTriggers.OVERSTRESSED, world, pos, 8); AllTriggers.triggerForNearbyPlayers(AllTriggers.OVERSTRESSED, world, pos, 8);
@ -160,7 +146,7 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
public void remove() { public void remove() {
if (!world.isRemote) { if (!world.isRemote) {
if (hasNetwork()) if (hasNetwork())
getNetwork().remove(this); getOrCreateNetwork().remove(this);
detachKinetics(); detachKinetics();
} }
super.remove(); super.remove();
@ -174,9 +160,11 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
compound.put("Source", NBTUtil.writeBlockPos(source)); compound.put("Source", NBTUtil.writeBlockPos(source));
if (hasNetwork()) { if (hasNetwork()) {
compound.putFloat("MaxStress", maxStress); CompoundNBT networkTag = new CompoundNBT();
compound.putFloat("Stress", currentStress); networkTag.putLong("Id", network);
compound.put("Id", NBTUtil.writeUniqueId(networkID)); networkTag.putFloat("Stress", stress);
networkTag.putFloat("Capacity", capacity);
compound.put("Network", networkTag);
} }
return super.write(compound); return super.write(compound);
@ -185,20 +173,22 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
@Override @Override
public void read(CompoundNBT compound) { public void read(CompoundNBT compound) {
speed = compound.getFloat("Speed"); speed = compound.getFloat("Speed");
source = null; source = null;
networkID = newNetworkID = null; network = null;
overStressed = false; overStressed = false;
stress = 0;
capacity = 0;
if (compound.contains("Source")) if (compound.contains("Source"))
source = NBTUtil.readBlockPos(compound.getCompound("Source")); source = NBTUtil.readBlockPos(compound.getCompound("Source"));
if (compound.contains("Id")) { if (compound.contains("Network")) {
maxStress = compound.getFloat("MaxStress"); CompoundNBT networkTag = compound.getCompound("Network");
currentStress = compound.getFloat("Stress"); network = networkTag.getLong("Id");
overStressed = maxStress < currentStress && StressImpact.isEnabled(); stress = networkTag.getFloat("Stress");
networkID = NBTUtil.readUniqueId(compound.getCompound("Id")); capacity = networkTag.getFloat("Capacity");
newNetworkID = networkID; overStressed = capacity < stress && StressImpact.isEnabled();
initNetwork = true;
} }
super.read(compound); super.read(compound);
@ -212,6 +202,10 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
effects.triggerOverStressedEffect(); effects.triggerOverStressedEffect();
} }
public float getGeneratedSpeed() {
return 0;
}
public boolean isSource() { public boolean isSource() {
return getGeneratedSpeed() != 0; return getGeneratedSpeed() != 0;
} }
@ -226,10 +220,6 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
return speed; return speed;
} }
public float getGeneratedSpeed() {
return 0;
}
public void setSpeed(float speed) { public void setSpeed(float speed) {
this.speed = speed; this.speed = speed;
} }
@ -238,10 +228,6 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
return source != null; return source != null;
} }
public BlockPos getSource() {
return source;
}
public void setSource(BlockPos source) { public void setSource(BlockPos source) {
this.source = source; this.source = source;
if (world == null || world.isRemote) if (world == null || world.isRemote)
@ -253,29 +239,42 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
return; return;
} }
newNetworkID = sourceTe.newNetworkID; setNetwork(sourceTe.network);
updateNetwork = true;
} }
public void removeSource() { public void removeSource() {
source = null;
newNetworkID = null;
updateNetwork = true;
float prevSpeed = getSpeed(); float prevSpeed = getSpeed();
setSpeed(0);
speed = 0;
source = null;
setNetwork(null);
onSpeedChanged(prevSpeed); 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); return Create.torquePropagator.getNetworkFor(this);
} }
public boolean hasNetwork() { public boolean hasNetwork() {
return networkID != null; return network != null;
}
public boolean canOverPower(KineticTileEntity other) {
return newNetworkID != null && !newNetworkID.equals(other.newNetworkID);
} }
public void attachKinetics() { public void attachKinetics() {
@ -286,14 +285,6 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
RotationPropagator.handleRemoved(world, pos, this); RotationPropagator.handleRemoved(world, pos, this);
} }
public UUID getNetworkID() {
return networkID;
}
public void setNetworkID(UUID networkID) {
this.networkID = networkID;
}
public boolean isSpeedRequirementFulfilled() { public boolean isSpeedRequirementFulfilled() {
BlockState state = getBlockState(); BlockState state = getBlockState();
if (!(getBlockState().getBlock() instanceof IRotate)) if (!(getBlockState().getBlock() instanceof IRotate))
@ -309,6 +300,21 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
return true; 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 @Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) { public void addBehaviours(List<TileEntityBehaviour> behaviours) {
} }

View file

@ -63,10 +63,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRendererFast<Kineti
int white = 0xFFFFFF; int white = 0xFFFFFF;
if (KineticDebugger.isActive()) { if (KineticDebugger.isActive()) {
rainbowMode = true; rainbowMode = true;
if (te.hasNetwork()) buffer.color(te.hasNetwork() ? ColorHelper.colorFromLong(te.network) : white);
buffer.color(ColorHelper.colorFromUUID(te.getNetworkID()));
else
buffer.color(white);
} else { } else {
float overStressedEffect = te.effects.overStressedEffect; float overStressedEffect = te.effects.overStressedEffect;
if (overStressedEffect != 0) if (overStressedEffect != 0)

View file

@ -11,7 +11,6 @@ import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Rotation; import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
public abstract class RotatedPillarKineticBlock extends KineticBlock { public abstract class RotatedPillarKineticBlock extends KineticBlock {
@ -79,13 +78,7 @@ public abstract class RotatedPillarKineticBlock extends KineticBlock {
World world = context.getWorld(); World world = context.getWorld();
if (axis == state.get(AXIS)) if (axis == state.get(AXIS))
return ActionResultType.PASS; return ActionResultType.PASS;
if (!world.isRemote) { KineticTileEntity.switchToBlockState(world, context.getPos(), state.with(AXIS, axis));
BlockPos pos = context.getPos();
world.removeTileEntity(pos);
world.setBlockState(pos, state.with(AXIS, axis), 3);
KineticTileEntity tileEntity = (KineticTileEntity) world.getTileEntity(pos);
tileEntity.attachKinetics();
}
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }

View file

@ -61,7 +61,7 @@ public class DrillBlock extends DirectionalKineticBlock implements IPortableBloc
@Override @Override
public PushReaction getPushReaction(BlockState state) { public PushReaction getPushReaction(BlockState state) {
return PushReaction.PUSH_ONLY; return PushReaction.NORMAL;
} }
@Override @Override

View file

@ -19,6 +19,7 @@ import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.config.AllConfigs; import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
import com.simibubi.create.modules.contraptions.components.saw.SawBlock; import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
@ -111,8 +112,8 @@ public abstract class Contraption {
} }
public void gatherStoredItems() { public void gatherStoredItems() {
List<IItemHandlerModifiable> list = storage.values().stream().map(MountedStorage::getItemHandler) List<IItemHandlerModifiable> list =
.collect(Collectors.toList()); storage.values().stream().map(MountedStorage::getItemHandler).collect(Collectors.toList());
inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class));
} }
@ -251,8 +252,8 @@ public abstract class Contraption {
CompoundNBT comp = (CompoundNBT) c; CompoundNBT comp = (CompoundNBT) c;
storage.put(NBTUtil.readBlockPos(comp.getCompound("Pos")), new MountedStorage(comp.getCompound("Data"))); storage.put(NBTUtil.readBlockPos(comp.getCompound("Pos")), new MountedStorage(comp.getCompound("Data")));
}); });
List<IItemHandlerModifiable> list = storage.values().stream().map(MountedStorage::getItemHandler) List<IItemHandlerModifiable> list =
.collect(Collectors.toList()); storage.values().stream().map(MountedStorage::getItemHandler).collect(Collectors.toList());
inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class));
if (nbt.contains("BoundsFront")) if (nbt.contains("BoundsFront"))
@ -358,6 +359,15 @@ public abstract class Contraption {
block.nbt.putInt("y", targetPos.getY()); block.nbt.putInt("y", targetPos.getY());
block.nbt.putInt("z", targetPos.getZ()); block.nbt.putInt("z", targetPos.getZ());
tileEntity.read(block.nbt); 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)) { if (storage.containsKey(block.pos)) {
MountedStorage mountedStorage = storage.get(block.pos); MountedStorage mountedStorage = storage.get(block.pos);
if (mountedStorage.isWorking()) if (mountedStorage.isWorking())

View file

@ -165,7 +165,6 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
running = true; running = true;
angle = 0; angle = 0;
sendData(); sendData();
updateGeneratedRotation(); updateGeneratedRotation();
} }

View file

@ -226,9 +226,12 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
} }
protected void applyContraptionMotion() { protected void applyContraptionMotion() {
if (movedContraption.isStalled()) if (movedContraption == null)
return;
if (movedContraption.isStalled()) {
movedContraption.setContraptionMotion(Vec3d.ZERO); movedContraption.setContraptionMotion(Vec3d.ZERO);
else return;
}
movedContraption.setContraptionMotion(getMotionVector()); movedContraption.setContraptionMotion(getMotionVector());
} }

View file

@ -44,7 +44,7 @@ public class DeployerBlock extends DirectionalAxisKineticBlock
@Override @Override
public PushReaction getPushReaction(BlockState state) { public PushReaction getPushReaction(BlockState state) {
return PushReaction.PUSH_ONLY; return PushReaction.NORMAL;
} }
@Override @Override

View file

@ -153,6 +153,8 @@ public class DeployerHandler {
RayTraceContext rayTraceContext = RayTraceContext rayTraceContext =
new RayTraceContext(rayOrigin, rayTarget, BlockMode.OUTLINE, FluidMode.NONE, player); new RayTraceContext(rayOrigin, rayTarget, BlockMode.OUTLINE, FluidMode.NONE, player);
BlockRayTraceResult result = world.rayTraceBlocks(rayTraceContext); BlockRayTraceResult result = world.rayTraceBlocks(rayTraceContext);
if (result.getPos() != clickedPos)
result = new BlockRayTraceResult(result.getHitVec(), result.getFace(), clickedPos, result.isInside());
BlockState clickedState = world.getBlockState(clickedPos); BlockState clickedState = world.getBlockState(clickedPos);
Direction face = result.getFace(); Direction face = result.getFace();
if (face == null) if (face == null)

View file

@ -272,7 +272,6 @@ public class DeployerTileEntity extends KineticTileEntity {
continue; continue;
if (list == inv.mainInventory && i == inv.currentItem && filtering.test(itemstack)) if (list == inv.mainInventory && i == inv.currentItem && filtering.test(itemstack))
if (itemstack.getCount() == 1)
continue; continue;
itemstack = insert(itemstack, false); itemstack = insert(itemstack, false);

View file

@ -1,7 +1,6 @@
package com.simibubi.create.modules.contraptions.components.motor; package com.simibubi.create.modules.contraptions.components.motor;
import java.util.List; import java.util.List;
import java.util.UUID;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.config.AllConfigs; import com.simibubi.create.config.AllConfigs;
@ -19,9 +18,6 @@ public class MotorTileEntity extends GeneratingKineticTileEntity {
public MotorTileEntity() { public MotorTileEntity() {
super(AllTileEntities.MOTOR.type); super(AllTileEntities.MOTOR.type);
updateNetwork = true;
newNetworkID = UUID.randomUUID();
speed = DEFAULT_SPEED;
} }
@Override @Override
@ -42,6 +38,13 @@ public class MotorTileEntity extends GeneratingKineticTileEntity {
behaviours.add(generatedSpeed); behaviours.add(generatedSpeed);
} }
@Override
public void initialize() {
super.initialize();
if (!hasSource())
updateGeneratedRotation();
}
@Override @Override
public float getGeneratedSpeed() { public float getGeneratedSpeed() {
return generatedSpeed.getValue(); return generatedSpeed.getValue();

View file

@ -102,7 +102,7 @@ public class SawBlock extends DirectionalAxisKineticBlock implements IWithTileEn
@Override @Override
public PushReaction getPushReaction(BlockState state) { public PushReaction getPushReaction(BlockState state) {
return PushReaction.PUSH_ONLY; return PushReaction.NORMAL;
} }
public static boolean isHorizontal(BlockState state) { public static boolean isHorizontal(BlockState state) {

View file

@ -50,6 +50,7 @@ public class WaterWheelTileEntity extends GeneratingKineticTileEntity {
public void setFlow(Direction direction, float speed) { public void setFlow(Direction direction, float speed) {
flows.put(direction, speed); flows.put(direction, speed);
markDirty();
} }
@Override @Override

View file

@ -44,7 +44,7 @@ public class SpeedControllerTileEntity extends KineticTileEntity {
private void updateTargetRotation() { private void updateTargetRotation() {
if (hasNetwork()) if (hasNetwork())
getNetwork().remove(this); getOrCreateNetwork().remove(this);
RotationPropagator.handleRemoved(world, pos, this); RotationPropagator.handleRemoved(world, pos, this);
removeSource(); removeSource();
attachKinetics(); attachKinetics();
@ -75,7 +75,7 @@ public class SpeedControllerTileEntity extends KineticTileEntity {
return 1; return 1;
} }
boolean wheelPowersController = speedController.getSource().equals(cogWheel.getPos()); boolean wheelPowersController = speedController.source.equals(cogWheel.getPos());
if (wheelPowersController) { if (wheelPowersController) {
if (targetingController) if (targetingController)

View file

@ -347,7 +347,6 @@ public class BeltBlock extends HorizontalKineticBlock implements IHaveNoBlockIte
return; return;
BeltTileEntity beltEntity = (BeltTileEntity) tileEntity; BeltTileEntity beltEntity = (BeltTileEntity) tileEntity;
BlockPos controller = beltEntity.getController(); BlockPos controller = beltEntity.getController();
beltEntity.removeSource();
beltEntity.remove(); beltEntity.remove();
int limit = 1000; int limit = 1000;
@ -368,7 +367,6 @@ public class BeltBlock extends HorizontalKineticBlock implements IHaveNoBlockIte
inv.eject(stack); inv.eject(stack);
} }
te.removeSource();
te.remove(); te.remove();
if (destroyedBlock.get(CASING)) if (destroyedBlock.get(CASING))

View file

@ -5,6 +5,7 @@ import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock; import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.material.PushReaction;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
@ -23,6 +24,11 @@ public class ShaftBlock extends RotatedPillarKineticBlock {
super(properties); super(properties);
} }
@Override
public PushReaction getPushReaction(BlockState state) {
return PushReaction.NORMAL;
}
@Override @Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) { public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new ShaftTileEntity(); return new ShaftTileEntity();

View file

@ -13,8 +13,8 @@ public class DirectionalShaftHalvesTileEntity extends KineticTileEntity {
} }
public Direction getSourceFacing() { public Direction getSourceFacing() {
BlockPos source = getSource().subtract(getPos()); BlockPos localSource = source.subtract(getPos());
return Direction.getFacingFromVector(source.getX(), source.getY(), source.getZ()); return Direction.getFacingFromVector(localSource.getX(), localSource.getY(), localSource.getZ());
} }
} }

View file

@ -8,6 +8,7 @@ import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.material.PushReaction;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemUseContext; import net.minecraft.item.ItemUseContext;
import net.minecraft.state.BooleanProperty; import net.minecraft.state.BooleanProperty;
@ -40,6 +41,11 @@ public class EncasedBeltBlock extends RotatedPillarKineticBlock {
return false; return false;
} }
@Override
public PushReaction getPushReaction(BlockState state) {
return PushReaction.NORMAL;
}
@Override @Override
protected void fillStateContainer(Builder<Block, BlockState> builder) { protected void fillStateContainer(Builder<Block, BlockState> builder) {
super.fillStateContainer(builder.add(PART, CONNECTED_ALONG_FIRST_COORDINATE)); super.fillStateContainer(builder.add(PART, CONNECTED_ALONG_FIRST_COORDINATE));

View file

@ -11,8 +11,8 @@ public class StressGaugeTileEntity extends GaugeTileEntity {
} }
@Override @Override
public void sync(float maxStress, float currentStress) { public void updateStressFromNetwork(float maxStress, float currentStress) {
super.sync(maxStress, currentStress); super.updateStressFromNetwork(maxStress, currentStress);
if (!StressImpact.isEnabled()) if (!StressImpact.isEnabled())
dialTarget = 0; dialTarget = 0;
@ -41,15 +41,15 @@ public class StressGaugeTileEntity extends GaugeTileEntity {
if (getSpeed() == 0) if (getSpeed() == 0)
dialTarget = 0; dialTarget = 0;
else else
sync(maxStress, currentStress); updateStressFromNetwork(capacity, stress);
} }
public float getNetworkStress() { public float getNetworkStress() {
return currentStress; return stress;
} }
public float getNetworkCapacity() { public float getNetworkCapacity() {
return maxStress; return capacity;
} }
} }

View file

@ -31,7 +31,7 @@ public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
float angle = (time * te.getSpeed() * 3f / 10) % 360; float angle = (time * te.getSpeed() * 3f / 10) % 360;
if (te.getSpeed() != 0 && te.hasSource()) { 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()); Direction sourceFacing = Direction.getFacingFromVector(source.getX(), source.getY(), source.getZ());
if (sourceFacing.getAxis() == direction.getAxis()) if (sourceFacing.getAxis() == direction.getAxis())
angle *= sourceFacing == direction ? 1 : -1; angle *= sourceFacing == direction ? 1 : -1;