package de.ellpeck.naturesaura.blocks; import de.ellpeck.naturesaura.blocks.tiles.TileEntityGratedChute; import net.minecraft.block.*; import net.minecraft.block.material.Material; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemStack; import net.minecraft.state.DirectionProperty; import net.minecraft.state.StateContainer; import net.minecraft.tileentity.IHopper; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.Direction; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.shapes.IBooleanFunction; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.items.IItemHandler; import javax.annotation.Nullable; public class BlockGratedChute extends BlockContainerImpl { public static final DirectionProperty FACING = HopperBlock.FACING; private static final VoxelShape INPUT_SHAPE = Block.makeCuboidShape(0.0D, 10.0D, 0.0D, 16.0D, 16.0D, 16.0D); private static final VoxelShape MIDDLE_SHAPE = Block.makeCuboidShape(4.0D, 4.0D, 4.0D, 12.0D, 10.0D, 12.0D); private static final VoxelShape INPUT_MIDDLE_SHAPE = VoxelShapes.or(MIDDLE_SHAPE, INPUT_SHAPE); private static final VoxelShape COMBINED_SHAPE = VoxelShapes.combineAndSimplify(INPUT_MIDDLE_SHAPE, IHopper.INSIDE_BOWL_SHAPE, IBooleanFunction.ONLY_FIRST); private static final VoxelShape DOWN_SHAPE = VoxelShapes.or(COMBINED_SHAPE, Block.makeCuboidShape(6.0D, 0.0D, 6.0D, 10.0D, 4.0D, 10.0D)); private static final VoxelShape EAST_SHAPE = VoxelShapes.or(COMBINED_SHAPE, Block.makeCuboidShape(12.0D, 4.0D, 6.0D, 16.0D, 8.0D, 10.0D)); private static final VoxelShape NORTH_SHAPE = VoxelShapes.or(COMBINED_SHAPE, Block.makeCuboidShape(6.0D, 4.0D, 0.0D, 10.0D, 8.0D, 4.0D)); private static final VoxelShape SOUTH_SHAPE = VoxelShapes.or(COMBINED_SHAPE, Block.makeCuboidShape(6.0D, 4.0D, 12.0D, 10.0D, 8.0D, 16.0D)); private static final VoxelShape WEST_SHAPE = VoxelShapes.or(COMBINED_SHAPE, Block.makeCuboidShape(0.0D, 4.0D, 6.0D, 4.0D, 8.0D, 10.0D)); private static final VoxelShape DOWN_RAYTRACE_SHAPE = IHopper.INSIDE_BOWL_SHAPE; private static final VoxelShape EAST_RAYTRACE_SHAPE = VoxelShapes.or(IHopper.INSIDE_BOWL_SHAPE, Block.makeCuboidShape(12.0D, 8.0D, 6.0D, 16.0D, 10.0D, 10.0D)); private static final VoxelShape NORTH_RAYTRACE_SHAPE = VoxelShapes.or(IHopper.INSIDE_BOWL_SHAPE, Block.makeCuboidShape(6.0D, 8.0D, 0.0D, 10.0D, 10.0D, 4.0D)); private static final VoxelShape SOUTH_RAYTRACE_SHAPE = VoxelShapes.or(IHopper.INSIDE_BOWL_SHAPE, Block.makeCuboidShape(6.0D, 8.0D, 12.0D, 10.0D, 10.0D, 16.0D)); private static final VoxelShape WEST_RAYTRACE_SHAPE = VoxelShapes.or(IHopper.INSIDE_BOWL_SHAPE, Block.makeCuboidShape(0.0D, 8.0D, 6.0D, 4.0D, 10.0D, 10.0D)); public BlockGratedChute() { super("grated_chute", TileEntityGratedChute::new, ModBlocks.prop(Material.IRON).hardnessAndResistance(3.0F, 8.0F).sound(SoundType.METAL)); } @Override public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { switch (state.get(FACING)) { case DOWN: return DOWN_SHAPE; case NORTH: return NORTH_SHAPE; case SOUTH: return SOUTH_SHAPE; case WEST: return WEST_SHAPE; case EAST: return EAST_SHAPE; default: return COMBINED_SHAPE; } } @Override public VoxelShape getRaytraceShape(BlockState state, IBlockReader worldIn, BlockPos pos) { switch (state.get(FACING)) { case DOWN: return DOWN_RAYTRACE_SHAPE; case NORTH: return NORTH_RAYTRACE_SHAPE; case SOUTH: return SOUTH_RAYTRACE_SHAPE; case WEST: return WEST_RAYTRACE_SHAPE; case EAST: return EAST_RAYTRACE_SHAPE; default: return IHopper.INSIDE_BOWL_SHAPE; } } @Override public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { if (!player.isSneaking()) return false; TileEntity tile = worldIn.getTileEntity(pos); if (!(tile instanceof TileEntityGratedChute)) return false; if (!worldIn.isRemote) { TileEntityGratedChute chute = (TileEntityGratedChute) tile; chute.isBlacklist = !chute.isBlacklist; chute.sendToClients(); } return true; } @Nullable @Override public BlockState getStateForPlacement(BlockItemUseContext context) { Direction newFacing = context.getFace().getOpposite(); if (newFacing == Direction.UP) newFacing = Direction.DOWN; return this.getDefaultState().with(FACING, newFacing); } @Override public BlockRenderType getRenderType(BlockState state) { return BlockRenderType.MODEL; } @Override public boolean hasComparatorInputOverride(BlockState state) { return true; } @Override public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) { TileEntity tile = worldIn.getTileEntity(pos); if (tile instanceof TileEntityGratedChute) { IItemHandler handler = ((TileEntityGratedChute) tile).getItemHandler(null); ItemStack stack = handler.getStackInSlot(0); if (stack.isEmpty()) return 0; return MathHelper.ceil((stack.getCount() / (float) stack.getMaxStackSize()) * 15); } else return 0; } @Override @OnlyIn(Dist.CLIENT) public BlockRenderLayer getRenderLayer() { return BlockRenderLayer.CUTOUT_MIPPED; } @Override protected void fillStateContainer(StateContainer.Builder builder) { builder.add(FACING); } }