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;
}
public static float convertToLinear(float speed) { return speed / 512f; }
public static float convertToAngular(float speed) { return speed * 3 / 10f; }
public boolean isOverStressed() {
return overStressed;
}

View file

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

View file

@ -270,7 +270,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity
}
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)
movementSpeed *= ServerSpeedProvider.get();
return movementSpeed;

View file

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

View file

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

View file

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

View file

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

View file

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