Optimize contraption assembling

This commit is contained in:
Snownee 2021-01-30 21:09:04 +08:00
parent 08a20972aa
commit 7221f72ddf
9 changed files with 62 additions and 55 deletions

View file

@ -38,7 +38,7 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
if (!(tileEntity instanceof KineticTileEntity)) if (!(tileEntity instanceof KineticTileEntity))
return; return;
KineticTileEntity sourceTe = (KineticTileEntity) tileEntity; 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; reActivateSource = false;
} }

View file

@ -53,8 +53,7 @@ import net.minecraft.world.World;
public class BlockMovementTraits { public class BlockMovementTraits {
public static boolean movementNecessary(World world, BlockPos pos) { public static boolean movementNecessary(BlockState state, World world, BlockPos pos) {
BlockState state = world.getBlockState(pos);
if (isBrittle(state)) if (isBrittle(state))
return true; return true;
if (state.getBlock() instanceof FenceGateBlock) if (state.getBlock() instanceof FenceGateBlock)
@ -68,18 +67,17 @@ public class BlockMovementTraits {
return true; return true;
} }
public static boolean movementAllowed(World world, BlockPos pos) { public static boolean movementAllowed(BlockState state, World world, BlockPos pos) {
BlockState blockState = world.getBlockState(pos); Block block = state.getBlock();
Block block = blockState.getBlock();
if (block instanceof AbstractChassisBlock) if (block instanceof AbstractChassisBlock)
return true; return true;
if (blockState.getBlockHardness(world, pos) == -1) if (state.getBlockHardness(world, pos) == -1)
return false; return false;
if (AllBlockTags.NON_MOVABLE.matches(blockState)) if (AllBlockTags.NON_MOVABLE.matches(state))
return false; return false;
// Move controllers only when they aren't moving // 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; return true;
if (block instanceof MechanicalBearingBlock) { if (block instanceof MechanicalBearingBlock) {
TileEntity te = world.getTileEntity(pos); TileEntity te = world.getTileEntity(pos);
@ -97,11 +95,11 @@ public class BlockMovementTraits {
return !((PulleyTileEntity) te).running; return !((PulleyTileEntity) te).running;
} }
if (AllBlocks.BELT.has(blockState)) if (AllBlocks.BELT.has(state))
return true; return true;
if (blockState.getBlock() instanceof GrindstoneBlock) if (state.getBlock() instanceof GrindstoneBlock)
return true; return true;
return blockState.getPushReaction() != PushReaction.BLOCK; return state.getPushReaction() != PushReaction.BLOCK;
} }
/** /**

View file

@ -8,9 +8,11 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Queue;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@ -148,7 +150,7 @@ public abstract class Contraption {
} }
protected boolean addToInitialFrontier(World world, BlockPos pos, Direction forcedDirection, protected boolean addToInitialFrontier(World world, BlockPos pos, Direction forcedDirection,
List<BlockPos> frontier) { Queue<BlockPos> frontier) {
return true; return true;
} }
@ -161,7 +163,7 @@ public abstract class Contraption {
public boolean searchMovedStructure(World world, BlockPos pos, @Nullable Direction forcedDirection) { public boolean searchMovedStructure(World world, BlockPos pos, @Nullable Direction forcedDirection) {
initialPassengers.clear(); initialPassengers.clear();
List<BlockPos> frontier = new ArrayList<>(); Queue<BlockPos> frontier = new LinkedList<>();
Set<BlockPos> visited = new HashSet<>(); Set<BlockPos> visited = new HashSet<>();
anchor = pos; anchor = pos;
@ -175,7 +177,7 @@ public abstract class Contraption {
for (int limit = 100000; limit > 0; limit--) { for (int limit = 100000; limit > 0; limit--) {
if (frontier.isEmpty()) if (frontier.isEmpty())
return true; return true;
if (!moveBlock(world, frontier.remove(0), forcedDirection, frontier, visited)) if (!moveBlock(world, forcedDirection, frontier, visited))
return false; return false;
} }
return false; return false;
@ -241,20 +243,22 @@ public abstract class Contraption {
fluidStorage.forEach((pos, mfs) -> mfs.tick(entity, pos, world.isRemote)); fluidStorage.forEach((pos, mfs) -> mfs.tick(entity, pos, world.isRemote));
} }
protected boolean moveBlock(World world, BlockPos pos, @Nullable Direction forcedDirection, List<BlockPos> frontier, protected boolean moveBlock(World world, @Nullable Direction forcedDirection, Queue<BlockPos> frontier,
Set<BlockPos> visited) { Set<BlockPos> visited) {
BlockPos pos = frontier.poll();
if (pos == null)
return false;
visited.add(pos); visited.add(pos);
frontier.remove(pos);
if (!world.isBlockPresent(pos)) if (!world.isBlockPresent(pos))
return false; return false;
if (isAnchoringBlockAt(pos)) if (isAnchoringBlockAt(pos))
return true; return true;
if (!BlockMovementTraits.movementNecessary(world, pos))
return true;
if (!movementAllowed(world, pos))
return false;
BlockState state = world.getBlockState(pos); BlockState state = world.getBlockState(pos);
if (!BlockMovementTraits.movementNecessary(state, world, pos))
return true;
if (!movementAllowed(state, world, pos))
return false;
if (state.getBlock() instanceof AbstractChassisBlock if (state.getBlock() instanceof AbstractChassisBlock
&& !moveChassis(world, pos, forcedDirection, frontier, visited)) && !moveChassis(world, pos, forcedDirection, frontier, visited))
return false; return false;
@ -290,9 +294,10 @@ public abstract class Contraption {
} }
// Cart assemblers attach themselves // Cart assemblers attach themselves
BlockState stateBelow = world.getBlockState(pos.down()); BlockPos posDown = pos.down();
if (!visited.contains(pos.down()) && AllBlocks.CART_ASSEMBLER.has(stateBelow)) BlockState stateBelow = world.getBlockState(posDown);
frontier.add(pos.down()); if (!visited.contains(posDown) && AllBlocks.CART_ASSEMBLER.has(stateBelow))
frontier.add(posDown);
Map<Direction, SuperGlueEntity> superglue = SuperGlueHandler.gatherGlue(world, pos); Map<Direction, SuperGlueEntity> superglue = SuperGlueHandler.gatherGlue(world, pos);
@ -302,7 +307,7 @@ public abstract class Contraption {
BlockState blockState = world.getBlockState(offsetPos); BlockState blockState = world.getBlockState(offsetPos);
if (isAnchoringBlockAt(offsetPos)) if (isAnchoringBlockAt(offsetPos))
continue; continue;
if (!movementAllowed(world, offsetPos)) { if (!movementAllowed(blockState, world, offsetPos)) {
if (offset == forcedDirection) if (offset == forcedDirection)
return false; return false;
continue; continue;
@ -336,7 +341,7 @@ public abstract class Contraption {
return blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get(); return blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get();
} }
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); Direction facing = state.get(MechanicalBearingBlock.FACING);
if (!canAxisBeStabilized(facing.getAxis())) { if (!canAxisBeStabilized(facing.getAxis())) {
BlockPos offset = pos.offset(facing); BlockPos offset = pos.offset(facing);
@ -347,7 +352,7 @@ public abstract class Contraption {
pendingSubContraptions.add(new BlockFace(pos, facing)); 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 nextPos = BeltBlock.nextSegmentPosition(state, pos, true);
BlockPos prevPos = BeltBlock.nextSegmentPosition(state, pos, false); BlockPos prevPos = BeltBlock.nextSegmentPosition(state, pos, false);
if (nextPos != null && !visited.contains(nextPos)) if (nextPos != null && !visited.contains(nextPos))
@ -368,7 +373,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(); int limit = AllConfigs.SERVER.kinetics.maxRopeLength.get();
BlockPos ropePos = pos; BlockPos ropePos = pos;
while (limit-- >= 0) { while (limit-- >= 0) {
@ -386,7 +391,7 @@ public abstract class Contraption {
} }
} }
private boolean moveMechanicalPiston(World world, BlockPos pos, List<BlockPos> frontier, Set<BlockPos> visited, private boolean moveMechanicalPiston(World world, BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited,
BlockState state) { BlockState state) {
int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get(); int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get();
Direction direction = state.get(MechanicalPistonBlock.FACING); Direction direction = state.get(MechanicalPistonBlock.FACING);
@ -432,7 +437,7 @@ public abstract class Contraption {
return true; 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) { Set<BlockPos> visited) {
TileEntity te = world.getTileEntity(pos); TileEntity te = world.getTileEntity(pos);
if (!(te instanceof ChassisTileEntity)) if (!(te instanceof ChassisTileEntity))
@ -517,8 +522,8 @@ public abstract class Contraption {
return globalPos.subtract(anchor); return globalPos.subtract(anchor);
} }
protected boolean movementAllowed(World world, BlockPos pos) { protected boolean movementAllowed(BlockState state, World world, BlockPos pos) {
return BlockMovementTraits.movementAllowed(world, pos); return BlockMovementTraits.movementAllowed(state, world, pos);
} }
protected boolean isAnchoringBlockAt(BlockPos pos) { protected boolean isAnchoringBlockAt(BlockPos pos) {

View file

@ -1,7 +1,7 @@
package com.simibubi.create.content.contraptions.components.structureMovement.bearing; package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.Queue;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
@ -92,11 +92,13 @@ public class ClockworkContraption extends Contraption {
} }
@Override @Override
protected boolean moveBlock(World world, BlockPos pos, Direction direction, List<BlockPos> frontier, protected boolean moveBlock(World world, Direction direction, Queue<BlockPos> frontier,
Set<BlockPos> visited) { Set<BlockPos> visited) {
if (ignoreBlocks.contains(pos)) if (ignoreBlocks.contains(frontier.peek())) {
frontier.poll();
return true; return true;
return super.moveBlock(world, pos, direction, frontier, visited); }
return super.moveBlock(world, direction, frontier, visited);
} }
@Override @Override

View file

@ -7,6 +7,7 @@ import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Queue;
import java.util.Set; import java.util.Set;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
@ -76,12 +77,12 @@ public class ChassisTileEntity extends SmartTileEntity {
} }
public List<ChassisTileEntity> collectChassisGroup() { public List<ChassisTileEntity> collectChassisGroup() {
List<BlockPos> frontier = new ArrayList<>(); Queue<BlockPos> frontier = new LinkedList<>();
List<ChassisTileEntity> collected = new ArrayList<>(); List<ChassisTileEntity> collected = new ArrayList<>();
Set<BlockPos> visited = new HashSet<>(); Set<BlockPos> visited = new HashSet<>();
frontier.add(pos); frontier.add(pos);
while (!frontier.isEmpty()) { while (!frontier.isEmpty()) {
BlockPos current = frontier.remove(0); BlockPos current = frontier.poll();
if (visited.contains(current)) if (visited.contains(current))
continue; continue;
visited.add(current); visited.add(current);
@ -96,7 +97,7 @@ public class ChassisTileEntity extends SmartTileEntity {
return collected; return collected;
} }
public boolean addAttachedChasses(List<BlockPos> frontier, Set<BlockPos> visited) { public boolean addAttachedChasses(Queue<BlockPos> frontier, Set<BlockPos> visited) {
BlockState state = getBlockState(); BlockState state = getBlockState();
if (!(state.getBlock() instanceof AbstractChassisBlock)) if (!(state.getBlock() instanceof AbstractChassisBlock))
return false; return false;
@ -166,7 +167,7 @@ public class ChassisTileEntity extends SmartTileEntity {
break; break;
// Ignore replaceable Blocks and Air-like // Ignore replaceable Blocks and Air-like
if (!BlockMovementTraits.movementNecessary(world, current)) if (!BlockMovementTraits.movementNecessary(currentState, world, current))
break; break;
if (BlockMovementTraits.isBrittle(currentState)) if (BlockMovementTraits.isBrittle(currentState))
break; break;
@ -207,7 +208,7 @@ public class ChassisTileEntity extends SmartTileEntity {
continue; continue;
if (!searchPos.withinDistance(pos, chassisRange + .5f)) if (!searchPos.withinDistance(pos, chassisRange + .5f))
continue; continue;
if (!BlockMovementTraits.movementNecessary(world, searchPos)) if (!BlockMovementTraits.movementNecessary(searchedState, world, searchPos))
continue; continue;
if (BlockMovementTraits.isBrittle(searchedState)) if (BlockMovementTraits.isBrittle(searchedState))
continue; continue;

View file

@ -180,7 +180,7 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
BlockState state = world.getBlockState(pos); BlockState state = world.getBlockState(pos);
if (BlockMovementTraits.isBlockAttachedTowards(world, pos, state, direction)) if (BlockMovementTraits.isBlockAttachedTowards(world, pos, state, direction))
return true; return true;
if (!BlockMovementTraits.movementNecessary(world, pos)) if (!BlockMovementTraits.movementNecessary(state, world, pos))
return false; return false;
if (BlockMovementTraits.notSupportive(state, direction)) if (BlockMovementTraits.notSupportive(state, direction))
return false; return false;

View file

@ -2,7 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.mo
import static com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlock.RAIL_SHAPE; 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 org.apache.commons.lang3.tuple.Pair;
@ -70,7 +70,7 @@ public class MountedContraption extends Contraption {
} }
@Override @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.clear();
frontier.add(pos.up()); frontier.add(pos.up());
return true; return true;
@ -104,11 +104,10 @@ public class MountedContraption extends Contraption {
} }
@Override @Override
protected boolean movementAllowed(World world, BlockPos pos) { protected boolean movementAllowed(BlockState state, World world, BlockPos pos) {
BlockState blockState = world.getBlockState(pos); if (!pos.equals(anchor) && AllBlocks.CART_ASSEMBLER.has(state))
if (!pos.equals(anchor) && AllBlocks.CART_ASSEMBLER.has(blockState)) return testSecondaryCartAssembler(world, state, pos);
return testSecondaryCartAssembler(world, blockState, pos); return super.movementAllowed(state, world, pos);
return super.movementAllowed(world, pos);
} }
protected boolean testSecondaryCartAssembler(World world, BlockState state, BlockPos pos) { protected boolean testSecondaryCartAssembler(World world, BlockState state, BlockPos pos) {

View file

@ -23,6 +23,7 @@ import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Queue;
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_EXTENSION_POLE; import static com.simibubi.create.AllBlocks.PISTON_EXTENSION_POLE;
@ -144,7 +145,7 @@ public class PistonContraption extends TranslatingContraption {
} }
@Override @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.clear();
boolean sticky = isStickyPiston(world.getBlockState(pos.offset(orientation, -1))); boolean sticky = isStickyPiston(world.getBlockState(pos.offset(orientation, -1)));
boolean retracting = direction != orientation; boolean retracting = direction != orientation;
@ -156,14 +157,14 @@ public class PistonContraption extends TranslatingContraption {
BlockPos currentPos = pos.offset(orientation, offset + initialExtensionProgress); BlockPos currentPos = pos.offset(orientation, offset + initialExtensionProgress);
if (!world.isBlockPresent(currentPos)) if (!world.isBlockPresent(currentPos))
return false; return false;
if (!BlockMovementTraits.movementNecessary(world, currentPos))
return true;
BlockState state = world.getBlockState(currentPos); BlockState state = world.getBlockState(currentPos);
if (!BlockMovementTraits.movementNecessary(state, world, currentPos))
return true;
if (BlockMovementTraits.isBrittle(state) && !(state.getBlock() instanceof CarpetBlock)) if (BlockMovementTraits.isBrittle(state) && !(state.getBlock() instanceof CarpetBlock))
return true; return true;
if (isPistonHead(state) && state.get(FACING) == direction.getOpposite()) if (isPistonHead(state) && state.get(FACING) == direction.getOpposite())
return true; return true;
if (!BlockMovementTraits.movementAllowed(world, currentPos)) if (!BlockMovementTraits.movementAllowed(state, world, currentPos))
return retracting; return retracting;
if (retracting && state.getPushReaction() == PushReaction.PUSH_ONLY) if (retracting && state.getPushReaction() == PushReaction.PUSH_ONLY)
return true; return true;

View file

@ -176,9 +176,10 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
return; return;
BlockPos posBelow = pos.down((int) (offset + getMovementSpeed()) + 1); 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; return;
if (BlockMovementTraits.isBrittle(world.getBlockState(posBelow))) if (BlockMovementTraits.isBrittle(state))
return; return;
disassemble(); disassemble();