Player Feedback, Part I

This commit is contained in:
Snownee 2021-01-31 02:12:31 +08:00
parent 7221f72ddf
commit 3525ce49ce
15 changed files with 169 additions and 32 deletions

View File

@ -0,0 +1,23 @@
package com.simibubi.create.content.contraptions.components.structureMovement;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
public class AssemblyException extends RuntimeException {
public final ITextComponent message;
public AssemblyException(ITextComponent message) {
this.message = message;
}
public AssemblyException(String langKey, Object... objects) {
this(new TranslationTextComponent("gui.goggles.contraptions." + langKey, objects));
}
public static AssemblyException unmovableBlock(BlockPos pos, BlockState state) {
return new AssemblyException("unmovableBlock", pos.getX(), pos.getY(), pos.getZ(),
new TranslationTextComponent(state.getBlock().getTranslationKey()));
}
}

View File

@ -135,7 +135,7 @@ public abstract class Contraption {
stabilizedSubContraptions = new HashMap<>(); stabilizedSubContraptions = new HashMap<>();
} }
public abstract boolean assemble(World world, BlockPos pos); public abstract boolean assemble(World world, BlockPos pos) throws AssemblyException;
protected abstract boolean canAxisBeStabilized(Axis axis); protected abstract boolean canAxisBeStabilized(Axis axis);
@ -180,7 +180,7 @@ public abstract class Contraption {
if (!moveBlock(world, forcedDirection, frontier, visited)) if (!moveBlock(world, forcedDirection, frontier, visited))
return false; return false;
} }
return false; throw new AssemblyException("structureTooLarge");
} }
public void onEntityCreated(AbstractContraptionEntity entity) { public void onEntityCreated(AbstractContraptionEntity entity) {
@ -192,8 +192,12 @@ public abstract class Contraption {
StabilizedContraption subContraption = new StabilizedContraption(face); StabilizedContraption subContraption = new StabilizedContraption(face);
World world = entity.world; World world = entity.world;
BlockPos pos = blockFace.getPos(); BlockPos pos = blockFace.getPos();
if (!subContraption.assemble(world, pos)) try {
if (!subContraption.assemble(world, pos))
continue;
} catch (AssemblyException e) {
continue; continue;
}
subContraption.removeBlocksFromWorld(world, BlockPos.ZERO); subContraption.removeBlocksFromWorld(world, BlockPos.ZERO);
OrientedContraptionEntity movedContraption = OrientedContraptionEntity movedContraption =
OrientedContraptionEntity.create(world, subContraption, Optional.of(face)); OrientedContraptionEntity.create(world, subContraption, Optional.of(face));
@ -243,6 +247,7 @@ public abstract class Contraption {
fluidStorage.forEach((pos, mfs) -> mfs.tick(entity, pos, world.isRemote)); fluidStorage.forEach((pos, mfs) -> mfs.tick(entity, pos, world.isRemote));
} }
/** move the first block in frontier queue */
protected boolean moveBlock(World world, @Nullable Direction forcedDirection, Queue<BlockPos> frontier, protected boolean moveBlock(World world, @Nullable Direction forcedDirection, Queue<BlockPos> frontier,
Set<BlockPos> visited) { Set<BlockPos> visited) {
BlockPos pos = frontier.poll(); BlockPos pos = frontier.poll();
@ -250,15 +255,17 @@ public abstract class Contraption {
return false; return false;
visited.add(pos); visited.add(pos);
if (World.isOutsideBuildHeight(pos))
return true;
if (!world.isBlockPresent(pos)) if (!world.isBlockPresent(pos))
return false; throw new AssemblyException("chunkNotLoaded");
if (isAnchoringBlockAt(pos)) if (isAnchoringBlockAt(pos))
return true; return true;
BlockState state = world.getBlockState(pos); BlockState state = world.getBlockState(pos);
if (!BlockMovementTraits.movementNecessary(state, world, pos)) if (!BlockMovementTraits.movementNecessary(state, world, pos))
return true; return true;
if (!movementAllowed(state, world, pos)) if (!movementAllowed(state, world, pos))
return false; throw AssemblyException.unmovableBlock(pos, state);
if (state.getBlock() instanceof AbstractChassisBlock if (state.getBlock() instanceof AbstractChassisBlock
&& !moveChassis(world, pos, forcedDirection, frontier, visited)) && !moveChassis(world, pos, forcedDirection, frontier, visited))
return false; return false;
@ -309,7 +316,7 @@ public abstract class Contraption {
continue; continue;
if (!movementAllowed(blockState, world, offsetPos)) { if (!movementAllowed(blockState, world, offsetPos)) {
if (offset == forcedDirection) if (offset == forcedDirection)
return false; throw AssemblyException.unmovableBlock(pos, state);
continue; continue;
} }
@ -338,7 +345,10 @@ public abstract class Contraption {
} }
addBlock(pos, capture(world, pos)); addBlock(pos, capture(world, pos));
return blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get(); if (blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get())
return true;
else
throw new AssemblyException("structureTooLarge");
} }
private void moveBearing(BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited, BlockState state) { private void moveBearing(BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited, BlockState state) {
@ -414,7 +424,7 @@ public abstract class Contraption {
break; break;
} }
if (limit <= -1) if (limit <= -1)
return false; throw new AssemblyException("tooManyPistonPoles");
} }
BlockPos searchPos = pos; BlockPos searchPos = pos;
@ -433,7 +443,7 @@ public abstract class Contraption {
} }
if (limit <= -1) if (limit <= -1)
return false; throw new AssemblyException("tooManyPistonPoles");
return true; return true;
} }

