下面列出了怎么用net.minecraft.util.math.BlockPos.MutableBlockPos的API类实例代码及写法,或者点击链接到github查看源代码。
protected HashMap<BlockPos, Node<NodeDataType>> findAllConnectedBlocks(BlockPos startPos) {
HashMap<BlockPos, Node<NodeDataType>> observedSet = new HashMap<>();
observedSet.put(startPos, getNodeAt(startPos));
Node<NodeDataType> firstNode = getNodeAt(startPos);
MutableBlockPos currentPos = new MutableBlockPos(startPos);
Stack<EnumFacing> moveStack = new Stack<>();
main:
while (true) {
for (EnumFacing facing : EnumFacing.VALUES) {
currentPos.move(facing);
Node<NodeDataType> secondNode = getNodeAt(currentPos);
//if there is node, and it can connect with previous node, add it to list, and set previous node as current
if (secondNode != null && canNodesConnect(firstNode, facing, secondNode, this) && !observedSet.containsKey(currentPos)) {
observedSet.put(currentPos.toImmutable(), getNodeAt(currentPos));
firstNode = secondNode;
moveStack.push(facing.getOpposite());
continue main;
} else currentPos.move(facing.getOpposite());
}
if (!moveStack.isEmpty()) {
currentPos.move(moveStack.pop());
firstNode = getNodeAt(currentPos);
} else break;
}
return observedSet;
}
private boolean checkMultiblockValid(Map<BlockPos, MetaTileEntityTank> tankMap, BlockPos lowestCorner, int sizeX, int sizeY, int sizeZ) {
//iterate each block to ensure that we have tanks in valid positions
HashSet<BlockPos> visitedPositions = new HashSet<>();
MutableBlockPos blockPos = new MutableBlockPos();
for (int i = 0; i < sizeX; i++) {
for (int j = 0; j < sizeY; j++) {
for (int k = 0; k < sizeZ; k++) {
blockPos.setPos(lowestCorner.getX() + i, lowestCorner.getY() + j, lowestCorner.getZ() + k);
MetaTileEntityTank tankHere = tankMap.get(blockPos);
if (tankHere == null) {
//tank is not here, so multiblock is not formed
return false;
}
//add found tank into the visited position list
visitedPositions.add(tankHere.getPos());
}
}
}
//multiblock is assembled only if every tank neighbour is in the multiblock
return visitedPositions.containsAll(tankMap.keySet());
}
@Override
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
ItemStack stackInHand = playerIn.getHeldItem(hand);
if (stackInHand.isEmpty() || !(stackInHand.getItem() instanceof FrameItemBlock))
return false;
IBlockState blockState = ((FrameItemBlock) stackInHand.getItem()).getBlockState(stackInHand);
if (blockState != worldIn.getBlockState(pos))
return false;
MutableBlockPos blockPos = new MutableBlockPos(pos);
for (int i = 0; i < 32; i++) {
IBlockState stateHere = worldIn.getBlockState(blockPos);
if (stateHere == state) {
blockPos.move(EnumFacing.UP);
continue;
}
if (canPlaceBlockAt(worldIn, blockPos)) {
worldIn.setBlockState(blockPos, blockState);
if (!playerIn.capabilities.isCreativeMode)
stackInHand.shrink(1);
return true;
} else {
return false;
}
}
return false;
}
public boolean checkStructure() {
MutableBlockPos position = new MutableBlockPos(pos);
int heighest = 0;
for (int i = pos.getY() + 1; i < (world.provider.getActualHeight() + 1); i++) {
position.setY(i);
if (!checkPos(position)) {
heighest = i - 1;
this.casingheight = i;
fenceCheck();
this.chance = 262 - (casingheight - (this.getPos().getY() + 1));
chanceCheck();
break;
}
}
return heighest > (pos.getY() + 7);
}
public ShipCollisionTask(WorldPhysicsCollider toTask, int taskStartIndex) {
this.taskStartIndex = taskStartIndex;
this.toTask = toTask;
this.mutablePos = new MutableBlockPos();
this.inLocalPos = new MutableBlockPos();
this.inWorld = new Vector();
this.collisionInformationGenerated = new ArrayList<>();
this.inWorldState = null;
int size = toTask.getCachedPotentialHitSize();
if (taskStartIndex + MAX_TASKS_TO_CHECK > size + 1) {
tasksToCheck = size + 1 - taskStartIndex;
} else {
tasksToCheck = MAX_TASKS_TO_CHECK;
}
}
public void processCollisionTask(ShipCollisionTask task) {
MutableBlockPos inWorldPos = new MutableBlockPos();
MutableBlockPos inLocalPos = new MutableBlockPos();
Iterator<CollisionInformationHolder> collisionIterator = task
.getCollisionInformationIterator();
while (collisionIterator.hasNext()) {
CollisionInformationHolder info = collisionIterator.next();
inWorldPos.setPos(info.inWorldX, info.inWorldY, info.inWorldZ);
inLocalPos.setPos(info.inLocalX, info.inLocalY, info.inLocalZ);
handleActualCollision(info.collider, inWorldPos, inLocalPos, info.inWorldState,
info.inLocalState);
}
/*
* for (CollisionInformationHolder info :
* task.getCollisionInformationGenerated()) { inWorldPos.setPos(info.inWorldX,
* info.inWorldY, info.inWorldZ); inLocalPos.setPos(info.inLocalX,
* info.inLocalY, info.inLocalZ); handleActualCollision(info.collider,
* inWorldPos, inLocalPos, info.inWorldState, info.inLocalState); }
*/
task.getCollisionInformationGenerated().clear();
}
public void physicsTickAfterAllPreForces(float timeStep) {
List<PhysicsParticle> aliveParticles = new ArrayList<PhysicsParticle>(
physicsParticles.size());
MutableBlockPos bufferBlockPos = new MutableBlockPos();
Vector bufferVector = new Vector();
Vector bufferVectorForcePos = new Vector();
Vector bufferVectorForce = new Vector();
for (PhysicsParticle physicsParticle : physicsParticles) {
physicsParticle.tickParticle(parent, bufferBlockPos, bufferVector, timeStep);
if (!physicsParticle.isParticleDead()) {
aliveParticles.add(physicsParticle);
} else {
if (physicsParticle.addMomentumToShip) {
bufferVectorForcePos
.setValue(physicsParticle.posX - parent.getParent().getWrapperEntity().posX,
physicsParticle.posY - parent.getParent().getWrapperEntity().posY,
physicsParticle.posZ - parent.getParent().getWrapperEntity().posZ);
bufferVectorForce.setValue(physicsParticle.velX * physicsParticle.mass,
physicsParticle.velY * physicsParticle.mass,
physicsParticle.velZ * physicsParticle.mass);
parent.addForceAtPoint(bufferVectorForcePos, bufferVectorForce);
}
}
}
this.physicsParticles = aliveParticles;
}
/**
* Returns the MutableBlockPos <b>pos</b> with a position set to <b>posReference</b> offset by <b>amount</b> in the direction <b>side</b>.
*/
public static MutableBlockPos getOffsetPosition(MutableBlockPos pos, BlockPos posReference, EnumFacing side, int amount)
{
switch (side)
{
case NORTH:
pos.setPos(posReference.getX(), posReference.getY(), posReference.getZ() - amount);
case SOUTH:
pos.setPos(posReference.getX(), posReference.getY(), posReference.getZ() + amount);
case EAST:
pos.setPos(posReference.getX() + amount, posReference.getY(), posReference.getZ());
case WEST:
pos.setPos(posReference.getX() - amount, posReference.getY(), posReference.getZ());
case UP:
pos.setPos(posReference.getX(), posReference.getY() + amount, posReference.getZ());
case DOWN:
pos.setPos(posReference.getX(), posReference.getY() - amount, posReference.getZ());
}
return pos;
}
@Override
public boolean handleHarvest(IBetterChest chest, IBlockState state, World world, BlockPos pos) {
MutableBlockPos start = new MutableBlockPos(pos);
while (canBreak(world, start)) {
start.move(EnumFacing.UP);
}
start.move(EnumFacing.DOWN);
if (start.getY() >= pos.getY()) {
BlockPos target = search(world, pos);
IBlockState targetState = world.getBlockState(target);
targetState.getBlock().breakBlock(world, pos, state);
PlantHarvestHelper.breakBlockHandleDrop(world, target, targetState, chest);
return true;
}
return false;
}
/** Scan an area for stuff */
public List<BlockPos> scanArea(World world) {
List<BlockPos> bpl = new ArrayList<BlockPos>();
Iterable<MutableBlockPos> set = BlockPos.getAllInBoxMutable(startX, startY, startZ, endX, endY, endZ);
Iterator<MutableBlockPos> in = set.iterator();
while (in.hasNext()) {
MutableBlockPos mbp = in.next();
if (!world.isAirBlock(mbp)) {
bpl.add(mbp.toImmutable());
}
}
return bpl;
}
public boolean populateChunk(World world) {
MutableBlockPos blockPos = new MutableBlockPos();
boolean generatedAnything = false;
for (OreDepositDefinition definition : oreBlocks.keySet()) {
TLongList blockIndexList = oreBlocks.get(definition);
TLongSet generatedBlocks = new TLongHashSet();
boolean generatedOreVein = false;
for (int i = 0; i < blockIndexList.size(); i++) {
long blockIndex = blockIndexList.get(i);
int xyzValue = (int) (blockIndex >> 32);
int blockX = (byte) xyzValue;
int blockZ = (byte) (xyzValue >> 8);
int blockY = (short) (xyzValue >> 16);
int index = (int) blockIndex;
blockPos.setPos(chunkX * 16 + blockX, blockY, chunkZ * 16 + blockZ);
IBlockState currentState = world.getBlockState(blockPos);
IBlockState newState;
if (index == 0) {
//it's primary ore block
if (!definition.getGenerationPredicate().test(currentState, world, blockPos))
continue; //do not generate if predicate didn't match
newState = definition.getBlockFiller().apply(currentState, world, blockPos, blockX, blockY, blockZ);
} else {
//it's populator-generated block with index
VeinBufferPopulator populator = (VeinBufferPopulator) definition.getVeinPopulator();
newState = populator.getBlockByIndex(world, blockPos, index - 1);
}
//set flags as 16 to avoid observer updates loading neighbour chunks
world.setBlockState(blockPos, newState, 16);
generatedBlocks.add(Block.getStateId(newState));
generatedOreVein = true;
generatedAnything = true;
}
if (generatedOreVein) {
this.generatedBlocksSet.put(definition, generatedBlocks);
this.generatedOres.add(definition);
}
}
return generatedAnything;
}
@Override
public void generate(Random gridRandom, IBlockGeneratorAccess relativeBlockAccess) {
MutableBlockPos relativePos = new MutableBlockPos();
int blocksCount = minBlocksCount == maxBlocksCount ? maxBlocksCount : minBlocksCount + gridRandom.nextInt(maxBlocksCount - minBlocksCount);
EnumFacing prevDirection = null;
for (int i = 0; i < blocksCount; i++) {
EnumFacing[] allowedFacings = ArrayUtils.removeElement(EnumFacing.VALUES, prevDirection);
prevDirection = allowedFacings[gridRandom.nextInt(allowedFacings.length)];
relativePos.offset(prevDirection);
relativeBlockAccess.generateBlock(relativePos.getX(), relativePos.getY(), relativePos.getZ());
}
}
private MutableBlockPos setActualRelativeOffset(MutableBlockPos pos, int x, int y, int z, EnumFacing facing) {
//if (!ArrayUtils.contains(ALLOWED_FACINGS, facing))
// throw new IllegalArgumentException("Can rotate only horizontally");
int[] c0 = new int[]{x, y, z}, c1 = new int[3];
for (int i = 0; i < 3; i++) {
switch (structureDir[i].getActualFacing(facing)) {
case UP:
c1[1] = c0[i];
break;
case DOWN:
c1[1] = -c0[i];
break;
case WEST:
c1[0] = -c0[i];
break;
case EAST:
c1[0] = c0[i];
break;
case NORTH:
c1[2] = -c0[i];
break;
case SOUTH:
c1[2] = c0[i];
break;
}
}
return pos.setPos(c1[0], c1[1], c1[2]);
}
public IBlockState getOffsetState(EnumFacing face) {
if (pos instanceof MutableBlockPos) {
((MutableBlockPos) pos).move(face);
IBlockState blockState = world.getBlockState(pos);
((MutableBlockPos) pos).move(face.getOpposite());
return blockState;
}
return world.getBlockState(this.pos.offset(face));
}
private static Map<BlockPos, MetaTileEntityTank> findConnectedTanks(MetaTileEntityTank tank, Set<BlockPos> visitedSet) {
BlockPos startPos = tank.getPos();
HashMap<BlockPos, MetaTileEntityTank> observedSet = new HashMap<>();
if (visitedSet.contains(startPos)) {
return observedSet;
}
observedSet.put(tank.getPos(), tank);
visitedSet.add(startPos);
MetaTileEntityTank firstNode = observedSet.get(startPos);
MutableBlockPos currentPos = new MutableBlockPos(startPos);
Stack<EnumFacing> moveStack = new Stack<>();
int currentAmount = 0;
int scanSizeLimit = tank.maxSizeHorizontal * tank.maxSizeHorizontal * tank.maxSizeVertical * 4;
main: while (true) {
if (currentAmount >= scanSizeLimit) {
break;
}
for (EnumFacing facing : EnumFacing.VALUES) {
currentPos.move(facing);
MetaTileEntityTank metaTileEntity;
if (!visitedSet.contains(currentPos) &&
!observedSet.containsKey(currentPos) &&
(metaTileEntity = tank.getTankTile(currentPos)) != null &&
canTanksConnect(firstNode, metaTileEntity, facing)) {
observedSet.put(metaTileEntity.getPos(), metaTileEntity);
visitedSet.add(metaTileEntity.getPos());
firstNode = metaTileEntity;
moveStack.push(facing.getOpposite());
currentAmount++;
continue main;
} else currentPos.move(facing.getOpposite());
}
if (!moveStack.isEmpty()) {
currentPos.move(moveStack.pop());
firstNode = observedSet.get(currentPos);
} else break;
}
return observedSet;
}
private boolean canFrameSupportVertical(World worldIn, BlockPos framePos) {
MutableBlockPos blockPos = new MutableBlockPos(framePos);
do {
blockPos.move(EnumFacing.DOWN);
IBlockState blockState = worldIn.getBlockState(blockPos);
if (!(blockState.getBlock() instanceof BlockFrame)) {
return blockState.getBlockFaceShape(worldIn, blockPos, EnumFacing.UP) == BlockFaceShape.SOLID;
}
} while (true);
}
public static BlockPos calculateAverageGroundLevel(World worldIn, BlockPos origin, BlockPos sizes) {
BlockPos dest = origin.add(sizes.getX(), 0, sizes.getZ());
int minGroundLevel = 256;
for (MutableBlockPos blockPos : MutableBlockPos.getAllInBoxMutable(origin, dest)) {
int groundLevel = worldIn.getTopSolidOrLiquidBlock(blockPos).getY();
minGroundLevel = Math.min(minGroundLevel, groundLevel);
}
return new BlockPos(origin.getX(), minGroundLevel, origin.getZ());
}
public List<RoutePath> computePatches(BlockPos startPos) {
ArrayList<RoutePath> readyPaths = new ArrayList<>();
RoutePath currentPath = new RoutePath();
Node<WireProperties> firstNode = getNodeAt(startPos);
currentPath.path.put(startPos, firstNode.data);
readyPaths.add(currentPath.cloneAndCompute(startPos));
HashSet<BlockPos> observedSet = new HashSet<>();
observedSet.add(startPos);
MutableBlockPos currentPos = new MutableBlockPos(startPos);
Stack<EnumFacing> moveStack = new Stack<>();
main:
while (true) {
for (EnumFacing facing : EnumFacing.VALUES) {
currentPos.move(facing);
Node<WireProperties> secondNode = getNodeAt(currentPos);
if (secondNode != null && canNodesConnect(firstNode, facing, secondNode, this) && !observedSet.contains(currentPos)) {
BlockPos immutablePos = currentPos.toImmutable();
observedSet.add(immutablePos);
firstNode = secondNode;
moveStack.push(facing.getOpposite());
currentPath.path.put(immutablePos, getNodeAt(immutablePos).data);
if (secondNode.isActive) {
//if we are on active node, this is end of our path
RoutePath finalizedPath = currentPath.cloneAndCompute(immutablePos);
readyPaths.add(finalizedPath);
}
continue main;
} else {
currentPos.move(facing.getOpposite());
}
}
if (!moveStack.isEmpty()) {
currentPos.move(moveStack.pop());
//also remove already visited block from path
currentPath.path.remove(currentPos);
} else break;
}
return readyPaths;
}
private static List<BlockPos> gatherReplacableBlocks(World worldIn, BlockPos centerPos, int maxRadiusSq) {
HashSet<BlockPos> observedSet = new HashSet<>();
ArrayList<BlockPos> resultAirBlocks = new ArrayList<>();
observedSet.add(centerPos);
resultAirBlocks.add(centerPos);
Stack<EnumFacing> moveStack = new Stack<>();
MutableBlockPos currentPos = new MutableBlockPos(centerPos);
main:
while (true) {
for (EnumFacing facing : EnumFacing.VALUES) {
currentPos.move(facing);
IBlockState blockStateHere = worldIn.getBlockState(currentPos);
//if there is node, and it can connect with previous node, add it to list, and set previous node as current
if (blockStateHere.getBlock().isReplaceable(worldIn, currentPos) &&
currentPos.distanceSq(centerPos) <= maxRadiusSq && !observedSet.contains(currentPos)) {
BlockPos immutablePos = currentPos.toImmutable();
observedSet.add(immutablePos);
resultAirBlocks.add(immutablePos);
moveStack.push(facing.getOpposite());
continue main;
} else currentPos.move(facing.getOpposite());
}
if (!moveStack.isEmpty()) {
currentPos.move(moveStack.pop());
} else break;
}
resultAirBlocks.sort(Comparator.comparing(it -> it.distanceSq(centerPos)));
return resultAirBlocks;
}
private static List<BlockPos> gatherFrameBlocks(World worldIn, BlockPos centerPos, int maxRadiusSq) {
HashSet<BlockPos> observedSet = new HashSet<>();
ArrayList<BlockPos> resultFrameBlocks = new ArrayList<>();
observedSet.add(centerPos);
resultFrameBlocks.add(centerPos);
IBlockState frameState = null;
Stack<EnumFacing> moveStack = new Stack<>();
MutableBlockPos currentPos = new MutableBlockPos(centerPos);
main:
while (true) {
for (EnumFacing facing : EnumFacing.VALUES) {
currentPos.move(facing);
IBlockState blockStateHere = worldIn.getBlockState(currentPos);
//if there is node, and it can connect with previous node, add it to list, and set previous node as current
if (blockStateHere.getBlock() instanceof BlockFrame &&
currentPos.distanceSq(centerPos) <= maxRadiusSq &&
(frameState == null || frameState == blockStateHere) && !observedSet.contains(currentPos)) {
BlockPos immutablePos = currentPos.toImmutable();
observedSet.add(immutablePos);
resultFrameBlocks.add(immutablePos);
moveStack.push(facing.getOpposite());
frameState = blockStateHere;
continue main;
} else currentPos.move(facing.getOpposite());
}
if (!moveStack.isEmpty()) {
currentPos.move(moveStack.pop());
} else break;
}
resultFrameBlocks.sort(Comparator.comparing(it -> it.distanceSq(centerPos)));
return resultFrameBlocks;
}
public static void setPosWithRespectTo(int hash, BlockPos start, MutableBlockPos toSet) {
int y = hash % maxRange;
int x = ((hash - y) / maxRange) % maxRange;
int z = (hash - (x * maxRange) - y) / (maxRangeSquared);
x -= maxRangeHalved;
z -= maxRangeHalved;
toSet.setPos(x + start.getX(), y, z + start.getZ());
}
public WorldPhysicsCollider(PhysicsCalculations calculations) {
this.calculator = calculations;
this.parent = calculations.getParent();
this.worldObj = parent.world();
this.cachedPotentialHits = TCollections.synchronizedList(new TIntArrayList());
this.cachedHitsToRemove = new TIntArrayList();
this.rand = new Random();
this.mutablePos = new MutableBlockPos();
this.tasks = new ArrayList<ShipCollisionTask>();
this.ticksSinceCacheUpdate = 25D;
this.updateCollisionTasksCache = true;
this.centerPotentialHit = null;
}
public void tickParticle(PhysicsCalculations physicsSource, MutableBlockPos bufferBlockPos,
Vector bufferVector, float timeStep) {
// First move the particle forward
this.posX += velX * timeStep;
this.posY += velY * timeStep;
this.posZ += velZ * timeStep;
// Then advance the particle death clock
this.particleLife -= timeStep;
this.isParticleDead = (particleLife < 0);
// Then check for collision in the world
bufferBlockPos.setPos(posX, posY, posZ);
if (!canParticlePassThrough(physicsSource.getParent().world(), bufferBlockPos)) {
// The particle hit a block in the world, so kill it.
this.isParticleDead = true;
}
// If the particle still isn't dead then check for collision in ship
if (!isParticleDead) {
bufferVector.setValue(posX, posY, posZ);
physicsSource.getParent().getShipTransformationManager()
.getCurrentPhysicsTransform()
.transform(bufferVector, TransformType.GLOBAL_TO_SUBSPACE);
bufferBlockPos.setPos(bufferVector.X, bufferVector.Y, bufferVector.Z);
if (!canParticlePassThrough(physicsSource.getParent().world(), bufferBlockPos)) {
this.isParticleDead = true;
addMomentumToShip = true;
}
}
}
@Override
public boolean placeInExistingPortal(Entity entityIn, float rotationYaw) {
double x, y, z;
x = entityIn.posX;
y = entityIn.posY;
z = entityIn.posZ;
MutableBlockPos pos = new MutableBlockPos();
for(int yy = (int) y; yy < world.getHeight(); yy++) {
pos.setPos(x, yy, z);
if(world.isAirBlock(pos) && world.isAirBlock(pos.add(0,1,0))){
y = yy;
break;
}
}
if (entityIn instanceof EntityPlayerMP)
{
((EntityPlayerMP)entityIn).connection.setPlayerLocation(x,y,z, entityIn.rotationYaw, entityIn.rotationPitch);
}
else
{
entityIn.setLocationAndAngles(x,y,z, entityIn.rotationYaw, entityIn.rotationPitch);
}
return true;
}
private Area3D(NBTTagCompound tag)
{
this.pos = new MutableBlockPos(0, 0, 0);
this.neg = new MutableBlockPos(0, 0, 0);
this.readFromNBT(tag);
}
private MutableBlockPos clampBounds(MutableBlockPos bounds)
{
int x = MathHelper.clamp(bounds.getX(), 0, this.maxSize);
int y = MathHelper.clamp(bounds.getY(), 0, this.maxSize);
int z = MathHelper.clamp(bounds.getZ(), 0, this.maxSize);
return bounds.setPos(x, y, z);
}
private void setFromPacked(MutableBlockPos bounds, int packed)
{
int x = MathHelper.clamp((packed >> 16) & 0xFF, 0, this.maxSize);
int y = MathHelper.clamp((packed >> 8) & 0xFF, 0, this.maxSize);
int z = MathHelper.clamp(packed & 0xFF, 0, this.maxSize);
bounds.setPos(x, y, z);
}
@Override
public boolean canHandlePlant(Collection<ItemStack> items, World world, BlockPos pos, IBlockState state) {
if (!WorldUtil.isBlockAir(world, pos)) {
return false;
}
MutableBlockPos mut = new MutableBlockPos();
for (EnumFacing facing : EnumFacing.HORIZONTALS) {
mut.setPos(pos).move(facing);
IBlockState other = world.getBlockState(mut);
if (other.getBlock() == Blocks.MELON_STEM || other.getBlock() == Blocks.PUMPKIN_STEM) {
return true;
}
}
return false;
}
@Override
public boolean handleHarvest(IBetterChest chest, IBlockState state, World world, BlockPos pos) {
MutableBlockPos mut = new MutableBlockPos(pos);
while (world.getBlockState(mut).getBlock() == state.getBlock()) {
mut.move(EnumFacing.UP);
}
mut.move(EnumFacing.DOWN);
if (mut.getY() != pos.getY()) {
PlantHarvestHelper.breakBlockHandleDrop(world, mut, state, chest);
return true;
}
return false;
}
protected boolean canBlockStay(World worldIn, BlockPos pos) {
MutableBlockPos currentPos = new MutableBlockPos(pos);
currentPos.move(EnumFacing.DOWN);
IBlockState downState = worldIn.getBlockState(currentPos);
if (downState.getBlock() instanceof BlockFrame) {
if (canFrameSupportVertical(worldIn, currentPos)) {
return true;
}
} else if (downState.getBlockFaceShape(worldIn, currentPos, EnumFacing.UP) == BlockFaceShape.SOLID) {
return true;
}
currentPos.move(EnumFacing.UP);
HashSet<BlockPos> observedSet = new HashSet<>();
Stack<EnumFacing> moveStack = new Stack<>();
main:
while (true) {
for (EnumFacing facing : EnumFacing.HORIZONTALS) {
currentPos.move(facing);
IBlockState blockStateHere = worldIn.getBlockState(currentPos);
//if there is node, and it can connect with previous node, add it to list, and set previous node as current
if (blockStateHere.getBlock() instanceof BlockFrame && currentPos.distanceSq(pos) <= SCAFFOLD_PILLAR_RADIUS_SQ && !observedSet.contains(currentPos)) {
observedSet.add(currentPos.toImmutable());
currentPos.move(EnumFacing.DOWN);
downState = worldIn.getBlockState(currentPos);
if (downState.getBlock() instanceof BlockFrame) {
if (canFrameSupportVertical(worldIn, currentPos)) {
return true;
}
} else if (downState.getBlockFaceShape(worldIn, currentPos, EnumFacing.UP) == BlockFaceShape.SOLID) {
return true;
}
currentPos.move(EnumFacing.UP);
moveStack.push(facing.getOpposite());
continue main;
} else currentPos.move(facing.getOpposite());
}
if (!moveStack.isEmpty()) {
currentPos.move(moveStack.pop());
} else break;
}
return false;
}