mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-25 06:27:41 +01:00
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: 'eclipse'
|
||||||
apply plugin: 'maven-publish'
|
apply plugin: 'maven-publish'
|
||||||
|
|
||||||
version = 'mc1.14.4_v0.1.1'
|
version = 'mc1.14.4_v0.2'
|
||||||
group = 'com.simibubi.create'
|
group = 'com.simibubi.create'
|
||||||
archivesBaseName = '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());
|
flowVec = flowVec.scale(f.getAxisDirection().getOffset());
|
||||||
boolean clockwise = wf.getAxisDirection() == AxisDirection.POSITIVE;
|
boolean clockwise = wf.getAxisDirection() == AxisDirection.POSITIVE;
|
||||||
|
int clockwiseMultiplier = 1; // No difference. Causes confusion
|
||||||
|
|
||||||
if (wf.getAxis() == Axis.Z) {
|
if (wf.getAxis() == Axis.Z) {
|
||||||
if (f.getAxis() == Axis.Y)
|
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)
|
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 (wf.getAxis() == Axis.X) {
|
||||||
if (f.getAxis() == Axis.Y)
|
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)
|
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) {
|
private void updateWheelSpeed(IWorld world, BlockPos pos) {
|
||||||
|
|
|
@ -140,18 +140,20 @@ public class DrillBlock extends DirectionalKineticBlock implements IHaveMovement
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
MechanicalPistonTileEntity piston) {
|
||||||
|
IMovementContext context = IdleMovementContext.INSTANCE;
|
||||||
|
|
||||||
if (movement != block.get(FACING))
|
if (movement != block.get(FACING))
|
||||||
return false;
|
return context;
|
||||||
|
|
||||||
pos = pos.offset(movement);
|
pos = pos.offset(movement);
|
||||||
BlockState stateVisited = world.getBlockState(pos);
|
BlockState stateVisited = world.getBlockState(pos);
|
||||||
|
|
||||||
if (stateVisited.getCollisionShape(world, pos).isEmpty())
|
if (stateVisited.getCollisionShape(world, pos).isEmpty())
|
||||||
return false;
|
return context;
|
||||||
if (stateVisited.getBlockHardness(world, pos) == -1)
|
if (stateVisited.getBlockHardness(world, pos) == -1)
|
||||||
return false;
|
return context;
|
||||||
|
|
||||||
world.playEvent(2001, pos, Block.getStateId(stateVisited));
|
world.playEvent(2001, pos, Block.getStateId(stateVisited));
|
||||||
List<ItemStack> drops = Block.getDrops(stateVisited, (ServerWorld) world, pos, null);
|
List<ItemStack> drops = Block.getDrops(stateVisited, (ServerWorld) world, pos, null);
|
||||||
|
@ -164,7 +166,7 @@ public class DrillBlock extends DirectionalKineticBlock implements IHaveMovement
|
||||||
world.addEntity(itemEntity);
|
world.addEntity(itemEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,10 +93,12 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
MechanicalPistonTileEntity piston) {
|
||||||
|
IMovementContext context = IdleMovementContext.INSTANCE;
|
||||||
|
|
||||||
if (movement != block.get(HORIZONTAL_FACING))
|
if (movement != block.get(HORIZONTAL_FACING))
|
||||||
return false;
|
return context;
|
||||||
|
|
||||||
BlockState stateVisited = world.getBlockState(pos);
|
BlockState stateVisited = world.getBlockState(pos);
|
||||||
boolean notCropButCuttable = false;
|
boolean notCropButCuttable = false;
|
||||||
|
@ -111,7 +113,7 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
|
||||||
if (isValidOther(world, pos, stateVisited))
|
if (isValidOther(world, pos, stateVisited))
|
||||||
notCropButCuttable = true;
|
notCropButCuttable = true;
|
||||||
else
|
else
|
||||||
return false;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ItemStack> drops = Block.getDrops(stateVisited, (ServerWorld) world, pos, null);
|
List<ItemStack> drops = Block.getDrops(stateVisited, (ServerWorld) world, pos, null);
|
||||||
|
@ -130,7 +132,7 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
|
||||||
world.addEntity(itemEntity);
|
world.addEntity(itemEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValidCrop(World world, BlockPos pos, BlockState state) {
|
private boolean isValidCrop(World world, BlockPos pos, BlockState state) {
|
||||||
|
|
|
@ -7,6 +7,26 @@ import net.minecraft.world.World;
|
||||||
|
|
||||||
public interface IHaveMovementBehavior {
|
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.block.Blocks;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
|
import net.minecraft.particles.ParticleTypes;
|
||||||
import net.minecraft.state.BooleanProperty;
|
import net.minecraft.state.BooleanProperty;
|
||||||
import net.minecraft.state.DirectionProperty;
|
import net.minecraft.state.DirectionProperty;
|
||||||
import net.minecraft.state.EnumProperty;
|
import net.minecraft.state.EnumProperty;
|
||||||
|
@ -18,13 +19,19 @@ import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.IStringSerializable;
|
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.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.ISelectionContext;
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.common.Tags;
|
||||||
|
|
||||||
public class MechanicalPistonBlock extends KineticBlock {
|
public class MechanicalPistonBlock extends KineticBlock {
|
||||||
|
|
||||||
|
@ -110,6 +117,33 @@ public class MechanicalPistonBlock extends KineticBlock {
|
||||||
.with(AXIS_ALONG_FIRST_COORDINATE, alongFirst);
|
.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
|
@Override
|
||||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||||
return new MechanicalPistonTileEntity();
|
return new MechanicalPistonTileEntity();
|
||||||
|
|
|
@ -255,10 +255,10 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ITi
|
||||||
BlockPos otherRelativePos = BlockPos.ZERO.offset(otherMovementDirection,
|
BlockPos otherRelativePos = BlockPos.ZERO.offset(otherMovementDirection,
|
||||||
getModulatedOffset(otherPiston.offset));
|
getModulatedOffset(otherPiston.offset));
|
||||||
|
|
||||||
for (AxisAlignedBB tBB : Arrays.asList(movingConstruct.collisionBoxFront,
|
for (AxisAlignedBB tBB : Arrays.asList(movingConstruct.constructCollisionBox,
|
||||||
movingConstruct.collisionBoxBack)) {
|
movingConstruct.pistonCollisionBox)) {
|
||||||
for (AxisAlignedBB oBB : Arrays.asList(otherPiston.movingConstruct.collisionBoxFront,
|
for (AxisAlignedBB oBB : Arrays.asList(otherPiston.movingConstruct.constructCollisionBox,
|
||||||
otherPiston.movingConstruct.collisionBoxBack)) {
|
otherPiston.movingConstruct.pistonCollisionBox)) {
|
||||||
if (tBB == null || oBB == null)
|
if (tBB == null || oBB == null)
|
||||||
continue;
|
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.MECHANICAL_PISTON_HEAD;
|
||||||
import static com.simibubi.create.AllBlocks.PISTON_POLE;
|
import static com.simibubi.create.AllBlocks.PISTON_POLE;
|
||||||
import static com.simibubi.create.AllBlocks.STICKY_MECHANICAL_PISTON;
|
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 com.simibubi.create.CreateConfig.parameters;
|
||||||
|
import static net.minecraft.state.properties.BlockStateProperties.AXIS;
|
||||||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -23,14 +25,17 @@ import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.FallingBlock;
|
import net.minecraft.block.FallingBlock;
|
||||||
import net.minecraft.block.PistonBlock;
|
import net.minecraft.block.PistonBlock;
|
||||||
import net.minecraft.block.ShulkerBoxBlock;
|
import net.minecraft.block.ShulkerBoxBlock;
|
||||||
|
import net.minecraft.block.SlimeBlock;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.nbt.FloatNBT;
|
import net.minecraft.nbt.FloatNBT;
|
||||||
import net.minecraft.nbt.ListNBT;
|
import net.minecraft.nbt.ListNBT;
|
||||||
import net.minecraft.nbt.NBTUtil;
|
import net.minecraft.nbt.NBTUtil;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.state.properties.PistonType;
|
import net.minecraft.state.properties.PistonType;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.Direction.AxisDirection;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
@ -41,14 +46,15 @@ public class TranslationConstruct {
|
||||||
protected Map<BlockPos, BlockInfo> blocks;
|
protected Map<BlockPos, BlockInfo> blocks;
|
||||||
protected List<BlockInfo> actors;
|
protected List<BlockInfo> actors;
|
||||||
|
|
||||||
protected AxisAlignedBB collisionBoxFront;
|
protected AxisAlignedBB constructCollisionBox;
|
||||||
protected AxisAlignedBB collisionBoxBack;
|
protected AxisAlignedBB pistonCollisionBox;
|
||||||
|
|
||||||
protected Set<BlockPos> cachedColliders;
|
protected Set<BlockPos> cachedColliders;
|
||||||
protected Direction cachedColliderDirection;
|
protected Direction cachedColliderDirection;
|
||||||
|
|
||||||
protected int extensionLength;
|
protected int extensionLength;
|
||||||
protected int initialExtensionProgress;
|
protected int initialExtensionProgress;
|
||||||
|
protected Axis movementAxis;
|
||||||
|
|
||||||
public TranslationConstruct() {
|
public TranslationConstruct() {
|
||||||
blocks = new HashMap<>();
|
blocks = new HashMap<>();
|
||||||
|
@ -157,12 +163,12 @@ public class TranslationConstruct {
|
||||||
|
|
||||||
extensionLength = extensionsInBack + extensionsInFront;
|
extensionLength = extensionsInBack + extensionsInFront;
|
||||||
initialExtensionProgress = extensionsInFront;
|
initialExtensionProgress = extensionsInFront;
|
||||||
collisionBoxBack = new AxisAlignedBB(end.offset(direction, -extensionsInFront));
|
pistonCollisionBox = new AxisAlignedBB(end.offset(direction, -extensionsInFront));
|
||||||
|
|
||||||
for (BlockInfo pole : poles) {
|
for (BlockInfo pole : poles) {
|
||||||
BlockPos polePos = pole.pos.offset(direction, -extensionsInFront);
|
BlockPos polePos = pole.pos.offset(direction, -extensionsInFront);
|
||||||
blocks.put(polePos, new BlockInfo(polePos, pole.state, null));
|
blocks.put(polePos, new BlockInfo(polePos, pole.state, null));
|
||||||
collisionBoxBack = collisionBoxBack.union(new AxisAlignedBB(polePos));
|
pistonCollisionBox = pistonCollisionBox.union(new AxisAlignedBB(polePos));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -189,7 +195,7 @@ public class TranslationConstruct {
|
||||||
|
|
||||||
BlockPos blockPos = pos.offset(direction).offset(direction, -offset);
|
BlockPos blockPos = pos.offset(direction).offset(direction, -offset);
|
||||||
blocks.put(blockPos, new BlockInfo(blockPos, state, null));
|
blocks.put(blockPos, new BlockInfo(blockPos, state, null));
|
||||||
collisionBoxFront = new AxisAlignedBB(blockPos);
|
constructCollisionBox = new AxisAlignedBB(blockPos);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (int distance = 1; distance <= parameters.maxChassisRange.get() + 1; distance++) {
|
for (int distance = 1; distance <= parameters.maxChassisRange.get() + 1; distance++) {
|
||||||
|
@ -213,10 +219,10 @@ public class TranslationConstruct {
|
||||||
BlockPos blockPos = currentPos.offset(direction, -offset);
|
BlockPos blockPos = currentPos.offset(direction, -offset);
|
||||||
blocks.put(blockPos, new BlockInfo(blockPos, state, null));
|
blocks.put(blockPos, new BlockInfo(blockPos, state, null));
|
||||||
|
|
||||||
if (collisionBoxFront == null)
|
if (constructCollisionBox == null)
|
||||||
collisionBoxFront = new AxisAlignedBB(blockPos);
|
constructCollisionBox = new AxisAlignedBB(blockPos);
|
||||||
else
|
else
|
||||||
collisionBoxFront = collisionBoxFront.union(new AxisAlignedBB(blockPos));
|
constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(blockPos));
|
||||||
|
|
||||||
// Don't collect in front of drills
|
// Don't collect in front of drills
|
||||||
if (AllBlocks.DRILL.typeOf(state) && state.get(FACING) == direction)
|
if (AllBlocks.DRILL.typeOf(state) && state.get(FACING) == direction)
|
||||||
|
@ -227,14 +233,14 @@ public class TranslationConstruct {
|
||||||
|
|
||||||
// Get attached blocks by chassis
|
// Get attached blocks by chassis
|
||||||
else {
|
else {
|
||||||
collisionBoxFront = new AxisAlignedBB(pos.offset(direction, -offset + 1));
|
constructCollisionBox = new AxisAlignedBB(pos.offset(direction, -offset + 1));
|
||||||
List<BlockInfo> attachedBlocksByChassis = getAttachedBlocksByChassis(world, direction, chassis,
|
List<BlockInfo> attachedBlocksByChassis = getAttachedBlocksByChassis(world, direction, chassis,
|
||||||
movementDirection, offset);
|
movementDirection, offset);
|
||||||
if (attachedBlocksByChassis == null)
|
if (attachedBlocksByChassis == null)
|
||||||
return false;
|
return false;
|
||||||
attachedBlocksByChassis.forEach(info -> {
|
attachedBlocksByChassis.forEach(info -> {
|
||||||
blocks.put(info.pos, info);
|
blocks.put(info.pos, info);
|
||||||
collisionBoxFront = collisionBoxFront.union(new AxisAlignedBB(info.pos));
|
constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(info.pos));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +334,7 @@ public class TranslationConstruct {
|
||||||
CompoundNBT nbt = new CompoundNBT();
|
CompoundNBT nbt = new CompoundNBT();
|
||||||
nbt.putInt("Range", chassisRange);
|
nbt.putInt("Range", chassisRange);
|
||||||
blocks.add(new BlockInfo(currentPos.offset(direction, -offset), state,
|
blocks.add(new BlockInfo(currentPos.offset(direction, -offset), state,
|
||||||
AllBlocks.TRANSLATION_CHASSIS.typeOf(state) ? nbt : null));
|
TRANSLATION_CHASSIS.typeOf(state) ? nbt : null));
|
||||||
|
|
||||||
// Expand search
|
// Expand search
|
||||||
for (Direction facing : Direction.values()) {
|
for (Direction facing : Direction.values()) {
|
||||||
|
@ -346,7 +352,7 @@ public class TranslationConstruct {
|
||||||
|
|
||||||
private static boolean canPush(World world, BlockPos pos, Direction direction) {
|
private static boolean canPush(World world, BlockPos pos, Direction direction) {
|
||||||
BlockState blockState = world.getBlockState(pos);
|
BlockState blockState = world.getBlockState(pos);
|
||||||
if (AllBlocks.TRANSLATION_CHASSIS.typeOf(blockState))
|
if (TRANSLATION_CHASSIS.typeOf(blockState))
|
||||||
return true;
|
return true;
|
||||||
if (blockState.getBlock() instanceof ShulkerBoxBlock)
|
if (blockState.getBlock() instanceof ShulkerBoxBlock)
|
||||||
return false;
|
return false;
|
||||||
|
@ -373,7 +379,7 @@ public class TranslationConstruct {
|
||||||
BlockState blockState = world.getBlockState(current);
|
BlockState blockState = world.getBlockState(current);
|
||||||
if (!(blockState.getBlock() instanceof TranslationChassisBlock))
|
if (!(blockState.getBlock() instanceof TranslationChassisBlock))
|
||||||
continue;
|
continue;
|
||||||
if (blockState.get(BlockStateProperties.AXIS) != direction.getAxis())
|
if (blockState.get(AXIS) != direction.getAxis())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
visited.add(current);
|
visited.add(current);
|
||||||
|
@ -388,12 +394,260 @@ public class TranslationConstruct {
|
||||||
return chassis;
|
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() {
|
public AxisAlignedBB getCollisionBoxFront() {
|
||||||
return collisionBoxFront;
|
return constructCollisionBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AxisAlignedBB getCollisionBoxBack() {
|
public AxisAlignedBB getCollisionBoxBack() {
|
||||||
return collisionBoxBack;
|
return pistonCollisionBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundNBT writeNBT() {
|
public CompoundNBT writeNBT() {
|
||||||
|
@ -408,13 +662,13 @@ public class TranslationConstruct {
|
||||||
blocks.add(c);
|
blocks.add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collisionBoxFront != null) {
|
if (constructCollisionBox != null) {
|
||||||
ListNBT bb = writeAABB(collisionBoxFront);
|
ListNBT bb = writeAABB(constructCollisionBox);
|
||||||
nbt.put("BoundsFront", bb);
|
nbt.put("BoundsFront", bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collisionBoxBack != null) {
|
if (pistonCollisionBox != null) {
|
||||||
ListNBT bb = writeAABB(collisionBoxBack);
|
ListNBT bb = writeAABB(pistonCollisionBox);
|
||||||
nbt.put("BoundsBack", bb);
|
nbt.put("BoundsBack", bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,9 +708,9 @@ public class TranslationConstruct {
|
||||||
construct.extensionLength = nbt.getInt("ExtensionLength");
|
construct.extensionLength = nbt.getInt("ExtensionLength");
|
||||||
|
|
||||||
if (nbt.contains("BoundsFront"))
|
if (nbt.contains("BoundsFront"))
|
||||||
construct.collisionBoxFront = construct.readAABB(nbt.getList("BoundsFront", 5));
|
construct.constructCollisionBox = construct.readAABB(nbt.getList("BoundsFront", 5));
|
||||||
if (nbt.contains("BoundsBack"))
|
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
|
// Find blocks with special movement behaviour
|
||||||
construct.blocks.values().forEach(block -> {
|
construct.blocks.values().forEach(block -> {
|
||||||
|
|
|
@ -101,16 +101,16 @@ public class ContactBlock extends ProperDirectionalBlock implements IHaveMovemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
MechanicalPistonTileEntity piston) {
|
||||||
Direction direction = block.get(FACING);
|
Direction direction = block.get(FACING);
|
||||||
if (!hasValidContact(world, pos, direction))
|
if (!hasValidContact(world, pos, direction))
|
||||||
return false;
|
return IdleMovementContext.INSTANCE;
|
||||||
|
|
||||||
int ticksToStayActive = (int) Math.ceil(1 / Math.abs(piston.getMovementSpeed()));
|
int ticksToStayActive = (int) Math.ceil(1 / Math.abs(piston.getMovementSpeed()));
|
||||||
world.setBlockState(pos.offset(direction), world.getBlockState(pos.offset(direction)).with(POWERED, true));
|
world.setBlockState(pos.offset(direction), world.getBlockState(pos.offset(direction)).with(POWERED, true));
|
||||||
world.getPendingBlockTicks().scheduleTick(pos.offset(direction), this, ticksToStayActive, TickPriority.NORMAL);
|
world.getPendingBlockTicks().scheduleTick(pos.offset(direction), this, ticksToStayActive, TickPriority.NORMAL);
|
||||||
return false;
|
return IdleMovementContext.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue