mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-15 14:13:42 +01:00
Merge branch 'mc1.18/0.5.1' into mc1.18/0.5.1-repolish
This commit is contained in:
commit
4ca885c933
14 changed files with 252 additions and 36 deletions
|
@ -426,14 +426,17 @@ public class RotationPropagator {
|
||||||
|
|
||||||
private static List<BlockPos> getPotentialNeighbourLocations(KineticBlockEntity be) {
|
private static List<BlockPos> getPotentialNeighbourLocations(KineticBlockEntity be) {
|
||||||
List<BlockPos> neighbours = new LinkedList<>();
|
List<BlockPos> neighbours = new LinkedList<>();
|
||||||
|
BlockPos blockPos = be.getBlockPos();
|
||||||
|
Level level = be.getLevel();
|
||||||
|
|
||||||
if (!be.getLevel()
|
if (!level.isLoaded(blockPos))
|
||||||
.isAreaLoaded(be.getBlockPos(), 1))
|
|
||||||
return neighbours;
|
return neighbours;
|
||||||
|
|
||||||
for (Direction facing : Iterate.directions)
|
for (Direction facing : Iterate.directions) {
|
||||||
neighbours.add(be.getBlockPos()
|
BlockPos relative = blockPos.relative(facing);
|
||||||
.relative(facing));
|
if (level.isLoaded(relative))
|
||||||
|
neighbours.add(relative);
|
||||||
|
}
|
||||||
|
|
||||||
BlockState blockState = be.getBlockState();
|
BlockState blockState = be.getBlockState();
|
||||||
if (!(blockState.getBlock() instanceof IRotate))
|
if (!(blockState.getBlock() instanceof IRotate))
|
||||||
|
|
|
@ -15,6 +15,7 @@ import com.simibubi.create.content.contraptions.base.IRotate.SpeedLevel;
|
||||||
import com.simibubi.create.content.contraptions.base.IRotate.StressImpact;
|
import com.simibubi.create.content.contraptions.base.IRotate.StressImpact;
|
||||||
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
||||||
import com.simibubi.create.content.contraptions.goggles.IHaveHoveringInformation;
|
import com.simibubi.create.content.contraptions.goggles.IHaveHoveringInformation;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftBlockEntity.SequenceContext;
|
||||||
import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel;
|
import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel;
|
||||||
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxBlock;
|
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxBlock;
|
||||||
import com.simibubi.create.foundation.block.BlockStressValues;
|
import com.simibubi.create.foundation.block.BlockStressValues;
|
||||||
|
@ -67,6 +68,8 @@ public class KineticBlockEntity extends SmartBlockEntity implements IHaveGoggleI
|
||||||
private int validationCountdown;
|
private int validationCountdown;
|
||||||
protected float lastStressApplied;
|
protected float lastStressApplied;
|
||||||
protected float lastCapacityProvided;
|
protected float lastCapacityProvided;
|
||||||
|
|
||||||
|
public SequenceContext sequenceContext;
|
||||||
|
|
||||||
public KineticBlockEntity(BlockEntityType<?> typeIn, BlockPos pos, BlockState state) {
|
public KineticBlockEntity(BlockEntityType<?> typeIn, BlockPos pos, BlockState state) {
|
||||||
super(typeIn, pos, state);
|
super(typeIn, pos, state);
|
||||||
|
@ -197,6 +200,8 @@ public class KineticBlockEntity extends SmartBlockEntity implements IHaveGoggleI
|
||||||
@Override
|
@Override
|
||||||
protected void write(CompoundTag compound, boolean clientPacket) {
|
protected void write(CompoundTag compound, boolean clientPacket) {
|
||||||
compound.putFloat("Speed", speed);
|
compound.putFloat("Speed", speed);
|
||||||
|
if (sequenceContext != null && (!clientPacket || syncSequenceContext()))
|
||||||
|
compound.put("Sequence", sequenceContext.serializeNBT());
|
||||||
|
|
||||||
if (needsSpeedUpdate())
|
if (needsSpeedUpdate())
|
||||||
compound.putBoolean("NeedsSpeedUpdate", true);
|
compound.putBoolean("NeedsSpeedUpdate", true);
|
||||||
|
@ -238,6 +243,7 @@ public class KineticBlockEntity extends SmartBlockEntity implements IHaveGoggleI
|
||||||
}
|
}
|
||||||
|
|
||||||
speed = compound.getFloat("Speed");
|
speed = compound.getFloat("Speed");
|
||||||
|
sequenceContext = SequenceContext.fromNBT(compound.getCompound("Sequence"));
|
||||||
|
|
||||||
if (compound.contains("Source"))
|
if (compound.contains("Source"))
|
||||||
source = NbtUtils.readBlockPos(compound.getCompound("Source"));
|
source = NbtUtils.readBlockPos(compound.getCompound("Source"));
|
||||||
|
@ -294,13 +300,17 @@ public class KineticBlockEntity extends SmartBlockEntity implements IHaveGoggleI
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BlockEntity blockEntity = level.getBlockEntity(source);
|
BlockEntity blockEntity = level.getBlockEntity(source);
|
||||||
if (!(blockEntity instanceof KineticBlockEntity)) {
|
if (!(blockEntity instanceof KineticBlockEntity sourceBE)) {
|
||||||
removeSource();
|
removeSource();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
KineticBlockEntity sourceBE = (KineticBlockEntity) blockEntity;
|
|
||||||
setNetwork(sourceBE.network);
|
setNetwork(sourceBE.network);
|
||||||
|
copySequenceContextFrom(sourceBE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void copySequenceContextFrom(KineticBlockEntity sourceBE) {
|
||||||
|
sequenceContext = sourceBE.sequenceContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeSource() {
|
public void removeSource() {
|
||||||
|
@ -309,6 +319,7 @@ public class KineticBlockEntity extends SmartBlockEntity implements IHaveGoggleI
|
||||||
speed = 0;
|
speed = 0;
|
||||||
source = null;
|
source = null;
|
||||||
setNetwork(null);
|
setNetwork(null);
|
||||||
|
sequenceContext = null;
|
||||||
|
|
||||||
onSpeedChanged(prevSpeed);
|
onSpeedChanged(prevSpeed);
|
||||||
}
|
}
|
||||||
|
@ -592,5 +603,9 @@ public class KineticBlockEntity extends SmartBlockEntity implements IHaveGoggleI
|
||||||
public int getRotationAngleOffset(Axis axis) {
|
public int getRotationAngleOffset(Axis axis) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean syncSequenceContext() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Abs
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencerInstructions;
|
||||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||||
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollOptionBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollOptionBehaviour;
|
||||||
|
@ -35,12 +36,14 @@ public class MechanicalBearingBlockEntity extends GeneratingKineticBlockEntity
|
||||||
protected boolean assembleNextTick;
|
protected boolean assembleNextTick;
|
||||||
protected float clientAngleDiff;
|
protected float clientAngleDiff;
|
||||||
protected AssemblyException lastException;
|
protected AssemblyException lastException;
|
||||||
|
protected double sequencedAngleLimit;
|
||||||
|
|
||||||
private float prevAngle;
|
private float prevAngle;
|
||||||
|
|
||||||
public MechanicalBearingBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
public MechanicalBearingBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
setLazyTickRate(3);
|
setLazyTickRate(3);
|
||||||
|
sequencedAngleLimit = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -48,11 +51,16 @@ public class MechanicalBearingBlockEntity extends GeneratingKineticBlockEntity
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean syncSequenceContext() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||||
super.addBehaviours(behaviours);
|
super.addBehaviours(behaviours);
|
||||||
movementMode = new ScrollOptionBehaviour<>(RotationMode.class, Lang.translateDirect("contraptions.movement_mode"),
|
movementMode = new ScrollOptionBehaviour<>(RotationMode.class,
|
||||||
this, getMovementModeSlot());
|
Lang.translateDirect("contraptions.movement_mode"), this, getMovementModeSlot());
|
||||||
behaviours.add(movementMode);
|
behaviours.add(movementMode);
|
||||||
registerAwardables(behaviours, AllAdvancements.CONTRAPTION_ACTORS);
|
registerAwardables(behaviours, AllAdvancements.CONTRAPTION_ACTORS);
|
||||||
}
|
}
|
||||||
|
@ -68,6 +76,8 @@ public class MechanicalBearingBlockEntity extends GeneratingKineticBlockEntity
|
||||||
public void write(CompoundTag compound, boolean clientPacket) {
|
public void write(CompoundTag compound, boolean clientPacket) {
|
||||||
compound.putBoolean("Running", running);
|
compound.putBoolean("Running", running);
|
||||||
compound.putFloat("Angle", angle);
|
compound.putFloat("Angle", angle);
|
||||||
|
if (sequencedAngleLimit >= 0)
|
||||||
|
compound.putDouble("SequencedAngleLimit", sequencedAngleLimit);
|
||||||
AssemblyException.write(compound, lastException);
|
AssemblyException.write(compound, lastException);
|
||||||
super.write(compound, clientPacket);
|
super.write(compound, clientPacket);
|
||||||
}
|
}
|
||||||
|
@ -82,6 +92,7 @@ public class MechanicalBearingBlockEntity extends GeneratingKineticBlockEntity
|
||||||
float angleBefore = angle;
|
float angleBefore = angle;
|
||||||
running = compound.getBoolean("Running");
|
running = compound.getBoolean("Running");
|
||||||
angle = compound.getFloat("Angle");
|
angle = compound.getFloat("Angle");
|
||||||
|
sequencedAngleLimit = compound.contains("SequencedAngleLimit") ? compound.getDouble("SequencedAngleLimit") : -1;
|
||||||
lastException = AssemblyException.read(compound);
|
lastException = AssemblyException.read(compound);
|
||||||
super.read(compound, clientPacket);
|
super.read(compound, clientPacket);
|
||||||
if (!clientPacket)
|
if (!clientPacket)
|
||||||
|
@ -101,18 +112,30 @@ public class MechanicalBearingBlockEntity extends GeneratingKineticBlockEntity
|
||||||
return Mth.lerp(partialTicks + .5f, prevAngle, angle);
|
return Mth.lerp(partialTicks + .5f, prevAngle, angle);
|
||||||
if (movedContraption == null || movedContraption.isStalled() || !running)
|
if (movedContraption == null || movedContraption.isStalled() || !running)
|
||||||
partialTicks = 0;
|
partialTicks = 0;
|
||||||
return Mth.lerp(partialTicks, angle, angle + getAngularSpeed());
|
float angularSpeed = getAngularSpeed();
|
||||||
|
if (sequencedAngleLimit >= 0)
|
||||||
|
angularSpeed = (float) Mth.clamp(angularSpeed, -sequencedAngleLimit, sequencedAngleLimit);
|
||||||
|
return Mth.lerp(partialTicks, angle, angle + angularSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSpeedChanged(float prevSpeed) {
|
public void onSpeedChanged(float prevSpeed) {
|
||||||
super.onSpeedChanged(prevSpeed);
|
super.onSpeedChanged(prevSpeed);
|
||||||
assembleNextTick = true;
|
assembleNextTick = true;
|
||||||
|
sequencedAngleLimit = -1;
|
||||||
|
|
||||||
if (movedContraption != null && Math.signum(prevSpeed) != Math.signum(getSpeed()) && prevSpeed != 0) {
|
if (movedContraption != null && Math.signum(prevSpeed) != Math.signum(getSpeed()) && prevSpeed != 0) {
|
||||||
|
if (!movedContraption.isStalled()) {
|
||||||
|
angle = Math.round(angle);
|
||||||
|
applyRotation();
|
||||||
|
}
|
||||||
movedContraption.getContraption()
|
movedContraption.getContraption()
|
||||||
.stop(level);
|
.stop(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isWindmill() && sequenceContext != null
|
||||||
|
&& sequenceContext.instruction() == SequencerInstructions.TURN_ANGLE)
|
||||||
|
sequencedAngleLimit = sequenceContext.getEffectiveValue(getTheoreticalSpeed());
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAngularSpeed() {
|
public float getAngularSpeed() {
|
||||||
|
@ -171,7 +194,7 @@ public class MechanicalBearingBlockEntity extends GeneratingKineticBlockEntity
|
||||||
level.addFreshEntity(movedContraption);
|
level.addFreshEntity(movedContraption);
|
||||||
|
|
||||||
AllSoundEvents.CONTRAPTION_ASSEMBLE.playOnServer(level, worldPosition);
|
AllSoundEvents.CONTRAPTION_ASSEMBLE.playOnServer(level, worldPosition);
|
||||||
|
|
||||||
if (contraption.containsBlockBreakers())
|
if (contraption.containsBlockBreakers())
|
||||||
award(AllAdvancements.CONTRAPTION_ACTORS);
|
award(AllAdvancements.CONTRAPTION_ACTORS);
|
||||||
|
|
||||||
|
@ -185,6 +208,7 @@ public class MechanicalBearingBlockEntity extends GeneratingKineticBlockEntity
|
||||||
if (!running && movedContraption == null)
|
if (!running && movedContraption == null)
|
||||||
return;
|
return;
|
||||||
angle = 0;
|
angle = 0;
|
||||||
|
sequencedAngleLimit = -1;
|
||||||
if (isWindmill())
|
if (isWindmill())
|
||||||
applyRotation();
|
applyRotation();
|
||||||
if (movedContraption != null) {
|
if (movedContraption != null) {
|
||||||
|
@ -233,6 +257,10 @@ public class MechanicalBearingBlockEntity extends GeneratingKineticBlockEntity
|
||||||
|
|
||||||
if (!(movedContraption != null && movedContraption.isStalled())) {
|
if (!(movedContraption != null && movedContraption.isStalled())) {
|
||||||
float angularSpeed = getAngularSpeed();
|
float angularSpeed = getAngularSpeed();
|
||||||
|
if (sequencedAngleLimit >= 0) {
|
||||||
|
angularSpeed = (float) Mth.clamp(angularSpeed, -sequencedAngleLimit, sequencedAngleLimit);
|
||||||
|
sequencedAngleLimit = Math.max(0, sequencedAngleLimit - Math.abs(angularSpeed));
|
||||||
|
}
|
||||||
float newAngle = angle + angularSpeed;
|
float newAngle = angle + angularSpeed;
|
||||||
angle = (float) (newAngle % 360);
|
angle = (float) (newAngle % 360);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Con
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
||||||
import com.simibubi.create.content.contraptions.relays.advanced.GantryShaftBlock;
|
import com.simibubi.create.content.contraptions.relays.advanced.GantryShaftBlock;
|
||||||
import com.simibubi.create.content.contraptions.relays.advanced.GantryShaftBlockEntity;
|
import com.simibubi.create.content.contraptions.relays.advanced.GantryShaftBlockEntity;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencerInstructions;
|
||||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||||
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
||||||
|
|
||||||
|
@ -83,14 +84,14 @@ public class GantryCarriageBlockEntity extends KineticBlockEntity implements IDi
|
||||||
Direction direction = blockState.getValue(GantryCarriageBlock.FACING);
|
Direction direction = blockState.getValue(GantryCarriageBlock.FACING);
|
||||||
GantryContraption contraption = new GantryContraption(direction);
|
GantryContraption contraption = new GantryContraption(direction);
|
||||||
|
|
||||||
BlockEntity shaftBE = level.getBlockEntity(worldPosition.relative(direction.getOpposite()));
|
BlockEntity blockEntity = level.getBlockEntity(worldPosition.relative(direction.getOpposite()));
|
||||||
if (!(shaftBE instanceof GantryShaftBlockEntity))
|
if (!(blockEntity instanceof GantryShaftBlockEntity shaftBE))
|
||||||
return;
|
return;
|
||||||
BlockState shaftState = shaftBE.getBlockState();
|
BlockState shaftState = shaftBE.getBlockState();
|
||||||
if (!AllBlocks.GANTRY_SHAFT.has(shaftState))
|
if (!AllBlocks.GANTRY_SHAFT.has(shaftState))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float pinionMovementSpeed = ((GantryShaftBlockEntity) shaftBE).getPinionMovementSpeed();
|
float pinionMovementSpeed = shaftBE.getPinionMovementSpeed();
|
||||||
Direction shaftOrientation = shaftState.getValue(GantryShaftBlock.FACING);
|
Direction shaftOrientation = shaftState.getValue(GantryShaftBlock.FACING);
|
||||||
Direction movementDirection = shaftOrientation;
|
Direction movementDirection = shaftOrientation;
|
||||||
if (pinionMovementSpeed < 0)
|
if (pinionMovementSpeed < 0)
|
||||||
|
@ -121,6 +122,10 @@ public class GantryCarriageBlockEntity extends KineticBlockEntity implements IDi
|
||||||
movedContraption.setPos(anchor.getX(), anchor.getY(), anchor.getZ());
|
movedContraption.setPos(anchor.getX(), anchor.getY(), anchor.getZ());
|
||||||
AllSoundEvents.CONTRAPTION_ASSEMBLE.playOnServer(level, worldPosition);
|
AllSoundEvents.CONTRAPTION_ASSEMBLE.playOnServer(level, worldPosition);
|
||||||
level.addFreshEntity(movedContraption);
|
level.addFreshEntity(movedContraption);
|
||||||
|
|
||||||
|
if (shaftBE.sequenceContext != null
|
||||||
|
&& shaftBE.sequenceContext.instruction() == SequencerInstructions.TURN_DISTANCE)
|
||||||
|
movedContraption.limitMovement(shaftBE.sequenceContext.getEffectiveValue(shaftBE.getTheoreticalSpeed()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -12,6 +12,7 @@ import com.simibubi.create.content.contraptions.relays.advanced.GantryShaftBlock
|
||||||
import com.simibubi.create.foundation.networking.AllPackets;
|
import com.simibubi.create.foundation.networking.AllPackets;
|
||||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -34,8 +35,11 @@ public class GantryContraptionEntity extends AbstractContraptionEntity {
|
||||||
double clientOffsetDiff;
|
double clientOffsetDiff;
|
||||||
double axisMotion;
|
double axisMotion;
|
||||||
|
|
||||||
|
public double sequencedOffsetLimit;
|
||||||
|
|
||||||
public GantryContraptionEntity(EntityType<?> entityTypeIn, Level worldIn) {
|
public GantryContraptionEntity(EntityType<?> entityTypeIn, Level worldIn) {
|
||||||
super(entityTypeIn, worldIn);
|
super(entityTypeIn, worldIn);
|
||||||
|
sequencedOffsetLimit = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GantryContraptionEntity create(Level world, Contraption contraption, Direction movementAxis) {
|
public static GantryContraptionEntity create(Level world, Contraption contraption, Direction movementAxis) {
|
||||||
|
@ -45,6 +49,10 @@ public class GantryContraptionEntity extends AbstractContraptionEntity {
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void limitMovement(double maxOffset) {
|
||||||
|
sequencedOffsetLimit = maxOffset;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void tickContraption() {
|
protected void tickContraption() {
|
||||||
if (!(contraption instanceof GantryContraption))
|
if (!(contraption instanceof GantryContraption))
|
||||||
|
@ -66,8 +74,13 @@ public class GantryContraptionEntity extends AbstractContraptionEntity {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isStalled() && tickCount > 2)
|
if (!isStalled() && tickCount > 2) {
|
||||||
|
if (sequencedOffsetLimit >= 0)
|
||||||
|
movementVec = VecHelper.clampComponentWise(movementVec, (float) sequencedOffsetLimit);
|
||||||
move(movementVec.x, movementVec.y, movementVec.z);
|
move(movementVec.x, movementVec.y, movementVec.z);
|
||||||
|
if (sequencedOffsetLimit > 0)
|
||||||
|
sequencedOffsetLimit = Math.max(0, sequencedOffsetLimit - movementVec.length());
|
||||||
|
}
|
||||||
|
|
||||||
if (Math.signum(prevAxisMotion) != Math.signum(axisMotion) && prevAxisMotion != 0)
|
if (Math.signum(prevAxisMotion) != Math.signum(axisMotion) && prevAxisMotion != 0)
|
||||||
contraption.stop(level);
|
contraption.stop(level);
|
||||||
|
@ -75,6 +88,12 @@ public class GantryContraptionEntity extends AbstractContraptionEntity {
|
||||||
sendPacket();
|
sendPacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disassemble() {
|
||||||
|
sequencedOffsetLimit = -1;
|
||||||
|
super.disassemble();
|
||||||
|
}
|
||||||
|
|
||||||
protected void checkPinionShaft() {
|
protected void checkPinionShaft() {
|
||||||
Vec3 movementVec;
|
Vec3 movementVec;
|
||||||
Direction facing = ((GantryContraption) contraption).getFacing();
|
Direction facing = ((GantryContraption) contraption).getFacing();
|
||||||
|
@ -95,8 +114,6 @@ public class GantryContraptionEntity extends AbstractContraptionEntity {
|
||||||
GantryShaftBlockEntity gantryShaftBlockEntity = (GantryShaftBlockEntity) be;
|
GantryShaftBlockEntity gantryShaftBlockEntity = (GantryShaftBlockEntity) be;
|
||||||
|
|
||||||
float pinionMovementSpeed = gantryShaftBlockEntity.getPinionMovementSpeed();
|
float pinionMovementSpeed = gantryShaftBlockEntity.getPinionMovementSpeed();
|
||||||
movementVec = Vec3.atLowerCornerOf(direction.getNormal()).scale(pinionMovementSpeed);
|
|
||||||
|
|
||||||
if (blockState.getValue(GantryShaftBlock.POWERED) || pinionMovementSpeed == 0) {
|
if (blockState.getValue(GantryShaftBlock.POWERED) || pinionMovementSpeed == 0) {
|
||||||
setContraptionMotion(Vec3.ZERO);
|
setContraptionMotion(Vec3.ZERO);
|
||||||
if (!level.isClientSide)
|
if (!level.isClientSide)
|
||||||
|
@ -104,6 +121,11 @@ public class GantryContraptionEntity extends AbstractContraptionEntity {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sequencedOffsetLimit >= 0)
|
||||||
|
pinionMovementSpeed = (float) Mth.clamp(pinionMovementSpeed, -sequencedOffsetLimit, sequencedOffsetLimit);
|
||||||
|
movementVec = Vec3.atLowerCornerOf(direction.getNormal())
|
||||||
|
.scale(pinionMovementSpeed);
|
||||||
|
|
||||||
Vec3 nextPosition = currentPosition.add(movementVec);
|
Vec3 nextPosition = currentPosition.add(movementVec);
|
||||||
double currentCoord = direction.getAxis()
|
double currentCoord = direction.getAxis()
|
||||||
.choose(currentPosition.x, currentPosition.y, currentPosition.z);
|
.choose(currentPosition.x, currentPosition.y, currentPosition.z);
|
||||||
|
@ -121,7 +143,7 @@ public class GantryContraptionEntity extends AbstractContraptionEntity {
|
||||||
|
|
||||||
if (level.isClientSide)
|
if (level.isClientSide)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
axisMotion = pinionMovementSpeed;
|
axisMotion = pinionMovementSpeed;
|
||||||
setContraptionMotion(movementVec);
|
setContraptionMotion(movementVec);
|
||||||
}
|
}
|
||||||
|
@ -129,11 +151,15 @@ public class GantryContraptionEntity extends AbstractContraptionEntity {
|
||||||
@Override
|
@Override
|
||||||
protected void writeAdditional(CompoundTag compound, boolean spawnPacket) {
|
protected void writeAdditional(CompoundTag compound, boolean spawnPacket) {
|
||||||
NBTHelper.writeEnum(compound, "GantryAxis", movementAxis);
|
NBTHelper.writeEnum(compound, "GantryAxis", movementAxis);
|
||||||
|
if (sequencedOffsetLimit >= 0)
|
||||||
|
compound.putDouble("SequencedOffsetLimit", sequencedOffsetLimit);
|
||||||
super.writeAdditional(compound, spawnPacket);
|
super.writeAdditional(compound, spawnPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void readAdditional(CompoundTag compound, boolean spawnData) {
|
protected void readAdditional(CompoundTag compound, boolean spawnData) {
|
||||||
movementAxis = NBTHelper.readEnum(compound, "GantryAxis", Direction.class);
|
movementAxis = NBTHelper.readEnum(compound, "GantryAxis", Direction.class);
|
||||||
|
sequencedOffsetLimit =
|
||||||
|
compound.contains("SequencedOffsetLimit") ? compound.getDouble("SequencedOffsetLimit") : -1;
|
||||||
super.readAdditional(compound, spawnData);
|
super.readAdditional(compound, spawnData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,13 +202,16 @@ public class GantryContraptionEntity extends AbstractContraptionEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyLocalTransforms(PoseStack matrixStack, float partialTicks) { }
|
public void applyLocalTransforms(PoseStack matrixStack, float partialTicks) {}
|
||||||
|
|
||||||
public void updateClientMotion() {
|
public void updateClientMotion() {
|
||||||
float modifier = movementAxis.getAxisDirection()
|
float modifier = movementAxis.getAxisDirection()
|
||||||
.getStep();
|
.getStep();
|
||||||
setContraptionMotion(Vec3.atLowerCornerOf(movementAxis.getNormal())
|
Vec3 motion = Vec3.atLowerCornerOf(movementAxis.getNormal())
|
||||||
.scale((axisMotion + clientOffsetDiff * modifier / 2f) * ServerSpeedProvider.get()));
|
.scale((axisMotion + clientOffsetDiff * modifier / 2f) * ServerSpeedProvider.get());
|
||||||
|
if (sequencedOffsetLimit >= 0)
|
||||||
|
motion = VecHelper.clampComponentWise(motion, (float) sequencedOffsetLimit);
|
||||||
|
setContraptionMotion(motion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getAxisCoord() {
|
public double getAxisCoord() {
|
||||||
|
@ -192,8 +221,9 @@ public class GantryContraptionEntity extends AbstractContraptionEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendPacket() {
|
public void sendPacket() {
|
||||||
AllPackets.getChannel().send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
|
AllPackets.getChannel()
|
||||||
new GantryContraptionUpdatePacket(getId(), getAxisCoord(), axisMotion));
|
.send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
|
||||||
|
new GantryContraptionUpdatePacket(getId(), getAxisCoord(), axisMotion, sequencedOffsetLimit));
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@ -204,6 +234,7 @@ public class GantryContraptionEntity extends AbstractContraptionEntity {
|
||||||
GantryContraptionEntity ce = (GantryContraptionEntity) entity;
|
GantryContraptionEntity ce = (GantryContraptionEntity) entity;
|
||||||
ce.axisMotion = packet.motion;
|
ce.axisMotion = packet.motion;
|
||||||
ce.clientOffsetDiff = packet.coord - ce.getAxisCoord();
|
ce.clientOffsetDiff = packet.coord - ce.getAxisCoord();
|
||||||
|
ce.sequencedOffsetLimit = packet.sequenceLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,17 +12,20 @@ public class GantryContraptionUpdatePacket extends SimplePacketBase {
|
||||||
int entityID;
|
int entityID;
|
||||||
double coord;
|
double coord;
|
||||||
double motion;
|
double motion;
|
||||||
|
double sequenceLimit;
|
||||||
|
|
||||||
public GantryContraptionUpdatePacket(int entityID, double coord, double motion) {
|
public GantryContraptionUpdatePacket(int entityID, double coord, double motion, double sequenceLimit) {
|
||||||
this.entityID = entityID;
|
this.entityID = entityID;
|
||||||
this.coord = coord;
|
this.coord = coord;
|
||||||
this.motion = motion;
|
this.motion = motion;
|
||||||
|
this.sequenceLimit = sequenceLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GantryContraptionUpdatePacket(FriendlyByteBuf buffer) {
|
public GantryContraptionUpdatePacket(FriendlyByteBuf buffer) {
|
||||||
entityID = buffer.readInt();
|
entityID = buffer.readInt();
|
||||||
coord = buffer.readFloat();
|
coord = buffer.readFloat();
|
||||||
motion = buffer.readFloat();
|
motion = buffer.readFloat();
|
||||||
|
sequenceLimit = buffer.readFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -30,6 +33,7 @@ public class GantryContraptionUpdatePacket extends SimplePacketBase {
|
||||||
buffer.writeInt(entityID);
|
buffer.writeInt(entityID);
|
||||||
buffer.writeFloat((float) coord);
|
buffer.writeFloat((float) coord);
|
||||||
buffer.writeFloat((float) motion);
|
buffer.writeFloat((float) motion);
|
||||||
|
buffer.writeFloat((float) sequenceLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Con
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.IControlContraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.IControlContraption;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencerInstructions;
|
||||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||||
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform;
|
import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform;
|
||||||
|
@ -35,6 +36,7 @@ public abstract class LinearActuatorBlockEntity extends KineticBlockEntity
|
||||||
protected ScrollOptionBehaviour<MovementMode> movementMode;
|
protected ScrollOptionBehaviour<MovementMode> movementMode;
|
||||||
protected boolean waitingForSpeedChange;
|
protected boolean waitingForSpeedChange;
|
||||||
protected AssemblyException lastException;
|
protected AssemblyException lastException;
|
||||||
|
protected double sequencedOffsetLimit;
|
||||||
|
|
||||||
// Custom position sync
|
// Custom position sync
|
||||||
protected float clientOffsetDiff;
|
protected float clientOffsetDiff;
|
||||||
|
@ -44,6 +46,7 @@ public abstract class LinearActuatorBlockEntity extends KineticBlockEntity
|
||||||
setLazyTickRate(3);
|
setLazyTickRate(3);
|
||||||
forceMove = true;
|
forceMove = true;
|
||||||
needsContraption = true;
|
needsContraption = true;
|
||||||
|
sequencedOffsetLimit = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,6 +58,11 @@ public abstract class LinearActuatorBlockEntity extends KineticBlockEntity
|
||||||
behaviours.add(movementMode);
|
behaviours.add(movementMode);
|
||||||
registerAwardables(behaviours, AllAdvancements.CONTRAPTION_ACTORS);
|
registerAwardables(behaviours, AllAdvancements.CONTRAPTION_ACTORS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean syncSequenceContext() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
|
@ -112,10 +120,21 @@ public abstract class LinearActuatorBlockEntity extends KineticBlockEntity
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float movementSpeed = getMovementSpeed();
|
float movementSpeed = getMovementSpeed();
|
||||||
|
boolean locked = false;
|
||||||
|
if (sequencedOffsetLimit > 0) {
|
||||||
|
sequencedOffsetLimit = Math.max(0, sequencedOffsetLimit - Math.abs(movementSpeed));
|
||||||
|
locked = sequencedOffsetLimit == 0;
|
||||||
|
}
|
||||||
float newOffset = offset + movementSpeed;
|
float newOffset = offset + movementSpeed;
|
||||||
if ((int) newOffset != (int) offset)
|
if ((int) newOffset != (int) offset)
|
||||||
visitNewPosition();
|
visitNewPosition();
|
||||||
|
|
||||||
|
if (locked) {
|
||||||
|
forceMove = true;
|
||||||
|
resetContraptionToOffset();
|
||||||
|
sendData();
|
||||||
|
}
|
||||||
|
|
||||||
if (contraptionPresent) {
|
if (contraptionPresent) {
|
||||||
if (moveAndCollideContraption()) {
|
if (moveAndCollideContraption()) {
|
||||||
movedContraption.setContraptionMotion(Vec3.ZERO);
|
movedContraption.setContraptionMotion(Vec3.ZERO);
|
||||||
|
@ -169,6 +188,7 @@ public abstract class LinearActuatorBlockEntity extends KineticBlockEntity
|
||||||
@Override
|
@Override
|
||||||
public void onSpeedChanged(float prevSpeed) {
|
public void onSpeedChanged(float prevSpeed) {
|
||||||
super.onSpeedChanged(prevSpeed);
|
super.onSpeedChanged(prevSpeed);
|
||||||
|
sequencedOffsetLimit = -1;
|
||||||
|
|
||||||
if (isPassive())
|
if (isPassive())
|
||||||
return;
|
return;
|
||||||
|
@ -177,9 +197,16 @@ public abstract class LinearActuatorBlockEntity extends KineticBlockEntity
|
||||||
waitingForSpeedChange = false;
|
waitingForSpeedChange = false;
|
||||||
|
|
||||||
if (movedContraption != null && Math.signum(prevSpeed) != Math.signum(getSpeed()) && prevSpeed != 0) {
|
if (movedContraption != null && Math.signum(prevSpeed) != Math.signum(getSpeed()) && prevSpeed != 0) {
|
||||||
|
if (!movedContraption.isStalled()) {
|
||||||
|
offset = Math.round(offset * 16) / 16;
|
||||||
|
resetContraptionToOffset();
|
||||||
|
}
|
||||||
movedContraption.getContraption()
|
movedContraption.getContraption()
|
||||||
.stop(level);
|
.stop(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sequenceContext != null && sequenceContext.instruction() == SequencerInstructions.TURN_DISTANCE)
|
||||||
|
sequencedOffsetLimit = sequenceContext.getEffectiveValue(getTheoreticalSpeed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -195,6 +222,8 @@ public abstract class LinearActuatorBlockEntity extends KineticBlockEntity
|
||||||
compound.putBoolean("Running", running);
|
compound.putBoolean("Running", running);
|
||||||
compound.putBoolean("Waiting", waitingForSpeedChange);
|
compound.putBoolean("Waiting", waitingForSpeedChange);
|
||||||
compound.putFloat("Offset", offset);
|
compound.putFloat("Offset", offset);
|
||||||
|
if (sequencedOffsetLimit >= 0)
|
||||||
|
compound.putDouble("SequencedOffsetLimit", sequencedOffsetLimit);
|
||||||
AssemblyException.write(compound, lastException);
|
AssemblyException.write(compound, lastException);
|
||||||
super.write(compound, clientPacket);
|
super.write(compound, clientPacket);
|
||||||
|
|
||||||
|
@ -212,6 +241,8 @@ public abstract class LinearActuatorBlockEntity extends KineticBlockEntity
|
||||||
running = compound.getBoolean("Running");
|
running = compound.getBoolean("Running");
|
||||||
waitingForSpeedChange = compound.getBoolean("Waiting");
|
waitingForSpeedChange = compound.getBoolean("Waiting");
|
||||||
offset = compound.getFloat("Offset");
|
offset = compound.getFloat("Offset");
|
||||||
|
sequencedOffsetLimit =
|
||||||
|
compound.contains("SequencedOffsetLimit") ? compound.getDouble("SequencedOffsetLimit") : -1;
|
||||||
lastException = AssemblyException.read(compound);
|
lastException = AssemblyException.read(compound);
|
||||||
super.read(compound, clientPacket);
|
super.read(compound, clientPacket);
|
||||||
|
|
||||||
|
@ -308,6 +339,8 @@ public abstract class LinearActuatorBlockEntity extends KineticBlockEntity
|
||||||
float movementSpeed = Mth.clamp(convertToLinear(getSpeed()), -.49f, .49f) + clientOffsetDiff / 2f;
|
float movementSpeed = Mth.clamp(convertToLinear(getSpeed()), -.49f, .49f) + clientOffsetDiff / 2f;
|
||||||
if (level.isClientSide)
|
if (level.isClientSide)
|
||||||
movementSpeed *= ServerSpeedProvider.get();
|
movementSpeed *= ServerSpeedProvider.get();
|
||||||
|
if (sequencedOffsetLimit >= 0)
|
||||||
|
movementSpeed = (float) Mth.clamp(movementSpeed, -sequencedOffsetLimit, sequencedOffsetLimit);
|
||||||
return movementSpeed;
|
return movementSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,8 @@ public class MechanicalPistonBlockEntity extends LinearActuatorBlockEntity {
|
||||||
|
|
||||||
int extensionRange = getExtensionRange();
|
int extensionRange = getExtensionRange();
|
||||||
movementSpeed = Mth.clamp(movementSpeed, 0 - offset, extensionRange - offset);
|
movementSpeed = Mth.clamp(movementSpeed, 0 - offset, extensionRange - offset);
|
||||||
|
if (sequencedOffsetLimit >= 0)
|
||||||
|
movementSpeed = (float) Mth.clamp(movementSpeed, -sequencedOffsetLimit, sequencedOffsetLimit);
|
||||||
return movementSpeed;
|
return movementSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -404,7 +404,7 @@ public class MinecartController implements INBTSerializable<CompoundTag> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void tick(AbstractMinecart entity) {
|
void tick(AbstractMinecart entity) {
|
||||||
entity.setPos(position.x, position.y, position.z);
|
// entity.setPos(position.x, position.y, position.z);
|
||||||
entity.setDeltaMovement(Vec3.ZERO);
|
entity.setDeltaMovement(Vec3.ZERO);
|
||||||
entity.setYRot(yaw);
|
entity.setYRot(yaw);
|
||||||
entity.setXRot(pitch);
|
entity.setXRot(pitch);
|
||||||
|
|
|
@ -19,6 +19,11 @@ public class GantryShaftBlockEntity extends KineticBlockEntity {
|
||||||
super(typeIn, pos, state);
|
super(typeIn, pos, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean syncSequenceContext() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void checkAttachedCarriageBlocks() {
|
public void checkAttachedCarriageBlocks() {
|
||||||
if (!canAssembleOn())
|
if (!canAssembleOn())
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -27,28 +27,23 @@ public class Instruction {
|
||||||
int getDuration(float currentProgress, float speed) {
|
int getDuration(float currentProgress, float speed) {
|
||||||
speed *= speedModifier.value;
|
speed *= speedModifier.value;
|
||||||
speed = Math.abs(speed);
|
speed = Math.abs(speed);
|
||||||
|
|
||||||
double target = value - currentProgress;
|
double target = value - currentProgress;
|
||||||
|
|
||||||
switch (instruction) {
|
switch (instruction) {
|
||||||
|
|
||||||
|
// Always overshoot, target will stop early
|
||||||
case TURN_ANGLE:
|
case TURN_ANGLE:
|
||||||
double degreesPerTick = KineticBlockEntity.convertToAngular(speed);
|
double degreesPerTick = KineticBlockEntity.convertToAngular(speed);
|
||||||
int ticks = (int) (target / degreesPerTick);
|
return (int) Math.ceil(target / degreesPerTick) + 2;
|
||||||
double degreesErr = target - degreesPerTick*ticks;
|
|
||||||
return ticks + (degreesPerTick > 2*degreesErr ? 0 : 1);
|
|
||||||
|
|
||||||
case TURN_DISTANCE:
|
case TURN_DISTANCE:
|
||||||
double metersPerTick = KineticBlockEntity.convertToLinear(speed);
|
double metersPerTick = KineticBlockEntity.convertToLinear(speed);
|
||||||
int offset = speed > 0 && speedModifier.value < 0 ? 1 : 2;
|
return (int) Math.ceil(target / metersPerTick) + 2;
|
||||||
return (int) (target / metersPerTick + offset);
|
|
||||||
|
|
||||||
|
// Timing instructions
|
||||||
case DELAY:
|
case DELAY:
|
||||||
return (int) target;
|
return (int) target;
|
||||||
|
|
||||||
case AWAIT:
|
case AWAIT:
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
case END:
|
case END:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -58,7 +53,7 @@ public class Instruction {
|
||||||
}
|
}
|
||||||
|
|
||||||
float getTickProgress(float speed) {
|
float getTickProgress(float speed) {
|
||||||
switch(instruction) {
|
switch (instruction) {
|
||||||
|
|
||||||
case TURN_ANGLE:
|
case TURN_ANGLE:
|
||||||
return KineticBlockEntity.convertToAngular(speed);
|
return KineticBlockEntity.convertToAngular(speed);
|
||||||
|
|
|
@ -2,7 +2,9 @@ package com.simibubi.create.content.contraptions.relays.advanced.sequencer;
|
||||||
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
|
||||||
import com.simibubi.create.content.contraptions.relays.encased.SplitShaftBlockEntity;
|
import com.simibubi.create.content.contraptions.relays.encased.SplitShaftBlockEntity;
|
||||||
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
|
@ -20,6 +22,35 @@ public class SequencedGearshiftBlockEntity extends SplitShaftBlockEntity {
|
||||||
int timer;
|
int timer;
|
||||||
boolean poweredPreviously;
|
boolean poweredPreviously;
|
||||||
|
|
||||||
|
public record SequenceContext(SequencerInstructions instruction, double relativeValue) {
|
||||||
|
|
||||||
|
static SequenceContext fromGearshift(SequencerInstructions instruction, double kineticSpeed,
|
||||||
|
int absoluteValue) {
|
||||||
|
return instruction.needsPropagation()
|
||||||
|
? new SequenceContext(instruction, kineticSpeed == 0 ? 0 : absoluteValue / kineticSpeed)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getEffectiveValue(double speedAtTarget) {
|
||||||
|
return Math.abs(relativeValue * speedAtTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundTag serializeNBT() {
|
||||||
|
CompoundTag nbt = new CompoundTag();
|
||||||
|
NBTHelper.writeEnum(nbt, "Mode", instruction);
|
||||||
|
nbt.putDouble("Value", relativeValue);
|
||||||
|
return nbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SequenceContext fromNBT(CompoundTag nbt) {
|
||||||
|
if (nbt.isEmpty())
|
||||||
|
return null;
|
||||||
|
return new SequenceContext(NBTHelper.readEnum(nbt, "Mode", SequencerInstructions.class),
|
||||||
|
nbt.getDouble("Value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public SequencedGearshiftBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
public SequencedGearshiftBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
instructions = Instruction.createDefault();
|
instructions = Instruction.createDefault();
|
||||||
|
@ -113,6 +144,7 @@ public class SequencedGearshiftBlockEntity extends SplitShaftBlockEntity {
|
||||||
currentInstruction = -1;
|
currentInstruction = -1;
|
||||||
currentInstructionDuration = -1;
|
currentInstructionDuration = -1;
|
||||||
currentInstructionProgress = 0;
|
currentInstructionProgress = 0;
|
||||||
|
sequenceContext = null;
|
||||||
timer = 0;
|
timer = 0;
|
||||||
if (!level.hasNeighborSignal(worldPosition))
|
if (!level.hasNeighborSignal(worldPosition))
|
||||||
level.setBlock(worldPosition, getBlockState().setValue(SequencedGearshiftBlock.STATE, 0), 3);
|
level.setBlock(worldPosition, getBlockState().setValue(SequencedGearshiftBlock.STATE, 0), 3);
|
||||||
|
@ -125,6 +157,8 @@ public class SequencedGearshiftBlockEntity extends SplitShaftBlockEntity {
|
||||||
currentInstructionDuration = instruction.getDuration(0, getTheoreticalSpeed());
|
currentInstructionDuration = instruction.getDuration(0, getTheoreticalSpeed());
|
||||||
currentInstruction = instructionIndex;
|
currentInstruction = instructionIndex;
|
||||||
currentInstructionProgress = 0;
|
currentInstructionProgress = 0;
|
||||||
|
sequenceContext = SequenceContext.fromGearshift(instruction.instruction, getTheoreticalSpeed() * getModifier(),
|
||||||
|
instruction.value);
|
||||||
timer = 0;
|
timer = 0;
|
||||||
level.setBlock(worldPosition, getBlockState().setValue(SequencedGearshiftBlock.STATE, instructionIndex + 1), 3);
|
level.setBlock(worldPosition, getBlockState().setValue(SequencedGearshiftBlock.STATE, instructionIndex + 1), 3);
|
||||||
}
|
}
|
||||||
|
@ -134,6 +168,9 @@ public class SequencedGearshiftBlockEntity extends SplitShaftBlockEntity {
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void copySequenceContextFrom(KineticBlockEntity sourceBE) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(CompoundTag compound, boolean clientPacket) {
|
public void write(CompoundTag compound, boolean clientPacket) {
|
||||||
compound.putInt("InstructionIndex", currentInstruction);
|
compound.putInt("InstructionIndex", currentInstruction);
|
||||||
|
|
|
@ -44,6 +44,10 @@ public enum SequencerInstructions {
|
||||||
descriptiveTranslationKey = translationKey + ".descriptive";
|
descriptiveTranslationKey = translationKey + ".descriptive";
|
||||||
parameterKey = translationKey + "." + parameterName;
|
parameterKey = translationKey + "." + parameterName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean needsPropagation() {
|
||||||
|
return this == TURN_ANGLE || this == TURN_DISTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
static List<Component> getOptions() {
|
static List<Component> getOptions() {
|
||||||
List<Component> options = new ArrayList<>();
|
List<Component> options = new ArrayList<>();
|
||||||
|
|
|
@ -4,6 +4,8 @@ import com.simibubi.create.AllBlockEntityTypes;
|
||||||
import com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock;
|
import com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
|
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock;
|
import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlock;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
import com.simibubi.create.foundation.block.IBE;
|
import com.simibubi.create.foundation.block.IBE;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
@ -18,6 +20,8 @@ import net.minecraft.world.item.context.UseOnContext;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.LevelReader;
|
import net.minecraft.world.level.LevelReader;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.Mirror;
|
||||||
|
import net.minecraft.world.level.block.Rotation;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||||
|
@ -27,7 +31,8 @@ import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||||
import net.minecraft.world.level.block.state.properties.Property;
|
import net.minecraft.world.level.block.state.properties.Property;
|
||||||
import net.minecraft.world.level.material.PushReaction;
|
import net.minecraft.world.level.material.PushReaction;
|
||||||
|
|
||||||
public class EncasedBeltBlock extends RotatedPillarKineticBlock implements IBE<KineticBlockEntity> {
|
public class EncasedBeltBlock extends RotatedPillarKineticBlock
|
||||||
|
implements IBE<KineticBlockEntity>, ITransformableBlock {
|
||||||
|
|
||||||
public static final Property<Part> PART = EnumProperty.create("part", Part.class);
|
public static final Property<Part> PART = EnumProperty.create("part", Part.class);
|
||||||
public static final BooleanProperty CONNECTED_ALONG_FIRST_COORDINATE =
|
public static final BooleanProperty CONNECTED_ALONG_FIRST_COORDINATE =
|
||||||
|
@ -218,4 +223,53 @@ public class EncasedBeltBlock extends RotatedPillarKineticBlock implements IBE<K
|
||||||
return AllBlockEntityTypes.ENCASED_SHAFT.get();
|
return AllBlockEntityTypes.ENCASED_SHAFT.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState rotate(BlockState state, Rotation rot) {
|
||||||
|
return rotate(state, rot, Axis.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BlockState rotate(BlockState pState, Rotation rot, Axis rotAxis) {
|
||||||
|
Axis connectionAxis = getConnectionAxis(pState);
|
||||||
|
Direction direction = Direction.fromAxisAndDirection(connectionAxis, AxisDirection.POSITIVE);
|
||||||
|
Direction normal = Direction.fromAxisAndDirection(pState.getValue(AXIS), AxisDirection.POSITIVE);
|
||||||
|
for (int i = 0; i < rot.ordinal(); i++) {
|
||||||
|
direction = direction.getClockWise(rotAxis);
|
||||||
|
normal = normal.getClockWise(rotAxis);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction.getAxisDirection() == AxisDirection.NEGATIVE)
|
||||||
|
pState = reversePart(pState);
|
||||||
|
|
||||||
|
Axis newAxis = normal.getAxis();
|
||||||
|
Axis newConnectingDirection = direction.getAxis();
|
||||||
|
boolean alongFirst = newAxis == Axis.X && newConnectingDirection == Axis.Y
|
||||||
|
|| newAxis != Axis.X && newConnectingDirection == Axis.X;
|
||||||
|
|
||||||
|
return pState.setValue(AXIS, newAxis)
|
||||||
|
.setValue(CONNECTED_ALONG_FIRST_COORDINATE, alongFirst);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState mirror(BlockState pState, Mirror pMirror) {
|
||||||
|
Axis connectionAxis = getConnectionAxis(pState);
|
||||||
|
if (pMirror.mirror(Direction.fromAxisAndDirection(connectionAxis, AxisDirection.POSITIVE))
|
||||||
|
.getAxisDirection() == AxisDirection.POSITIVE)
|
||||||
|
return pState;
|
||||||
|
return reversePart(pState);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BlockState reversePart(BlockState pState) {
|
||||||
|
Part part = pState.getValue(PART);
|
||||||
|
if (part == Part.START)
|
||||||
|
return pState.setValue(PART, Part.END);
|
||||||
|
if (part == Part.END)
|
||||||
|
return pState.setValue(PART, Part.START);
|
||||||
|
return pState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState transform(BlockState state, StructureTransform transform) {
|
||||||
|
return rotate(mirror(state, transform.mirror), transform.rotation, transform.rotationAxis);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue