package choonster.testmod3.block.pipe;
import choonster.testmod3.block.BlockTestMod3;
import com.google.common.collect.ImmutableList;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nullable;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Base class for pipe blocks that connect to adjacent pipes and blocks.
*
* @author Choonster
*/
public abstract class BlockPipeBase extends BlockTestMod3 {
public static final float PIPE_MIN_POS = 0.25f;
public static final float PIPE_MAX_POS = 0.75f;
public static final ImmutableList<IProperty<Boolean>> CONNECTED_PROPERTIES = ImmutableList.copyOf(
Stream.of(EnumFacing.VALUES)
.map(facing -> PropertyBool.create(facing.getName()))
.collect(Collectors.toList())
);
public static final ImmutableList<AxisAlignedBB> CONNECTED_BOUNDING_BOXES = ImmutableList.copyOf(
Stream.of(EnumFacing.VALUES)
.map(facing -> {
Vec3i directionVec = facing.getDirectionVec();
return new AxisAlignedBB(
getMinBound(directionVec.getX()), getMinBound(directionVec.getY()), getMinBound(directionVec.getZ()),
getMaxBound(directionVec.getX()), getMaxBound(directionVec.getY()), getMaxBound(directionVec.getZ())
);
})
.collect(Collectors.toList())
);
private static float getMinBound(int dir) {
return dir == -1 ? 0 : PIPE_MIN_POS;
}
private static float getMaxBound(int dir) {
return dir == 1 ? 1 : PIPE_MAX_POS;
}
public BlockPipeBase(Material material, String blockName) {
super(material, blockName);
}
@SuppressWarnings("deprecation")
@Override
public boolean isOpaqueCube(IBlockState state) {
return false;
}
@SuppressWarnings("deprecation")
@Override
public boolean isFullCube(IBlockState state) {
return false;
}
/**
* Is the neighbouring block a valid connection for this pipe?
*
* @param ownState This pipe's state
* @param neighbourState The neighbouring block's state
* @param world The world
* @param ownPos This pipe's position
* @param neighbourDirection The direction of the neighbouring block
* @return Is the neighbouring block a valid connection?
*/
protected boolean isValidConnection(IBlockState ownState, IBlockState neighbourState, IBlockAccess world, BlockPos ownPos, EnumFacing neighbourDirection) {
return neighbourState.getBlock() instanceof BlockPipeBase;
}
/**
* Can this pipe connect to the neighbouring block?
*
* @param ownState This pipe's state
* @param worldIn The world
* @param ownPos This pipe's position
* @param neighbourDirection The direction of the neighbouring block
* @return Can this pipe connect?
*/
private boolean canConnectTo(IBlockState ownState, IBlockAccess worldIn, BlockPos ownPos, EnumFacing neighbourDirection) {
final BlockPos neighbourPos = ownPos.offset(neighbourDirection);
final IBlockState neighbourState = worldIn.getBlockState(neighbourPos);
final Block neighbourBlock = neighbourState.getBlock();
final boolean neighbourIsValidForThis = isValidConnection(ownState, neighbourState, worldIn, ownPos, neighbourDirection);
final boolean thisIsValidForNeighbour = !(neighbourBlock instanceof BlockPipeBase) || ((BlockPipeBase) neighbourBlock).isValidConnection(neighbourState, ownState, worldIn, neighbourPos, neighbourDirection.getOpposite());
return neighbourIsValidForThis && thisIsValidForNeighbour;
}
@SuppressWarnings("deprecation")
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) {
for (final EnumFacing facing : EnumFacing.VALUES) {
state = state.withProperty(CONNECTED_PROPERTIES.get(facing.getIndex()), canConnectTo(state, world, pos, facing));
}
return state;
}
public final boolean isConnected(IBlockState state, EnumFacing facing) {
return state.getValue(CONNECTED_PROPERTIES.get(facing.getIndex()));
}
@SuppressWarnings("deprecation")
@Override
public void addCollisionBoxToList(IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, @Nullable Entity entityIn, boolean p_185477_7_) {
final AxisAlignedBB bb = new AxisAlignedBB(PIPE_MIN_POS, PIPE_MIN_POS, PIPE_MIN_POS, PIPE_MAX_POS, PIPE_MAX_POS, PIPE_MAX_POS);
addCollisionBoxToList(pos, entityBox, collidingBoxes, bb);
if (!p_185477_7_) {
state = state.getActualState(worldIn, pos);
}
for (final EnumFacing facing : EnumFacing.VALUES) {
if (isConnected(state, facing)) {
final AxisAlignedBB axisAlignedBB = CONNECTED_BOUNDING_BOXES.get(facing.getIndex());
addCollisionBoxToList(pos, entityBox, collidingBoxes, axisAlignedBB);
}
}
}
}