package com.thebrokenrail.energonrelics.block.forcefield.util; import com.thebrokenrail.energonrelics.EnergonRelics; import com.thebrokenrail.energonrelics.block.entity.forcefield.FieldProjectorBlockEntity; import com.thebrokenrail.energonrelics.api.block.SimpleBlock; import com.thebrokenrail.energonrelics.config.HardcodedConfig; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.ShapeContext; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.piston.PistonBehavior; import net.minecraft.sound.BlockSoundGroup; import net.minecraft.state.StateManager; import net.minecraft.state.property.DirectionProperty; import net.minecraft.state.property.Properties; import net.minecraft.util.BlockMirror; import net.minecraft.util.BlockRotation; 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.WorldAccess; @SuppressWarnings("deprecation") public abstract class AbstractFieldBlock extends SimpleBlock { public static final DirectionProperty FACING = Properties.FACING; public AbstractFieldBlock(boolean hasCollision) { super((hasCollision ? FabricBlockSettings.of(EnergonRelics.FIELD_MATERIAL) : FabricBlockSettings.of(EnergonRelics.FIELD_MATERIAL).noCollision()).strength(-1.0F, 3600000.8F).dropsNothing().nonOpaque().lightLevel(4).emissiveLighting((state, world, pos) -> true).nonOpaque().sounds(BlockSoundGroup.GLASS).allowsSpawning((state, world, pos, type) -> false).solidBlock((state, world, pos) -> false).suffocates((state, world, pos) -> false).blockVision((state, world, pos) -> false)); setDefaultState(getDefaultState().with(FACING, Direction.NORTH)); } protected abstract BlockState getProjectorBlockState(); @Override protected void appendProperties(StateManager.Builder builder) { builder.add(FACING); } @Override public BlockState rotate(BlockState state, BlockRotation rotation) { return state.with(FACING, rotation.rotate(state.get(FACING))); } @Override public BlockState mirror(BlockState state, BlockMirror mirror) { return state.rotate(mirror.getRotation(state.get(FACING))); } @Override @Environment(EnvType.CLIENT) public float getAmbientOcclusionLightLevel(BlockState state, BlockView world, BlockPos pos) { return 1f; } @Override public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) { return true; } @Override public VoxelShape getVisualShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { return VoxelShapes.empty(); } @Override protected boolean registerItem() { return false; } public FieldProjectorBlockEntity findProjector(BlockView world, BlockPos pos, BlockState state) { Direction facing = state.get(FACING).getOpposite(); FieldProjectorBlockEntity found = null; for (int i = 0; i < HardcodedConfig.FIELD_MAX_SIZE + 1; i++) { BlockPos targetPos = pos.offset(facing, i); BlockState targetState = world.getBlockState(targetPos); if (targetState.getBlock() == this) { if (!facing.equals(targetState.get(FACING).getOpposite())) { break; } } else if (targetState == getProjectorBlockState().with(FACING, facing.getOpposite()).with(FieldProjectorBlock.POWERED, true)) { BlockEntity entity = world.getBlockEntity(targetPos); if (entity instanceof FieldProjectorBlockEntity) { found = (FieldProjectorBlockEntity) entity; } break; } else { break; } } return found; } @Override public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom) { BlockState defaultState = super.getStateForNeighborUpdate(state, direction, newState, world, pos, posFrom); Direction facing = state.get(FACING).getOpposite(); if (direction.equals(facing)) { return findProjector(world, pos, state) != null ? defaultState : Blocks.AIR.getDefaultState(); } else { return defaultState; } } @Override @Environment(EnvType.CLIENT) public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) { return state.get(FACING).getOpposite() == direction || stateFrom == state || super.isSideInvisible(state, stateFrom, direction); } @Override public PistonBehavior getPistonBehavior(BlockState state) { return PistonBehavior.DESTROY; } @Override public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { return collidable ? super.getOutlineShape(state, world, pos, context) : VoxelShapes.empty(); } }