View File

@ -4,6 +4,7 @@ import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.AllTags.AllBlockTags; import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes;
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
@ -29,7 +30,7 @@ public class BearingContraption extends Contraption {
} }
@Override @Override
public boolean assemble(World world, BlockPos pos) { public boolean assemble(World world, BlockPos pos) throws AssemblyException {
BlockPos offset = pos.offset(facing); BlockPos offset = pos.offset(facing);
if (!searchMovedStructure(world, offset, null)) if (!searchMovedStructure(world, offset, null))
return false; return false;

View File

@ -6,6 +6,7 @@ import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; 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.ControlledContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkContraption.HandType; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkContraption.HandType;
import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.advancement.AllTriggers;
@ -25,6 +26,7 @@ import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
public class ClockworkBearingTileEntity extends KineticTileEntity implements IBearingTileEntity { public class ClockworkBearingTileEntity extends KineticTileEntity implements IBearingTileEntity {
@ -37,6 +39,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
protected boolean running; protected boolean running;
protected boolean assembleNextTick; protected boolean assembleNextTick;
protected ITextComponent lastException;
protected ScrollOptionBehaviour<ClockHands> operationMode; protected ScrollOptionBehaviour<ClockHands> operationMode;
@ -199,8 +202,14 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
Direction direction = getBlockState().get(BlockStateProperties.FACING); Direction direction = getBlockState().get(BlockStateProperties.FACING);
// Collect Construct // Collect Construct
Pair<ClockworkContraption, ClockworkContraption> contraption = Pair<ClockworkContraption, ClockworkContraption> contraption;
ClockworkContraption.assembleClockworkAt(world, pos, direction); try {
contraption = ClockworkContraption.assembleClockworkAt(world, pos, direction);
lastException = null;
} catch (AssemblyException e) {
lastException = e.message;
return;
}
if (contraption == null) if (contraption == null)
return; return;
if (contraption.getLeft() == null) if (contraption.getLeft() == null)
@ -284,6 +293,8 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
compound.putBoolean("Running", running); compound.putBoolean("Running", running);
compound.putFloat("HourAngle", hourAngle); compound.putFloat("HourAngle", hourAngle);
compound.putFloat("MinuteAngle", minuteAngle); compound.putFloat("MinuteAngle", minuteAngle);
if (lastException != null)
compound.putString("LastException", ITextComponent.Serializer.toJson(lastException));
super.write(compound, clientPacket); super.write(compound, clientPacket);
} }
@ -295,6 +306,10 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
running = compound.getBoolean("Running"); running = compound.getBoolean("Running");
hourAngle = compound.getFloat("HourAngle"); hourAngle = compound.getFloat("HourAngle");
minuteAngle = compound.getFloat("MinuteAngle"); minuteAngle = compound.getFloat("MinuteAngle");
if (compound.contains("LastException"))
lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException"));
else
lastException = null;
super.read(compound, clientPacket); super.read(compound, clientPacket);
if (!clientPacket) if (!clientPacket)
@ -393,4 +408,12 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
return pos; return pos;
} }
@Override
public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) {
boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking);
if (lastException != null)
tooltip.add(lastException.getFormattedText());
return lastException != null || added;
}
} }

