package net.minecraft.core.dispenser;

import net.minecraft.world.level.block.state.StateHolder;
import net.minecraft.world.level.block.RespawnAnchorBlock;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.tags.FluidTags;
import net.minecraft.world.level.block.entity.BeehiveBlockEntity;
import net.minecraft.tags.Tag;
import net.minecraft.world.level.block.BeehiveBlock;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.block.ShulkerBoxBlock;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.CarvedPumpkinBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.SkullBlockEntity;
import net.minecraft.world.level.block.SkullBlock;
import net.minecraft.world.level.block.WitherSkullBlock;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.entity.item.PrimedTnt;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.item.BoneMealItem;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.block.TntBlock;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.CampfireBlock;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.BaseFireBlock;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.entity.DispenserBlockEntity;
import net.minecraft.world.level.material.FlowingFluid;
import net.minecraft.world.level.block.BucketPickup;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.item.BucketItem;
import net.minecraft.world.entity.vehicle.Boat;
import java.util.Random;
import net.minecraft.world.entity.projectile.SmallFireball;
import net.minecraft.world.entity.projectile.FireworkRocketEntity;
import net.minecraft.world.entity.animal.horse.AbstractChestedHorse;
import java.util.Iterator;
import net.minecraft.world.entity.animal.horse.AbstractHorse;
import java.util.List;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.Saddleable;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.decoration.ArmorStand;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.item.SpawnEggItem;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.projectile.ThrownPotion;
import net.minecraft.world.entity.projectile.ThrownExperienceBottle;
import net.minecraft.world.entity.projectile.Snowball;
import net.minecraft.Util;
import net.minecraft.world.entity.projectile.ThrownEgg;
import net.minecraft.world.entity.projectile.SpectralArrow;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.DispenserBlock;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.entity.projectile.Arrow;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.core.Position;
import net.minecraft.world.level.Level;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ItemStack;
import net.minecraft.core.BlockSource;

public interface DispenseItemBehavior {
    public static final DispenseItemBehavior NOOP = (fv, bki) -> bki;
    
    ItemStack dispense(final BlockSource fv, final ItemStack bki);
    
