mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-29 08:27:03 +01:00
Merge branch 'mc1.15/dev' into mc1.15/ponder-ui
This commit is contained in:
commit
fd99acc00a
41 changed files with 732 additions and 356 deletions
|
@ -822,6 +822,12 @@
|
|||
"create.gui.goggles.kinetic_stats": "Kinetic Stats:",
|
||||
"create.gui.goggles.at_current_speed": "at current speed",
|
||||
"create.gui.goggles.pole_length": "Pole Length:",
|
||||
"create.gui.assembly.exception": "This Contraption was unable to assemble:",
|
||||
"create.gui.assembly.exception.unmovableBlock": "Unmovable Block (%4$s) at [%1$s %2$s %3$s]",
|
||||
"create.gui.assembly.exception.chunkNotLoaded": "The Block at [%1$s %2$s %3$s] was not in a loaded chunk",
|
||||
"create.gui.assembly.exception.structureTooLarge": "There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s",
|
||||
"create.gui.assembly.exception.tooManyPistonPoles": "There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s",
|
||||
"create.gui.assembly.exception.noPistonPoles": "The Piston is missing some extension Poles",
|
||||
"create.gui.gauge.info_header": "Gauge Information:",
|
||||
"create.gui.speedometer.title": "Rotation Speed",
|
||||
"create.gui.stressometer.title": "Network Stress",
|
||||
|
|
|
@ -823,6 +823,12 @@
|
|||
"create.gui.goggles.kinetic_stats": "UNLOCALIZED: Kinetic Stats:",
|
||||
"create.gui.goggles.at_current_speed": "UNLOCALIZED: at current speed",
|
||||
"create.gui.goggles.pole_length": "UNLOCALIZED: Pole Length:",
|
||||
"create.gui.assembly.exception": "UNLOCALIZED: This Contraption was unable to assemble:",
|
||||
"create.gui.assembly.exception.unmovableBlock": "UNLOCALIZED: Unmovable Block (%4$s) at [%1$s %2$s %3$s]",
|
||||
"create.gui.assembly.exception.chunkNotLoaded": "UNLOCALIZED: The Block at [%1$s %2$s %3$s] was not in a loaded chunk",
|
||||
"create.gui.assembly.exception.structureTooLarge": "UNLOCALIZED: There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s",
|
||||
"create.gui.assembly.exception.tooManyPistonPoles": "UNLOCALIZED: There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s",
|
||||
"create.gui.assembly.exception.noPistonPoles": "UNLOCALIZED: The Piston is missing some extension Poles",
|
||||
"create.gui.gauge.info_header": "UNLOCALIZED: Gauge Information:",
|
||||
"create.gui.speedometer.title": "UNLOCALIZED: Rotation Speed",
|
||||
"create.gui.stressometer.title": "UNLOCALIZED: Network Stress",
|
||||
|
|
|
@ -38,7 +38,7 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
|
|||
if (!(tileEntity instanceof KineticTileEntity))
|
||||
return;
|
||||
KineticTileEntity sourceTe = (KineticTileEntity) tileEntity;
|
||||
if (reActivateSource && sourceTe != null && Math.abs(sourceTe.getSpeed()) >= Math.abs(getGeneratedSpeed()))
|
||||
if (reActivateSource && Math.abs(sourceTe.getSpeed()) >= Math.abs(getGeneratedSpeed()))
|
||||
reActivateSource = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
|
||||
public class AssemblyException extends Exception {
|
||||
public final ITextComponent component;
|
||||
private BlockPos position = null;
|
||||
|
||||
public static void write(CompoundNBT compound, AssemblyException exception) {
|
||||
if (exception == null)
|
||||
return;
|
||||
|
||||
CompoundNBT nbt = new CompoundNBT();
|
||||
nbt.putString("Component", ITextComponent.Serializer.toJson(exception.component));
|
||||
if (exception.hasPosition())
|
||||
nbt.putLong("Position", exception.getPosition().toLong());
|
||||
|
||||
compound.put("LastException", nbt);
|
||||
}
|
||||
|
||||
public static AssemblyException read(CompoundNBT compound) {
|
||||
if (!compound.contains("LastException"))
|
||||
return null;
|
||||
|
||||
CompoundNBT nbt = compound.getCompound("LastException");
|
||||
String string = nbt.getString("Component");
|
||||
AssemblyException exception = new AssemblyException(ITextComponent.Serializer.fromJson(string));
|
||||
if (nbt.contains("Position"))
|
||||
exception.position = BlockPos.fromLong(nbt.getLong("Position"));
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
public AssemblyException(ITextComponent component) {
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public AssemblyException(String langKey, Object... objects) {
|
||||
this(new TranslationTextComponent("create.gui.assembly.exception." + langKey, objects));
|
||||
}
|
||||
|
||||
public static AssemblyException unmovableBlock(BlockPos pos, BlockState state) {
|
||||
AssemblyException e = new AssemblyException("unmovableBlock",
|
||||
pos.getX(),
|
||||
pos.getY(),
|
||||
pos.getZ(),
|
||||
new TranslationTextComponent(state.getBlock().getTranslationKey()));
|
||||
e.position = pos;
|
||||
return e;
|
||||
}
|
||||
|
||||
public static AssemblyException unloadedChunk(BlockPos pos) {
|
||||
AssemblyException e = new AssemblyException("chunkNotLoaded",
|
||||
pos.getX(),
|
||||
pos.getY(),
|
||||
pos.getZ());
|
||||
e.position = pos;
|
||||
return e;
|
||||
}
|
||||
|
||||
public static AssemblyException structureTooLarge() {
|
||||
return new AssemblyException("structureTooLarge",
|
||||
AllConfigs.SERVER.kinetics.maxBlocksMoved.get());
|
||||
}
|
||||
|
||||
public static AssemblyException tooManyPistonPoles() {
|
||||
return new AssemblyException("tooManyPistonPoles",
|
||||
AllConfigs.SERVER.kinetics.maxPistonPoles.get());
|
||||
}
|
||||
|
||||
public static AssemblyException noPistonPoles() {
|
||||
return new AssemblyException("noPistonPoles");
|
||||
}
|
||||
|
||||
public String getFormattedText() {
|
||||
return component.getFormattedText();
|
||||
}
|
||||
|
||||
public boolean hasPosition() {
|
||||
return position != null;
|
||||
}
|
||||
|
||||
public BlockPos getPosition() {
|
||||
return position;
|
||||
}
|
||||
}
|
|
@ -53,8 +53,7 @@ import net.minecraft.world.World;
|
|||
|
||||
public class BlockMovementTraits {
|
||||
|
||||
public static boolean movementNecessary(World world, BlockPos pos) {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
public static boolean movementNecessary(BlockState state, World world, BlockPos pos) {
|
||||
if (isBrittle(state))
|
||||
return true;
|
||||
if (state.getBlock() instanceof FenceGateBlock)
|
||||
|
@ -68,18 +67,17 @@ public class BlockMovementTraits {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static boolean movementAllowed(World world, BlockPos pos) {
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
Block block = blockState.getBlock();
|
||||
public static boolean movementAllowed(BlockState state, World world, BlockPos pos) {
|
||||
Block block = state.getBlock();
|
||||
if (block instanceof AbstractChassisBlock)
|
||||
return true;
|
||||
if (blockState.getBlockHardness(world, pos) == -1)
|
||||
if (state.getBlockHardness(world, pos) == -1)
|
||||
return false;
|
||||
if (AllBlockTags.NON_MOVABLE.matches(blockState))
|
||||
if (AllBlockTags.NON_MOVABLE.matches(state))
|
||||
return false;
|
||||
|
||||
// Move controllers only when they aren't moving
|
||||
if (block instanceof MechanicalPistonBlock && blockState.get(MechanicalPistonBlock.STATE) != PistonState.MOVING)
|
||||
if (block instanceof MechanicalPistonBlock && state.get(MechanicalPistonBlock.STATE) != PistonState.MOVING)
|
||||
return true;
|
||||
if (block instanceof MechanicalBearingBlock) {
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
|
@ -97,11 +95,11 @@ public class BlockMovementTraits {
|
|||
return !((PulleyTileEntity) te).running;
|
||||
}
|
||||
|
||||
if (AllBlocks.BELT.has(blockState))
|
||||
if (AllBlocks.BELT.has(state))
|
||||
return true;
|
||||
if (blockState.getBlock() instanceof GrindstoneBlock)
|
||||
if (state.getBlock() instanceof GrindstoneBlock)
|
||||
return true;
|
||||
return blockState.getPushReaction() != PushReaction.BLOCK;
|
||||
return state.getPushReaction() != PushReaction.BLOCK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,26 +1,5 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||
|
||||
import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isExtensionPole;
|
||||
import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isPistonHead;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
import com.simibubi.create.content.contraptions.base.IRotate;
|
||||
|
@ -55,15 +34,7 @@ import com.simibubi.create.foundation.utility.NBTHelper;
|
|||
import com.simibubi.create.foundation.utility.NBTProcessors;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
|
||||
|
||||
import net.minecraft.block.AbstractButtonBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.ChestBlock;
|
||||
import net.minecraft.block.DoorBlock;
|
||||
import net.minecraft.block.IWaterLoggable;
|
||||
import net.minecraft.block.PressurePlateBlock;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
|
@ -96,6 +67,16 @@ import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
|
|||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isExtensionPole;
|
||||
import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isPistonHead;
|
||||
|
||||
public abstract class Contraption {
|
||||
|
||||
|
@ -139,7 +120,7 @@ public abstract class Contraption {
|
|||
stabilizedSubContraptions = new HashMap<>();
|
||||
}
|
||||
|
||||
public abstract boolean assemble(World world, BlockPos pos);
|
||||
public abstract boolean assemble(World world, BlockPos pos) throws AssemblyException;
|
||||
|
||||
public abstract boolean canBeStabilized(Direction facing, BlockPos localPos);
|
||||
|
||||
|
@ -154,7 +135,7 @@ public abstract class Contraption {
|
|||
}
|
||||
|
||||
protected boolean addToInitialFrontier(World world, BlockPos pos, Direction forcedDirection,
|
||||
List<BlockPos> frontier) {
|
||||
Queue<BlockPos> frontier) throws AssemblyException {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -165,9 +146,9 @@ public abstract class Contraption {
|
|||
return contraption;
|
||||
}
|
||||
|
||||
public boolean searchMovedStructure(World world, BlockPos pos, @Nullable Direction forcedDirection) {
|
||||
public boolean searchMovedStructure(World world, BlockPos pos, @Nullable Direction forcedDirection) throws AssemblyException {
|
||||
initialPassengers.clear();
|
||||
List<BlockPos> frontier = new ArrayList<>();
|
||||
Queue<BlockPos> frontier = new LinkedList<>();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
anchor = pos;
|
||||
|
||||
|
@ -181,10 +162,10 @@ public abstract class Contraption {
|
|||
for (int limit = 100000; limit > 0; limit--) {
|
||||
if (frontier.isEmpty())
|
||||
return true;
|
||||
if (!moveBlock(world, frontier.remove(0), forcedDirection, frontier, visited))
|
||||
if (!moveBlock(world, forcedDirection, frontier, visited))
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
throw AssemblyException.structureTooLarge();
|
||||
}
|
||||
|
||||
public void onEntityCreated(AbstractContraptionEntity entity) {
|
||||
|
@ -196,8 +177,12 @@ public abstract class Contraption {
|
|||
StabilizedContraption subContraption = new StabilizedContraption(face);
|
||||
World world = entity.world;
|
||||
BlockPos pos = blockFace.getPos();
|
||||
if (!subContraption.assemble(world, pos))
|
||||
try {
|
||||
if (!subContraption.assemble(world, pos))
|
||||
continue;
|
||||
} catch (AssemblyException e) {
|
||||
continue;
|
||||
}
|
||||
subContraption.removeBlocksFromWorld(world, BlockPos.ZERO);
|
||||
OrientedContraptionEntity movedContraption =
|
||||
OrientedContraptionEntity.create(world, subContraption, Optional.of(face));
|
||||
|
@ -247,20 +232,25 @@ public abstract class Contraption {
|
|||
fluidStorage.forEach((pos, mfs) -> mfs.tick(entity, pos, world.isRemote));
|
||||
}
|
||||
|
||||
protected boolean moveBlock(World world, BlockPos pos, @Nullable Direction forcedDirection, List<BlockPos> frontier,
|
||||
Set<BlockPos> visited) {
|
||||
visited.add(pos);
|
||||
frontier.remove(pos);
|
||||
|
||||
if (!world.isBlockPresent(pos))
|
||||
/** move the first block in frontier queue */
|
||||
protected boolean moveBlock(World world, @Nullable Direction forcedDirection, Queue<BlockPos> frontier,
|
||||
Set<BlockPos> visited) throws AssemblyException {
|
||||
BlockPos pos = frontier.poll();
|
||||
if (pos == null)
|
||||
return false;
|
||||
visited.add(pos);
|
||||
|
||||
if (World.isOutsideBuildHeight(pos))
|
||||
return true;
|
||||
if (!world.isBlockPresent(pos))
|
||||
throw AssemblyException.unloadedChunk(pos);
|
||||
if (isAnchoringBlockAt(pos))
|
||||
return true;
|
||||
if (!BlockMovementTraits.movementNecessary(world, pos))
|
||||
return true;
|
||||
if (!movementAllowed(world, pos))
|
||||
return false;
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (!BlockMovementTraits.movementNecessary(state, world, pos))
|
||||
return true;
|
||||
if (!movementAllowed(state, world, pos))
|
||||
throw AssemblyException.unmovableBlock(pos, state);
|
||||
if (state.getBlock() instanceof AbstractChassisBlock
|
||||
&& !moveChassis(world, pos, forcedDirection, frontier, visited))
|
||||
return false;
|
||||
|
@ -306,9 +296,10 @@ public abstract class Contraption {
|
|||
}
|
||||
|
||||
// Cart assemblers attach themselves
|
||||
BlockState stateBelow = world.getBlockState(pos.down());
|
||||
if (!visited.contains(pos.down()) && AllBlocks.CART_ASSEMBLER.has(stateBelow))
|
||||
frontier.add(pos.down());
|
||||
BlockPos posDown = pos.down();
|
||||
BlockState stateBelow = world.getBlockState(posDown);
|
||||
if (!visited.contains(posDown) && AllBlocks.CART_ASSEMBLER.has(stateBelow))
|
||||
frontier.add(posDown);
|
||||
|
||||
Map<Direction, SuperGlueEntity> superglue = SuperGlueHandler.gatherGlue(world, pos);
|
||||
|
||||
|
@ -318,9 +309,9 @@ public abstract class Contraption {
|
|||
BlockState blockState = world.getBlockState(offsetPos);
|
||||
if (isAnchoringBlockAt(offsetPos))
|
||||
continue;
|
||||
if (!movementAllowed(world, offsetPos)) {
|
||||
if (!movementAllowed(blockState, world, offsetPos)) {
|
||||
if (offset == forcedDirection)
|
||||
return false;
|
||||
throw AssemblyException.unmovableBlock(pos, state);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -349,10 +340,13 @@ public abstract class Contraption {
|
|||
}
|
||||
|
||||
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 AssemblyException.structureTooLarge();
|
||||
}
|
||||
|
||||
protected void movePistonHead(World world, BlockPos pos, List<BlockPos> frontier, Set<BlockPos> visited,
|
||||
protected void movePistonHead(World world, BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited,
|
||||
BlockState state) {
|
||||
Direction direction = state.get(MechanicalPistonHeadBlock.FACING);
|
||||
BlockPos offset = pos.offset(direction.getOpposite());
|
||||
|
@ -374,7 +368,7 @@ public abstract class Contraption {
|
|||
}
|
||||
}
|
||||
|
||||
protected void movePistonPole(World world, BlockPos pos, List<BlockPos> frontier, Set<BlockPos> visited,
|
||||
protected void movePistonPole(World world, BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited,
|
||||
BlockState state) {
|
||||
for (Direction d : Iterate.directionsInAxis(state.get(PistonExtensionPoleBlock.FACING)
|
||||
.getAxis())) {
|
||||
|
@ -397,7 +391,7 @@ public abstract class Contraption {
|
|||
}
|
||||
}
|
||||
|
||||
protected void moveGantryPinion(World world, BlockPos pos, List<BlockPos> frontier, Set<BlockPos> visited,
|
||||
protected void moveGantryPinion(World world, BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited,
|
||||
BlockState state) {
|
||||
BlockPos offset = pos.offset(state.get(GantryPinionBlock.FACING));
|
||||
if (!visited.contains(offset))
|
||||
|
@ -413,7 +407,7 @@ public abstract class Contraption {
|
|||
}
|
||||
}
|
||||
|
||||
protected void moveGantryShaft(World world, BlockPos pos, List<BlockPos> frontier, Set<BlockPos> visited,
|
||||
protected void moveGantryShaft(World world, BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited,
|
||||
BlockState state) {
|
||||
for (Direction d : Iterate.directions) {
|
||||
BlockPos offset = pos.offset(d);
|
||||
|
@ -429,7 +423,7 @@ public abstract class Contraption {
|
|||
}
|
||||
}
|
||||
|
||||
private void moveBearing(BlockPos pos, List<BlockPos> frontier, Set<BlockPos> visited, BlockState state) {
|
||||
private void moveBearing(BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited, BlockState state) {
|
||||
Direction facing = state.get(MechanicalBearingBlock.FACING);
|
||||
if (!canBeStabilized(facing, pos.subtract(anchor))) {
|
||||
BlockPos offset = pos.offset(facing);
|
||||
|
@ -440,7 +434,7 @@ public abstract class Contraption {
|
|||
pendingSubContraptions.add(new BlockFace(pos, facing));
|
||||
}
|
||||
|
||||
private void moveBelt(BlockPos pos, List<BlockPos> frontier, Set<BlockPos> visited, BlockState state) {
|
||||
private void moveBelt(BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited, BlockState state) {
|
||||
BlockPos nextPos = BeltBlock.nextSegmentPosition(state, pos, true);
|
||||
BlockPos prevPos = BeltBlock.nextSegmentPosition(state, pos, false);
|
||||
if (nextPos != null && !visited.contains(nextPos))
|
||||
|
@ -461,7 +455,7 @@ public abstract class Contraption {
|
|||
}
|
||||
}
|
||||
|
||||
private void movePulley(World world, BlockPos pos, List<BlockPos> frontier, Set<BlockPos> visited) {
|
||||
private void movePulley(World world, BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited) {
|
||||
int limit = AllConfigs.SERVER.kinetics.maxRopeLength.get();
|
||||
BlockPos ropePos = pos;
|
||||
while (limit-- >= 0) {
|
||||
|
@ -479,8 +473,8 @@ public abstract class Contraption {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean moveMechanicalPiston(World world, BlockPos pos, List<BlockPos> frontier, Set<BlockPos> visited,
|
||||
BlockState state) {
|
||||
private boolean moveMechanicalPiston(World world, BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited, BlockState state) throws AssemblyException {
|
||||
int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get();
|
||||
Direction direction = state.get(MechanicalPistonBlock.FACING);
|
||||
PistonState pistonState = state.get(MechanicalPistonBlock.STATE);
|
||||
if (pistonState == PistonState.MOVING)
|
||||
|
@ -503,7 +497,7 @@ public abstract class Contraption {
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean moveChassis(World world, BlockPos pos, Direction movementDirection, List<BlockPos> frontier,
|
||||
private boolean moveChassis(World world, BlockPos pos, Direction movementDirection, Queue<BlockPos> frontier,
|
||||
Set<BlockPos> visited) {
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
if (!(te instanceof ChassisTileEntity))
|
||||
|
@ -588,8 +582,8 @@ public abstract class Contraption {
|
|||
return globalPos.subtract(anchor);
|
||||
}
|
||||
|
||||
protected boolean movementAllowed(World world, BlockPos pos) {
|
||||
return BlockMovementTraits.movementAllowed(world, pos);
|
||||
protected boolean movementAllowed(BlockState state, World world, BlockPos pos) {
|
||||
return BlockMovementTraits.movementAllowed(state, world, pos);
|
||||
}
|
||||
|
||||
protected boolean isAnchoringBlockAt(BlockPos pos) {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||
|
||||
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public interface IDisplayAssemblyExceptions {
|
||||
|
||||
default boolean addExceptionToTooltip(List<String> tooltip) {
|
||||
AssemblyException e = getLastAssemblyException();
|
||||
if (e == null)
|
||||
return false;
|
||||
|
||||
if (!tooltip.isEmpty())
|
||||
tooltip.add("");
|
||||
|
||||
tooltip.add(IHaveGoggleInformation.spacing + TextFormatting.GOLD + Lang.translate("gui.assembly.exception"));
|
||||
String text = e.getFormattedText();
|
||||
Arrays.stream(text.split("\n")).forEach(l -> tooltip.add(IHaveGoggleInformation.spacing + TextFormatting.GRAY + l));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AssemblyException getLastAssemblyException();
|
||||
}
|
|
@ -4,6 +4,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
@ -28,7 +29,7 @@ public class BearingContraption extends Contraption {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean assemble(World world, BlockPos pos) {
|
||||
public boolean assemble(World world, BlockPos pos) throws AssemblyException {
|
||||
BlockPos offset = pos.offset(facing);
|
||||
if (!searchMovedStructure(world, offset, null))
|
||||
return false;
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
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;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkContraption.HandType;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
|
@ -16,7 +14,6 @@ import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOpt
|
|||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
|
@ -25,8 +22,11 @@ import net.minecraft.util.Direction;
|
|||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
public class ClockworkBearingTileEntity extends KineticTileEntity implements IBearingTileEntity {
|
||||
import java.util.List;
|
||||
|
||||
public class ClockworkBearingTileEntity extends KineticTileEntity implements IBearingTileEntity, IDisplayAssemblyExceptions {
|
||||
|
||||
protected ControlledContraptionEntity hourHand;
|
||||
protected ControlledContraptionEntity minuteHand;
|
||||
|
@ -37,6 +37,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
|
||||
protected boolean running;
|
||||
protected boolean assembleNextTick;
|
||||
protected AssemblyException lastException;
|
||||
|
||||
protected ScrollOptionBehaviour<ClockHands> operationMode;
|
||||
|
||||
|
@ -105,6 +106,11 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
applyRotations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssemblyException getLastAssemblyException() {
|
||||
return lastException;
|
||||
}
|
||||
|
||||
protected void applyRotations() {
|
||||
BlockState blockState = getBlockState();
|
||||
Axis axis = Axis.X;
|
||||
|
@ -199,8 +205,15 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||
|
||||
// Collect Construct
|
||||
Pair<ClockworkContraption, ClockworkContraption> contraption =
|
||||
ClockworkContraption.assembleClockworkAt(world, pos, direction);
|
||||
Pair<ClockworkContraption, ClockworkContraption> contraption;
|
||||
try {
|
||||
contraption = ClockworkContraption.assembleClockworkAt(world, pos, direction);
|
||||
lastException = null;
|
||||
} catch (AssemblyException e) {
|
||||
lastException = e;
|
||||
sendData();
|
||||
return;
|
||||
}
|
||||
if (contraption == null)
|
||||
return;
|
||||
if (contraption.getLeft() == null)
|
||||
|
@ -284,6 +297,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
compound.putBoolean("Running", running);
|
||||
compound.putFloat("HourAngle", hourAngle);
|
||||
compound.putFloat("MinuteAngle", minuteAngle);
|
||||
AssemblyException.write(compound, lastException);
|
||||
super.write(compound, clientPacket);
|
||||
}
|
||||
|
||||
|
@ -295,6 +309,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
running = compound.getBoolean("Running");
|
||||
hourAngle = compound.getFloat("HourAngle");
|
||||
minuteAngle = compound.getFloat("MinuteAngle");
|
||||
lastException = AssemblyException.read(compound);
|
||||
super.read(compound, clientPacket);
|
||||
|
||||
if (!clientPacket)
|
||||
|
|
|
@ -7,13 +7,18 @@ import java.util.Set;
|
|||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
||||
public class ClockworkContraption extends Contraption {
|
||||
|
||||
|
@ -38,7 +43,7 @@ public class ClockworkContraption extends Contraption {
|
|||
}
|
||||
|
||||
public static Pair<ClockworkContraption, ClockworkContraption> assembleClockworkAt(World world, BlockPos pos,
|
||||
Direction direction) {
|
||||
Direction direction) throws AssemblyException {
|
||||
int hourArmBlocks = 0;
|
||||
|
||||
ClockworkContraption hourArm = new ClockworkContraption();
|
||||
|
@ -81,21 +86,23 @@ public class ClockworkContraption extends Contraption {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean assemble(World world, BlockPos pos) {
|
||||
public boolean assemble(World world, BlockPos pos) throws AssemblyException {
|
||||
return searchMovedStructure(world, pos, facing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean searchMovedStructure(World world, BlockPos pos, Direction direction) {
|
||||
public boolean searchMovedStructure(World world, BlockPos pos, Direction direction) throws AssemblyException {
|
||||
return super.searchMovedStructure(world, pos.offset(direction, offset + 1), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean moveBlock(World world, BlockPos pos, Direction direction, List<BlockPos> frontier,
|
||||
Set<BlockPos> visited) {
|
||||
if (ignoreBlocks.contains(pos))
|
||||
protected boolean moveBlock(World world, Direction direction, Queue<BlockPos> frontier,
|
||||
Set<BlockPos> visited) throws AssemblyException {
|
||||
if (ignoreBlocks.contains(frontier.peek())) {
|
||||
frontier.poll();
|
||||
return true;
|
||||
return super.moveBlock(world, pos, direction, frontier, visited);
|
||||
}
|
||||
return super.moveBlock(world, direction, frontier, visited);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
|
||||
|
||||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.item.TooltipHelper;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
@ -14,7 +12,6 @@ import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOpt
|
|||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
|
@ -23,7 +20,11 @@ import net.minecraft.util.Direction;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IBearingTileEntity {
|
||||
import java.util.List;
|
||||
|
||||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||
|
||||
public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IBearingTileEntity, IDisplayAssemblyExceptions {
|
||||
|
||||
protected ScrollOptionBehaviour<RotationMode> movementMode;
|
||||
protected ControlledContraptionEntity movedContraption;
|
||||
|
@ -31,6 +32,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
protected boolean running;
|
||||
protected boolean assembleNextTick;
|
||||
protected float clientAngleDiff;
|
||||
protected AssemblyException lastException;
|
||||
|
||||
public MechanicalBearingTileEntity(TileEntityType<? extends MechanicalBearingTileEntity> type) {
|
||||
super(type);
|
||||
|
@ -62,6 +64,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
public void write(CompoundNBT compound, boolean clientPacket) {
|
||||
compound.putBoolean("Running", running);
|
||||
compound.putFloat("Angle", angle);
|
||||
AssemblyException.write(compound, lastException);
|
||||
super.write(compound, clientPacket);
|
||||
}
|
||||
|
||||
|
@ -70,6 +73,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
float angleBefore = angle;
|
||||
running = compound.getBoolean("Running");
|
||||
angle = compound.getFloat("Angle");
|
||||
lastException = AssemblyException.read(compound);
|
||||
super.read(compound, clientPacket);
|
||||
if (!clientPacket)
|
||||
return;
|
||||
|
@ -104,6 +108,11 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
return speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssemblyException getLastAssemblyException() {
|
||||
return lastException;
|
||||
}
|
||||
|
||||
protected boolean isWindmill() {
|
||||
return false;
|
||||
}
|
||||
|
@ -120,8 +129,16 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
|
||||
Direction direction = getBlockState().get(FACING);
|
||||
BearingContraption contraption = new BearingContraption(isWindmill(), direction);
|
||||
if (!contraption.assemble(world, pos))
|
||||
try {
|
||||
if (!contraption.assemble(world, pos))
|
||||
return;
|
||||
|
||||
lastException = null;
|
||||
} catch (AssemblyException e) {
|
||||
lastException = e;
|
||||
sendData();
|
||||
return;
|
||||
}
|
||||
|
||||
if (isWindmill())
|
||||
AllTriggers.triggerForNearbyPlayers(AllTriggers.WINDMILL, world, pos, 5);
|
||||
|
@ -281,5 +298,4 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
TooltipHelper.addHint(tooltip, "hint.empty_bearing");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -64,16 +64,9 @@ public class SailBlock extends ProperDirectionalBlock {
|
|||
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) {
|
||||
ItemStack heldItem = player.getHeldItem(hand);
|
||||
|
||||
if (AllBlocks.SAIL.isIn(heldItem) || AllBlocks.SAIL_FRAME.isIn(heldItem)) {
|
||||
IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId);
|
||||
PlacementOffset offset = placementHelper.getOffset(world, state, pos, ray);
|
||||
|
||||
if (!offset.isReplaceable(world))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
offset.placeInWorld(world, ((BlockItem) heldItem.getItem()).getBlock().getDefaultState(), player, heldItem);
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId);
|
||||
if (placementHelper.matchesItem(heldItem))
|
||||
return placementHelper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray);
|
||||
|
||||
if (heldItem.getItem() instanceof ShearsItem) {
|
||||
if (!world.isRemote)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
@ -20,7 +21,7 @@ public class StabilizedContraption extends Contraption {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean assemble(World world, BlockPos pos) {
|
||||
public boolean assemble(World world, BlockPos pos) throws AssemblyException {
|
||||
BlockPos offset = pos.offset(facing);
|
||||
if (!searchMovedStructure(world, offset, null))
|
||||
return false;
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Collections;
|
|||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
|
@ -76,12 +77,12 @@ public class ChassisTileEntity extends SmartTileEntity {
|
|||
}
|
||||
|
||||
public List<ChassisTileEntity> collectChassisGroup() {
|
||||
List<BlockPos> frontier = new ArrayList<>();
|
||||
Queue<BlockPos> frontier = new LinkedList<>();
|
||||
List<ChassisTileEntity> collected = new ArrayList<>();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
frontier.add(pos);
|
||||
while (!frontier.isEmpty()) {
|
||||
BlockPos current = frontier.remove(0);
|
||||
BlockPos current = frontier.poll();
|
||||
if (visited.contains(current))
|
||||
continue;
|
||||
visited.add(current);
|
||||
|
@ -96,7 +97,7 @@ public class ChassisTileEntity extends SmartTileEntity {
|
|||
return collected;
|
||||
}
|
||||
|
||||
public boolean addAttachedChasses(List<BlockPos> frontier, Set<BlockPos> visited) {
|
||||
public boolean addAttachedChasses(Queue<BlockPos> frontier, Set<BlockPos> visited) {
|
||||
BlockState state = getBlockState();
|
||||
if (!(state.getBlock() instanceof AbstractChassisBlock))
|
||||
return false;
|
||||
|
@ -166,7 +167,7 @@ public class ChassisTileEntity extends SmartTileEntity {
|
|||
break;
|
||||
|
||||
// Ignore replaceable Blocks and Air-like
|
||||
if (!BlockMovementTraits.movementNecessary(world, current))
|
||||
if (!BlockMovementTraits.movementNecessary(currentState, world, current))
|
||||
break;
|
||||
if (BlockMovementTraits.isBrittle(currentState))
|
||||
break;
|
||||
|
@ -207,7 +208,7 @@ public class ChassisTileEntity extends SmartTileEntity {
|
|||
continue;
|
||||
if (!searchPos.withinDistance(pos, chassisRange + .5f))
|
||||
continue;
|
||||
if (!BlockMovementTraits.movementNecessary(world, searchPos))
|
||||
if (!BlockMovementTraits.movementNecessary(searchedState, world, searchPos))
|
||||
continue;
|
||||
if (BlockMovementTraits.isBrittle(searchedState))
|
||||
continue;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.gantry;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -21,7 +21,7 @@ public class GantryContraption extends TranslatingContraption {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean assemble(World world, BlockPos pos) {
|
||||
public boolean assemble(World world, BlockPos pos) throws AssemblyException {
|
||||
if (!searchMovedStructure(world, pos, null))
|
||||
return false;
|
||||
startMoving(world);
|
||||
|
|
|
@ -1,23 +1,26 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.gantry;
|
||||
|
||||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
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.IDisplayAssemblyExceptions;
|
||||
import com.simibubi.create.content.contraptions.relays.advanced.GantryShaftBlock;
|
||||
import com.simibubi.create.content.contraptions.relays.advanced.GantryShaftTileEntity;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class GantryPinionTileEntity extends KineticTileEntity {
|
||||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||
|
||||
public class GantryPinionTileEntity extends KineticTileEntity implements IDisplayAssemblyExceptions {
|
||||
|
||||
boolean assembleNextTick;
|
||||
protected AssemblyException lastException;
|
||||
|
||||
public GantryPinionTileEntity(TileEntityType<?> typeIn) {
|
||||
super(typeIn);
|
||||
|
@ -50,6 +53,11 @@ public class GantryPinionTileEntity extends KineticTileEntity {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssemblyException getLastAssemblyException() {
|
||||
return lastException;
|
||||
}
|
||||
|
||||
private void tryAssemble() {
|
||||
BlockState blockState = getBlockState();
|
||||
if (!(blockState.getBlock() instanceof GantryPinionBlock))
|
||||
|
@ -71,8 +79,17 @@ public class GantryPinionTileEntity extends KineticTileEntity {
|
|||
if (pinionMovementSpeed < 0)
|
||||
movementDirection = movementDirection.getOpposite();
|
||||
|
||||
if (!contraption.assemble(world, pos))
|
||||
try {
|
||||
lastException = null;
|
||||
if (!contraption.assemble(world, pos))
|
||||
return;
|
||||
|
||||
sendData();
|
||||
} catch (AssemblyException e) {
|
||||
lastException = e;
|
||||
sendData();
|
||||
return;
|
||||
}
|
||||
if (ContraptionCollider.isCollidingWithWorld(world, contraption, pos.offset(movementDirection),
|
||||
movementDirection))
|
||||
return;
|
||||
|
@ -85,6 +102,18 @@ public class GantryPinionTileEntity extends KineticTileEntity {
|
|||
world.addEntity(movedContraption);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(CompoundNBT compound, boolean clientPacket) {
|
||||
AssemblyException.write(compound, lastException);
|
||||
super.write(compound, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void read(CompoundNBT compound, boolean clientPacket) {
|
||||
lastException = AssemblyException.read(compound);
|
||||
super.read(compound, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float propagateRotationTo(KineticTileEntity target, BlockState stateFrom, BlockState stateTo, BlockPos diff,
|
||||
boolean connectedViaAxes, boolean connectedViaCogs) {
|
||||
|
|
|
@ -180,7 +180,7 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
|||
BlockState state = world.getBlockState(pos);
|
||||
if (BlockMovementTraits.isBlockAttachedTowards(world, pos, state, direction))
|
||||
return true;
|
||||
if (!BlockMovementTraits.movementNecessary(world, pos))
|
||||
if (!BlockMovementTraits.movementNecessary(state, world, pos))
|
||||
return false;
|
||||
if (BlockMovementTraits.notSupportive(state, direction))
|
||||
return false;
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.glue;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
|
||||
import com.simibubi.create.foundation.utility.worldWrappers.RayTraceWorld;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
|
@ -15,12 +11,8 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.RayTraceContext;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.util.math.RayTraceResult.Type;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.world.BlockEvent.EntityPlaceEvent;
|
||||
|
@ -28,6 +20,10 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class SuperGlueHandler {
|
||||
|
||||
|
@ -65,6 +61,8 @@ public class SuperGlueHandler {
|
|||
return;
|
||||
if (AllItems.WRENCH.isIn(placer.getHeldItemMainhand()))
|
||||
return;
|
||||
if (event.getPlacedAgainst() == IPlacementHelper.ID)
|
||||
return;
|
||||
|
||||
double distance = placer.getAttribute(PlayerEntity.REACH_DISTANCE)
|
||||
.getValue();
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.mo
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllShapes;
|
||||
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.mounted.CartAssemblerTileEntity.CartMovementMode;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingHandler;
|
||||
|
@ -229,13 +230,27 @@ public class CartAssemblerBlock extends AbstractRailBlock
|
|||
.isCoupledThroughContraption())
|
||||
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);
|
||||
|
||||
MountedContraption contraption = new MountedContraption(mode);
|
||||
if (!contraption.assemble(world, pos))
|
||||
try {
|
||||
if (!contraption.assemble(world, pos))
|
||||
return;
|
||||
|
||||
assembler.ifPresent(te -> {
|
||||
te.lastException = null;
|
||||
te.sendData();
|
||||
});
|
||||
} catch (AssemblyException e) {
|
||||
assembler.ifPresent(te -> {
|
||||
te.lastException = e;
|
||||
te.sendData();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
boolean couplingFound = contraption.connectedCart != null;
|
||||
Optional<Direction> initialOrientation = cart.getMotion()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.mounted;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
@ -11,17 +11,20 @@ import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.INamedIco
|
|||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOptionBehaviour;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.state.properties.RailShape;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class CartAssemblerTileEntity extends SmartTileEntity {
|
||||
import java.util.List;
|
||||
|
||||
public class CartAssemblerTileEntity extends SmartTileEntity implements IDisplayAssemblyExceptions {
|
||||
private static final int assemblyCooldown = 8;
|
||||
|
||||
protected ScrollOptionBehaviour<CartMovementMode> movementMode;
|
||||
private int ticksSinceMinecartUpdate;
|
||||
protected AssemblyException lastException;
|
||||
|
||||
public CartAssemblerTileEntity(TileEntityType<? extends CartAssemblerTileEntity> type) {
|
||||
super(type);
|
||||
|
@ -44,6 +47,23 @@ public class CartAssemblerTileEntity extends SmartTileEntity {
|
|||
behaviours.add(movementMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundNBT compound, boolean clientPacket) {
|
||||
AssemblyException.write(compound, lastException);
|
||||
super.write(compound, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void read(CompoundNBT compound, boolean clientPacket) {
|
||||
lastException = AssemblyException.read(compound);
|
||||
super.read(compound, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssemblyException getLastAssemblyException() {
|
||||
return lastException;
|
||||
}
|
||||
|
||||
protected ValueBoxTransform getMovementModeSlot() {
|
||||
return new CartAssemblerValueBoxTransform();
|
||||
}
|
||||
|
@ -103,5 +123,4 @@ public class CartAssemblerTileEntity extends SmartTileEntity {
|
|||
public boolean isMinecartUpdateValid() {
|
||||
return ticksSinceMinecartUpdate >= assemblyCooldown;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,12 +2,13 @@ package com.simibubi.create.content.contraptions.components.structureMovement.mo
|
|||
|
||||
import static com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlock.RAIL_SHAPE;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionType;
|
||||
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.mounted.CartAssemblerTileEntity.CartMovementMode;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
@ -52,7 +53,7 @@ public class MountedContraption extends Contraption {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean assemble(World world, BlockPos pos) {
|
||||
public boolean assemble(World world, BlockPos pos) throws AssemblyException {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (!state.has(RAIL_SHAPE))
|
||||
return false;
|
||||
|
@ -70,7 +71,7 @@ public class MountedContraption extends Contraption {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, List<BlockPos> frontier) {
|
||||
protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, Queue<BlockPos> frontier) {
|
||||
frontier.clear();
|
||||
frontier.add(pos.up());
|
||||
return true;
|
||||
|
@ -104,11 +105,10 @@ public class MountedContraption extends Contraption {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean movementAllowed(World world, BlockPos pos) {
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
if (!pos.equals(anchor) && AllBlocks.CART_ASSEMBLER.has(blockState))
|
||||
return testSecondaryCartAssembler(world, blockState, pos);
|
||||
return super.movementAllowed(world, pos);
|
||||
protected boolean movementAllowed(BlockState state, World world, BlockPos pos) {
|
||||
if (!pos.equals(anchor) && AllBlocks.CART_ASSEMBLER.has(state))
|
||||
return testSecondaryCartAssembler(world, state, pos);
|
||||
return super.movementAllowed(state, world, pos);
|
||||
}
|
||||
|
||||
protected boolean testSecondaryCartAssembler(World world, BlockState state, BlockPos pos) {
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.piston;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.ControlledContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.IControlContraption;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.*;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOptionBehaviour;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public abstract class LinearActuatorTileEntity extends KineticTileEntity implements IControlContraption {
|
||||
import java.util.List;
|
||||
|
||||
public abstract class LinearActuatorTileEntity extends KineticTileEntity implements IControlContraption, IDisplayAssemblyExceptions {
|
||||
|
||||
public float offset;
|
||||
public boolean running;
|
||||
|
@ -27,6 +24,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
protected boolean forceMove;
|
||||
protected ScrollOptionBehaviour<MovementMode> movementMode;
|
||||
protected boolean waitingForSpeedChange;
|
||||
protected AssemblyException lastException;
|
||||
|
||||
// Custom position sync
|
||||
protected float clientOffsetDiff;
|
||||
|
@ -80,7 +78,13 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
return;
|
||||
} else {
|
||||
if (getSpeed() != 0)
|
||||
assemble();
|
||||
try {
|
||||
assemble();
|
||||
lastException = null;
|
||||
} catch (AssemblyException e) {
|
||||
lastException = e;
|
||||
}
|
||||
sendData();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -153,6 +157,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
compound.putBoolean("Running", running);
|
||||
compound.putBoolean("Waiting", waitingForSpeedChange);
|
||||
compound.putFloat("Offset", offset);
|
||||
AssemblyException.write(compound, lastException);
|
||||
super.write(compound, clientPacket);
|
||||
|
||||
if (clientPacket && forceMove) {
|
||||
|
@ -169,6 +174,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
running = compound.getBoolean("Running");
|
||||
waitingForSpeedChange = compound.getBoolean("Waiting");
|
||||
offset = compound.getFloat("Offset");
|
||||
lastException = AssemblyException.read(compound);
|
||||
super.read(compound, clientPacket);
|
||||
|
||||
if (!clientPacket)
|
||||
|
@ -183,9 +189,14 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
movedContraption = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssemblyException getLastAssemblyException() {
|
||||
return lastException;
|
||||
}
|
||||
|
||||
public abstract void disassemble();
|
||||
|
||||
protected abstract void assemble();
|
||||
protected abstract void assemble() throws AssemblyException;
|
||||
|
||||
protected abstract int getExtensionRange();
|
||||
|
||||
|
@ -288,5 +299,4 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
public BlockPos getBlockPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.pi
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
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.ControlledContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.DirectionalExtenderScrollOptionSlot;
|
||||
|
@ -41,7 +42,7 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void assemble() {
|
||||
public void assemble() throws AssemblyException {
|
||||
if (!(world.getBlockState(pos)
|
||||
.getBlock() instanceof MechanicalPistonBlock))
|
||||
return;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.piston;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionType;
|
||||
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.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.*;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
|
@ -23,6 +24,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import static com.simibubi.create.AllBlocks.MECHANICAL_PISTON_HEAD;
|
||||
import static com.simibubi.create.AllBlocks.PISTON_EXTENSION_POLE;
|
||||
|
@ -51,7 +53,7 @@ public class PistonContraption extends TranslatingContraption {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean assemble(World world, BlockPos pos) {
|
||||
public boolean assemble(World world, BlockPos pos) throws AssemblyException {
|
||||
if (!collectExtensions(world, pos, orientation))
|
||||
return false;
|
||||
int count = blocks.size();
|
||||
|
@ -66,7 +68,7 @@ public class PistonContraption extends TranslatingContraption {
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean collectExtensions(World world, BlockPos pos, Direction direction) {
|
||||
private boolean collectExtensions(World world, BlockPos pos, Direction direction) throws AssemblyException {
|
||||
List<BlockInfo> poles = new ArrayList<>();
|
||||
BlockPos actualStart = pos;
|
||||
BlockState nextBlock = world.getBlockState(actualStart.offset(direction));
|
||||
|
@ -89,7 +91,7 @@ public class PistonContraption extends TranslatingContraption {
|
|||
|
||||
nextBlock = world.getBlockState(actualStart.offset(direction));
|
||||
if (extensionsInFront > MechanicalPistonBlock.maxAllowedPistonPoles())
|
||||
return false;
|
||||
throw AssemblyException.tooManyPistonPoles();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +114,7 @@ public class PistonContraption extends TranslatingContraption {
|
|||
nextBlock = world.getBlockState(end.offset(direction.getOpposite()));
|
||||
|
||||
if (extensionsInFront + extensionsInBack > MechanicalPistonBlock.maxAllowedPistonPoles())
|
||||
return false;
|
||||
throw AssemblyException.tooManyPistonPoles();
|
||||
}
|
||||
|
||||
anchor = pos.offset(direction, initialExtensionProgress + 1);
|
||||
|
@ -124,7 +126,7 @@ public class PistonContraption extends TranslatingContraption {
|
|||
1, 1);
|
||||
|
||||
if (extensionLength == 0)
|
||||
return false;
|
||||
throw AssemblyException.noPistonPoles();
|
||||
|
||||
bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
||||
|
||||
|
@ -144,7 +146,7 @@ public class PistonContraption extends TranslatingContraption {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, List<BlockPos> frontier) {
|
||||
protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, Queue<BlockPos> frontier) throws AssemblyException {
|
||||
frontier.clear();
|
||||
boolean sticky = isStickyPiston(world.getBlockState(pos.offset(orientation, -1)));
|
||||
boolean retracting = direction != orientation;
|
||||
|
@ -154,17 +156,22 @@ public class PistonContraption extends TranslatingContraption {
|
|||
if (offset == 1 && retracting)
|
||||
return true;
|
||||
BlockPos currentPos = pos.offset(orientation, offset + initialExtensionProgress);
|
||||
if (!world.isBlockPresent(currentPos))
|
||||
return false;
|
||||
if (!BlockMovementTraits.movementNecessary(world, currentPos))
|
||||
if (retracting && World.isOutsideBuildHeight(currentPos))
|
||||
return true;
|
||||
if (!world.isBlockPresent(currentPos))
|
||||
throw AssemblyException.unloadedChunk(currentPos);
|
||||
BlockState state = world.getBlockState(currentPos);
|
||||
if (!BlockMovementTraits.movementNecessary(state, world, currentPos))
|
||||
return true;
|
||||
if (BlockMovementTraits.isBrittle(state) && !(state.getBlock() instanceof CarpetBlock))
|
||||
return true;
|
||||
if (isPistonHead(state) && state.get(FACING) == direction.getOpposite())
|
||||
return true;
|
||||
if (!BlockMovementTraits.movementAllowed(world, currentPos))
|
||||
return retracting;
|
||||
if (!BlockMovementTraits.movementAllowed(state, world, currentPos))
|
||||
if (retracting)
|
||||
return true;
|
||||
else
|
||||
throw AssemblyException.unmovableBlock(currentPos, state);
|
||||
if (retracting && state.getPushReaction() == PushReaction.PUSH_ONLY)
|
||||
return true;
|
||||
frontier.add(currentPos);
|
||||
|
|
|
@ -7,7 +7,6 @@ import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
|||
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
|
||||
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
|
||||
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
|
||||
import com.simibubi.create.foundation.utility.placement.PlacementOffset;
|
||||
import com.simibubi.create.foundation.utility.placement.util.PoleHelper;
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -17,6 +16,7 @@ import net.minecraft.block.material.PushReaction;
|
|||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
|
@ -114,26 +114,9 @@ public class PistonExtensionPoleBlock extends ProperDirectionalBlock implements
|
|||
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) {
|
||||
ItemStack heldItem = player.getHeldItem(hand);
|
||||
|
||||
if (AllBlocks.PISTON_EXTENSION_POLE.isIn(heldItem) && !player.isSneaking()) {
|
||||
IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId);
|
||||
PlacementOffset offset = placementHelper.getOffset(world, state, pos, ray);
|
||||
|
||||
if (!offset.isReplaceable(world))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
offset.placeInWorld(world, AllBlocks.PISTON_EXTENSION_POLE.getDefaultState(), player, heldItem);
|
||||
|
||||
/*BlockPos newPos = new BlockPos(offset.getPos());
|
||||
|
||||
if (world.isRemote)
|
||||
return ActionResultType.SUCCESS;
|
||||
|
||||
world.setBlockState(newPos, offset.getTransform().apply(AllBlocks.PISTON_EXTENSION_POLE.getDefaultState()));
|
||||
if (!player.isCreative())
|
||||
heldItem.shrink(1);*/
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId);
|
||||
if (placementHelper.matchesItem(heldItem) && !player.isSneaking())
|
||||
return placementHelper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray);
|
||||
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.pulley;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption;
|
||||
|
||||
|
@ -23,7 +24,7 @@ public class PulleyContraption extends TranslatingContraption {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean assemble(World world, BlockPos pos) {
|
||||
public boolean assemble(World world, BlockPos pos) throws AssemblyException {
|
||||
if (!searchMovedStructure(world, pos, null))
|
||||
return false;
|
||||
startMoving(world);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.pulley;
|
||||
|
||||
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.ContraptionCollider;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity;
|
||||
|
@ -8,7 +9,6 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pis
|
|||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.CenteredSideValueBoxTransform;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.IWaterLoggable;
|
||||
|
@ -42,7 +42,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void assemble() {
|
||||
protected void assemble() throws AssemblyException {
|
||||
if (!(world.getBlockState(pos)
|
||||
.getBlock() instanceof PulleyBlock))
|
||||
return;
|
||||
|
@ -176,9 +176,10 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
|||
return;
|
||||
|
||||
BlockPos posBelow = pos.down((int) (offset + getMovementSpeed()) + 1);
|
||||
if (!BlockMovementTraits.movementNecessary(world, posBelow))
|
||||
BlockState state = world.getBlockState(posBelow);
|
||||
if (!BlockMovementTraits.movementNecessary(state, world, posBelow))
|
||||
return;
|
||||
if (BlockMovementTraits.isBrittle(world.getBlockState(posBelow)))
|
||||
if (BlockMovementTraits.isBrittle(state))
|
||||
return;
|
||||
|
||||
disassemble();
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonExtensionPoleBlock;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
|
@ -92,6 +93,14 @@ public class GoggleOverlayRenderer {
|
|||
tooltip.remove(tooltip.size() - 1);
|
||||
}
|
||||
|
||||
if (te instanceof IDisplayAssemblyExceptions) {
|
||||
boolean exceptionAdded = ((IDisplayAssemblyExceptions) te).addExceptionToTooltip(tooltip);
|
||||
if (exceptionAdded) {
|
||||
hasHoveringInformation = true;
|
||||
hoverAddedInformation = true;
|
||||
}
|
||||
}
|
||||
|
||||
// break early if goggle or hover returned false when present
|
||||
if ((hasGoggleInformation && !goggleAddedInformation) && (hasHoveringInformation && !hoverAddedInformation))
|
||||
return;
|
||||
|
|
|
@ -9,13 +9,13 @@ import java.util.List;
|
|||
public interface IHaveGoggleInformation {
|
||||
|
||||
DecimalFormat decimalFormat = new DecimalFormat("#.##");
|
||||
public static String spacing = " ";
|
||||
String spacing = " ";
|
||||
|
||||
/**
|
||||
* this method will be called when looking at a TileEntity that implemented this interface
|
||||
*
|
||||
* @return {{@code true}} if the tooltip creation was successful and should be displayed,
|
||||
* or {{@code false}} if the overlay should not be displayed
|
||||
* @return {@code true} if the tooltip creation was successful and should be displayed,
|
||||
* or {@code false} if the overlay should not be displayed
|
||||
* */
|
||||
default boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking){
|
||||
return false;
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package com.simibubi.create.content.contraptions.relays.advanced;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllShapes;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
|
@ -15,7 +11,6 @@ import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
|
|||
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
|
||||
import com.simibubi.create.foundation.utility.placement.PlacementOffset;
|
||||
import com.simibubi.create.foundation.utility.placement.util.PoleHelper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -44,6 +39,10 @@ import net.minecraft.world.IWorld;
|
|||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class GantryShaftBlock extends DirectionalKineticBlock {
|
||||
|
||||
public static final IProperty<Part> PART = EnumProperty.create("part", Part.class);
|
||||
|
@ -66,22 +65,14 @@ public class GantryShaftBlock extends DirectionalKineticBlock {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||
BlockRayTraceResult ray) {
|
||||
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) {
|
||||
ItemStack heldItem = player.getHeldItem(hand);
|
||||
|
||||
IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId);
|
||||
if (!placementHelper.matchesItem(heldItem))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
PlacementOffset offset = placementHelper.getOffset(world, state, pos, ray);
|
||||
|
||||
if (!offset.isReplaceable(world))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
offset.placeInWorld(world, ((BlockItem) heldItem.getItem()).getBlock()
|
||||
.getDefaultState(), player, heldItem);
|
||||
return ActionResultType.SUCCESS;
|
||||
return placementHelper.getOffset(world, state, pos, ray).placeInWorld(world, ((BlockItem) heldItem.getItem()), player, hand, ray);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.simibubi.create.content.contraptions.relays.advanced;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllShapes;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
|
@ -13,11 +11,11 @@ import com.simibubi.create.foundation.utility.VecHelper;
|
|||
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
|
||||
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
|
||||
import com.simibubi.create.foundation.utility.placement.PlacementOffset;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
@ -32,6 +30,8 @@ import net.minecraft.util.math.shapes.VoxelShape;
|
|||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class SpeedControllerBlock extends HorizontalAxisKineticBlock implements ITE<SpeedControllerTileEntity> {
|
||||
|
||||
private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
|
||||
|
@ -67,19 +67,10 @@ public class SpeedControllerBlock extends HorizontalAxisKineticBlock implements
|
|||
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||
BlockRayTraceResult ray) {
|
||||
|
||||
IPlacementHelper helper = PlacementHelpers.get(placementHelperId);
|
||||
ItemStack heldItem = player.getHeldItem(hand);
|
||||
if (helper.matchesItem(heldItem)) {
|
||||
PlacementOffset offset = helper.getOffset(world, state, pos, ray);
|
||||
|
||||
if (!offset.isReplaceable(world))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
offset.placeInWorld(world, AllBlocks.LARGE_COGWHEEL.getDefaultState(), player, heldItem);
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
|
||||
}
|
||||
IPlacementHelper helper = PlacementHelpers.get(placementHelperId);
|
||||
if (helper.matchesItem(heldItem))
|
||||
return helper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray);
|
||||
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
package com.simibubi.create.content.contraptions.relays.elementary;
|
||||
|
||||
import static com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock.AXIS;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllShapes;
|
||||
import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock;
|
||||
|
@ -16,13 +11,13 @@ import com.simibubi.create.foundation.utility.VecHelper;
|
|||
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
|
||||
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
|
||||
import com.simibubi.create.foundation.utility.placement.PlacementOffset;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
|
@ -31,6 +26,11 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock.AXIS;
|
||||
|
||||
public class CogwheelBlockItem extends BlockItem {
|
||||
|
||||
boolean large;
|
||||
|
@ -47,49 +47,27 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType tryPlace(BlockItemUseContext context) {
|
||||
public ActionResultType onItemUseFirst(ItemStack stack, ItemUseContext context) {
|
||||
World world = context.getWorld();
|
||||
BlockPos pos = context.getPos()
|
||||
.offset(context.getFace()
|
||||
.getOpposite());
|
||||
BlockPos pos = context.getPos();
|
||||
BlockState state = world.getBlockState(pos);
|
||||
|
||||
IPlacementHelper helper = PlacementHelpers.get(placementHelperId);
|
||||
PlayerEntity player = context.getPlayer();
|
||||
|
||||
if (helper.matchesState(state)) {
|
||||
PlacementOffset offset = helper.getOffset(world, state, pos,
|
||||
new BlockRayTraceResult(context.getHitVec(), context.getFace(), pos, true));
|
||||
|
||||
if (!offset.isReplaceable(world))
|
||||
return super.tryPlace(context);
|
||||
|
||||
offset.placeInWorld(world, this, player, context.getItem());
|
||||
triggerShiftingGearsAdvancement(world, new BlockPos(offset.getPos()), offset.getTransform()
|
||||
.apply(getBlock().getDefaultState()), player);
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
BlockRayTraceResult ray = new BlockRayTraceResult(context.getHitVec(), context.getFace(), pos, true);
|
||||
if (helper.matchesState(state) && player != null && !player.isSneaking()) {
|
||||
return helper.getOffset(world, state, pos, ray).placeInWorld(world, this, player, context.getHand(), ray);
|
||||
}
|
||||
|
||||
if (integratedCogHelperId != -1) {
|
||||
helper = PlacementHelpers.get(integratedCogHelperId);
|
||||
|
||||
if (helper.matchesState(state)) {
|
||||
PlacementOffset offset = helper.getOffset(world, state, pos,
|
||||
new BlockRayTraceResult(context.getHitVec(), context.getFace(), pos, true));
|
||||
|
||||
if (!offset.isReplaceable(world))
|
||||
return super.tryPlace(context);
|
||||
|
||||
offset.placeInWorld(world, this, player, context.getItem());
|
||||
triggerShiftingGearsAdvancement(world, new BlockPos(offset.getPos()), offset.getTransform()
|
||||
.apply(getBlock().getDefaultState()), player);
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
if (helper.matchesState(state) && player != null && !player.isSneaking()) {
|
||||
return helper.getOffset(world, state, pos, ray).placeInWorld(world, this, player, context.getHand(), ray);
|
||||
}
|
||||
}
|
||||
|
||||
return super.tryPlace(context);
|
||||
return super.onItemUseFirst(stack, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,7 +7,6 @@ import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftBlock
|
|||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
|
||||
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
|
||||
import com.simibubi.create.foundation.utility.placement.PlacementOffset;
|
||||
import com.simibubi.create.foundation.utility.placement.util.PoleHelper;
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -77,26 +76,8 @@ public class ShaftBlock extends AbstractShaftBlock {
|
|||
}
|
||||
|
||||
IPlacementHelper helper = PlacementHelpers.get(placementHelperId);
|
||||
if (helper.getItemPredicate().test(heldItem)) {
|
||||
PlacementOffset offset = helper.getOffset(world, state, pos, ray);
|
||||
|
||||
if (!offset.isReplaceable(world))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
offset.placeInWorld(world, (BlockItem) heldItem.getItem(), player, heldItem);
|
||||
|
||||
/*BlockPos newPos = new BlockPos(offset.getPos());
|
||||
|
||||
if (world.isRemote)
|
||||
return ActionResultType.SUCCESS;
|
||||
|
||||
Block block = ((BlockItem) heldItem.getItem()).getBlock();
|
||||
world.setBlockState(newPos, offset.getTransform().apply(block.getDefaultState()));
|
||||
if (!player.isCreative())
|
||||
heldItem.shrink(1);*/
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
if (helper.matchesItem(heldItem))
|
||||
return helper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray);
|
||||
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
|
|
|
@ -1,25 +1,42 @@
|
|||
package com.simibubi.create.foundation.command;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.command.Commands;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class AllCommands {
|
||||
|
||||
public static void register(CommandDispatcher<CommandSource> dispatcher) {
|
||||
dispatcher.register(Commands.literal("create")
|
||||
//general purpose
|
||||
.then(ToggleDebugCommand.register())
|
||||
.then(OverlayConfigCommand.register())
|
||||
.then(FixLightingCommand.register())
|
||||
.then(ReplaceInCommandBlocksCommand.register())
|
||||
public static Predicate<CommandSource> sourceIsPlayer = (cs) -> cs.getEntity() instanceof PlayerEntity;
|
||||
|
||||
//dev-util
|
||||
//Comment out for release
|
||||
.then(ClearBufferCacheCommand.register())
|
||||
.then(ChunkUtilCommand.register())
|
||||
// .then(KillTPSCommand.register())
|
||||
public static void register(CommandDispatcher<CommandSource> dispatcher) {
|
||||
|
||||
LiteralCommandNode<CommandSource> createRoot = dispatcher.register(Commands.literal("create")
|
||||
//general purpose
|
||||
.then(ToggleDebugCommand.register())
|
||||
.then(OverlayConfigCommand.register())
|
||||
.then(FixLightingCommand.register())
|
||||
.then(ReplaceInCommandBlocksCommand.register())
|
||||
.then(HighlightCommand.register())
|
||||
|
||||
//dev-util
|
||||
//Comment out for release
|
||||
.then(ClearBufferCacheCommand.register())
|
||||
.then(ChunkUtilCommand.register())
|
||||
//.then(KillTPSCommand.register())
|
||||
);
|
||||
|
||||
CommandNode<CommandSource> c = dispatcher.findNode(Collections.singleton("c"));
|
||||
if (c != null)
|
||||
return;
|
||||
|
||||
dispatcher.register(Commands.literal("c")
|
||||
.redirect(createRoot)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
package com.simibubi.create.foundation.command;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.command.Commands;
|
||||
import net.minecraft.command.arguments.BlockPosArgument;
|
||||
import net.minecraft.command.arguments.EntityArgument;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class HighlightCommand {
|
||||
|
||||
public static ArgumentBuilder<CommandSource, ?> register() {
|
||||
return Commands.literal("highlight")
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
.requires(AllCommands.sourceIsPlayer)
|
||||
.then(Commands.argument("pos", BlockPosArgument.blockPos())
|
||||
.requires(AllCommands.sourceIsPlayer)
|
||||
.executes(ctx -> {
|
||||
BlockPos pos = BlockPosArgument.getLoadedBlockPos(ctx, "pos");
|
||||
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()),
|
||||
new HighlightPacket(pos)
|
||||
);
|
||||
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})
|
||||
.then(Commands.argument("players", EntityArgument.players())
|
||||
.executes(ctx -> {
|
||||
Collection<ServerPlayerEntity> players = EntityArgument.getPlayers(ctx, "players");
|
||||
BlockPos pos = BlockPosArgument.getBlockPos(ctx, "pos");
|
||||
|
||||
for (ServerPlayerEntity p : players) {
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> p),
|
||||
new HighlightPacket(pos)
|
||||
);
|
||||
}
|
||||
|
||||
return players.size();
|
||||
})
|
||||
)
|
||||
)
|
||||
.executes(ctx -> {
|
||||
ServerPlayerEntity player = ctx.getSource().asPlayer();
|
||||
return highlightAssemblyExceptionFor(player, ctx.getSource());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static void sendMissMessage(CommandSource source) {
|
||||
source.sendFeedback(new StringTextComponent("Try looking at a Block that has failed to assemble a Contraption and try again."), true);
|
||||
}
|
||||
|
||||
private static int highlightAssemblyExceptionFor(ServerPlayerEntity player, CommandSource source) {
|
||||
double distance = player.getAttribute(PlayerEntity.REACH_DISTANCE).getValue();
|
||||
Vec3d start = player.getEyePosition(1);
|
||||
Vec3d look = player.getLook(1);
|
||||
Vec3d end = start.add(look.x * distance, look.y * distance, look.z * distance);
|
||||
World world = player.world;
|
||||
|
||||
BlockRayTraceResult ray = world.rayTraceBlocks(new RayTraceContext(start, end, RayTraceContext.BlockMode.OUTLINE, RayTraceContext.FluidMode.NONE, player));
|
||||
if (ray.getType() == RayTraceResult.Type.MISS) {
|
||||
sendMissMessage(source);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BlockPos pos = ray.getPos();
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
if (!(te instanceof IDisplayAssemblyExceptions)) {
|
||||
sendMissMessage(source);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IDisplayAssemblyExceptions display = (IDisplayAssemblyExceptions) te;
|
||||
AssemblyException exception = display.getLastAssemblyException();
|
||||
if (exception == null) {
|
||||
sendMissMessage(source);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!exception.hasPosition()) {
|
||||
source.sendFeedback(new StringTextComponent("Can't highlight a specific position for this issue"), true);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}
|
||||
|
||||
BlockPos p = exception.getPosition();
|
||||
String command = "/create highlight " + p.getX() + " " + p.getY() + " " + p.getZ();
|
||||
return player.server.getCommandManager().handleCommand(source, command);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.simibubi.create.foundation.command;
|
||||
|
||||
import com.simibubi.create.AllSpecialTextures;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class HighlightPacket extends SimplePacketBase {
|
||||
|
||||
private final BlockPos pos;
|
||||
|
||||
public HighlightPacket(BlockPos pos) {
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
public HighlightPacket(PacketBuffer buffer) {
|
||||
this.pos = BlockPos.fromLong(buffer.readLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer) {
|
||||
buffer.writeLong(pos.toLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<NetworkEvent.Context> ctx) {
|
||||
ctx.get().enqueueWork(() -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||
performHighlight(pos);
|
||||
}));
|
||||
|
||||
ctx.get().setPacketHandled(true);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static void performHighlight(BlockPos pos) {
|
||||
if (Minecraft.getInstance().world == null || !Minecraft.getInstance().world.isBlockPresent(pos))
|
||||
return;
|
||||
|
||||
CreateClient.outliner.showAABB("highlightCommand", VoxelShapes.fullCube().getBoundingBox().offset(pos), 200)
|
||||
.lineWidth(1 / 32f)
|
||||
.colored(0xEeEeEe)
|
||||
//.colored(0x243B50)
|
||||
.withFaceTexture(AllSpecialTextures.SELECTION);
|
||||
|
||||
}
|
||||
}
|
|
@ -1,19 +1,11 @@
|
|||
package com.simibubi.create.foundation.networking;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionDisassemblyPacket;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryContraptionUpdatePacket;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionFluidPacket;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionInteractionPacket;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionSeatMappingPacket;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.LimbSwingUpdatePacket;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.*;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingCreationPacket;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.MinecartControllerUpdatePacket;
|
||||
import com.simibubi.create.content.contraptions.fluids.actors.FluidSplashPacket;
|
||||
|
@ -25,16 +17,12 @@ import com.simibubi.create.content.logistics.block.mechanicalArm.ArmPlacementPac
|
|||
import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket;
|
||||
import com.simibubi.create.content.logistics.packet.ConfigureFlexcratePacket;
|
||||
import com.simibubi.create.content.logistics.packet.ConfigureStockswitchPacket;
|
||||
import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket;
|
||||
import com.simibubi.create.content.schematics.packet.InstantSchematicPacket;
|
||||
import com.simibubi.create.content.schematics.packet.SchematicPlacePacket;
|
||||
import com.simibubi.create.content.schematics.packet.SchematicSyncPacket;
|
||||
import com.simibubi.create.content.schematics.packet.SchematicUploadPacket;
|
||||
import com.simibubi.create.content.schematics.packet.*;
|
||||
import com.simibubi.create.foundation.command.ConfigureConfigPacket;
|
||||
import com.simibubi.create.foundation.command.HighlightPacket;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket;
|
||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -46,8 +34,12 @@ import net.minecraftforge.fml.network.PacketDistributor;
|
|||
import net.minecraftforge.fml.network.PacketDistributor.TargetPoint;
|
||||
import net.minecraftforge.fml.network.simple.SimpleChannel;
|
||||
|
||||
import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_SERVER;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_CLIENT;
|
||||
import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_SERVER;
|
||||
|
||||
public enum AllPackets {
|
||||
|
||||
|
@ -85,6 +77,7 @@ public enum AllPackets {
|
|||
FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket::new, PLAY_TO_CLIENT),
|
||||
CONTRAPTION_FLUID(ContraptionFluidPacket.class, ContraptionFluidPacket::new, PLAY_TO_CLIENT),
|
||||
GANTRY_UPDATE(GantryContraptionUpdatePacket.class, GantryContraptionUpdatePacket::new, PLAY_TO_CLIENT),
|
||||
BLOCK_HIGHLIGHT(HighlightPacket.class, HighlightPacket::new, PLAY_TO_CLIENT)
|
||||
|
||||
;
|
||||
|
||||
|
|
|
@ -1,24 +1,18 @@
|
|||
package com.simibubi.create.foundation.utility.outliner;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBox;
|
||||
import com.simibubi.create.foundation.utility.outliner.LineOutline.EndChasingLineOutline;
|
||||
import com.simibubi.create.foundation.utility.outliner.Outline.OutlineParams;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Outliner {
|
||||
|
||||
final Map<Object, OutlineEntry> outlines;
|
||||
|
@ -57,6 +51,13 @@ public class Outliner {
|
|||
return entry.outline.getParams();
|
||||
}
|
||||
|
||||
public OutlineParams showAABB(Object slot, AxisAlignedBB bb, int ttl) {
|
||||
createAABBOutlineIfMissing(slot, bb);
|
||||
ChasingAABBOutline outline = getAndRefreshAABB(slot, ttl);
|
||||
outline.prevBB = outline.targetBB = bb;
|
||||
return outline.getParams();
|
||||
}
|
||||
|
||||
public OutlineParams showAABB(Object slot, AxisAlignedBB bb) {
|
||||
createAABBOutlineIfMissing(slot, bb);
|
||||
ChasingAABBOutline outline = getAndRefreshAABB(slot);
|
||||
|
@ -112,6 +113,12 @@ public class Outliner {
|
|||
return (ChasingAABBOutline) entry.getOutline();
|
||||
}
|
||||
|
||||
private ChasingAABBOutline getAndRefreshAABB(Object slot, int ttl) {
|
||||
OutlineEntry entry = outlines.get(slot);
|
||||
entry.ticksTillRemoval = ttl;
|
||||
return (ChasingAABBOutline) entry.getOutline();
|
||||
}
|
||||
|
||||
// Maintenance
|
||||
|
||||
public Outliner() {
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.simibubi.create.foundation.utility.Pair;
|
|||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -22,6 +23,11 @@ import java.util.stream.Collectors;
|
|||
@MethodsReturnNonnullByDefault
|
||||
public interface IPlacementHelper {
|
||||
|
||||
/**
|
||||
* used as an identifier in SuperGlueHandler to skip blocks placed by helpers
|
||||
*/
|
||||
BlockState ID = new BlockState(Blocks.AIR, null);
|
||||
|
||||
/**
|
||||
* @return a predicate that gets tested with the items held in the players hands,
|
||||
* should return true if this placement helper is active with the given item
|
||||
|
@ -61,24 +67,6 @@ public interface IPlacementHelper {
|
|||
CreateClient.outliner.showLine("placementArrowB" + center + target, start.add(offset), endB.add(offset)).lineWidth(1/16f);
|
||||
}
|
||||
|
||||
/*@OnlyIn(Dist.CLIENT)
|
||||
static void renderArrow(Vec3d center, Direction towards, BlockRayTraceResult ray) {
|
||||
Direction hitFace = ray.getFace();
|
||||
|
||||
if (hitFace.getAxis() == towards.getAxis())
|
||||
return;
|
||||
|
||||
//get the two perpendicular directions to form the arrow
|
||||
Direction[] directions = Arrays.stream(Direction.Axis.values()).filter(axis -> axis != hitFace.getAxis() && axis != towards.getAxis()).map(Iterate::directionsInAxis).findFirst().orElse(new Direction[]{});
|
||||
Vec3d startOffset = new Vec3d(towards.getDirectionVec());
|
||||
Vec3d start = center.add(startOffset);
|
||||
for (Direction dir : directions) {
|
||||
Vec3d arrowOffset = new Vec3d(dir.getDirectionVec()).scale(.25);
|
||||
Vec3d target = center.add(startOffset.scale(0.75)).add(arrowOffset);
|
||||
CreateClient.outliner.showLine("placementArrow" + towards + dir, start, target).lineWidth(1/16f);
|
||||
}
|
||||
}*/
|
||||
|
||||
static List<Direction> orderedByDistanceOnlyAxis(BlockPos pos, Vec3d hit, Direction.Axis axis) {
|
||||
return orderedByDistance(pos, hit, dir -> dir.getAxis() == axis);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,26 @@
|
|||
package com.simibubi.create.foundation.utility.placement;
|
||||
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.stats.Stats;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.util.BlockSnapshot;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
|
@ -55,25 +66,49 @@ public class PlacementOffset {
|
|||
|
||||
return world.getBlockState(new BlockPos(pos)).getMaterial().isReplaceable();
|
||||
}
|
||||
|
||||
public void placeInWorld(World world, BlockItem blockItem, PlayerEntity player, ItemStack item) {
|
||||
placeInWorld(world, blockItem.getBlock().getDefaultState(), player, item);
|
||||
}
|
||||
|
||||
public void placeInWorld(World world, BlockState defaultState, PlayerEntity player, ItemStack item) {
|
||||
if (world.isRemote)
|
||||
return;
|
||||
public ActionResultType placeInWorld(World world, BlockItem blockItem, PlayerEntity player, Hand hand, BlockRayTraceResult ray) {
|
||||
|
||||
ItemUseContext context = new ItemUseContext(player, hand, ray);
|
||||
|
||||
BlockPos newPos = new BlockPos(pos);
|
||||
BlockState state = stateTransform.apply(defaultState);
|
||||
|
||||
if (!world.isBlockModifiable(player, newPos))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
if (!isReplaceable(world))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
BlockState state = stateTransform.apply(blockItem.getBlock().getDefaultState());
|
||||
if (state.has(BlockStateProperties.WATERLOGGED)) {
|
||||
IFluidState fluidState = world.getFluidState(newPos);
|
||||
state = state.with(BlockStateProperties.WATERLOGGED, fluidState.getFluid() == Fluids.WATER);
|
||||
}
|
||||
|
||||
BlockSnapshot snapshot = BlockSnapshot.getBlockSnapshot(world, newPos);
|
||||
world.setBlockState(newPos, state);
|
||||
|
||||
BlockEvent.EntityPlaceEvent event = new BlockEvent.EntityPlaceEvent(snapshot, IPlacementHelper.ID, player);
|
||||
if (MinecraftForge.EVENT_BUS.post(event)) {
|
||||
snapshot.restore(true, false);
|
||||
return ActionResultType.FAIL;
|
||||
}
|
||||
|
||||
BlockState newState = world.getBlockState(newPos);
|
||||
SoundType soundtype = newState.getSoundType(world, newPos, player);
|
||||
world.playSound(player, newPos, soundtype.getPlaceSound(), SoundCategory.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F);
|
||||
|
||||
player.addStat(Stats.ITEM_USED.get(blockItem));
|
||||
|
||||
if (world.isRemote)
|
||||
return ActionResultType.SUCCESS;
|
||||
|
||||
if (player instanceof ServerPlayerEntity)
|
||||
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayerEntity) player, newPos, context.getItem());
|
||||
|
||||
if (!player.isCreative())
|
||||
item.shrink(1);
|
||||
context.getItem().shrink(1);
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,6 +172,13 @@
|
|||
"create.gui.goggles.at_current_speed": "at current speed",
|
||||
"create.gui.goggles.pole_length": "Pole Length:",
|
||||
|
||||
"create.gui.assembly.exception": "This Contraption was unable to assemble:",
|
||||
"create.gui.assembly.exception.unmovableBlock": "Unmovable Block (%4$s) at [%1$s %2$s %3$s]",
|
||||
"create.gui.assembly.exception.chunkNotLoaded": "The Block at [%1$s %2$s %3$s] was not in a loaded chunk",
|
||||
"create.gui.assembly.exception.structureTooLarge": "There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s",
|
||||
"create.gui.assembly.exception.tooManyPistonPoles": "There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s",
|
||||
"create.gui.assembly.exception.noPistonPoles": "The Piston is missing some extension Poles",
|
||||
|
||||
"create.gui.gauge.info_header": "Gauge Information:",
|
||||
"create.gui.speedometer.title": "Rotation Speed",
|
||||
"create.gui.stressometer.title": "Network Stress",
|
||||
|
|
Loading…
Reference in a new issue