package net.minecraft.world.entity;

import java.util.AbstractList;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.item.AxeItem;
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
import net.minecraft.world.entity.monster.Enemy;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.core.Vec3i;
import java.util.Optional;
import net.minecraft.world.item.SpawnEggItem;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.AbstractSkullBlock;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.BlockGetter;
import java.util.Random;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.util.Mth;
import net.minecraft.network.protocol.game.DebugPackets;
import net.minecraft.world.Difficulty;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.DiggerItem;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.item.CrossbowItem;
import net.minecraft.world.item.BowItem;
import net.minecraft.world.item.SwordItem;
import java.util.List;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.storage.loot.LootContext;
import java.util.UUID;
import java.util.Iterator;
import net.minecraft.world.entity.decoration.HangingEntity;
import net.minecraft.nbt.FloatTag;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.ListTag;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.item.ProjectileWeaponItem;
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import java.util.Arrays;
import com.google.common.collect.Maps;
import net.minecraft.world.level.Level;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import javax.annotation.Nullable;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.pathfinder.BlockPathTypes;
import java.util.Map;
import net.minecraft.world.item.ItemStack;
import net.minecraft.core.NonNullList;
import net.minecraft.world.entity.ai.sensing.Sensing;
import net.minecraft.world.entity.ai.goal.GoalSelector;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.entity.ai.control.BodyRotationControl;
import net.minecraft.world.entity.ai.control.JumpControl;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.ai.control.LookControl;
import net.minecraft.network.syncher.EntityDataAccessor;

public abstract class Mob extends LivingEntity {
    private static final EntityDataAccessor<Byte> DATA_MOB_FLAGS_ID;
    public int ambientSoundTime;
    protected int xpReward;
    protected LookControl lookControl;
    protected MoveControl moveControl;
    protected JumpControl jumpControl;
    private final BodyRotationControl bodyRotationControl;
    protected PathNavigation navigation;
    protected final GoalSelector goalSelector;
    protected final GoalSelector targetSelector;
    private LivingEntity target;
    private final Sensing sensing;
    private final NonNullList<ItemStack> handItems;
    protected final float[] handDropChances;
    private final NonNullList<ItemStack> armorItems;
    protected final float[] armorDropChances;
    private boolean canPickUpLoot;
    private boolean persistenceRequired;
    private final Map<BlockPathTypes, Float> pathfindingMalus;
    private ResourceLocation lootTable;
    private long lootTableSeed;
    @Nullable
    private Entity leashHolder;
    private int delayedLeashHolderId;
    @Nullable
    private CompoundTag leashInfoTag;
    private BlockPos restrictCenter;
    private float restrictRadius;
    
    protected Mob(final EntityType<? extends Mob> aoq, final Level bqb) {
        super(aoq, bqb);
        this.handItems = NonNullList.<ItemStack>withSize(2, ItemStack.EMPTY);
        this.handDropChances = new float[2];
        this.armorItems = NonNullList.<ItemStack>withSize(4, ItemStack.EMPTY);
        this.armorDropChances = new float[4];
        this.pathfindingMalus = Maps.newEnumMap(BlockPathTypes.class);
        this.restrictCenter = BlockPos.ZERO;
        this.restrictRadius = -1.0f;
        this.goalSelector = new GoalSelector(bqb.getProfilerSupplier());
        this.targetSelector = new GoalSelector(bqb.getProfilerSupplier());
        this.lookControl = new LookControl(this);
        this.moveControl = new MoveControl(this);
        this.jumpControl = new JumpControl(this);
        this.bodyRotationControl = this.createBodyControl();
        this.navigation = this.createNavigation(bqb);
        this.sensing = new Sensing(this);
        Arrays.fill(this.armorDropChances, 0.085f);
        Arrays.fill(this.handDropChances, 0.085f);
        if (bqb != null && !bqb.isClientSide) {
            this.registerGoals();
        }
    }
    
    protected void registerGoals() {
    }
    
    public static AttributeSupplier.Builder createMobAttributes() {
        return LivingEntity.createLivingAttributes().add(Attributes.FOLLOW_RANGE, 16.0).add(Attributes.ATTACK_KNOCKBACK);
    }
    
    protected PathNavigation createNavigation(final Level bqb) {
        return new GroundPathNavigation(this, bqb);
    }
    
    protected boolean shouldPassengersInheritMalus() {
        return false;
    }
    
    public float getPathfindingMalus(final BlockPathTypes czb) {
        Mob aoz3;
        if (this.getVehicle() instanceof Mob && ((Mob)this.getVehicle()).shouldPassengersInheritMalus()) {
            aoz3 = (Mob)this.getVehicle();
        }
        else {
            aoz3 = this;
        }
        final Float float4 = aoz3.pathfindingMalus.get(czb);
        return (float4 == null) ? czb.getMalus() : float4;
    }
    
    public void setPathfindingMalus(final BlockPathTypes czb, final float float2) {
        this.pathfindingMalus.put(czb, float2);
    }
    
    public boolean canCutCorner(final BlockPathTypes czb) {
        return czb != BlockPathTypes.DANGER_FIRE && czb != BlockPathTypes.DANGER_CACTUS && czb != BlockPathTypes.DANGER_OTHER;
    }
    
    protected BodyRotationControl createBodyControl() {
        return new BodyRotationControl(this);
    }
    
    public LookControl getLookControl() {
        return this.lookControl;
    }
    
    public MoveControl getMoveControl() {
        if (this.isPassenger() && this.getVehicle() instanceof Mob) {
            final Mob aoz2 = (Mob)this.getVehicle();
            return aoz2.getMoveControl();
        }
        return this.moveControl;
    }
    
    public JumpControl getJumpControl() {
        return this.jumpControl;
    }
    
    public PathNavigation getNavigation() {
        if (this.isPassenger() && this.getVehicle() instanceof Mob) {
            final Mob aoz2 = (Mob)this.getVehicle();
            return aoz2.getNavigation();
        }
        return this.navigation;
    }
    
    public Sensing getSensing() {
        return this.sensing;
    }
    
    @Nullable
    public LivingEntity getTarget() {
        return this.target;
    }
    
    public void setTarget(@Nullable final LivingEntity aoy) {
        this.target = aoy;
    }
    
