content: package com.accbdd.complicated_bees.block;
  
  import com.accbdd.complicated_bees.block.entity.BaseGeneratorBlockEntity;
  import com.accbdd.complicated_bees.block.entity.FurnaceGeneratorBlockEntity;
  import com.accbdd.complicated_bees.screen.FurnaceGeneratorMenu;
  import net.minecraft.core.BlockPos;
  import net.minecraft.core.Direction;
  import net.minecraft.core.particles.ParticleTypes;
  import net.minecraft.network.chat.Component;
  import net.minecraft.server.level.ServerPlayer;
  import net.minecraft.sounds.SoundEvents;
  import net.minecraft.sounds.SoundSource;
  import net.minecraft.util.RandomSource;
  import net.minecraft.world.Containers;
  import net.minecraft.world.InteractionHand;
  import net.minecraft.world.InteractionResult;
  import net.minecraft.world.MenuProvider;
  import net.minecraft.world.entity.player.Inventory;
  import net.minecraft.world.entity.player.Player;
  import net.minecraft.world.inventory.AbstractContainerMenu;
  import net.minecraft.world.item.context.BlockPlaceContext;
  import net.minecraft.world.level.Level;
  import net.minecraft.world.level.block.BaseEntityBlock;
  import net.minecraft.world.level.block.Block;
  import net.minecraft.world.level.block.RenderShape;
  import net.minecraft.world.level.block.SoundType;
  import net.minecraft.world.level.block.entity.BlockEntity;
  import net.minecraft.world.level.block.entity.BlockEntityTicker;
  import net.minecraft.world.level.block.entity.BlockEntityType;
  import net.minecraft.world.level.block.state.BlockBehaviour;
  import net.minecraft.world.level.block.state.BlockState;
  import net.minecraft.world.level.block.state.StateDefinition;
  import net.minecraft.world.level.block.state.properties.BlockStateProperties;
  import net.minecraft.world.phys.BlockHitResult;
  import net.minecraftforge.items.IItemHandler;
  import net.minecraftforge.network.NetworkHooks;
  import org.jetbrains.annotations.Nullable;
  
  public class FurnaceGeneratorBlock extends BaseEntityBlock {
  
      public static final String SCREEN_GENERATOR = "gui.complicated_bees.furnace_generator";
  
      public FurnaceGeneratorBlock() {
          super(BlockBehaviour.Properties.of()
                  .strength(3.5F)
                  .requiresCorrectToolForDrops()
                  .sound(SoundType.METAL));
      }
  
      @Nullable
      @Override
      public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) {
          return new FurnaceGeneratorBlockEntity(pPos, pState);
      }
  
      @Nullable
      @Override
      public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
          if (level.isClientSide) {
              return null;
          } else {
              return (lvl, pos, st, be) -> {
                  if (be instanceof BaseGeneratorBlockEntity generator) {
                      generator.tickServer();
                  }
              };
          }
      }
  
      @Override
      public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) {
          if (!level.isClientSide) {
              BlockEntity be = level.getBlockEntity(pos);
              if (be instanceof FurnaceGeneratorBlockEntity) {
                  MenuProvider containerProvider = new MenuProvider() {
                      @Override
                      public Component getDisplayName() {
                          return Component.translatable(SCREEN_GENERATOR);
                      }
  
                      @Override
                      public AbstractContainerMenu createMenu(int windowId, Inventory playerInventory, Player playerEntity) {
                          return new FurnaceGeneratorMenu(windowId, playerEntity, pos);
                      }
                  };
                  NetworkHooks.openScreen((ServerPlayer) player, containerProvider, be.getBlockPos());
              } else {
                  throw new IllegalStateException("Our named container provider is missing!");
              }
          }
          return InteractionResult.SUCCESS;
      }
  
      @Override
      public RenderShape getRenderShape(BlockState pState) {
          return RenderShape.MODEL;
      }
  
      @Nullable
      @Override
      public BlockState getStateForPlacement(BlockPlaceContext pContext) {
          return this.defaultBlockState()
                  .setValue(BlockStateProperties.FACING, pContext.getHorizontalDirection().getOpposite())
                  .setValue(BlockStateProperties.POWERED, false);
      }
  
      @Override
      protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
          super.createBlockStateDefinition(pBuilder);
          pBuilder.add(BlockStateProperties.POWERED, BlockStateProperties.FACING);
      }
  
      @Override
      public void animateTick(BlockState pState, Level pLevel, BlockPos pPos, RandomSource pRandom) {
          if (pState.getValue(BlockStateProperties.POWERED)) {
              double d0 = (double) pPos.getX() + 0.5;
              double d1 = (double) pPos.getY() + 0.2;
              double d2 = (double) pPos.getZ() + 0.5;
              if (pRandom.nextDouble() < 0.1) {
                  pLevel.playLocalSound(d0, d1, d2, SoundEvents.FURNACE_FIRE_CRACKLE, SoundSource.BLOCKS, 1.0F, 1.0F, false);
              }
  
              Direction direction = pState.getValue(BlockStateProperties.FACING);
              Direction.Axis direction$axis = direction.getAxis();
              double d4 = pRandom.nextDouble() * 0.6 - 0.3;
              double d5 = direction$axis == Direction.Axis.X ? (double) direction.getStepX() * 0.52 : d4;
              double d6 = pRandom.nextDouble() * 6.0 / 16.0;
              double d7 = direction$axis == Direction.Axis.Z ? (double) direction.getStepZ() * 0.52 : d4;
              pLevel.addParticle(ParticleTypes.SMOKE, d0 + d5, d1 + d6, d2 + d7, 0.0, 0.0, 0.0);
              pLevel.addParticle(ParticleTypes.FLAME, d0 + d5, d1 + d6, d2 + d7, 0.0, 0.0, 0.0);
          }
      }
  
      @Override
      public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pMovedByPiston) {
          BlockEntity blockentity = pLevel.getBlockEntity(pPos);
          if (blockentity instanceof FurnaceGeneratorBlockEntity generator && !pNewState.is(this)) {
              IItemHandler handler = generator.getItems();
              for (int i = 0; i < handler.getSlots(); i++) {
                  Containers.dropItemStack(pLevel, pPos.getX(), pPos.getY(), pPos.getZ(), handler.getStackInSlot(i));
              }
              IItemHandler upgrades = generator.getUpgradeItemHandler().orElseThrow(() -> new RuntimeException("no upgrade item handler found!"));
              for (int i = 0; i < upgrades.getSlots(); i++) {
                  Containers.dropItemStack(pLevel, pPos.getX(), pPos.getY(), pPos.getZ(), upgrades.getStackInSlot(i));
              }
          }
          super.onRemove(pState, pLevel, pPos, pNewState, pMovedByPiston);
      }
  }
  