From 3d8b10d9a7c39171ad1b3b0eda00a32c44ab6ca2 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sat, 6 Feb 2021 16:07:22 +0100 Subject: [PATCH] Gantry improvements - Fixed gantry shafts not locking to correct orientations when placed near others - Gantry pinions can now be kickstarted by player interaction - Gantry pinions now update properly after being moved onto different gantry shafts - Fixed Encased Fans not providing kinetic power after being moved by contraption - Sticky Mechanical Pistons now drag attached structures with them - Mechanical piston heads and poles now drag their entire piston multiblock with them --- .../components/fan/EncasedFanBlock.java | 14 +- .../components/fan/EncasedFanTileEntity.java | 28 ++- .../structureMovement/Contraption.java | 160 ++++++++++++------ .../gantry/GantryPinionBlock.java | 23 ++- .../relays/advanced/GantryShaftBlock.java | 22 ++- 5 files changed, 173 insertions(+), 74 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java index 27e3107b7..b70de3e10 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java @@ -1,6 +1,5 @@ package com.simibubi.create.content.contraptions.components.fan; -import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock; import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock; @@ -33,9 +32,16 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements ITE te.updateGenerator(state.get(FACING))); + withTileEntityDo(worldIn, pos, te -> te.queueGeneratorUpdate()); } protected void notifyFanTile(IWorld world, BlockPos pos) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java index db7f42639..132f9f65d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.fan; import javax.annotation.Nullable; +import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTags.AllBlockTags; import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; @@ -18,7 +19,6 @@ import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; - @MethodsReturnNonnullByDefault public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements IAirCurrentSource { @@ -27,18 +27,21 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements protected int entitySearchCooldown; protected boolean isGenerator; protected boolean updateAirFlow; + protected boolean updateGenerator; public EncasedFanTileEntity(TileEntityType type) { super(type); isGenerator = false; airCurrent = new AirCurrent(this); updateAirFlow = true; + updateGenerator = false; } @Override protected void read(CompoundNBT compound, boolean clientPacket) { super.read(compound, clientPacket); - isGenerator = compound.getBoolean("Generating"); + if (!wasMoved) + isGenerator = compound.getBoolean("Generating"); if (clientPacket) airCurrent.rebuild(); } @@ -64,12 +67,20 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements return isGenerator ? AllConfigs.SERVER.kinetics.generatingFanSpeed.get() : 0; } - public void updateGenerator(Direction facing) { - boolean shouldGenerate = world.isBlockPowered(pos) && facing == Direction.DOWN - && world.isBlockPresent(pos.down()) && blockBelowIsHot(); + public void queueGeneratorUpdate() { + updateGenerator = true; + } + + public void updateGenerator() { + BlockState blockState = getBlockState(); + if (!AllBlocks.ENCASED_FAN.has(blockState)) + return; + if (blockState.get(EncasedFanBlock.FACING) != Direction.DOWN) + return; + + boolean shouldGenerate = world.isBlockPowered(pos) && world.isBlockPresent(pos.down()) && blockBelowIsHot(); if (shouldGenerate == isGenerator) return; - isGenerator = shouldGenerate; updateGeneratedRotation(); } @@ -170,6 +181,11 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements airCurrent.rebuild(); sendData(); } + + if (updateGenerator) { + updateGenerator = false; + updateGenerator(); + } if (getSpeed() == 0 || isGenerator) return; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 67d6b929d..91daa8f04 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -23,6 +23,7 @@ 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; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.components.actors.SeatBlock; import com.simibubi.create.content.contraptions.components.actors.SeatEntity; @@ -35,6 +36,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.glu import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueHandler; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState; +import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonHeadBlock; import com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonExtensionPoleBlock; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock.MagnetBlock; @@ -71,6 +73,7 @@ import net.minecraft.nbt.NBTUtil; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.ChestType; import net.minecraft.state.properties.DoubleBlockHalf; +import net.minecraft.state.properties.PistonType; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; @@ -266,25 +269,11 @@ public abstract class Contraption { if (AllBlocks.BELT.has(state)) moveBelt(pos, frontier, visited, state); - if (AllBlocks.GANTRY_PINION.has(state)) { - BlockPos offset = pos.offset(state.get(GantryPinionBlock.FACING)); - if (!visited.contains(offset)) - frontier.add(offset); - } + if (AllBlocks.GANTRY_PINION.has(state)) + moveGantryPinion(world, pos, frontier, visited, state); if (AllBlocks.GANTRY_SHAFT.has(state)) - for (Direction d : Iterate.directions) { - BlockPos offset = pos.offset(d); - if (!visited.contains(offset)) { - BlockState offsetState = world.getBlockState(offset); - Direction facing = state.get(GantryShaftBlock.FACING); - if (d.getAxis() == facing.getAxis() && AllBlocks.GANTRY_SHAFT.has(offsetState) - && offsetState.get(GantryShaftBlock.FACING) == facing) - frontier.add(offset); - else if (AllBlocks.GANTRY_PINION.has(offsetState) && offsetState.get(GantryPinionBlock.FACING) == d) - frontier.add(offset); - } - } + moveGantryShaft(world, pos, frontier, visited, state); // Bearings potentially create stabilized sub-contraptions if (AllBlocks.MECHANICAL_BEARING.has(state)) @@ -302,6 +291,10 @@ public abstract class Contraption { if (state.getBlock() instanceof MechanicalPistonBlock) if (!moveMechanicalPiston(world, pos, frontier, visited, state)) return false; + if (isExtensionPole(state)) + movePistonPole(world, pos, frontier, visited, state); + if (isPistonHead(state)) + movePistonHead(world, pos, frontier, visited, state); // Doors try to stay whole if (state.getBlock() instanceof DoorBlock) { @@ -346,6 +339,83 @@ public abstract class Contraption { return blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get(); } + protected void movePistonHead(World world, BlockPos pos, List frontier, Set visited, + BlockState state) { + Direction direction = state.get(MechanicalPistonHeadBlock.FACING); + BlockPos offset = pos.offset(direction.getOpposite()); + if (!visited.contains(offset)) { + BlockState blockState = world.getBlockState(offset); + if (isExtensionPole(blockState) && blockState.get(PistonExtensionPoleBlock.FACING) + .getAxis() == direction.getAxis()) + frontier.add(offset); + if (blockState.getBlock() instanceof MechanicalPistonBlock) { + Direction pistonFacing = blockState.get(MechanicalPistonBlock.FACING); + if (pistonFacing == direction && blockState.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) + frontier.add(offset); + } + } + if (state.get(MechanicalPistonHeadBlock.TYPE) == PistonType.STICKY) { + BlockPos attached = pos.offset(direction); + if (!visited.contains(attached)) + frontier.add(attached); + } + } + + protected void movePistonPole(World world, BlockPos pos, List frontier, Set visited, + BlockState state) { + for (Direction d : Iterate.directionsInAxis(state.get(PistonExtensionPoleBlock.FACING) + .getAxis())) { + BlockPos offset = pos.offset(d); + if (!visited.contains(offset)) { + BlockState blockState = world.getBlockState(offset); + if (isExtensionPole(blockState) && blockState.get(PistonExtensionPoleBlock.FACING) + .getAxis() == d.getAxis()) + frontier.add(offset); + if (isPistonHead(blockState) && blockState.get(MechanicalPistonHeadBlock.FACING) + .getAxis() == d.getAxis()) + frontier.add(offset); + if (blockState.getBlock() instanceof MechanicalPistonBlock) { + Direction pistonFacing = blockState.get(MechanicalPistonBlock.FACING); + if (pistonFacing == d || pistonFacing == d.getOpposite() + && blockState.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) + frontier.add(offset); + } + } + } + } + + protected void moveGantryPinion(World world, BlockPos pos, List frontier, Set visited, + BlockState state) { + BlockPos offset = pos.offset(state.get(GantryPinionBlock.FACING)); + if (!visited.contains(offset)) + frontier.add(offset); + Axis rotationAxis = ((IRotate) state.getBlock()).getRotationAxis(state); + for (Direction d : Iterate.directionsInAxis(rotationAxis)) { + offset = pos.offset(d); + BlockState offsetState = world.getBlockState(offset); + if (AllBlocks.GANTRY_SHAFT.has(offsetState) && offsetState.get(GantryShaftBlock.FACING) + .getAxis() == d.getAxis()) + if (!visited.contains(offset)) + frontier.add(offset); + } + } + + protected void moveGantryShaft(World world, BlockPos pos, List frontier, Set visited, + BlockState state) { + for (Direction d : Iterate.directions) { + BlockPos offset = pos.offset(d); + if (!visited.contains(offset)) { + BlockState offsetState = world.getBlockState(offset); + Direction facing = state.get(GantryShaftBlock.FACING); + if (d.getAxis() == facing.getAxis() && AllBlocks.GANTRY_SHAFT.has(offsetState) + && offsetState.get(GantryShaftBlock.FACING) == facing) + frontier.add(offset); + else if (AllBlocks.GANTRY_PINION.has(offsetState) && offsetState.get(GantryPinionBlock.FACING) == d) + frontier.add(offset); + } + } + } + private void moveBearing(BlockPos pos, List frontier, Set visited, BlockState state) { Direction facing = state.get(MechanicalBearingBlock.FACING); if (!canAxisBeStabilized(facing.getAxis())) { @@ -398,47 +468,25 @@ public abstract class Contraption { private boolean moveMechanicalPiston(World world, BlockPos pos, List frontier, Set visited, BlockState state) { - int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get(); Direction direction = state.get(MechanicalPistonBlock.FACING); - if (state.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) { - BlockPos searchPos = pos; - while (limit-- >= 0) { - searchPos = searchPos.offset(direction); - BlockState blockState = world.getBlockState(searchPos); - if (isExtensionPole(blockState)) { - if (blockState.get(PistonExtensionPoleBlock.FACING) - .getAxis() != direction.getAxis()) - break; - if (!visited.contains(searchPos)) - frontier.add(searchPos); - continue; - } - if (isPistonHead(blockState)) - if (!visited.contains(searchPos)) - frontier.add(searchPos); - break; - } - if (limit <= -1) - return false; - } - - BlockPos searchPos = pos; - while (limit-- >= 0) { - searchPos = searchPos.offset(direction.getOpposite()); - BlockState blockState = world.getBlockState(searchPos); - if (isExtensionPole(blockState)) { - if (blockState.get(PistonExtensionPoleBlock.FACING) - .getAxis() != direction.getAxis()) - break; - if (!visited.contains(searchPos)) - frontier.add(searchPos); - continue; - } - break; - } - - if (limit <= -1) + PistonState pistonState = state.get(MechanicalPistonBlock.STATE); + if (pistonState == PistonState.MOVING) return false; + + BlockPos offset = pos.offset(direction.getOpposite()); + if (!visited.contains(offset)) { + BlockState poleState = world.getBlockState(offset); + if (AllBlocks.PISTON_EXTENSION_POLE.has(poleState) && poleState.get(PistonExtensionPoleBlock.FACING) + .getAxis() == direction.getAxis()) + frontier.add(offset); + } + + if (pistonState == PistonState.EXTENDED || MechanicalPistonBlock.isStickyPiston(state)) { + offset = pos.offset(direction); + if (!visited.contains(offset)) + frontier.add(offset); + } + return true; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionBlock.java index 5f8874bcf..85c41d0af 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionBlock.java @@ -10,11 +10,15 @@ import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItemUseContext; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.IWorldReader; @@ -34,10 +38,15 @@ public class GantryPinionBlock extends DirectionalAxisKineticBlock implements IT .getAxis() != direction.getAxis(); } + @Override + public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) { + super.updateNeighbors(stateIn, worldIn, pos, flags); + withTileEntityDo(worldIn, pos, GantryPinionTileEntity::checkValidGantryShaft); + } + @Override public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { super.onBlockAdded(state, worldIn, pos, oldState, isMoving); - withTileEntityDo(worldIn, pos, GantryPinionTileEntity::checkValidGantryShaft); } @Override @@ -50,6 +59,18 @@ public class GantryPinionBlock extends DirectionalAxisKineticBlock implements IT return context.getFace(); } + public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + if (!player.isAllowEdit() || player.isSneaking()) + return ActionResultType.PASS; + if (player.getHeldItem(handIn) + .isEmpty()) { + withTileEntityDo(worldIn, pos, te -> te.checkValidGantryShaft()); + return ActionResultType.SUCCESS; + } + return ActionResultType.PASS; + } + @Override public BlockState getStateForPlacement(BlockItemUseContext context) { BlockState stateForPlacement = super.getStateForPlacement(context); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java index d231d00be..15cd24040 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java @@ -113,17 +113,25 @@ public class GantryShaftBlock extends DirectionalKineticBlock { @Override public BlockState getStateForPlacement(BlockItemUseContext context) { BlockState state = super.getStateForPlacement(context); + BlockPos pos = context.getPos(); + World world = context.getWorld(); Direction face = context.getFace(); - BlockState blockState = context.getWorld() - .getBlockState(context.getPos() - .offset(face.getOpposite())); - if (AllBlocks.GANTRY_SHAFT.has(blockState) && blockState.get(FACING) - .getAxis() == face.getAxis()) { - Direction facing = blockState.get(FACING); + + BlockState neighbour = world.getBlockState(pos.offset(state.get(FACING) + .getOpposite())); + + BlockState clickedState = + AllBlocks.GANTRY_SHAFT.has(neighbour) ? neighbour : world.getBlockState(pos.offset(face.getOpposite())); + + if (AllBlocks.GANTRY_SHAFT.has(clickedState) && clickedState.get(FACING) + .getAxis() == state.get(FACING) + .getAxis()) { + Direction facing = clickedState.get(FACING); state = state.with(FACING, context.getPlayer() == null || !context.getPlayer() .isSneaking() ? facing : facing.getOpposite()); } - return state.with(POWERED, shouldBePowered(state, context.getWorld(), context.getPos())); + + return state.with(POWERED, shouldBePowered(state, world, pos)); } @Override