View File

@ -7,6 +7,7 @@ import java.util.Set;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes;
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
@ -39,7 +40,7 @@ public class ClockworkContraption extends Contraption {
} }
public static Pair<ClockworkContraption, ClockworkContraption> assembleClockworkAt(World world, BlockPos pos, public static Pair<ClockworkContraption, ClockworkContraption> assembleClockworkAt(World world, BlockPos pos,
Direction direction) { Direction direction) throws AssemblyException {
int hourArmBlocks = 0; int hourArmBlocks = 0;
ClockworkContraption hourArm = new ClockworkContraption(); ClockworkContraption hourArm = new ClockworkContraption();
@ -82,7 +83,7 @@ public class ClockworkContraption extends Contraption {
} }
@Override @Override
public boolean assemble(World world, BlockPos pos) { public boolean assemble(World world, BlockPos pos) throws AssemblyException {
return searchMovedStructure(world, pos, facing); return searchMovedStructure(world, pos, facing);
} }

View File

@ -6,6 +6,7 @@ import java.util.List;
import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity;
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.ControlledContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity;
import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.advancement.AllTriggers;
import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.item.TooltipHelper;
@ -22,6 +23,7 @@ import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IBearingTileEntity { public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IBearingTileEntity {
@ -31,6 +33,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
protected boolean running; protected boolean running;
protected boolean assembleNextTick; protected boolean assembleNextTick;
protected float clientAngleDiff; protected float clientAngleDiff;
protected ITextComponent lastException;
public MechanicalBearingTileEntity(TileEntityType<? extends MechanicalBearingTileEntity> type) { public MechanicalBearingTileEntity(TileEntityType<? extends MechanicalBearingTileEntity> type) {
super(type); super(type);
@ -62,6 +65,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
public void write(CompoundNBT compound, boolean clientPacket) { public void write(CompoundNBT compound, boolean clientPacket) {
compound.putBoolean("Running", running); compound.putBoolean("Running", running);
compound.putFloat("Angle", angle); compound.putFloat("Angle", angle);
if (lastException != null)
compound.putString("LastException", ITextComponent.Serializer.toJson(lastException));
super.write(compound, clientPacket); super.write(compound, clientPacket);
} }
@ -70,6 +75,10 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
float angleBefore = angle; float angleBefore = angle;
running = compound.getBoolean("Running"); running = compound.getBoolean("Running");
angle = compound.getFloat("Angle"); angle = compound.getFloat("Angle");
if (compound.contains("LastException"))
lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException"));
else
lastException = null;
super.read(compound, clientPacket); super.read(compound, clientPacket);
if (!clientPacket) if (!clientPacket)
return; return;
@ -120,8 +129,14 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
Direction direction = getBlockState().get(FACING); Direction direction = getBlockState().get(FACING);
BearingContraption contraption = new BearingContraption(isWindmill(), direction); BearingContraption contraption = new BearingContraption(isWindmill(), direction);
if (!contraption.assemble(world, pos)) try {
lastException = null;
if (!contraption.assemble(world, pos))
return;
} catch (AssemblyException e) {
lastException = e.message;
return; return;
}
if (isWindmill()) if (isWindmill())
AllTriggers.triggerForNearbyPlayers(AllTriggers.WINDMILL, world, pos, 5); AllTriggers.triggerForNearbyPlayers(AllTriggers.WINDMILL, world, pos, 5);
@ -282,4 +297,11 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
return true; return true;
} }
@Override
public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) {
boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking);
if (lastException != null)
tooltip.add(lastException.getFormattedText());
return lastException != null || added;
}
} }

View File

@ -1,6 +1,7 @@
package com.simibubi.create.content.contraptions.components.structureMovement.bearing; package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes;
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
@ -20,7 +21,7 @@ public class StabilizedContraption extends Contraption {
} }
@Override @Override
public boolean assemble(World world, BlockPos pos) { public boolean assemble(World world, BlockPos pos) throws AssemblyException {
BlockPos offset = pos.offset(facing); BlockPos offset = pos.offset(facing);
if (!searchMovedStructure(world, offset, null)) if (!searchMovedStructure(world, offset, null))
return false; return false;

View File

@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.mo
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes; import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode;
import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingHandler; import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingHandler;
@ -229,13 +230,20 @@ public class CartAssemblerBlock extends AbstractRailBlock
.isCoupledThroughContraption()) .isCoupledThroughContraption())
return; return;
CartMovementMode mode =
getTileEntityOptional(world, pos).map(te -> CartMovementMode.values()[te.movementMode.value]) Optional<CartAssemblerTileEntity> assembler = getTileEntityOptional(world, pos);
CartMovementMode mode = assembler.map(te -> CartMovementMode.values()[te.movementMode.value])
.orElse(CartMovementMode.ROTATE); .orElse(CartMovementMode.ROTATE);
MountedContraption contraption = new MountedContraption(mode); MountedContraption contraption = new MountedContraption(mode);
if (!contraption.assemble(world, pos)) try {
assembler.ifPresent(te -> te.lastException = null);
if (!contraption.assemble(world, pos))
return;
} catch (AssemblyException e) {
assembler.ifPresent(te -> te.lastException = e.message);
return; return;
}
boolean couplingFound = contraption.connectedCart != null; boolean couplingFound = contraption.connectedCart != null;
Optional<Direction> initialOrientation = cart.getMotion() Optional<Direction> initialOrientation = cart.getMotion()

View File

@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.mo
import java.util.List; import java.util.List;
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
@ -16,12 +17,14 @@ import net.minecraft.state.properties.RailShape;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.ITextComponent;
public class CartAssemblerTileEntity extends SmartTileEntity { public class CartAssemblerTileEntity extends SmartTileEntity implements IHaveGoggleInformation {
private static final int assemblyCooldown = 8; private static final int assemblyCooldown = 8;
protected ScrollOptionBehaviour<CartMovementMode> movementMode; protected ScrollOptionBehaviour<CartMovementMode> movementMode;
private int ticksSinceMinecartUpdate; private int ticksSinceMinecartUpdate;
protected ITextComponent lastException; //TODO
public CartAssemblerTileEntity(TileEntityType<? extends CartAssemblerTileEntity> type) { public CartAssemblerTileEntity(TileEntityType<? extends CartAssemblerTileEntity> type) {
super(type); super(type);
@ -104,4 +107,10 @@ public class CartAssemblerTileEntity extends SmartTileEntity {
return ticksSinceMinecartUpdate >= assemblyCooldown; return ticksSinceMinecartUpdate >= assemblyCooldown;
} }
@Override
public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) {
if (lastException != null)
tooltip.add(lastException.getFormattedText());
return lastException != null;
}
} }

View File