    default void bootStrap() {
        DispenserBlock.registerBehavior(Items.ARROW, new AbstractProjectileDispenseBehavior() {
            @Override
            protected Projectile getProjectile(final Level bqb, final Position gj, final ItemStack bki) {
                final Arrow bei5 = new Arrow(bqb, gj.x(), gj.y(), gj.z());
                bei5.pickup = AbstractArrow.Pickup.ALLOWED;
                return bei5;
            }
        });
        DispenserBlock.registerBehavior(Items.TIPPED_ARROW, new AbstractProjectileDispenseBehavior() {
            @Override
            protected Projectile getProjectile(final Level bqb, final Position gj, final ItemStack bki) {
                final Arrow bei5 = new Arrow(bqb, gj.x(), gj.y(), gj.z());
                bei5.setEffectsFromItem(bki);
                bei5.pickup = AbstractArrow.Pickup.ALLOWED;
                return bei5;
            }
        });
        DispenserBlock.registerBehavior(Items.SPECTRAL_ARROW, new AbstractProjectileDispenseBehavior() {
            @Override
            protected Projectile getProjectile(final Level bqb, final Position gj, final ItemStack bki) {
                final AbstractArrow beg5 = new SpectralArrow(bqb, gj.x(), gj.y(), gj.z());
                beg5.pickup = AbstractArrow.Pickup.ALLOWED;
                return beg5;
            }
        });
        DispenserBlock.registerBehavior(Items.EGG, new AbstractProjectileDispenseBehavior() {
            @Override
            protected Projectile getProjectile(final Level bqb, final Position gj, final ItemStack bki) {
                return Util.<ThrownEgg>make(new ThrownEgg(bqb, gj.x(), gj.y(), gj.z()), bfa -> bfa.setItem(bki));
            }
        });
        DispenserBlock.registerBehavior(Items.SNOWBALL, new AbstractProjectileDispenseBehavior() {
            @Override
            protected Projectile getProjectile(final Level bqb, final Position gj, final ItemStack bki) {
                return Util.<Snowball>make(new Snowball(bqb, gj.x(), gj.y(), gj.z()), bew -> bew.setItem(bki));
            }
        });
        DispenserBlock.registerBehavior(Items.EXPERIENCE_BOTTLE, new AbstractProjectileDispenseBehavior() {
            @Override
            protected Projectile getProjectile(final Level bqb, final Position gj, final ItemStack bki) {
                return Util.<ThrownExperienceBottle>make(new ThrownExperienceBottle(bqb, gj.x(), gj.y(), gj.z()), bfc -> bfc.setItem(bki));
            }
            
            @Override
            protected float getUncertainty() {
                return super.getUncertainty() * 0.5f;
            }
            
            @Override
            protected float getPower() {
                return super.getPower() * 1.25f;
            }
        });
        DispenserBlock.registerBehavior(Items.SPLASH_POTION, new DispenseItemBehavior() {
            @Override
            public ItemStack dispense(final BlockSource fv, final ItemStack bki) {
                return new AbstractProjectileDispenseBehavior() {
                    @Override
                    protected Projectile getProjectile(final Level bqb, final Position gj, final ItemStack bki) {
                        return Util.<ThrownPotion>make(new ThrownPotion(bqb, gj.x(), gj.y(), gj.z()), bfd -> bfd.setItem(bki));
                    }
                    
                    @Override
                    protected float getUncertainty() {
                        return super.getUncertainty() * 0.5f;
                    }
                    
                    @Override
                    protected float getPower() {
                        return super.getPower() * 1.25f;
                    }
                }.dispense(fv, bki);
            }
        });
        DispenserBlock.registerBehavior(Items.LINGERING_POTION, new DispenseItemBehavior() {
            @Override
            public ItemStack dispense(final BlockSource fv, final ItemStack bki) {
                return new AbstractProjectileDispenseBehavior() {
                    @Override
                    protected Projectile getProjectile(final Level bqb, final Position gj, final ItemStack bki) {
                        return Util.<ThrownPotion>make(new ThrownPotion(bqb, gj.x(), gj.y(), gj.z()), bfd -> bfd.setItem(bki));
                    }
                    
                    @Override
                    protected float getUncertainty() {
                        return super.getUncertainty() * 0.5f;
                    }
                    
                    @Override
                    protected float getPower() {
                        return super.getPower() * 1.25f;
                    }
                }.dispense(fv, bki);
            }
        });
        final DefaultDispenseItemBehavior gv1 = new DefaultDispenseItemBehavior() {
            public ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final Direction fz4 = fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING);
                final EntityType<?> aoq5 = ((SpawnEggItem)bki.getItem()).getType(bki.getTag());
                aoq5.spawn(fv.getLevel(), bki, null, fv.getPos().relative(fz4), MobSpawnType.DISPENSER, fz4 != Direction.UP, false);
                bki.shrink(1);
                return bki;
            }
        };
        for (final SpawnEggItem blh3 : SpawnEggItem.eggs()) {
            DispenserBlock.registerBehavior(blh3, gv1);
        }
        DispenserBlock.registerBehavior(Items.ARMOR_STAND, new DefaultDispenseItemBehavior() {
            public ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final Direction fz4 = fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING);
                final BlockPos fu5 = fv.getPos().relative(fz4);
                final Level bqb6 = fv.getLevel();
                final ArmorStand bay7 = new ArmorStand(bqb6, fu5.getX() + 0.5, fu5.getY(), fu5.getZ() + 0.5);
                EntityType.updateCustomEntityTag(bqb6, null, bay7, bki.getTag());
                bay7.yRot = fz4.toYRot();
                bqb6.addFreshEntity(bay7);
                bki.shrink(1);
                return bki;
            }
        });
        DispenserBlock.registerBehavior(Items.SADDLE, new OptionalDispenseItemBehavior() {
            public ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final BlockPos fu4 = fv.getPos().relative(fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING));
                Saddleable apm2;
                final List<LivingEntity> list5 = fv.getLevel().<LivingEntity>getEntitiesOfClass(LivingEntity.class, new AABB(fu4), aoy -> {
                    if (aoy instanceof Saddleable) {
                        apm2 = aoy;
                        return !apm2.isSaddled() && apm2.isSaddleable();
                    }
                    else {
                        return false;
                    }
                });
                if (!list5.isEmpty()) {
                    ((Saddleable)list5.get(0)).equipSaddle(SoundSource.BLOCKS);
                    bki.shrink(1);
                    this.setSuccess(true);
                    return bki;
                }
                return super.execute(fv, bki);
            }
        });
        final DefaultDispenseItemBehavior gv2 = new OptionalDispenseItemBehavior() {
            @Override
            protected ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final BlockPos fu4 = fv.getPos().relative(fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING));
                final List<AbstractHorse> list5 = fv.getLevel().<AbstractHorse>getEntitiesOfClass(AbstractHorse.class, new AABB(fu4), azm -> azm.isAlive() && azm.canWearArmor());
                for (final AbstractHorse azm2 : list5) {
                    if (azm2.isArmor(bki) && !azm2.isWearingArmor() && azm2.isTamed()) {
                        azm2.setSlot(401, bki.split(1));
                        this.setSuccess(true);
                        return bki;
                    }
                }
                return super.execute(fv, bki);
            }
        };
        DispenserBlock.registerBehavior(Items.LEATHER_HORSE_ARMOR, gv2);
        DispenserBlock.registerBehavior(Items.IRON_HORSE_ARMOR, gv2);
        DispenserBlock.registerBehavior(Items.GOLDEN_HORSE_ARMOR, gv2);
        DispenserBlock.registerBehavior(Items.DIAMOND_HORSE_ARMOR, gv2);
        DispenserBlock.registerBehavior(Items.WHITE_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.ORANGE_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.CYAN_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.BLUE_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.BROWN_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.BLACK_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.GRAY_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.GREEN_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.LIGHT_BLUE_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.LIGHT_GRAY_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.LIME_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.MAGENTA_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.PINK_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.PURPLE_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.RED_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.YELLOW_CARPET, gv2);
        DispenserBlock.registerBehavior(Items.CHEST, new OptionalDispenseItemBehavior() {
            public ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final BlockPos fu4 = fv.getPos().relative(fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING));
                final List<AbstractChestedHorse> list5 = fv.getLevel().<AbstractChestedHorse>getEntitiesOfClass(AbstractChestedHorse.class, new AABB(fu4), azl -> azl.isAlive() && !azl.hasChest());
                for (final AbstractChestedHorse azl2 : list5) {
                    if (azl2.isTamed() && azl2.setSlot(499, bki)) {
                        bki.shrink(1);
                        this.setSuccess(true);
                        return bki;
                    }
                }
                return super.execute(fv, bki);
            }
        });
        DispenserBlock.registerBehavior(Items.FIREWORK_ROCKET, new DefaultDispenseItemBehavior() {
            public ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final Direction fz4 = fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING);
                final FireworkRocketEntity ben5 = new FireworkRocketEntity(fv.getLevel(), bki, fv.x(), fv.y(), fv.x(), true);
                DispenseItemBehavior.setEntityPokingOutOfBlock(fv, ben5, fz4);
                ben5.shoot(fz4.getStepX(), fz4.getStepY(), fz4.getStepZ(), 0.5f, 1.0f);
                fv.getLevel().addFreshEntity(ben5);
                bki.shrink(1);
                return bki;
            }
            
            @Override
            protected void playSound(final BlockSource fv) {
                fv.getLevel().levelEvent(1004, fv.getPos(), 0);
            }
        });
        DispenserBlock.registerBehavior(Items.FIRE_CHARGE, new DefaultDispenseItemBehavior() {
            public ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final Direction fz4 = fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING);
                final Position gj5 = DispenserBlock.getDispensePosition(fv);
                final double double6 = gj5.x() + fz4.getStepX() * 0.3f;
                final double double7 = gj5.y() + fz4.getStepY() * 0.3f;
                final double double8 = gj5.z() + fz4.getStepZ() * 0.3f;
                final Level bqb12 = fv.getLevel();
                final Random random13 = bqb12.random;
                final double double9 = random13.nextGaussian() * 0.05 + fz4.getStepX();
                final double double10 = random13.nextGaussian() * 0.05 + fz4.getStepY();
                final double double11 = random13.nextGaussian() * 0.05 + fz4.getStepZ();
                bqb12.addFreshEntity(Util.<SmallFireball>make(new SmallFireball(bqb12, double6, double7, double8, double9, double10, double11), bev -> bev.setItem(bki)));
                bki.shrink(1);
                return bki;
            }
            
            @Override
            protected void playSound(final BlockSource fv) {
                fv.getLevel().levelEvent(1018, fv.getPos(), 0);
            }
        });
        DispenserBlock.registerBehavior(Items.OAK_BOAT, new BoatDispenseItemBehavior(Boat.Type.OAK));
        DispenserBlock.registerBehavior(Items.SPRUCE_BOAT, new BoatDispenseItemBehavior(Boat.Type.SPRUCE));
        DispenserBlock.registerBehavior(Items.BIRCH_BOAT, new BoatDispenseItemBehavior(Boat.Type.BIRCH));
        DispenserBlock.registerBehavior(Items.JUNGLE_BOAT, new BoatDispenseItemBehavior(Boat.Type.JUNGLE));
        DispenserBlock.registerBehavior(Items.DARK_OAK_BOAT, new BoatDispenseItemBehavior(Boat.Type.DARK_OAK));
        DispenserBlock.registerBehavior(Items.ACACIA_BOAT, new BoatDispenseItemBehavior(Boat.Type.ACACIA));
        final DispenseItemBehavior gw3 = new DefaultDispenseItemBehavior() {
            private final DefaultDispenseItemBehavior defaultDispenseItemBehavior = new DefaultDispenseItemBehavior();
            
            public ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final BucketItem biu4 = (BucketItem)bki.getItem();
                final BlockPos fu5 = fv.getPos().relative(fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING));
                final Level bqb6 = fv.getLevel();
                if (biu4.emptyBucket(null, bqb6, fu5, null)) {
                    biu4.checkExtraContent(bqb6, bki, fu5);
                    return new ItemStack(Items.BUCKET);
                }
                return this.defaultDispenseItemBehavior.dispense(fv, bki);
            }
        };
        DispenserBlock.registerBehavior(Items.LAVA_BUCKET, gw3);
        DispenserBlock.registerBehavior(Items.WATER_BUCKET, gw3);
        DispenserBlock.registerBehavior(Items.SALMON_BUCKET, gw3);
        DispenserBlock.registerBehavior(Items.COD_BUCKET, gw3);
        DispenserBlock.registerBehavior(Items.PUFFERFISH_BUCKET, gw3);
        DispenserBlock.registerBehavior(Items.TROPICAL_FISH_BUCKET, gw3);
        DispenserBlock.registerBehavior(Items.BUCKET, new DefaultDispenseItemBehavior() {
            private final DefaultDispenseItemBehavior defaultDispenseItemBehavior = new DefaultDispenseItemBehavior();
            
            public ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final LevelAccessor bqc4 = fv.getLevel();
                final BlockPos fu5 = fv.getPos().relative(fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING));
                final BlockState cfj6 = bqc4.getBlockState(fu5);
                final Block bvr7 = cfj6.getBlock();
                if (!(bvr7 instanceof BucketPickup)) {
                    return super.execute(fv, bki);
                }
                final Fluid cwz9 = ((BucketPickup)bvr7).takeLiquid(bqc4, fu5, cfj6);
                if (!(cwz9 instanceof FlowingFluid)) {
                    return super.execute(fv, bki);
                }
                final Item bke8 = cwz9.getBucket();
                bki.shrink(1);
                if (bki.isEmpty()) {
                    return new ItemStack(bke8);
                }
                if (fv.<DispenserBlockEntity>getEntity().addItem(new ItemStack(bke8)) < 0) {
                    this.defaultDispenseItemBehavior.dispense(fv, new ItemStack(bke8));
                }
                return bki;
            }
        });
        DispenserBlock.registerBehavior(Items.FLINT_AND_STEEL, new OptionalDispenseItemBehavior() {
            @Override
            protected ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final Level bqb4 = fv.getLevel();
                this.setSuccess(true);
                final BlockPos fu5 = fv.getPos().relative(fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING));
                final BlockState cfj6 = bqb4.getBlockState(fu5);
                if (BaseFireBlock.canBePlacedAt(bqb4, fu5)) {
                    bqb4.setBlockAndUpdate(fu5, BaseFireBlock.getState(bqb4, fu5));
                }
                else if (CampfireBlock.canLight(cfj6)) {
                    bqb4.setBlockAndUpdate(fu5, ((StateHolder<O, BlockState>)cfj6).<Comparable, Boolean>setValue((Property<Comparable>)BlockStateProperties.LIT, true));
                }
                else if (cfj6.getBlock() instanceof TntBlock) {
                    TntBlock.explode(bqb4, fu5);
                    bqb4.removeBlock(fu5, false);
                }
                else {
                    this.setSuccess(false);
                }
                if (this.isSuccess() && bki.hurt(1, bqb4.random, null)) {
                    bki.setCount(0);
                }
                return bki;
            }
        });
        DispenserBlock.registerBehavior(Items.BONE_MEAL, new OptionalDispenseItemBehavior() {
            @Override
            protected ItemStack execute(final BlockSource fv, final ItemStack bki) {
                this.setSuccess(true);
                final Level bqb4 = fv.getLevel();
                final BlockPos fu5 = fv.getPos().relative(fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING));
                if (BoneMealItem.growCrop(bki, bqb4, fu5) || BoneMealItem.growWaterPlant(bki, bqb4, fu5, null)) {
                    if (!bqb4.isClientSide) {
                        bqb4.levelEvent(2005, fu5, 0);
                    }
                }
                else {
                    this.setSuccess(false);
                }
                return bki;
            }
        });
        DispenserBlock.registerBehavior(Blocks.TNT, new DefaultDispenseItemBehavior() {
            @Override
            protected ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final Level bqb4 = fv.getLevel();
                final BlockPos fu5 = fv.getPos().relative(fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING));
                final PrimedTnt bbh6 = new PrimedTnt(bqb4, fu5.getX() + 0.5, fu5.getY(), fu5.getZ() + 0.5, null);
                bqb4.addFreshEntity(bbh6);
                bqb4.playSound(null, bbh6.getX(), bbh6.getY(), bbh6.getZ(), SoundEvents.TNT_PRIMED, SoundSource.BLOCKS, 1.0f, 1.0f);
                bki.shrink(1);
                return bki;
            }
        });
        final DispenseItemBehavior gw4 = new OptionalDispenseItemBehavior() {
            @Override
            protected ItemStack execute(final BlockSource fv, final ItemStack bki) {
                this.setSuccess(ArmorItem.dispenseArmor(fv, bki));
                return bki;
            }
        };
        DispenserBlock.registerBehavior(Items.CREEPER_HEAD, gw4);
        DispenserBlock.registerBehavior(Items.ZOMBIE_HEAD, gw4);
        DispenserBlock.registerBehavior(Items.DRAGON_HEAD, gw4);
        DispenserBlock.registerBehavior(Items.SKELETON_SKULL, gw4);
        DispenserBlock.registerBehavior(Items.PLAYER_HEAD, gw4);
        DispenserBlock.registerBehavior(Items.WITHER_SKELETON_SKULL, new OptionalDispenseItemBehavior() {
            @Override
            protected ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final Level bqb4 = fv.getLevel();
                final Direction fz5 = fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING);
                final BlockPos fu6 = fv.getPos().relative(fz5);
                if (bqb4.isEmptyBlock(fu6) && WitherSkullBlock.canSpawnMob(bqb4, fu6, bki)) {
                    bqb4.setBlock(fu6, ((StateHolder<O, BlockState>)Blocks.WITHER_SKELETON_SKULL.defaultBlockState()).<Comparable, Integer>setValue((Property<Comparable>)SkullBlock.ROTATION, (fz5.getAxis() == Direction.Axis.Y) ? 0 : (fz5.getOpposite().get2DDataValue() * 4)), 3);
                    final BlockEntity cdl7 = bqb4.getBlockEntity(fu6);
                    if (cdl7 instanceof SkullBlockEntity) {
                        WitherSkullBlock.checkSpawn(bqb4, fu6, (SkullBlockEntity)cdl7);
                    }
                    bki.shrink(1);
                    this.setSuccess(true);
                }
                else {
                    this.setSuccess(ArmorItem.dispenseArmor(fv, bki));
                }
                return bki;
            }
        });
        DispenserBlock.registerBehavior(Blocks.CARVED_PUMPKIN, new OptionalDispenseItemBehavior() {
            @Override
            protected ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final Level bqb4 = fv.getLevel();
                final BlockPos fu5 = fv.getPos().relative(fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING));
                final CarvedPumpkinBlock bwe6 = (CarvedPumpkinBlock)Blocks.CARVED_PUMPKIN;
                if (bqb4.isEmptyBlock(fu5) && bwe6.canSpawnGolem(bqb4, fu5)) {
                    if (!bqb4.isClientSide) {
                        bqb4.setBlock(fu5, bwe6.defaultBlockState(), 3);
                    }
                    bki.shrink(1);
                    this.setSuccess(true);
                }
                else {
                    this.setSuccess(ArmorItem.dispenseArmor(fv, bki));
                }
                return bki;
            }
        });
        DispenserBlock.registerBehavior(Blocks.SHULKER_BOX.asItem(), new ShulkerBoxDispenseBehavior());
        for (final DyeColor bje8 : DyeColor.values()) {
            DispenserBlock.registerBehavior(ShulkerBoxBlock.getBlockByColor(bje8).asItem(), new ShulkerBoxDispenseBehavior());
        }
        DispenserBlock.registerBehavior(Items.GLASS_BOTTLE.asItem(), new OptionalDispenseItemBehavior() {
            private final DefaultDispenseItemBehavior defaultDispenseItemBehavior = new DefaultDispenseItemBehavior();
            
            private ItemStack takeLiquid(final BlockSource fv, final ItemStack bki2, final ItemStack bki3) {
                bki2.shrink(1);
                if (bki2.isEmpty()) {
                    return bki3.copy();
                }
                if (fv.<DispenserBlockEntity>getEntity().addItem(bki3.copy()) < 0) {
                    this.defaultDispenseItemBehavior.dispense(fv, bki3.copy());
                }
                return bki2;
            }
            
            public ItemStack execute(final BlockSource fv, final ItemStack bki) {
                this.setSuccess(false);
                final LevelAccessor bqc4 = fv.getLevel();
                final BlockPos fu5 = fv.getPos().relative(fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING));
                final BlockState cfj6 = bqc4.getBlockState(fu5);
                if (cfj6.is(BlockTags.BEEHIVES, a -> a.<Comparable>hasProperty((Property<Comparable>)BeehiveBlock.HONEY_LEVEL)) && cfj6.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL) >= 5) {
                    ((BeehiveBlock)cfj6.getBlock()).releaseBeesAndResetHoneyLevel(bqc4.getLevel(), cfj6, fu5, null, BeehiveBlockEntity.BeeReleaseStatus.BEE_RELEASED);
                    this.setSuccess(true);
                    return this.takeLiquid(fv, bki, new ItemStack(Items.HONEY_BOTTLE));
                }
                if (bqc4.getFluidState(fu5).is(FluidTags.WATER)) {
                    this.setSuccess(true);
                    return this.takeLiquid(fv, bki, PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER));
                }
                return super.execute(fv, bki);
            }
        });
        DispenserBlock.registerBehavior(Items.GLOWSTONE, new OptionalDispenseItemBehavior() {
            public ItemStack execute(final BlockSource fv, final ItemStack bki) {
                final Direction fz4 = fv.getBlockState().<Direction>getValue((Property<Direction>)DispenserBlock.FACING);
                final BlockPos fu5 = fv.getPos().relative(fz4);
                final Level bqb6 = fv.getLevel();
                final BlockState cfj7 = bqb6.getBlockState(fu5);
                this.setSuccess(true);
                if (cfj7.is(Blocks.RESPAWN_ANCHOR)) {
                    if (cfj7.<Integer>getValue((Property<Integer>)RespawnAnchorBlock.CHARGE) != 4) {
                        RespawnAnchorBlock.charge(bqb6, fu5, cfj7);
                        bki.shrink(1);
                    }
                    else {
                        this.setSuccess(false);
                    }
                    return bki;
                }
                return super.execute(fv, bki);
            }
        });
        DispenserBlock.registerBehavior(Items.SHEARS.asItem(), new ShearsDispenseItemBehavior());
    }
    
    default void setEntityPokingOutOfBlock(final BlockSource fv, final Entity aom, final Direction fz) {
        aom.setPos(fv.x() + fz.getStepX() * (0.5000099999997474 - aom.getBbWidth() / 2.0), fv.y() + fz.getStepY() * (0.5000099999997474 - aom.getBbHeight() / 2.0) - aom.getBbHeight() / 2.0, fv.z() + fz.getStepZ() * (0.5000099999997474 - aom.getBbWidth() / 2.0));
    }
}
