package de.ellpeck.naturesaura.blocks; import de.ellpeck.naturesaura.blocks.tiles.TileEntityGratedChute; import de.ellpeck.naturesaura.data.BlockStateGenerator; import de.ellpeck.naturesaura.data.ItemModelGenerator; import de.ellpeck.naturesaura.reg.ICustomBlockState; import de.ellpeck.naturesaura.reg.ICustomItemModel; 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.ActionResultType; 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.items.IItemHandler; import javax.annotation.Nullable; public class BlockGratedChute extends BlockContainerImpl implements ICustomBlockState, ICustomItemModel { 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, Properties.create(Material.IRON).hardnessAndResistance(3.0F, 8.0F).sound(SoundType.METAL)); } @Override protected boolean hasWaterlogging() { return true; } @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 ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { if (!player.isSneaking()) return ActionResultType.FAIL; TileEntity tile = worldIn.getTileEntity(pos); if (!(tile instanceof TileEntityGratedChute)) return ActionResultType.FAIL; if (!worldIn.isRemote) { TileEntityGratedChute chute = (TileEntityGratedChute) tile; chute.isBlacklist = !chute.isBlacklist; chute.sendToClients(); } return ActionResultType.SUCCESS; } @Nullable @Override public BlockState getStateForPlacement(BlockItemUseContext context) { Direction newFacing = context.getFace().getOpposite(); if (newFacing == Direction.UP) newFacing = Direction.DOWN; return super.getStateForPlacement(context).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(); ItemStack stack = handler.getStackInSlot(0); if (stack.isEmpty()) return 0; return MathHelper.ceil(stack.getCount() / (float) stack.getMaxStackSize() * 15); } else return 0; } @Override protected void fillStateContainer(StateContainer.Builder builder) { super.fillStateContainer(builder); builder.add(FACING); } @Override public void generateCustomBlockState(BlockStateGenerator generator) { // noop } @Override public void generateCustomItemModel(ItemModelGenerator generator) { generator.withExistingParent(this.getBaseName(), generator.modLoc("block/" + this.getBaseName() + "_down")); } }