@ -8,6 +8,7 @@ import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes;
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
@ -52,7 +53,7 @@ public class MountedContraption extends Contraption {
} }
@Override @Override
public boolean assemble(World world, BlockPos pos) { public boolean assemble(World world, BlockPos pos) throws AssemblyException {
BlockState state = world.getBlockState(pos); BlockState state = world.getBlockState(pos);
if (!state.has(RAIL_SHAPE)) if (!state.has(RAIL_SHAPE))
return false; return false;

View File

@ -4,6 +4,7 @@ import java.util.List;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; 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.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.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
@ -17,6 +18,7 @@ import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.ITextComponent;
public abstract class LinearActuatorTileEntity extends KineticTileEntity implements IControlContraption { public abstract class LinearActuatorTileEntity extends KineticTileEntity implements IControlContraption {
@ -27,6 +29,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
protected boolean forceMove; protected boolean forceMove;
protected ScrollOptionBehaviour<MovementMode> movementMode; protected ScrollOptionBehaviour<MovementMode> movementMode;
protected boolean waitingForSpeedChange; protected boolean waitingForSpeedChange;
protected ITextComponent lastException;
// Custom position sync // Custom position sync
protected float clientOffsetDiff; protected float clientOffsetDiff;
@ -80,7 +83,12 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
return; return;
} else { } else {
if (getSpeed() != 0) if (getSpeed() != 0)
assemble(); try {
assemble();
lastException = null;
} catch (AssemblyException e) {
lastException = e.message;
}
} }
return; return;
} }
@ -153,6 +161,8 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
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 (lastException != null)
compound.putString("LastException", ITextComponent.Serializer.toJson(lastException));
super.write(compound, clientPacket); super.write(compound, clientPacket);
if (clientPacket && forceMove) { if (clientPacket && forceMove) {
@ -169,6 +179,10 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
running = compound.getBoolean("Running"); running = compound.getBoolean("Running");
waitingForSpeedChange = compound.getBoolean("Waiting"); waitingForSpeedChange = compound.getBoolean("Waiting");
offset = compound.getFloat("Offset"); offset = compound.getFloat("Offset");
if (compound.contains("LastException"))
lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException"));
else
lastException = null;
super.read(compound, clientPacket); super.read(compound, clientPacket);
if (!clientPacket) if (!clientPacket)
@ -185,7 +199,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
public abstract void disassemble(); public abstract void disassemble();
protected abstract void assemble(); protected abstract void assemble() throws AssemblyException;
protected abstract int getExtensionRange(); protected abstract int getExtensionRange();
@ -289,4 +303,12 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
return pos; return pos;
} }
@Override
public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) {
boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking);
if (lastException != null)
tooltip.add(lastException.getFormattedText());
return lastException != null || added;
}
} }

View File

