Addressing Todos
- Started work on changing how moving constructs are assembled and ticked
This commit is contained in:
parent
488a9f63a9
commit
98f568f887
10 changed files with 364 additions and 47 deletions
|
@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle'
|
|||
apply plugin: 'eclipse'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
version = 'mc1.14.4_v0.1.1'
|
||||
version = 'mc1.14.4_v0.2'
|
||||
group = 'com.simibubi.create'
|
||||
archivesBaseName = 'create'
|
||||
|
||||
|
|
4
gradle.properties
Normal file
4
gradle.properties
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
|
||||
# This is required to provide enough memory for the Minecraft decompilation process.
|
||||
org.gradle.jvmargs=-Xmx3G
|
||||
org.gradle.daemon=false
|
|
@ -83,22 +83,23 @@ public class WaterWheelBlock extends HorizontalKineticBlock {
|
|||
|
||||
flowVec = flowVec.scale(f.getAxisDirection().getOffset());
|
||||
boolean clockwise = wf.getAxisDirection() == AxisDirection.POSITIVE;
|
||||
int clockwiseMultiplier = 1; // No difference. Causes confusion
|
||||
|
||||
if (wf.getAxis() == Axis.Z) {
|
||||
if (f.getAxis() == Axis.Y)
|
||||
flow = flowVec.x > 0 ^ !clockwise ? -flowVec.x * 2 : -flowVec.x;
|
||||
flow = flowVec.x > 0 ^ !clockwise ? -flowVec.x * clockwiseMultiplier : -flowVec.x;
|
||||
if (f.getAxis() == Axis.X)
|
||||
flow = flowVec.y < 0 ^ !clockwise ? flowVec.y * 2 : flowVec.y;
|
||||
flow = flowVec.y < 0 ^ !clockwise ? flowVec.y * clockwiseMultiplier : flowVec.y;
|
||||
}
|
||||
|
||||
if (wf.getAxis() == Axis.X) {
|
||||
if (f.getAxis() == Axis.Y)
|
||||
flow = flowVec.z < 0 ^ !clockwise ? flowVec.z * 2 : flowVec.z;
|
||||
flow = flowVec.z < 0 ^ !clockwise ? flowVec.z * clockwiseMultiplier : flowVec.z;
|
||||
if (f.getAxis() == Axis.Z)
|
||||
flow = flowVec.y > 0 ^ !clockwise ? -flowVec.y * 2 : -flowVec.y;
|
||||
flow = flowVec.y > 0 ^ !clockwise ? -flowVec.y * clockwiseMultiplier : -flowVec.y;
|
||||
}
|
||||
|
||||
te.setFlow(f, (int) (flow * 10));
|
||||
te.setFlow(f, (int) (flow * 20));
|
||||
}
|
||||
|
||||
private void updateWheelSpeed(IWorld world, BlockPos pos) {
|
||||
|
|
|
@ -140,18 +140,20 @@ public class DrillBlock extends DirectionalKineticBlock implements IHaveMovement
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean visitPosition(World world, BlockPos pos, BlockState block, Direction movement,
|
||||
public IMovementContext visitPosition(World world, BlockPos pos, BlockState block, Direction movement,
|
||||
MechanicalPistonTileEntity piston) {
|
||||
IMovementContext context = IdleMovementContext.INSTANCE;
|
||||
|
||||
if (movement != block.get(FACING))
|
||||
return false;
|
||||
return context;
|
||||
|
||||
pos = pos.offset(movement);
|
||||
BlockState stateVisited = world.getBlockState(pos);
|
||||
|
||||
if (stateVisited.getCollisionShape(world, pos).isEmpty())
|
||||
return false;
|
||||
return context;
|
||||
if (stateVisited.getBlockHardness(world, pos) == -1)
|
||||
return false;
|
||||
return context;
|
||||
|
||||
world.playEvent(2001, pos, Block.getStateId(stateVisited));
|
||||
List<ItemStack> drops = Block.getDrops(stateVisited, (ServerWorld) world, pos, null);
|
||||
|
@ -164,7 +166,7 @@ public class DrillBlock extends DirectionalKineticBlock implements IHaveMovement
|
|||
world.addEntity(itemEntity);
|
||||
}
|
||||
|
||||
return false;
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -93,10 +93,12 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean visitPosition(World world, BlockPos pos, BlockState block, Direction movement,
|
||||
public IMovementContext visitPosition(World world, BlockPos pos, BlockState block, Direction movement,
|
||||
MechanicalPistonTileEntity piston) {
|
||||
IMovementContext context = IdleMovementContext.INSTANCE;
|
||||
|
||||
if (movement != block.get(HORIZONTAL_FACING))
|
||||
return false;
|
||||
return context;
|
||||
|
||||
BlockState stateVisited = world.getBlockState(pos);
|
||||
boolean notCropButCuttable = false;
|
||||
|
@ -111,7 +113,7 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
|
|||
if (isValidOther(world, pos, stateVisited))
|
||||
notCropButCuttable = true;
|
||||
else
|
||||
return false;
|
||||
return context;
|
||||
}
|
||||
|
||||
List<ItemStack> drops = Block.getDrops(stateVisited, (ServerWorld) world, pos, null);
|
||||
|
@ -130,7 +132,7 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
|
|||
world.addEntity(itemEntity);
|
||||
}
|
||||
|
||||
return false;
|
||||
return context;
|
||||
}
|
||||
|
||||
private boolean isValidCrop(World world, BlockPos pos, BlockState state) {
|
||||
|
|
|
@ -7,6 +7,26 @@ import net.minecraft.world.World;
|
|||
|
||||
public interface IHaveMovementBehavior {
|
||||
|
||||
public boolean visitPosition(World world, BlockPos pos, BlockState block, Direction movement, MechanicalPistonTileEntity piston);
|
||||
|
||||
default IMovementContext visitPosition(World world, BlockPos pos, BlockState block, Direction movement,
|
||||
MechanicalPistonTileEntity piston) {
|
||||
return IdleMovementContext.INSTANCE;
|
||||
}
|
||||
|
||||
default void tick(MechanicalPistonTileEntity piston) {
|
||||
}
|
||||
|
||||
default boolean hasSpecialRenderer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public interface IMovementContext {
|
||||
default boolean isBlocking() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class IdleMovementContext implements IMovementContext {
|
||||
public static IdleMovementContext INSTANCE = new IdleMovementContext();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.DirectionProperty;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
|
@ -18,13 +19,19 @@ import net.minecraft.state.properties.BlockStateProperties;
|
|||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.Tags;
|
||||
|
||||
public class MechanicalPistonBlock extends KineticBlock {
|
||||
|
||||
|
@ -110,6 +117,33 @@ public class MechanicalPistonBlock extends KineticBlock {
|
|||
.with(AXIS_ALONG_FIRST_COORDINATE, alongFirst);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
if (state.get(STATE) != PistonState.RETRACTED)
|
||||
return false;
|
||||
if (!player.isAllowEdit())
|
||||
return false;
|
||||
if (!player.getHeldItem(handIn).getItem().isIn(Tags.Items.SLIMEBALLS))
|
||||
return false;
|
||||
Direction direction = state.get(FACING);
|
||||
if (hit.getFace() != direction)
|
||||
return false;
|
||||
if (((MechanicalPistonBlock) state.getBlock()).isSticky)
|
||||
return false;
|
||||
if (worldIn.isRemote) {
|
||||
Vec3d vec = hit.getHitVec();
|
||||
worldIn.addParticle(ParticleTypes.ITEM_SLIME, vec.x, vec.y, vec.z, 0, 0, 0);
|
||||
return true;
|
||||
}
|
||||
worldIn.playSound(null, pos, SoundEvents.BLOCK_SLIME_BLOCK_PLACE, SoundCategory.BLOCKS, .5f, 1);
|
||||
if (!player.isCreative())
|
||||
player.getHeldItem(handIn).shrink(1);
|
||||
worldIn.setBlockState(pos, AllBlocks.STICKY_MECHANICAL_PISTON.get().getDefaultState().with(FACING, direction)
|
||||
.with(AXIS_ALONG_FIRST_COORDINATE, state.get(AXIS_ALONG_FIRST_COORDINATE)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new MechanicalPistonTileEntity();
|
||||
|
|
|
@ -255,10 +255,10 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ITi
|
|||
BlockPos otherRelativePos = BlockPos.ZERO.offset(otherMovementDirection,
|
||||
getModulatedOffset(otherPiston.offset));
|
||||
|
||||
for (AxisAlignedBB tBB : Arrays.asList(movingConstruct.collisionBoxFront,
|
||||
movingConstruct.collisionBoxBack)) {
|
||||
for (AxisAlignedBB oBB : Arrays.asList(otherPiston.movingConstruct.collisionBoxFront,
|
||||
otherPiston.movingConstruct.collisionBoxBack)) {
|
||||
for (AxisAlignedBB tBB : Arrays.asList(movingConstruct.constructCollisionBox,
|
||||
movingConstruct.pistonCollisionBox)) {
|
||||
for (AxisAlignedBB oBB : Arrays.asList(otherPiston.movingConstruct.constructCollisionBox,
|
||||
otherPiston.movingConstruct.pistonCollisionBox)) {
|
||||
if (tBB == null || oBB == null)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -3,7 +3,9 @@ package com.simibubi.create.modules.contraptions.receivers.constructs;
|
|||
import static com.simibubi.create.AllBlocks.MECHANICAL_PISTON_HEAD;
|
||||
import static com.simibubi.create.AllBlocks.PISTON_POLE;
|
||||
import static com.simibubi.create.AllBlocks.STICKY_MECHANICAL_PISTON;
|
||||
import static com.simibubi.create.AllBlocks.TRANSLATION_CHASSIS;
|
||||
import static com.simibubi.create.CreateConfig.parameters;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.AXIS;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -23,14 +25,17 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.block.FallingBlock;
|
||||
import net.minecraft.block.PistonBlock;
|
||||
import net.minecraft.block.ShulkerBoxBlock;
|
||||
import net.minecraft.block.SlimeBlock;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.FloatNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.state.properties.PistonType;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -41,14 +46,15 @@ public class TranslationConstruct {
|
|||
protected Map<BlockPos, BlockInfo> blocks;
|
||||
protected List<BlockInfo> actors;
|
||||
|
||||
protected AxisAlignedBB collisionBoxFront;
|
||||
protected AxisAlignedBB collisionBoxBack;
|
||||
protected AxisAlignedBB constructCollisionBox;
|
||||
protected AxisAlignedBB pistonCollisionBox;
|
||||
|
||||
protected Set<BlockPos> cachedColliders;
|
||||
protected Direction cachedColliderDirection;
|
||||
|
||||
protected int extensionLength;
|
||||
protected int initialExtensionProgress;
|
||||
protected Axis movementAxis;
|
||||
|
||||
public TranslationConstruct() {
|
||||
blocks = new HashMap<>();
|
||||
|
@ -157,12 +163,12 @@ public class TranslationConstruct {
|
|||
|
||||
extensionLength = extensionsInBack + extensionsInFront;
|
||||
initialExtensionProgress = extensionsInFront;
|
||||
collisionBoxBack = new AxisAlignedBB(end.offset(direction, -extensionsInFront));
|
||||
pistonCollisionBox = new AxisAlignedBB(end.offset(direction, -extensionsInFront));
|
||||
|
||||
for (BlockInfo pole : poles) {
|
||||
BlockPos polePos = pole.pos.offset(direction, -extensionsInFront);
|
||||
blocks.put(polePos, new BlockInfo(polePos, pole.state, null));
|
||||
collisionBoxBack = collisionBoxBack.union(new AxisAlignedBB(polePos));
|
||||
pistonCollisionBox = pistonCollisionBox.union(new AxisAlignedBB(polePos));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -189,7 +195,7 @@ public class TranslationConstruct {
|
|||
|
||||
BlockPos blockPos = pos.offset(direction).offset(direction, -offset);
|
||||
blocks.put(blockPos, new BlockInfo(blockPos, state, null));
|
||||
collisionBoxFront = new AxisAlignedBB(blockPos);
|
||||
constructCollisionBox = new AxisAlignedBB(blockPos);
|
||||
|
||||
} else {
|
||||
for (int distance = 1; distance <= parameters.maxChassisRange.get() + 1; distance++) {
|
||||
|
@ -213,10 +219,10 @@ public class TranslationConstruct {
|
|||
BlockPos blockPos = currentPos.offset(direction, -offset);
|
||||
blocks.put(blockPos, new BlockInfo(blockPos, state, null));
|
||||
|
||||
if (collisionBoxFront == null)
|
||||
collisionBoxFront = new AxisAlignedBB(blockPos);
|
||||
if (constructCollisionBox == null)
|
||||
constructCollisionBox = new AxisAlignedBB(blockPos);
|
||||
else
|
||||
collisionBoxFront = collisionBoxFront.union(new AxisAlignedBB(blockPos));
|
||||
constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(blockPos));
|
||||
|
||||
// Don't collect in front of drills
|
||||
if (AllBlocks.DRILL.typeOf(state) && state.get(FACING) == direction)
|
||||
|
@ -227,14 +233,14 @@ public class TranslationConstruct {
|
|||
|
||||
// Get attached blocks by chassis
|
||||
else {
|
||||
collisionBoxFront = new AxisAlignedBB(pos.offset(direction, -offset + 1));
|
||||
constructCollisionBox = new AxisAlignedBB(pos.offset(direction, -offset + 1));
|
||||
List<BlockInfo> attachedBlocksByChassis = getAttachedBlocksByChassis(world, direction, chassis,
|
||||
movementDirection, offset);
|
||||
if (attachedBlocksByChassis == null)
|
||||
return false;
|
||||
attachedBlocksByChassis.forEach(info -> {
|
||||
blocks.put(info.pos, info);
|
||||
collisionBoxFront = collisionBoxFront.union(new AxisAlignedBB(info.pos));
|
||||
constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(info.pos));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -296,11 +302,11 @@ public class TranslationConstruct {
|
|||
|
||||
// Skip if pushed column ended already
|
||||
if (!currentPos.equals(currentChassisPos)) {
|
||||
|
||||
|
||||
// Don't pull if not sticky
|
||||
if (!chassisSticky && !pushing)
|
||||
continue;
|
||||
|
||||
|
||||
for (BlockPos p = currentPos; !p.equals(currentChassisPos); p = p.offset(direction.getOpposite())) {
|
||||
BlockState blockState = world.getBlockState(p);
|
||||
|
||||
|
@ -328,7 +334,7 @@ public class TranslationConstruct {
|
|||
CompoundNBT nbt = new CompoundNBT();
|
||||
nbt.putInt("Range", chassisRange);
|
||||
blocks.add(new BlockInfo(currentPos.offset(direction, -offset), state,
|
||||
AllBlocks.TRANSLATION_CHASSIS.typeOf(state) ? nbt : null));
|
||||
TRANSLATION_CHASSIS.typeOf(state) ? nbt : null));
|
||||
|
||||
// Expand search
|
||||
for (Direction facing : Direction.values()) {
|
||||
|
@ -346,7 +352,7 @@ public class TranslationConstruct {
|
|||
|
||||
private static boolean canPush(World world, BlockPos pos, Direction direction) {
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
if (AllBlocks.TRANSLATION_CHASSIS.typeOf(blockState))
|
||||
if (TRANSLATION_CHASSIS.typeOf(blockState))
|
||||
return true;
|
||||
if (blockState.getBlock() instanceof ShulkerBoxBlock)
|
||||
return false;
|
||||
|
@ -373,7 +379,7 @@ public class TranslationConstruct {
|
|||
BlockState blockState = world.getBlockState(current);
|
||||
if (!(blockState.getBlock() instanceof TranslationChassisBlock))
|
||||
continue;
|
||||
if (blockState.get(BlockStateProperties.AXIS) != direction.getAxis())
|
||||
if (blockState.get(AXIS) != direction.getAxis())
|
||||
continue;
|
||||
|
||||
visited.add(current);
|
||||
|
@ -388,12 +394,260 @@ public class TranslationConstruct {
|
|||
return chassis;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
|
||||
public static TranslationConstruct moveConstructAt(World world, BlockPos pos, Direction direction) {
|
||||
if (isFrozen())
|
||||
return null;
|
||||
TranslationConstruct construct = new TranslationConstruct();
|
||||
construct.movementAxis = direction.getAxis();
|
||||
|
||||
// collect piston extensions
|
||||
|
||||
if (!construct.searchMovedStructure(world, pos, direction))
|
||||
return null;
|
||||
return construct;
|
||||
}
|
||||
|
||||
private boolean searchMovedStructure(World world, BlockPos pos, Direction direction) {
|
||||
List<BlockPos> frontier = new ArrayList<>();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
constructCollisionBox = new AxisAlignedBB(pos);
|
||||
frontier.add(pos);
|
||||
|
||||
for (int offset = 1; offset <= parameters.maxChassisRange.get(); offset++) {
|
||||
BlockPos currentPos = pos.offset(direction, offset);
|
||||
if (!world.isAreaLoaded(currentPos, 1))
|
||||
return false;
|
||||
if (!world.isBlockPresent(currentPos))
|
||||
continue;
|
||||
BlockState state = world.getBlockState(currentPos);
|
||||
if (state.getMaterial().isReplaceable())
|
||||
break;
|
||||
if (state.getCollisionShape(world, currentPos).isEmpty())
|
||||
break;
|
||||
if (!canPush(world, currentPos, direction))
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
for (int limit = 1000; limit > 0; limit--) {
|
||||
if (frontier.isEmpty())
|
||||
return true;
|
||||
if (!moveBlock(world, frontier.remove(0), direction, frontier, visited))
|
||||
return false;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean moveBlock(World world, BlockPos pos, Direction direction, List<BlockPos> frontier,
|
||||
Set<BlockPos> visited) {
|
||||
visited.add(pos);
|
||||
frontier.remove(pos);
|
||||
|
||||
if (!world.isBlockPresent(pos))
|
||||
return false;
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (state.getMaterial().isReplaceable())
|
||||
return true;
|
||||
if (state.getCollisionShape(world, pos).isEmpty())
|
||||
return true;
|
||||
if (!canPush(world, pos, direction))
|
||||
return false;
|
||||
if (TRANSLATION_CHASSIS.typeOf(state) && !moveChassis(world, pos, direction, frontier, visited))
|
||||
return false;
|
||||
if (state.getBlock() instanceof SlimeBlock)
|
||||
for (Direction offset : Direction.values())
|
||||
frontier.add(pos.offset(offset));
|
||||
|
||||
add(pos, capture(world, pos));
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean moveChassis(World world, BlockPos pos, Direction movementDirection, List<BlockPos> frontier,
|
||||
Set<BlockPos> visited) {
|
||||
List<BlockInfo> cluster = getChassisClusterAt(world, pos);
|
||||
if (cluster == null)
|
||||
return false;
|
||||
if (cluster.isEmpty())
|
||||
return true;
|
||||
|
||||
BlockInfo anchorChassis = cluster.get(0);
|
||||
Axis chassisAxis = anchorChassis.state.get(AXIS);
|
||||
List<BlockPos> chassisFrontier = new LinkedList<>();
|
||||
Set<BlockPos> chassisVisited = new HashSet<>();
|
||||
cluster.forEach(c -> frontier.add(c.pos));
|
||||
int chassisCoord = chassisAxis.getCoordinate(anchorChassis.pos.getX(), anchorChassis.pos.getY(),
|
||||
anchorChassis.pos.getZ());
|
||||
|
||||
Function<BlockPos, BlockPos> getChassisPos = position -> new BlockPos(
|
||||
chassisAxis == Axis.X ? chassisCoord : position.getX(),
|
||||
chassisAxis == Axis.Y ? chassisCoord : position.getY(),
|
||||
chassisAxis == Axis.Z ? chassisCoord : position.getZ());
|
||||
|
||||
// Collect blocks on both sides
|
||||
for (AxisDirection axisDirection : AxisDirection.values()) {
|
||||
Direction chassisDirection = Direction.getFacingFromAxis(axisDirection, chassisAxis);
|
||||
boolean pushing = chassisDirection == movementDirection;
|
||||
|
||||
Search: while (!chassisFrontier.isEmpty()) {
|
||||
BlockPos currentPos = chassisFrontier.remove(0);
|
||||
if (!world.isAreaLoaded(currentPos, 1))
|
||||
return false;
|
||||
if (!world.isBlockPresent(currentPos))
|
||||
continue;
|
||||
if (chassisVisited.contains(currentPos))
|
||||
continue;
|
||||
chassisVisited.add(currentPos);
|
||||
|
||||
BlockState state = world.getBlockState(currentPos);
|
||||
BlockPos currentChassisPos = getChassisPos.apply(currentPos);
|
||||
BlockState chassisState = world.getBlockState(currentChassisPos);
|
||||
|
||||
// Not attached to a chassis
|
||||
if (!AllBlocks.TRANSLATION_CHASSIS.typeOf(chassisState) || chassisState.get(AXIS) != chassisAxis)
|
||||
continue;
|
||||
|
||||
int chassisRange = ((ChassisTileEntity) world.getTileEntity(currentChassisPos)).getRange();
|
||||
boolean chassisSticky = chassisState.get(((AbstractChassisBlock) chassisState.getBlock())
|
||||
.getGlueableSide(chassisState, chassisDirection));
|
||||
|
||||
// Ignore replaceable Blocks and Air-like
|
||||
if (state.getMaterial().isReplaceable() || state.isAir(world, currentPos))
|
||||
continue;
|
||||
if (state.getCollisionShape(world, currentPos).isEmpty())
|
||||
continue;
|
||||
|
||||
// Too many Blocks
|
||||
boolean notInRange = !currentChassisPos.withinDistance(currentPos, chassisRange + 1);
|
||||
if (pushing && notInRange)
|
||||
return false;
|
||||
if (!pushing && notInRange)
|
||||
continue;
|
||||
|
||||
boolean isBaseChassis = currentPos.equals(currentChassisPos);
|
||||
if (!isBaseChassis) {
|
||||
// Don't pull if chassis not sticky
|
||||
if (!chassisSticky && !pushing)
|
||||
continue;
|
||||
|
||||
// Skip if pushed column ended already
|
||||
for (BlockPos posInbetween = currentPos; !posInbetween.equals(
|
||||
currentChassisPos); posInbetween = posInbetween.offset(chassisDirection.getOpposite())) {
|
||||
BlockState blockState = world.getBlockState(posInbetween);
|
||||
|
||||
if (!chassisSticky && (blockState.getMaterial().isReplaceable()))
|
||||
continue Search;
|
||||
if (!pushing && chassisSticky && !canPush(world, posInbetween, movementDirection))
|
||||
continue Search;
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore sand and co.
|
||||
if (chassisSticky && !pushing && state.getBlock() instanceof FallingBlock)
|
||||
continue;
|
||||
|
||||
// Structure is immobile
|
||||
boolean cannotPush = !canPush(world, currentPos, movementDirection);
|
||||
if (pushing && cannotPush)
|
||||
return false;
|
||||
if (!pushing && cannotPush)
|
||||
continue;
|
||||
|
||||
if (isBaseChassis) {
|
||||
add(currentPos, capture(world, currentPos));
|
||||
visited.add(currentPos);
|
||||
} else {
|
||||
frontier.add(currentPos);
|
||||
}
|
||||
|
||||
// Expand search
|
||||
for (Direction facing : Direction.values()) {
|
||||
if (isBaseChassis && facing == chassisDirection.getOpposite())
|
||||
continue;
|
||||
if (notSupportive(world, pos, facing))
|
||||
continue;
|
||||
chassisFrontier.add(currentPos.offset(facing));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<BlockInfo> getChassisClusterAt(World world, BlockPos pos) {
|
||||
List<BlockPos> search = new LinkedList<>();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
List<BlockInfo> chassis = new LinkedList<>();
|
||||
Axis axis = world.getBlockState(pos).get(AXIS);
|
||||
search.add(pos);
|
||||
|
||||
while (!search.isEmpty()) {
|
||||
if (chassis.size() > parameters.maxChassisForTranslation.get())
|
||||
return null;
|
||||
|
||||
BlockPos current = search.remove(0);
|
||||
if (visited.contains(current))
|
||||
continue;
|
||||
if (!world.isAreaLoaded(current, 1))
|
||||
return null;
|
||||
|
||||
BlockState state = world.getBlockState(current);
|
||||
if (!TRANSLATION_CHASSIS.typeOf(state))
|
||||
continue;
|
||||
if (state.get(AXIS) != axis)
|
||||
continue;
|
||||
|
||||
visited.add(current);
|
||||
chassis.add(capture(world, current));
|
||||
|
||||
for (Direction offset : Direction.values()) {
|
||||
if (offset.getAxis() == axis)
|
||||
continue;
|
||||
search.add(current.offset(offset));
|
||||
}
|
||||
}
|
||||
return chassis;
|
||||
}
|
||||
|
||||
private boolean notSupportive(World world, BlockPos pos, Direction facing) {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (AllBlocks.DRILL.typeOf(state))
|
||||
return state.get(BlockStateProperties.FACING) == facing;
|
||||
if (AllBlocks.HARVESTER.typeOf(state))
|
||||
return state.get(BlockStateProperties.HORIZONTAL_FACING) == facing;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void add(BlockPos pos, BlockInfo block) {
|
||||
BlockPos localPos = pos.offset(Direction.getFacingFromAxisDirection(movementAxis, AxisDirection.POSITIVE),
|
||||
-initialExtensionProgress);
|
||||
blocks.put(localPos, block);
|
||||
if (block.state.getBlock() instanceof IHaveMovementBehavior)
|
||||
actors.add(block);
|
||||
constructCollisionBox.union(new AxisAlignedBB(pos));
|
||||
}
|
||||
|
||||
private static BlockInfo capture(World world, BlockPos pos) {
|
||||
BlockState blockstate = world.getBlockState(pos);
|
||||
TileEntity tileentity = world.getTileEntity(pos);
|
||||
CompoundNBT compoundnbt = null;
|
||||
if (tileentity != null) {
|
||||
compoundnbt = tileentity.write(new CompoundNBT());
|
||||
compoundnbt.remove("x");
|
||||
compoundnbt.remove("y");
|
||||
compoundnbt.remove("z");
|
||||
}
|
||||
return new BlockInfo(pos, blockstate, compoundnbt);
|
||||
}
|
||||
|
||||
public AxisAlignedBB getCollisionBoxFront() {
|
||||
return collisionBoxFront;
|
||||
return constructCollisionBox;
|
||||
}
|
||||
|
||||
public AxisAlignedBB getCollisionBoxBack() {
|
||||
return collisionBoxBack;
|
||||
return pistonCollisionBox;
|
||||
}
|
||||
|
||||
public CompoundNBT writeNBT() {
|
||||
|
@ -408,13 +662,13 @@ public class TranslationConstruct {
|
|||
blocks.add(c);
|
||||
}
|
||||
|
||||
if (collisionBoxFront != null) {
|
||||
ListNBT bb = writeAABB(collisionBoxFront);
|
||||
if (constructCollisionBox != null) {
|
||||
ListNBT bb = writeAABB(constructCollisionBox);
|
||||
nbt.put("BoundsFront", bb);
|
||||
}
|
||||
|
||||
if (collisionBoxBack != null) {
|
||||
ListNBT bb = writeAABB(collisionBoxBack);
|
||||
if (pistonCollisionBox != null) {
|
||||
ListNBT bb = writeAABB(pistonCollisionBox);
|
||||
nbt.put("BoundsBack", bb);
|
||||
}
|
||||
|
||||
|
@ -454,9 +708,9 @@ public class TranslationConstruct {
|
|||
construct.extensionLength = nbt.getInt("ExtensionLength");
|
||||
|
||||
if (nbt.contains("BoundsFront"))
|
||||
construct.collisionBoxFront = construct.readAABB(nbt.getList("BoundsFront", 5));
|
||||
construct.constructCollisionBox = construct.readAABB(nbt.getList("BoundsFront", 5));
|
||||
if (nbt.contains("BoundsBack"))
|
||||
construct.collisionBoxBack = construct.readAABB(nbt.getList("BoundsBack", 5));
|
||||
construct.pistonCollisionBox = construct.readAABB(nbt.getList("BoundsBack", 5));
|
||||
|
||||
// Find blocks with special movement behaviour
|
||||
construct.blocks.values().forEach(block -> {
|
||||
|
|
|
@ -101,16 +101,16 @@ public class ContactBlock extends ProperDirectionalBlock implements IHaveMovemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean visitPosition(World world, BlockPos pos, BlockState block, Direction movement,
|
||||
public IMovementContext visitPosition(World world, BlockPos pos, BlockState block, Direction movement,
|
||||
MechanicalPistonTileEntity piston) {
|
||||
Direction direction = block.get(FACING);
|
||||
if (!hasValidContact(world, pos, direction))
|
||||
return false;
|
||||
return IdleMovementContext.INSTANCE;
|
||||
|
||||
int ticksToStayActive = (int) Math.ceil(1 / Math.abs(piston.getMovementSpeed()));
|
||||
world.setBlockState(pos.offset(direction), world.getBlockState(pos.offset(direction)).with(POWERED, true));
|
||||
world.getPendingBlockTicks().scheduleTick(pos.offset(direction), this, ticksToStayActive, TickPriority.NORMAL);
|
||||
return false;
|
||||
return IdleMovementContext.INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue