Improve stability of sequenced gearshift (esp. for rotations) (#1695)

This commit is contained in:
reidbhuntley 2021-05-31 15:42:12 -04:00 committed by GitHub
parent a9ced3fea2
commit 53ba59c082
Failed to generate hash of commit
8 changed files with 57 additions and 20 deletions

View file

@ -477,6 +477,10 @@ public abstract class KineticTileEntity extends SmartTileEntity
return d.getAxisDirection() == AxisDirection.POSITIVE ? axisSpeed : -axisSpeed; return d.getAxisDirection() == AxisDirection.POSITIVE ? axisSpeed : -axisSpeed;
} }
public static float convertToLinear(float speed) { return speed / 512f; }
public static float convertToAngular(float speed) { return speed * 3 / 10f; }
public boolean isOverStressed() { public boolean isOverStressed() {
return overStressed; return overStressed;
} }

View file

@ -6,6 +6,7 @@ import java.util.List;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
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;
@ -80,7 +81,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity
super.fromTag(state, compound, clientPacket); super.fromTag(state, compound, clientPacket);
return; return;
} }
float angleBefore = angle; float angleBefore = angle;
running = compound.getBoolean("Running"); running = compound.getBoolean("Running");
angle = compound.getFloat("Angle"); angle = compound.getFloat("Angle");
@ -108,7 +109,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity
public void onSpeedChanged(float prevSpeed) { public void onSpeedChanged(float prevSpeed) {
super.onSpeedChanged(prevSpeed); super.onSpeedChanged(prevSpeed);
assembleNextTick = true; assembleNextTick = true;
if (movedContraption != null && Math.signum(prevSpeed) != Math.signum(getSpeed()) && prevSpeed != 0) { if (movedContraption != null && Math.signum(prevSpeed) != Math.signum(getSpeed()) && prevSpeed != 0) {
movedContraption.getContraption() movedContraption.getContraption()
.stop(world); .stop(world);
@ -116,7 +117,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity
} }
public float getAngularSpeed() { public float getAngularSpeed() {
float speed = (isWindmill() ? getGeneratedSpeed() : getSpeed()) * 3 / 10f; float speed = convertToAngular(isWindmill() ? getGeneratedSpeed() : getSpeed());
if (getSpeed() == 0) if (getSpeed() == 0)
speed = 0; speed = 0;
if (world.isRemote) { if (world.isRemote) {
@ -169,7 +170,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity
movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ()); movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
movedContraption.setRotationAxis(direction.getAxis()); movedContraption.setRotationAxis(direction.getAxis());
world.addEntity(movedContraption); world.addEntity(movedContraption);
AllSoundEvents.CONTRAPTION_ASSEMBLE.playOnServer(world, pos); AllSoundEvents.CONTRAPTION_ASSEMBLE.playOnServer(world, pos);
running = true; running = true;
@ -216,14 +217,13 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity
movedContraption.getContraption() movedContraption.getContraption()
.stop(world); .stop(world);
disassemble(); disassemble();
return;
} }
return;
} else { } else {
if (speed == 0 && !isWindmill()) if (speed == 0 && !isWindmill())
return; return;
assemble(); assemble();
} }
return;
} }
if (!running) if (!running)

View file