@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.pi
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider;
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.DirectionalExtenderScrollOptionSlot; import com.simibubi.create.content.contraptions.components.structureMovement.DirectionalExtenderScrollOptionSlot;
@ -41,7 +42,7 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
} }
@Override @Override
public void assemble() { public void assemble() throws AssemblyException {
if (!(world.getBlockState(pos) if (!(world.getBlockState(pos)
.getBlock() instanceof MechanicalPistonBlock)) .getBlock() instanceof MechanicalPistonBlock))
return; return;

View File

@ -1,6 +1,7 @@
package com.simibubi.create.content.contraptions.components.structureMovement.piston; package com.simibubi.create.content.contraptions.components.structureMovement.piston;
import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes;
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits; import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits;
import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption; import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption;
import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.*; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.*;
@ -52,7 +53,7 @@ public class PistonContraption extends TranslatingContraption {
} }
@Override @Override
public boolean assemble(World world, BlockPos pos) { public boolean assemble(World world, BlockPos pos) throws AssemblyException {
if (!collectExtensions(world, pos, orientation)) if (!collectExtensions(world, pos, orientation))
return false; return false;
int count = blocks.size(); int count = blocks.size();
@ -90,7 +91,7 @@ public class PistonContraption extends TranslatingContraption {
nextBlock = world.getBlockState(actualStart.offset(direction)); nextBlock = world.getBlockState(actualStart.offset(direction));
if (extensionsInFront > MechanicalPistonBlock.maxAllowedPistonPoles()) if (extensionsInFront > MechanicalPistonBlock.maxAllowedPistonPoles())
return false; throw new AssemblyException("tooManyPistonPoles");
} }
} }
@ -113,7 +114,7 @@ public class PistonContraption extends TranslatingContraption {
nextBlock = world.getBlockState(end.offset(direction.getOpposite())); nextBlock = world.getBlockState(end.offset(direction.getOpposite()));
if (extensionsInFront + extensionsInBack > MechanicalPistonBlock.maxAllowedPistonPoles()) if (extensionsInFront + extensionsInBack > MechanicalPistonBlock.maxAllowedPistonPoles())
return false; throw new AssemblyException("tooManyPistonPoles");
} }
anchor = pos.offset(direction, initialExtensionProgress + 1); anchor = pos.offset(direction, initialExtensionProgress + 1);
@ -125,7 +126,7 @@ public class PistonContraption extends TranslatingContraption {
1, 1); 1, 1);
if (extensionLength == 0) if (extensionLength == 0)
return false; throw new AssemblyException("noPistonPoles");
bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0); bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
@ -155,8 +156,10 @@ public class PistonContraption extends TranslatingContraption {
if (offset == 1 && retracting) if (offset == 1 && retracting)
return true; return true;
BlockPos currentPos = pos.offset(orientation, offset + initialExtensionProgress); BlockPos currentPos = pos.offset(orientation, offset + initialExtensionProgress);
if (retracting && World.isOutsideBuildHeight(currentPos))
return true;
if (!world.isBlockPresent(currentPos)) if (!world.isBlockPresent(currentPos))
return false; throw new AssemblyException("chunkNotLoaded");
BlockState state = world.getBlockState(currentPos); BlockState state = world.getBlockState(currentPos);
if (!BlockMovementTraits.movementNecessary(state, world, currentPos)) if (!BlockMovementTraits.movementNecessary(state, world, currentPos))
return true; return true;
@ -165,7 +168,10 @@ public class PistonContraption extends TranslatingContraption {
if (isPistonHead(state) && state.get(FACING) == direction.getOpposite()) if (isPistonHead(state) && state.get(FACING) == direction.getOpposite())
return true; return true;
if (!BlockMovementTraits.movementAllowed(state, world, currentPos)) if (!BlockMovementTraits.movementAllowed(state, world, currentPos))
return retracting; if (retracting)
return true;
else
throw AssemblyException.unmovableBlock(currentPos, state);
if (retracting && state.getPushReaction() == PushReaction.PUSH_ONLY) if (retracting && state.getPushReaction() == PushReaction.PUSH_ONLY)
return true; return true;
frontier.add(currentPos); frontier.add(currentPos);

View File

@ -1,6 +1,7 @@
package com.simibubi.create.content.contraptions.components.structureMovement.pulley; package com.simibubi.create.content.contraptions.components.structureMovement.pulley;
import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes;
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption; import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
@ -23,7 +24,7 @@ public class PulleyContraption extends TranslatingContraption {
} }
@Override @Override
public boolean assemble(World world, BlockPos pos) { public boolean assemble(World world, BlockPos pos) throws AssemblyException {
if (!searchMovedStructure(world, pos, null)) if (!searchMovedStructure(world, pos, null))
return false; return false;
startMoving(world); startMoving(world);

View File

@ -1,6 +1,7 @@
package com.simibubi.create.content.contraptions.components.structureMovement.pulley; package com.simibubi.create.content.contraptions.components.structureMovement.pulley;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits; import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider;
import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity;
@ -22,6 +23,7 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.ITextComponent;
public class PulleyTileEntity extends LinearActuatorTileEntity { public class PulleyTileEntity extends LinearActuatorTileEntity {
@ -42,7 +44,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
} }
@Override @Override
protected void assemble() { protected void assemble() throws AssemblyException {
if (!(world.getBlockState(pos) if (!(world.getBlockState(pos)
.getBlock() instanceof PulleyBlock)) .getBlock() instanceof PulleyBlock))
return; return;
@ -189,12 +191,18 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
@Override @Override
protected void read(CompoundNBT compound, boolean clientPacket) { protected void read(CompoundNBT compound, boolean clientPacket) {
initialOffset = compound.getInt("InitialOffset"); initialOffset = compound.getInt("InitialOffset");
if (compound.contains("LastException"))
lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException"));
else
lastException = null;
super.read(compound, clientPacket); super.read(compound, clientPacket);
} }
@Override @Override
public void write(CompoundNBT compound, boolean clientPacket) { public void write(CompoundNBT compound, boolean clientPacket) {
compound.putInt("InitialOffset", initialOffset); compound.putInt("InitialOffset", initialOffset);
if (lastException != null)
compound.putString("LastException", ITextComponent.Serializer.toJson(lastException));
super.write(compound, clientPacket); super.write(compound, clientPacket);
} }