    @Override
    public boolean canAttackType(final EntityType<?> aoq) {
        return aoq != EntityType.GHAST;
    }
    
    public boolean canFireProjectileWeapon(final ProjectileWeaponItem bkv) {
        return false;
    }
    
    public void ate() {
    }
    
    @Override
    protected void defineSynchedData() {
        super.defineSynchedData();
        this.entityData.<Byte>define(Mob.DATA_MOB_FLAGS_ID, (Byte)0);
    }
    
    public int getAmbientSoundInterval() {
        return 80;
    }
    
    public void playAmbientSound() {
        final SoundEvent ack2 = this.getAmbientSound();
        if (ack2 != null) {
            this.playSound(ack2, this.getSoundVolume(), this.getVoicePitch());
        }
    }
    
    @Override
    public void baseTick() {
        super.baseTick();
        this.level.getProfiler().push("mobBaseTick");
        if (this.isAlive() && this.random.nextInt(1000) < this.ambientSoundTime++) {
            this.resetAmbientSoundTime();
            this.playAmbientSound();
        }
        this.level.getProfiler().pop();
    }
    
    @Override
    protected void playHurtSound(final DamageSource anw) {
        this.resetAmbientSoundTime();
        super.playHurtSound(anw);
    }
    
    private void resetAmbientSoundTime() {
        this.ambientSoundTime = -this.getAmbientSoundInterval();
    }
    
    @Override
    protected int getExperienceReward(final Player bec) {
        if (this.xpReward > 0) {
            int integer3 = this.xpReward;
            for (int integer4 = 0; integer4 < this.armorItems.size(); ++integer4) {
                if (!this.armorItems.get(integer4).isEmpty() && this.armorDropChances[integer4] <= 1.0f) {
                    integer3 += 1 + this.random.nextInt(3);
                }
            }
            for (int integer4 = 0; integer4 < this.handItems.size(); ++integer4) {
                if (!this.handItems.get(integer4).isEmpty() && this.handDropChances[integer4] <= 1.0f) {
                    integer3 += 1 + this.random.nextInt(3);
                }
            }
            return integer3;
        }
        return this.xpReward;
    }
    
    public void spawnAnim() {
        if (this.level.isClientSide) {
            for (int integer2 = 0; integer2 < 20; ++integer2) {
                final double double3 = this.random.nextGaussian() * 0.02;
                final double double4 = this.random.nextGaussian() * 0.02;
                final double double5 = this.random.nextGaussian() * 0.02;
                final double double6 = 10.0;
                this.level.addParticle(ParticleTypes.POOF, this.getX(1.0) - double3 * 10.0, this.getRandomY() - double4 * 10.0, this.getRandomZ(1.0) - double5 * 10.0, double3, double4, double5);
            }
        }
        else {
            this.level.broadcastEntityEvent(this, (byte)20);
        }
    }
    
    @Override
    public void handleEntityEvent(final byte byte1) {
        if (byte1 == 20) {
            this.spawnAnim();
        }
        else {
            super.handleEntityEvent(byte1);
        }
    }
    
    @Override
    public void tick() {
        super.tick();
        if (!this.level.isClientSide) {
            this.tickLeash();
            if (this.tickCount % 5 == 0) {
                this.updateControlFlags();
            }
        }
    }
    
    protected void updateControlFlags() {
        final boolean boolean2 = !(this.getControllingPassenger() instanceof Mob);
        final boolean boolean3 = !(this.getVehicle() instanceof Boat);
        this.goalSelector.setControlFlag(Goal.Flag.MOVE, boolean2);
        this.goalSelector.setControlFlag(Goal.Flag.JUMP, boolean2 && boolean3);
        this.goalSelector.setControlFlag(Goal.Flag.LOOK, boolean2);
    }
    
    @Override
    protected float tickHeadTurn(final float float1, final float float2) {
        this.bodyRotationControl.clientTick();
        return float2;
    }
    
    @Nullable
    protected SoundEvent getAmbientSound() {
        return null;
    }
    
    @Override
    public void addAdditionalSaveData(final CompoundTag le) {
        super.addAdditionalSaveData(le);
        le.putBoolean("CanPickUpLoot", this.canPickUpLoot());
        le.putBoolean("PersistenceRequired", this.persistenceRequired);
        final ListTag lk3 = new ListTag();
        for (final ItemStack bki5 : this.armorItems) {
            final CompoundTag le2 = new CompoundTag();
            if (!bki5.isEmpty()) {
                bki5.save(le2);
            }
            ((AbstractList<CompoundTag>)lk3).add(le2);
        }
        le.put("ArmorItems", lk3);
        final ListTag lk4 = new ListTag();
        for (final ItemStack bki6 : this.handItems) {
            final CompoundTag le3 = new CompoundTag();
            if (!bki6.isEmpty()) {
                bki6.save(le3);
            }
            ((AbstractList<CompoundTag>)lk4).add(le3);
        }
        le.put("HandItems", lk4);
        final ListTag lk5 = new ListTag();
        for (final float float9 : this.armorDropChances) {
            ((AbstractList<FloatTag>)lk5).add(FloatTag.valueOf(float9));
        }
        le.put("ArmorDropChances", lk5);
        final ListTag lk6 = new ListTag();
        for (final float float10 : this.handDropChances) {
            ((AbstractList<FloatTag>)lk6).add(FloatTag.valueOf(float10));
        }
        le.put("HandDropChances", lk6);
        if (this.leashHolder != null) {
            final CompoundTag le3 = new CompoundTag();
            if (this.leashHolder instanceof LivingEntity) {
                final UUID uUID8 = this.leashHolder.getUUID();
                le3.putUUID("UUID", uUID8);
            }
            else if (this.leashHolder instanceof HangingEntity) {
                final BlockPos fu8 = ((HangingEntity)this.leashHolder).getPos();
                le3.putInt("X", fu8.getX());
                le3.putInt("Y", fu8.getY());
                le3.putInt("Z", fu8.getZ());
            }
            le.put("Leash", le3);
        }
        else if (this.leashInfoTag != null) {
            le.put("Leash", this.leashInfoTag.copy());
        }
        le.putBoolean("LeftHanded", this.isLeftHanded());
        if (this.lootTable != null) {
            le.putString("DeathLootTable", this.lootTable.toString());
            if (this.lootTableSeed != 0L) {
                le.putLong("DeathLootTableSeed", this.lootTableSeed);
            }
        }
        if (this.isNoAi()) {
            le.putBoolean("NoAI", this.isNoAi());
        }
    }
    
