package com.thebrokenrail.energonrelics.block.portal; import com.thebrokenrail.energonrelics.EnergonRelics; import com.thebrokenrail.energonrelics.block.util.SimpleBlock; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.ShapeContext; import net.minecraft.block.piston.PistonBehavior; import net.minecraft.entity.Entity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; import net.minecraft.world.World; import net.minecraft.world.WorldAccess; @SuppressWarnings("deprecation") public class EnergyPortalBlock extends SimpleBlock { public EnergyPortalBlock() { super(FabricBlockSettings.copy(Blocks.NETHER_PORTAL).dropsNothing().emissiveLighting((state, world, pos) -> true).noCollision()); } @Override protected boolean registerItem() { return false; } @Override public VoxelShape getVisualShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { return VoxelShapes.empty(); } private static final VoxelShape SHAPE = createCuboidShape(0, 6, 0, 16, 10, 16); @Override public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { return SHAPE; } public static boolean isValidDirection(Direction dir) { return dir != Direction.UP && dir != Direction.DOWN; } private static boolean isObsidian(BlockState state) { return state.getBlock() == Blocks.OBSIDIAN || state.getBlock() == EnergonRelics.ENERGIZED_OBSIDIAN_BLOCK; } public static boolean isValidFrame(WorldAccess world, BlockPos centerPos) { int validSides = 0; for (Direction side : Direction.values()) { if (isValidDirection(side)) { BlockPos energizedPos = centerPos.offset(side, 2); BlockState energizedObsidian = world.getBlockState(energizedPos); if (energizedObsidian.getBlock() == EnergonRelics.ENERGIZED_OBSIDIAN_BLOCK) { BlockState obsidian1 = world.getBlockState(energizedPos.offset(side.rotateYClockwise(), 1)); BlockState obsidian2 = world.getBlockState(energizedPos.offset(side.rotateYCounterclockwise(), 1)); if (isObsidian(obsidian1) && isObsidian(obsidian2)) { validSides++; } } } } return validSides == 4; } private static BlockPos getCenterPos(WorldAccess world, BlockPos pos) { BlockPos centerPos = pos; for (Direction side : Direction.values()) { if (isValidDirection(side)) { if (world.getBlockState(pos.offset(side)).getBlock() != EnergonRelics.ENERGY_PORTAL_BLOCK) { centerPos = centerPos.offset(side.getOpposite()); } } } return centerPos; } private static boolean isValidCenter(WorldAccess world, BlockPos centerPos) { boolean valid = true; BlockPos startPos = centerPos.add(-1, 0, -1); for (int x = 0; x < 3; x++) { for (int z = 0; z < 3; z++) { if (world.getBlockState(startPos.add(x, 0, z)).getBlock() != EnergonRelics.ENERGY_PORTAL_BLOCK) { valid = false; break; } } } return valid; } public static void fillFrame(WorldAccess world, BlockPos centerPos) { BlockPos startPos = centerPos.add(-1, 0, -1); for (int x = 0; x < 3; x++) { for (int z = 0; z < 3; z++) { BlockState state = world.getBlockState(startPos.add(x, 0, z)); if (state.getBlock() != EnergonRelics.ENERGY_PORTAL_BLOCK && !state.isAir()) { return; } } } for (int x = 0; x < 3; x++) { for (int z = 0; z < 3; z++) { world.setBlockState(startPos.add(x, 0, z), EnergonRelics.ENERGY_PORTAL_BLOCK.getDefaultState(), 3 | 16); } } } @Override public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom) { boolean valid; if (isValidDirection(direction)) { BlockPos centerPos = getCenterPos(world, pos); boolean isValidFrame = isValidFrame(world, centerPos); boolean isValidCenter = isValidCenter(world, centerPos); valid = isValidCenter && isValidFrame; } else { valid = true; } if (valid) { return super.getStateForNeighborUpdate(state, direction, newState, world, pos, posFrom); } else { return Blocks.AIR.getDefaultState(); } } @Override public PistonBehavior getPistonBehavior(BlockState state) { return PistonBehavior.BLOCK; } @Override public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { super.onEntityCollision(state, world, pos, entity); if (!world.isClient() && entity.canUsePortals() && ((PortalCooldownEntity) entity).isEnergyPortalCooldown()) { // Teleport ((PortalCooldownEntity) entity).resetEnergyPortalCooldown(); } } }