@ -270,7 +270,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity
} }
public float getMovementSpeed() { public float getMovementSpeed() {
float movementSpeed = MathHelper.clamp(getSpeed() / 512f, -.49f, .49f) + clientOffsetDiff / 2f; float movementSpeed = MathHelper.clamp(convertToLinear(getSpeed()), -.49f, .49f) + clientOffsetDiff / 2f;
if (world.isRemote) if (world.isRemote)
movementSpeed *= ServerSpeedProvider.get(); movementSpeed *= ServerSpeedProvider.get();
return movementSpeed; return movementSpeed;

View file

@ -84,7 +84,7 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
applyContraptionPosition(); applyContraptionPosition();
forceMove = true; forceMove = true;
world.addEntity(movedContraption); world.addEntity(movedContraption);
AllSoundEvents.CONTRAPTION_ASSEMBLE.playOnServer(world, pos); AllSoundEvents.CONTRAPTION_ASSEMBLE.playOnServer(world, pos);
} }
@ -118,7 +118,7 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
@Override @Override
public float getMovementSpeed() { public float getMovementSpeed() {
float movementSpeed = MathHelper.clamp(getSpeed() / 512f, -.49f, .49f); float movementSpeed = MathHelper.clamp(convertToLinear(getSpeed()), -.49f, .49f);
if (world.isRemote) if (world.isRemote)
movementSpeed *= ServerSpeedProvider.get(); movementSpeed *= ServerSpeedProvider.get();
Direction pistonDirection = getBlockState().get(BlockStateProperties.FACING); Direction pistonDirection = getBlockState().get(BlockStateProperties.FACING);

View file

@ -175,7 +175,7 @@ public class HosePulleyTileEntity extends KineticTileEntity {
} }
public float getMovementSpeed() { public float getMovementSpeed() {
float movementSpeed = getSpeed() / 512f; float movementSpeed = convertToLinear(getSpeed());
if (world.isRemote) if (world.isRemote)
movementSpeed *= ServerSpeedProvider.get(); movementSpeed *= ServerSpeedProvider.get();
return movementSpeed; return movementSpeed;

View file

@ -99,7 +99,7 @@ public class GantryShaftTileEntity extends KineticTileEntity {
BlockState blockState = getBlockState(); BlockState blockState = getBlockState();
if (!AllBlocks.GANTRY_SHAFT.has(blockState)) if (!AllBlocks.GANTRY_SHAFT.has(blockState))
return 0; return 0;
return MathHelper.clamp(-getSpeed() / 512f, -.49f, .49f); return MathHelper.clamp(convertToLinear(-getSpeed()), -.49f, .49f);
} }
@Override @Override

View file

@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.relays.advanced.sequencer;
import java.util.Vector; import java.util.Vector;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
@ -23,23 +24,27 @@ public class Instruction {
this.value = value; this.value = value;
} }
int getDuration(float initialProgress, float speed) { int getDuration(float currentProgress, float speed) {
int offset = speed > 0 && speedModifier.value < 0 ? 1 : 2;
speed *= speedModifier.value; speed *= speedModifier.value;
speed = Math.abs(speed); speed = Math.abs(speed);
double degreesPerTick = (speed * 360) / 60 / 20; double target = value - currentProgress;
double metersPerTick = speed / 512;
switch (instruction) { switch (instruction) {
case TURN_ANGLE: case TURN_ANGLE:
return (int) ((1 - initialProgress) * value / degreesPerTick + 1); double degreesPerTick = KineticTileEntity.convertToAngular(speed);
int ticks = (int) (target / degreesPerTick);
double degreesErr = target - degreesPerTick*ticks;
return ticks + (degreesPerTick > 2*degreesErr ? 0 : 1);
case TURN_DISTANCE: case TURN_DISTANCE:
return (int) ((1 - initialProgress) * value / metersPerTick + offset); double metersPerTick = KineticTileEntity.convertToLinear(speed);
int offset = speed > 0 && speedModifier.value < 0 ? 1 : 2;
return (int) (target / metersPerTick + offset);
case DELAY: case DELAY:
return (int) ((1 - initialProgress) * value + 1); return (int) target;
case AWAIT: case AWAIT:
return -1; return -1;
@ -52,6 +57,27 @@ public class Instruction {
return 0; return 0;
} }
float getTickProgress(float speed) {
switch(instruction) {
case TURN_ANGLE:
return KineticTileEntity.convertToAngular(speed);
case TURN_DISTANCE:
return KineticTileEntity.convertToLinear(speed);
case DELAY:
return 1;
case AWAIT:
case END:
default:
break;
}
return 0;
}
int getSpeedModifier() { int getSpeedModifier() {
switch (instruction) { switch (instruction) {

View file

@ -15,6 +15,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
Vector<Instruction> instructions; Vector<Instruction> instructions;
int currentInstruction; int currentInstruction;
int currentInstructionDuration; int currentInstructionDuration;
float currentInstructionProgress;
int timer; int timer;
boolean poweredPreviously; boolean poweredPreviously;
@ -23,6 +24,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
instructions = Instruction.createDefault(); instructions = Instruction.createDefault();
currentInstruction = -1; currentInstruction = -1;
currentInstructionDuration = -1; currentInstructionDuration = -1;
currentInstructionProgress = 0;
timer = 0; timer = 0;
poweredPreviously = false; poweredPreviously = false;
} }
@ -39,6 +41,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
return; return;
if (timer < currentInstructionDuration) { if (timer < currentInstructionDuration) {
timer++; timer++;
currentInstructionProgress += getInstruction(currentInstruction).getTickProgress(speed);
return; return;
} }
run(currentInstruction + 1); run(currentInstruction + 1);
@ -59,8 +62,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
run(-1); run(-1);
// Update instruction time with regards to new speed // Update instruction time with regards to new speed
float initialProgress = timer / (float) currentInstructionDuration; currentInstructionDuration = instruction.getDuration(currentInstructionProgress, getTheoreticalSpeed());
currentInstructionDuration = instruction.getDuration(initialProgress, getTheoreticalSpeed());
timer = 0; timer = 0;
} }
@ -109,6 +111,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
detachKinetics(); detachKinetics();
currentInstruction = -1; currentInstruction = -1;
currentInstructionDuration = -1; currentInstructionDuration = -1;
currentInstructionProgress = 0;
timer = 0; timer = 0;
if (!world.isBlockPowered(pos)) if (!world.isBlockPowered(pos))
world.setBlockState(pos, getBlockState().with(SequencedGearshiftBlock.STATE, 0), 3); world.setBlockState(pos, getBlockState().with(SequencedGearshiftBlock.STATE, 0), 3);
@ -119,7 +122,9 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
detachKinetics(); detachKinetics();
currentInstructionDuration = instruction.getDuration(0, getTheoreticalSpeed()); currentInstructionDuration = instruction.getDuration(0, getTheoreticalSpeed());
System.out.println("Dur.: " + currentInstructionDuration);
currentInstruction = instructionIndex; currentInstruction = instructionIndex;
currentInstructionProgress = 0;
timer = 0; timer = 0;
world.setBlockState(pos, getBlockState().with(SequencedGearshiftBlock.STATE, instructionIndex + 1), 3); world.setBlockState(pos, getBlockState().with(SequencedGearshiftBlock.STATE, instructionIndex + 1), 3);
} }
@ -133,6 +138,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
public void write(CompoundNBT compound, boolean clientPacket) { public void write(CompoundNBT compound, boolean clientPacket) {
compound.putInt("InstructionIndex", currentInstruction); compound.putInt("InstructionIndex", currentInstruction);
compound.putInt("InstructionDuration", currentInstructionDuration); compound.putInt("InstructionDuration", currentInstructionDuration);
compound.putFloat("InstructionProgress", currentInstructionProgress);
compound.putInt("Timer", timer); compound.putInt("Timer", timer);
compound.putBoolean("PrevPowered", poweredPreviously); compound.putBoolean("PrevPowered", poweredPreviously);
compound.put("Instructions", Instruction.serializeAll(instructions)); compound.put("Instructions", Instruction.serializeAll(instructions));
@ -143,6 +149,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) { protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) {
currentInstruction = compound.getInt("InstructionIndex"); currentInstruction = compound.getInt("InstructionIndex");
currentInstructionDuration = compound.getInt("InstructionDuration"); currentInstructionDuration = compound.getInt("InstructionDuration");
currentInstructionProgress = compound.getFloat("InstructionProgress");
poweredPreviously = compound.getBoolean("PrevPowered"); poweredPreviously = compound.getBoolean("PrevPowered");
timer = compound.getInt("Timer"); timer = compound.getInt("Timer");
instructions = Instruction.deserializeAll(compound.getList("Instructions", NBT.TAG_COMPOUND)); instructions = Instruction.deserializeAll(compound.getList("Instructions", NBT.TAG_COMPOUND));