    @Override
    public void readAdditionalSaveData(final CompoundTag le) {
        super.readAdditionalSaveData(le);
        if (le.contains("CanPickUpLoot", 1)) {
            this.setCanPickUpLoot(le.getBoolean("CanPickUpLoot"));
        }
        this.persistenceRequired = le.getBoolean("PersistenceRequired");
        if (le.contains("ArmorItems", 9)) {
            final ListTag lk3 = le.getList("ArmorItems", 10);
            for (int integer4 = 0; integer4 < this.armorItems.size(); ++integer4) {
                this.armorItems.set(integer4, ItemStack.of(lk3.getCompound(integer4)));
            }
        }
        if (le.contains("HandItems", 9)) {
            final ListTag lk3 = le.getList("HandItems", 10);
            for (int integer4 = 0; integer4 < this.handItems.size(); ++integer4) {
                this.handItems.set(integer4, ItemStack.of(lk3.getCompound(integer4)));
            }
        }
        if (le.contains("ArmorDropChances", 9)) {
            final ListTag lk3 = le.getList("ArmorDropChances", 5);
            for (int integer4 = 0; integer4 < lk3.size(); ++integer4) {
                this.armorDropChances[integer4] = lk3.getFloat(integer4);
            }
        }
        if (le.contains("HandDropChances", 9)) {
            final ListTag lk3 = le.getList("HandDropChances", 5);
            for (int integer4 = 0; integer4 < lk3.size(); ++integer4) {
                this.handDropChances[integer4] = lk3.getFloat(integer4);
            }
        }
        if (le.contains("Leash", 10)) {
            this.leashInfoTag = le.getCompound("Leash");
        }
        this.setLeftHanded(le.getBoolean("LeftHanded"));
        if (le.contains("DeathLootTable", 8)) {
            this.lootTable = new ResourceLocation(le.getString("DeathLootTable"));
            this.lootTableSeed = le.getLong("DeathLootTableSeed");
        }
        this.setNoAi(le.getBoolean("NoAI"));
    }
    
    @Override
    protected void dropFromLootTable(final DamageSource anw, final boolean boolean2) {
        super.dropFromLootTable(anw, boolean2);
        this.lootTable = null;
    }
    
    @Override
    protected LootContext.Builder createLootContext(final boolean boolean1, final DamageSource anw) {
        return super.createLootContext(boolean1, anw).withOptionalRandomSeed(this.lootTableSeed, this.random);
    }
    
    @Override
    public final ResourceLocation getLootTable() {
        return (this.lootTable == null) ? this.getDefaultLootTable() : this.lootTable;
    }
    
    protected ResourceLocation getDefaultLootTable() {
        return super.getLootTable();
    }
    
    public void setZza(final float float1) {
        this.zza = float1;
    }
    
    public void setYya(final float float1) {
        this.yya = float1;
    }
    
    public void setXxa(final float float1) {
        this.xxa = float1;
    }
    
    @Override
    public void setSpeed(final float float1) {
        super.setSpeed(float1);
        this.setZza(float1);
    }
    
    @Override
    public void aiStep() {
        super.aiStep();
        this.level.getProfiler().push("looting");
        if (!this.level.isClientSide && this.canPickUpLoot() && this.isAlive() && !this.dead && this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
            final List<ItemEntity> list2 = this.level.<ItemEntity>getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(1.0, 0.0, 1.0));
            for (final ItemEntity bbg4 : list2) {
                if (!bbg4.removed && !bbg4.getItem().isEmpty()) {
                    if (bbg4.hasPickUpDelay()) {
                        continue;
                    }
                    if (!this.wantsToPickUp(bbg4.getItem())) {
                        continue;
                    }
                    this.pickUpItem(bbg4);
                }
            }
        }
        this.level.getProfiler().pop();
    }
    
    protected void pickUpItem(final ItemEntity bbg) {
        final ItemStack bki3 = bbg.getItem();
        if (this.equipItemIfPossible(bki3)) {
            this.onItemPickup(bbg);
            this.take(bbg, bki3.getCount());
            bbg.remove();
        }
    }
    
    public boolean equipItemIfPossible(final ItemStack bki) {
        final EquipmentSlot aor3 = getEquipmentSlotForItem(bki);
        final ItemStack bki2 = this.getItemBySlot(aor3);
        final boolean boolean5 = this.canReplaceCurrentItem(bki, bki2);
        if (boolean5 && this.canHoldItem(bki)) {
            final double double6 = this.getEquipmentDropChance(aor3);
            if (!bki2.isEmpty() && Math.max(this.random.nextFloat() - 0.1f, 0.0f) < double6) {
                this.spawnAtLocation(bki2);
            }
            this.setItemSlotAndDropWhenKilled(aor3, bki);
            this.playEquipSound(bki);
            return true;
        }
        return false;
    }
    
    protected void setItemSlotAndDropWhenKilled(final EquipmentSlot aor, final ItemStack bki) {
        this.setItemSlot(aor, bki);
        this.setGuaranteedDrop(aor);
        this.persistenceRequired = true;
    }
    
    public void setGuaranteedDrop(final EquipmentSlot aor) {
        switch (aor.getType()) {
            case HAND: {
                this.handDropChances[aor.getIndex()] = 2.0f;
                break;
            }
            case ARMOR: {
                this.armorDropChances[aor.getIndex()] = 2.0f;
                break;
            }
        }
    }
    
    protected boolean canReplaceCurrentItem(final ItemStack bki1, final ItemStack bki2) {
        if (bki2.isEmpty()) {
            return true;
        }
        if (bki1.getItem() instanceof SwordItem) {
            if (!(bki2.getItem() instanceof SwordItem)) {
                return true;
            }
            final SwordItem blm4 = (SwordItem)bki1.getItem();
            final SwordItem blm5 = (SwordItem)bki2.getItem();
            if (blm4.getDamage() != blm5.getDamage()) {
                return blm4.getDamage() > blm5.getDamage();
            }
            return this.canReplaceEqualItem(bki1, bki2);
        }
        else {
            if (bki1.getItem() instanceof BowItem && bki2.getItem() instanceof BowItem) {
                return this.canReplaceEqualItem(bki1, bki2);
            }
            if (bki1.getItem() instanceof CrossbowItem && bki2.getItem() instanceof CrossbowItem) {
                return this.canReplaceEqualItem(bki1, bki2);
            }
            if (!(bki1.getItem() instanceof ArmorItem)) {
                if (bki1.getItem() instanceof DiggerItem) {
                    if (bki2.getItem() instanceof BlockItem) {
                        return true;
                    }
                    if (bki2.getItem() instanceof DiggerItem) {
                        final DiggerItem bjb4 = (DiggerItem)bki1.getItem();
                        final DiggerItem bjb5 = (DiggerItem)bki2.getItem();
                        if (bjb4.getAttackDamage() != bjb5.getAttackDamage()) {
                            return bjb4.getAttackDamage() > bjb5.getAttackDamage();
                        }
                        return this.canReplaceEqualItem(bki1, bki2);
                    }
                }
                return false;
            }
            if (EnchantmentHelper.hasBindingCurse(bki2)) {
                return false;
            }
            if (!(bki2.getItem() instanceof ArmorItem)) {
                return true;
            }
            final ArmorItem bid4 = (ArmorItem)bki1.getItem();
            final ArmorItem bid5 = (ArmorItem)bki2.getItem();
            if (bid4.getDefense() != bid5.getDefense()) {
                return bid4.getDefense() > bid5.getDefense();
            }
            if (bid4.getToughness() != bid5.getToughness()) {
                return bid4.getToughness() > bid5.getToughness();
            }
            return this.canReplaceEqualItem(bki1, bki2);
        }
    }
    
    public boolean canReplaceEqualItem(final ItemStack bki1, final ItemStack bki2) {
        return bki1.getDamageValue() < bki2.getDamageValue() || (bki1.hasTag() && !bki2.hasTag()) || (bki1.hasTag() && bki2.hasTag() && bki1.getTag().getAllKeys().stream().anyMatch(string -> !string.equals("Damage")) && !bki2.getTag().getAllKeys().stream().anyMatch(string -> !string.equals("Damage")));
    }
    
    public boolean canHoldItem(final ItemStack bki) {
        return true;
    }
    
    public boolean wantsToPickUp(final ItemStack bki) {
        return this.canHoldItem(bki);
    }
    
    public boolean removeWhenFarAway(final double double1) {
        return true;
    }
    
    public boolean requiresCustomPersistence() {
        return this.isPassenger();
    }
    
    protected boolean shouldDespawnInPeaceful() {
        return false;
    }
    
    @Override
    public void checkDespawn() {
        if (this.level.getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) {
            this.remove();
            return;
        }
        if (this.isPersistenceRequired() || this.requiresCustomPersistence()) {
            this.noActionTime = 0;
            return;
        }
        final Entity aom2 = this.level.getNearestPlayer(this, -1.0);
        if (aom2 != null) {
            final double double3 = aom2.distanceToSqr(this);
            final int integer5 = this.getType().getCategory().getDespawnDistance();
            final int integer6 = integer5 * integer5;
            if (double3 > integer6 && this.removeWhenFarAway(double3)) {
                this.remove();
            }
            final int integer7 = this.getType().getCategory().getNoDespawnDistance();
            final int integer8 = integer7 * integer7;
            if (this.noActionTime > 600 && this.random.nextInt(800) == 0 && double3 > integer8 && this.removeWhenFarAway(double3)) {
                this.remove();
            }
            else if (double3 < integer8) {
                this.noActionTime = 0;
            }
        }
    }
    
    @Override
    protected final void serverAiStep() {
        ++this.noActionTime;
        this.level.getProfiler().push("sensing");
        this.sensing.tick();
        this.level.getProfiler().pop();
        this.level.getProfiler().push("targetSelector");
        this.targetSelector.tick();
        this.level.getProfiler().pop();
        this.level.getProfiler().push("goalSelector");
        this.goalSelector.tick();
        this.level.getProfiler().pop();
        this.level.getProfiler().push("navigation");
        this.navigation.tick();
        this.level.getProfiler().pop();
        this.level.getProfiler().push("mob tick");
        this.customServerAiStep();
        this.level.getProfiler().pop();
        this.level.getProfiler().push("controls");
        this.level.getProfiler().push("move");
        this.moveControl.tick();
        this.level.getProfiler().popPush("look");
        this.lookControl.tick();
        this.level.getProfiler().popPush("jump");
        this.jumpControl.tick();
        this.level.getProfiler().pop();
        this.level.getProfiler().pop();
        this.sendDebugPackets();
    }
    
    protected void sendDebugPackets() {
        DebugPackets.sendGoalSelector(this.level, this, this.goalSelector);
    }
    
    protected void customServerAiStep() {
    }
    
    public int getMaxHeadXRot() {
        return 40;
    }
    
    public int getMaxHeadYRot() {
        return 75;
    }
    
    public int getHeadRotSpeed() {
        return 10;
    }
    
    public void lookAt(final Entity aom, final float float2, final float float3) {
        final double double5 = aom.getX() - this.getX();
        final double double6 = aom.getZ() - this.getZ();
        double double7;
        if (aom instanceof LivingEntity) {
            final LivingEntity aoy11 = (LivingEntity)aom;
            double7 = aoy11.getEyeY() - this.getEyeY();
        }
        else {
            double7 = (aom.getBoundingBox().minY + aom.getBoundingBox().maxY) / 2.0 - this.getEyeY();
        }
        final double double8 = Mth.sqrt(double5 * double5 + double6 * double6);
        final float float4 = (float)(Mth.atan2(double6, double5) * 57.2957763671875) - 90.0f;
        final float float5 = (float)(-(Mth.atan2(double7, double8) * 57.2957763671875));
        this.xRot = this.rotlerp(this.xRot, float5, float3);
        this.yRot = this.rotlerp(this.yRot, float4, float2);
    }
    
    private float rotlerp(final float float1, final float float2, final float float3) {
        float float4 = Mth.wrapDegrees(float2 - float1);
        if (float4 > float3) {
            float4 = float3;
        }
        if (float4 < -float3) {
            float4 = -float3;
        }
        return float1 + float4;
    }
    
    public static boolean checkMobSpawnRules(final EntityType<? extends Mob> aoq, final LevelAccessor bqc, final MobSpawnType apb, final BlockPos fu, final Random random) {
        final BlockPos fu2 = fu.below();
        return apb == MobSpawnType.SPAWNER || bqc.getBlockState(fu2).isValidSpawn(bqc, fu2, aoq);
    }
    
    public boolean checkSpawnRules(final LevelAccessor bqc, final MobSpawnType apb) {
        return true;
    }
    
    public boolean checkSpawnObstruction(final LevelReader bqd) {
        return !bqd.containsAnyLiquid(this.getBoundingBox()) && bqd.isUnobstructed(this);
    }
    
    public int getMaxSpawnClusterSize() {
        return 4;
    }
    
    public boolean isMaxGroupSizeReached(final int integer) {
        return false;
    }
    
    @Override
    public int getMaxFallDistance() {
        if (this.getTarget() == null) {
            return 3;
        }
        int integer2 = (int)(this.getHealth() - this.getMaxHealth() * 0.33f);
        integer2 -= (3 - this.level.getDifficulty().getId()) * 4;
        if (integer2 < 0) {
            integer2 = 0;
        }
        return integer2 + 3;
    }
    
    @Override
    public Iterable<ItemStack> getHandSlots() {
        return this.handItems;
    }
    
    @Override
    public Iterable<ItemStack> getArmorSlots() {
        return this.armorItems;
    }
    
    @Override
    public ItemStack getItemBySlot(final EquipmentSlot aor) {
        switch (aor.getType()) {
            case HAND: {
                return this.handItems.get(aor.getIndex());
            }
            case ARMOR: {
                return this.armorItems.get(aor.getIndex());
            }
            default: {
                return ItemStack.EMPTY;
            }
        }
    }
    
    @Override
    public void setItemSlot(final EquipmentSlot aor, final ItemStack bki) {
        switch (aor.getType()) {
            case HAND: {
                this.handItems.set(aor.getIndex(), bki);
                break;
            }
            case ARMOR: {
                this.armorItems.set(aor.getIndex(), bki);
                break;
            }
        }
    }
    
    @Override
    protected void dropCustomDeathLoot(final DamageSource anw, final int integer, final boolean boolean3) {
        super.dropCustomDeathLoot(anw, integer, boolean3);
        for (final EquipmentSlot aor8 : EquipmentSlot.values()) {
            final ItemStack bki9 = this.getItemBySlot(aor8);
            final float float10 = this.getEquipmentDropChance(aor8);
            final boolean boolean4 = float10 > 1.0f;
            if (!bki9.isEmpty() && !EnchantmentHelper.hasVanishingCurse(bki9) && (boolean3 || boolean4) && Math.max(this.random.nextFloat() - integer * 0.01f, 0.0f) < float10) {
                if (!boolean4 && bki9.isDamageableItem()) {
                    bki9.setDamageValue(bki9.getMaxDamage() - this.random.nextInt(1 + this.random.nextInt(Math.max(bki9.getMaxDamage() - 3, 1))));
                }
                this.spawnAtLocation(bki9);
            }
        }
    }
    
    protected float getEquipmentDropChance(final EquipmentSlot aor) {
        float float3 = 0.0f;
        switch (aor.getType()) {
            case HAND: {
                float3 = this.handDropChances[aor.getIndex()];
                break;
            }
            case ARMOR: {
                float3 = this.armorDropChances[aor.getIndex()];
                break;
            }
            default: {
                float3 = 0.0f;
                break;
            }
        }
        return float3;
    }
    
    protected void populateDefaultEquipmentSlots(final DifficultyInstance ane) {
        if (this.random.nextFloat() < 0.15f * ane.getSpecialMultiplier()) {
            int integer3 = this.random.nextInt(2);
            final float float4 = (this.level.getDifficulty() == Difficulty.HARD) ? 0.1f : 0.25f;
            if (this.random.nextFloat() < 0.095f) {
                ++integer3;
            }
            if (this.random.nextFloat() < 0.095f) {
                ++integer3;
            }
            if (this.random.nextFloat() < 0.095f) {
                ++integer3;
            }
            boolean boolean5 = true;
            for (final EquipmentSlot aor9 : EquipmentSlot.values()) {
                if (aor9.getType() == EquipmentSlot.Type.ARMOR) {
                    final ItemStack bki10 = this.getItemBySlot(aor9);
                    if (!boolean5 && this.random.nextFloat() < float4) {
                        break;
                    }
                    boolean5 = false;
                    if (bki10.isEmpty()) {
                        final Item bke11 = getEquipmentForSlot(aor9, integer3);
                        if (bke11 != null) {
                            this.setItemSlot(aor9, new ItemStack(bke11));
                        }
                    }
                }
            }
        }
    }
    
    public static EquipmentSlot getEquipmentSlotForItem(final ItemStack bki) {
        final Item bke2 = bki.getItem();
        if (bke2 == Blocks.CARVED_PUMPKIN.asItem() || (bke2 instanceof BlockItem && ((BlockItem)bke2).getBlock() instanceof AbstractSkullBlock)) {
            return EquipmentSlot.HEAD;
        }
        if (bke2 instanceof ArmorItem) {
            return ((ArmorItem)bke2).getSlot();
        }
        if (bke2 == Items.ELYTRA) {
            return EquipmentSlot.CHEST;
        }
        if (bke2 == Items.SHIELD) {
            return EquipmentSlot.OFFHAND;
        }
        return EquipmentSlot.MAINHAND;
    }
    
    @Nullable
    public static Item getEquipmentForSlot(final EquipmentSlot aor, final int integer) {
        switch (aor) {
            case HEAD: {
                if (integer == 0) {
                    return Items.LEATHER_HELMET;
                }
                if (integer == 1) {
                    return Items.GOLDEN_HELMET;
                }
                if (integer == 2) {
                    return Items.CHAINMAIL_HELMET;
                }
                if (integer == 3) {
                    return Items.IRON_HELMET;
                }
                if (integer == 4) {
                    return Items.DIAMOND_HELMET;
                }
            }
            case CHEST: {
                if (integer == 0) {
                    return Items.LEATHER_CHESTPLATE;
                }
                if (integer == 1) {
                    return Items.GOLDEN_CHESTPLATE;
                }
                if (integer == 2) {
                    return Items.CHAINMAIL_CHESTPLATE;
                }
                if (integer == 3) {
                    return Items.IRON_CHESTPLATE;
                }
                if (integer == 4) {
                    return Items.DIAMOND_CHESTPLATE;
                }
            }
            case LEGS: {
                if (integer == 0) {
                    return Items.LEATHER_LEGGINGS;
                }
                if (integer == 1) {
                    return Items.GOLDEN_LEGGINGS;
                }
                if (integer == 2) {
                    return Items.CHAINMAIL_LEGGINGS;
                }
                if (integer == 3) {
                    return Items.IRON_LEGGINGS;
                }
                if (integer == 4) {
                    return Items.DIAMOND_LEGGINGS;
                }
            }
            case FEET: {
                if (integer == 0) {
                    return Items.LEATHER_BOOTS;
                }
                if (integer == 1) {
                    return Items.GOLDEN_BOOTS;
                }
                if (integer == 2) {
                    return Items.CHAINMAIL_BOOTS;
                }
                if (integer == 3) {
                    return Items.IRON_BOOTS;
                }
                if (integer == 4) {
                    return Items.DIAMOND_BOOTS;
                }
                break;
            }
        }
        return null;
    }
    
    protected void populateDefaultEquipmentEnchantments(final DifficultyInstance ane) {
        final float float3 = ane.getSpecialMultiplier();
        if (!this.getMainHandItem().isEmpty() && this.random.nextFloat() < 0.25f * float3) {
            this.setItemSlot(EquipmentSlot.MAINHAND, EnchantmentHelper.enchantItem(this.random, this.getMainHandItem(), (int)(5.0f + float3 * this.random.nextInt(18)), false));
        }
        for (final EquipmentSlot aor7 : EquipmentSlot.values()) {
            if (aor7.getType() == EquipmentSlot.Type.ARMOR) {
                final ItemStack bki8 = this.getItemBySlot(aor7);
                if (!bki8.isEmpty() && this.random.nextFloat() < 0.5f * float3) {
                    this.setItemSlot(aor7, EnchantmentHelper.enchantItem(this.random, bki8, (int)(5.0f + float3 * this.random.nextInt(18)), false));
                }
            }
        }
    }
    
    @Nullable
    public SpawnGroupData finalizeSpawn(final LevelAccessor bqc, final DifficultyInstance ane, final MobSpawnType apb, @Nullable final SpawnGroupData apo, @Nullable final CompoundTag le) {
        this.getAttribute(Attributes.FOLLOW_RANGE).addPermanentModifier(new AttributeModifier("Random spawn bonus", this.random.nextGaussian() * 0.05, AttributeModifier.Operation.MULTIPLY_BASE));
        if (this.random.nextFloat() < 0.05f) {
            this.setLeftHanded(true);
        }
        else {
            this.setLeftHanded(false);
        }
        return apo;
    }
    
    public boolean canBeControlledByRider() {
        return false;
    }
    
    public void setPersistenceRequired() {
        this.persistenceRequired = true;
    }
    
    public void setDropChance(final EquipmentSlot aor, final float float2) {
        switch (aor.getType()) {
            case HAND: {
                this.handDropChances[aor.getIndex()] = float2;
                break;
            }
            case ARMOR: {
                this.armorDropChances[aor.getIndex()] = float2;
                break;
            }
        }
    }
    
    public boolean canPickUpLoot() {
        return this.canPickUpLoot;
    }
    
    public void setCanPickUpLoot(final boolean boolean1) {
        this.canPickUpLoot = boolean1;
    }
    
    @Override
    public boolean canTakeItem(final ItemStack bki) {
        final EquipmentSlot aor3 = getEquipmentSlotForItem(bki);
        return this.getItemBySlot(aor3).isEmpty() && this.canPickUpLoot();
    }
    
    public boolean isPersistenceRequired() {
        return this.persistenceRequired;
    }
    
    @Override
    public final InteractionResult interact(final Player bec, final InteractionHand anf) {
        if (!this.isAlive()) {
            return InteractionResult.PASS;
        }
        if (this.getLeashHolder() == bec) {
            this.dropLeash(true, !bec.abilities.instabuild);
            return InteractionResult.sidedSuccess(this.level.isClientSide);
        }
        InteractionResult ang4 = this.checkAndHandleImportantInteractions(bec, anf);
        if (ang4.consumesAction()) {
            return ang4;
        }
        ang4 = this.mobInteract(bec, anf);
        if (ang4.consumesAction()) {
            return ang4;
        }
        return super.interact(bec, anf);
    }
    
    private InteractionResult checkAndHandleImportantInteractions(final Player bec, final InteractionHand anf) {
        final ItemStack bki4 = bec.getItemInHand(anf);
        if (bki4.getItem() == Items.LEAD && this.canBeLeashed(bec)) {
            this.setLeashedTo(bec, true);
            bki4.shrink(1);
            return InteractionResult.sidedSuccess(this.level.isClientSide);
        }
        if (bki4.getItem() == Items.NAME_TAG) {
            final InteractionResult ang5 = bki4.interactLivingEntity(bec, this, anf);
            if (ang5.consumesAction()) {
                return ang5;
            }
        }
        if (!(bki4.getItem() instanceof SpawnEggItem)) {
            return InteractionResult.PASS;
        }
        if (!this.level.isClientSide) {
            final SpawnEggItem blh5 = (SpawnEggItem)bki4.getItem();
            final Optional<Mob> optional6 = blh5.spawnOffspringFromSpawnEgg(bec, this, this.getType(), this.level, this.position(), bki4);
            optional6.ifPresent(aoz -> this.onOffspringSpawnedFromEgg(bec, aoz));
            return optional6.isPresent() ? InteractionResult.SUCCESS : InteractionResult.PASS;
        }
        return InteractionResult.CONSUME;
    }
    
    protected void onOffspringSpawnedFromEgg(final Player bec, final Mob aoz) {
    }
    
    protected InteractionResult mobInteract(final Player bec, final InteractionHand anf) {
        return InteractionResult.PASS;
    }
    
    public boolean isWithinRestriction() {
        return this.isWithinRestriction(this.blockPosition());
    }
    
    public boolean isWithinRestriction(final BlockPos fu) {
        return this.restrictRadius == -1.0f || this.restrictCenter.distSqr(fu) < this.restrictRadius * this.restrictRadius;
    }
    
    public void restrictTo(final BlockPos fu, final int integer) {
        this.restrictCenter = fu;
        this.restrictRadius = (float)integer;
    }
    
    public BlockPos getRestrictCenter() {
        return this.restrictCenter;
    }
    
    public float getRestrictRadius() {
        return this.restrictRadius;
    }
    
    public boolean hasRestriction() {
        return this.restrictRadius != -1.0f;
    }
    
    @Nullable
    protected <T extends Mob> T convertTo(final EntityType<T> aoq) {
        if (this.removed) {
            return null;
        }
        final T aoz3 = aoq.create(this.level);
        aoz3.copyPosition(this);
        aoz3.setCanPickUpLoot(this.canPickUpLoot());
        aoz3.setBaby(this.isBaby());
        aoz3.setNoAi(this.isNoAi());
        if (this.hasCustomName()) {
            aoz3.setCustomName(this.getCustomName());
            aoz3.setCustomNameVisible(this.isCustomNameVisible());
        }
        if (this.isPersistenceRequired()) {
            aoz3.setPersistenceRequired();
        }
        aoz3.setInvulnerable(this.isInvulnerable());
        for (final EquipmentSlot aor7 : EquipmentSlot.values()) {
            final ItemStack bki8 = this.getItemBySlot(aor7);
            if (!bki8.isEmpty()) {
                aoz3.setItemSlot(aor7, bki8.copy());
                aoz3.setDropChance(aor7, this.getEquipmentDropChance(aor7));
                bki8.setCount(0);
            }
        }
        this.level.addFreshEntity(aoz3);
        this.remove();
        return aoz3;
    }
    
    protected void tickLeash() {
        if (this.leashInfoTag != null) {
            this.restoreLeashFromSave();
        }
        if (this.leashHolder == null) {
            return;
        }
        if (!this.isAlive() || !this.leashHolder.isAlive()) {
            this.dropLeash(true, true);
        }
    }
    
    public void dropLeash(final boolean boolean1, final boolean boolean2) {
        if (this.leashHolder != null) {
            this.forcedLoading = false;
            if (!(this.leashHolder instanceof Player)) {
                this.leashHolder.forcedLoading = false;
            }
            this.leashHolder = null;
            this.leashInfoTag = null;
            if (!this.level.isClientSide && boolean2) {
                this.spawnAtLocation(Items.LEAD);
            }
            if (!this.level.isClientSide && boolean1 && this.level instanceof ServerLevel) {
                ((ServerLevel)this.level).getChunkSource().broadcast(this, new ClientboundSetEntityLinkPacket(this, null));
            }
        }
    }
    
    public boolean canBeLeashed(final Player bec) {
        return !this.isLeashed() && !(this instanceof Enemy);
    }
    
    public boolean isLeashed() {
        return this.leashHolder != null;
    }
    
    @Nullable
    public Entity getLeashHolder() {
        if (this.leashHolder == null && this.delayedLeashHolderId != 0 && this.level.isClientSide) {
            this.leashHolder = this.level.getEntity(this.delayedLeashHolderId);
        }
        return this.leashHolder;
    }
    
    public void setLeashedTo(final Entity aom, final boolean boolean2) {
        this.leashHolder = aom;
        this.leashInfoTag = null;
        this.forcedLoading = true;
        if (!(this.leashHolder instanceof Player)) {
            this.leashHolder.forcedLoading = true;
        }
        if (!this.level.isClientSide && boolean2 && this.level instanceof ServerLevel) {
            ((ServerLevel)this.level).getChunkSource().broadcast(this, new ClientboundSetEntityLinkPacket(this, this.leashHolder));
        }
        if (this.isPassenger()) {
            this.stopRiding();
        }
    }
    
    public void setDelayedLeashHolderId(final int integer) {
        this.delayedLeashHolderId = integer;
        this.dropLeash(false, false);
    }
    
    @Override
    public boolean startRiding(final Entity aom, final boolean boolean2) {
        final boolean boolean3 = super.startRiding(aom, boolean2);
        if (boolean3 && this.isLeashed()) {
            this.dropLeash(true, true);
        }
        return boolean3;
    }
    
    private void restoreLeashFromSave() {
        if (this.leashInfoTag != null && this.level instanceof ServerLevel) {
            if (this.leashInfoTag.hasUUID("UUID")) {
                final UUID uUID2 = this.leashInfoTag.getUUID("UUID");
                final Entity aom3 = ((ServerLevel)this.level).getEntity(uUID2);
                if (aom3 != null) {
                    this.setLeashedTo(aom3, true);
                    return;
                }
            }
            else if (this.leashInfoTag.contains("X", 99) && this.leashInfoTag.contains("Y", 99) && this.leashInfoTag.contains("Z", 99)) {
                final BlockPos fu2 = new BlockPos(this.leashInfoTag.getInt("X"), this.leashInfoTag.getInt("Y"), this.leashInfoTag.getInt("Z"));
                this.setLeashedTo(LeashFenceKnotEntity.getOrCreateKnot(this.level, fu2), true);
                return;
            }
            if (this.tickCount > 100) {
                this.spawnAtLocation(Items.LEAD);
                this.leashInfoTag = null;
            }
        }
    }
    
    @Override
    public boolean setSlot(final int integer, final ItemStack bki) {
        EquipmentSlot aor4;
        if (integer == 98) {
            aor4 = EquipmentSlot.MAINHAND;
        }
        else if (integer == 99) {
            aor4 = EquipmentSlot.OFFHAND;
        }
        else if (integer == 100 + EquipmentSlot.HEAD.getIndex()) {
            aor4 = EquipmentSlot.HEAD;
        }
        else if (integer == 100 + EquipmentSlot.CHEST.getIndex()) {
            aor4 = EquipmentSlot.CHEST;
        }
        else if (integer == 100 + EquipmentSlot.LEGS.getIndex()) {
            aor4 = EquipmentSlot.LEGS;
        }
        else {
            if (integer != 100 + EquipmentSlot.FEET.getIndex()) {
                return false;
            }
            aor4 = EquipmentSlot.FEET;
        }
        if (bki.isEmpty() || isValidSlotForItem(aor4, bki) || aor4 == EquipmentSlot.HEAD) {
            this.setItemSlot(aor4, bki);
            return true;
        }
        return false;
    }
    
    @Override
    public boolean isControlledByLocalInstance() {
        return this.canBeControlledByRider() && super.isControlledByLocalInstance();
    }
    
    public static boolean isValidSlotForItem(final EquipmentSlot aor, final ItemStack bki) {
        final EquipmentSlot aor2 = getEquipmentSlotForItem(bki);
        return aor2 == aor || (aor2 == EquipmentSlot.MAINHAND && aor == EquipmentSlot.OFFHAND) || (aor2 == EquipmentSlot.OFFHAND && aor == EquipmentSlot.MAINHAND);
    }
    
    @Override
    public boolean isEffectiveAi() {
        return super.isEffectiveAi() && !this.isNoAi();
    }
    
    public void setNoAi(final boolean boolean1) {
        final byte byte3 = this.entityData.<Byte>get(Mob.DATA_MOB_FLAGS_ID);
        this.entityData.<Byte>set(Mob.DATA_MOB_FLAGS_ID, boolean1 ? ((byte)(byte3 | 0x1)) : ((byte)(byte3 & 0xFFFFFFFE)));
    }
    
    public void setLeftHanded(final boolean boolean1) {
        final byte byte3 = this.entityData.<Byte>get(Mob.DATA_MOB_FLAGS_ID);
        this.entityData.<Byte>set(Mob.DATA_MOB_FLAGS_ID, boolean1 ? ((byte)(byte3 | 0x2)) : ((byte)(byte3 & 0xFFFFFFFD)));
    }
    
    public void setAggressive(final boolean boolean1) {
        final byte byte3 = this.entityData.<Byte>get(Mob.DATA_MOB_FLAGS_ID);
        this.entityData.<Byte>set(Mob.DATA_MOB_FLAGS_ID, boolean1 ? ((byte)(byte3 | 0x4)) : ((byte)(byte3 & 0xFFFFFFFB)));
    }
    
    public boolean isNoAi() {
        return (this.entityData.<Byte>get(Mob.DATA_MOB_FLAGS_ID) & 0x1) != 0x0;
    }
    
    public boolean isLeftHanded() {
        return (this.entityData.<Byte>get(Mob.DATA_MOB_FLAGS_ID) & 0x2) != 0x0;
    }
    
    public boolean isAggressive() {
        return (this.entityData.<Byte>get(Mob.DATA_MOB_FLAGS_ID) & 0x4) != 0x0;
    }
    
    public void setBaby(final boolean boolean1) {
    }
    
    @Override
    public HumanoidArm getMainArm() {
        return this.isLeftHanded() ? HumanoidArm.LEFT : HumanoidArm.RIGHT;
    }
    
    @Override
    public boolean canAttack(final LivingEntity aoy) {
        return (aoy.getType() != EntityType.PLAYER || !((Player)aoy).abilities.invulnerable) && super.canAttack(aoy);
    }
    
    @Override
    public boolean doHurtTarget(final Entity aom) {
        float float3 = (float)this.getAttributeValue(Attributes.ATTACK_DAMAGE);
        float float4 = (float)this.getAttributeValue(Attributes.ATTACK_KNOCKBACK);
        if (aom instanceof LivingEntity) {
            float3 += EnchantmentHelper.getDamageBonus(this.getMainHandItem(), ((LivingEntity)aom).getMobType());
            float4 += EnchantmentHelper.getKnockbackBonus(this);
        }
        final int integer5 = EnchantmentHelper.getFireAspect(this);
        if (integer5 > 0) {
            aom.setSecondsOnFire(integer5 * 4);
        }
        final boolean boolean6 = aom.hurt(DamageSource.mobAttack(this), float3);
        if (boolean6) {
            if (float4 > 0.0f && aom instanceof LivingEntity) {
                ((LivingEntity)aom).knockback(float4 * 0.5f, Mth.sin(this.yRot * 0.017453292f), -Mth.cos(this.yRot * 0.017453292f));
                this.setDeltaMovement(this.getDeltaMovement().multiply(0.6, 1.0, 0.6));
            }
            if (aom instanceof Player) {
                final Player bec7 = (Player)aom;
                this.maybeDisableShield(bec7, this.getMainHandItem(), bec7.isUsingItem() ? bec7.getUseItem() : ItemStack.EMPTY);
            }
            this.doEnchantDamageEffects(this, aom);
            this.setLastHurtMob(aom);
        }
        return boolean6;
    }
    
    private void maybeDisableShield(final Player bec, final ItemStack bki2, final ItemStack bki3) {
        if (!bki2.isEmpty() && !bki3.isEmpty() && bki2.getItem() instanceof AxeItem && bki3.getItem() == Items.SHIELD) {
            final float float5 = 0.25f + EnchantmentHelper.getBlockEfficiency(this) * 0.05f;
            if (this.random.nextFloat() < float5) {
                bec.getCooldowns().addCooldown(Items.SHIELD, 100);
                this.level.broadcastEntityEvent(bec, (byte)30);
            }
        }
    }
    
    protected boolean isSunBurnTick() {
        if (this.level.isDay() && !this.level.isClientSide) {
            final float float2 = this.getBrightness();
            final BlockPos fu3 = (this.getVehicle() instanceof Boat) ? new BlockPos(this.getX(), (double)Math.round(this.getY()), this.getZ()).above() : new BlockPos(this.getX(), (double)Math.round(this.getY()), this.getZ());
            if (float2 > 0.5f && this.random.nextFloat() * 30.0f < (float2 - 0.4f) * 2.0f && this.level.canSeeSky(fu3)) {
                return true;
            }
        }
        return false;
    }
    
    @Override
    protected void jumpInLiquid(final net.minecraft.tags.Tag<Fluid> adf) {
        if (this.getNavigation().canFloat()) {
            super.jumpInLiquid(adf);
        }
        else {
            this.setDeltaMovement(this.getDeltaMovement().add(0.0, 0.3, 0.0));
        }
    }
    
    @Override
    protected void removeAfterChangingDimensions() {
        super.removeAfterChangingDimensions();
        this.dropLeash(true, false);
    }
    
    static {
        DATA_MOB_FLAGS_ID = SynchedEntityData.<Byte>defineId(Mob.class, EntityDataSerializers.BYTE);
    }
}
