package net.minecraft.world.entity.animal;

import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.world.entity.AgableMob;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.monster.ZombifiedPiglin;
import net.minecraft.world.Difficulty;
import net.minecraft.world.entity.LightningBolt;
import net.minecraft.world.phys.AABB;
import com.google.common.collect.UnmodifiableIterator;
import net.minecraft.core.Vec3i;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.vehicle.DismountHelper;
import net.minecraft.core.Direction;
import net.minecraft.world.phys.Vec3;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.BlockPos;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.nbt.CompoundTag;
import javax.annotation.Nullable;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal;
import net.minecraft.world.entity.ai.goal.FollowParentGoal;
import net.minecraft.world.entity.ai.goal.TemptGoal;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.entity.ai.goal.BreedGoal;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.goal.PanicGoal;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.goal.FloatGoal;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ItemBasedSteering;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.world.entity.Saddleable;
import net.minecraft.world.entity.ItemSteerable;

public class Pig extends Animal implements ItemSteerable, Saddleable {
    private static final EntityDataAccessor<Boolean> DATA_SADDLE_ID;
    private static final EntityDataAccessor<Integer> DATA_BOOST_TIME;
    private static final Ingredient FOOD_ITEMS;
    private final ItemBasedSteering steering;
    
    public Pig(final EntityType<? extends Pig> aoq, final Level bqb) {
        super(aoq, bqb);
        this.steering = new ItemBasedSteering(this.entityData, Pig.DATA_BOOST_TIME, Pig.DATA_SADDLE_ID);
    }
    
    @Override
    protected void registerGoals() {
        this.goalSelector.addGoal(0, new FloatGoal(this));
        this.goalSelector.addGoal(1, new PanicGoal(this, 1.25));
        this.goalSelector.addGoal(3, new BreedGoal(this, 1.0));
        this.goalSelector.addGoal(4, new TemptGoal(this, 1.2, Ingredient.of(Items.CARROT_ON_A_STICK), false));
        this.goalSelector.addGoal(4, new TemptGoal(this, 1.2, false, Pig.FOOD_ITEMS));
        this.goalSelector.addGoal(5, new FollowParentGoal(this, 1.1));
        this.goalSelector.addGoal(6, new WaterAvoidingRandomStrollGoal(this, 1.0));
        this.goalSelector.addGoal(7, new LookAtPlayerGoal(this, Player.class, 6.0f));
        this.goalSelector.addGoal(8, new RandomLookAroundGoal(this));
    }
    
    public static AttributeSupplier.Builder createAttributes() {
        return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0).add(Attributes.MOVEMENT_SPEED, 0.25);
    }
    
    @Nullable
    @Override
    public Entity getControllingPassenger() {
        if (this.getPassengers().isEmpty()) {
            return null;
        }
        return this.getPassengers().get(0);
    }
    
    @Override
    public boolean canBeControlledByRider() {
        final Entity aom2 = this.getControllingPassenger();
        if (!(aom2 instanceof Player)) {
            return false;
        }
        final Player bec3 = (Player)aom2;
        return bec3.getMainHandItem().getItem() == Items.CARROT_ON_A_STICK || bec3.getOffhandItem().getItem() == Items.CARROT_ON_A_STICK;
    }
    
    @Override
    public void onSyncedDataUpdated(final EntityDataAccessor<?> tq) {
        if (Pig.DATA_BOOST_TIME.equals(tq) && this.level.isClientSide) {
            this.steering.onSynced();
        }
        super.onSyncedDataUpdated(tq);
    }
    
    @Override
    protected void defineSynchedData() {
        super.defineSynchedData();
        this.entityData.<Boolean>define(Pig.DATA_SADDLE_ID, false);
        this.entityData.<Integer>define(Pig.DATA_BOOST_TIME, 0);
    }
    
    @Override
    public void addAdditionalSaveData(final CompoundTag le) {
        super.addAdditionalSaveData(le);
        this.steering.addAdditionalSaveData(le);
    }
    
    @Override
    public void readAdditionalSaveData(final CompoundTag le) {
        super.readAdditionalSaveData(le);
        this.steering.readAdditionalSaveData(le);
    }
    
    @Override
    protected SoundEvent getAmbientSound() {
        return SoundEvents.PIG_AMBIENT;
    }
    
    @Override
    protected SoundEvent getHurtSound(final DamageSource anw) {
        return SoundEvents.PIG_HURT;
    }
    
    @Override
    protected SoundEvent getDeathSound() {
        return SoundEvents.PIG_DEATH;
    }
    
    @Override
    protected void playStepSound(final BlockPos fu, final BlockState cfj) {
        this.playSound(SoundEvents.PIG_STEP, 0.15f, 1.0f);
    }
    
    @Override
    public InteractionResult mobInteract(final Player bec, final InteractionHand anf) {
        final boolean boolean4 = this.isFood(bec.getItemInHand(anf));
        if (!boolean4 && this.isSaddled() && !this.isVehicle()) {
            if (!this.level.isClientSide) {
                bec.startRiding(this);
            }
            return InteractionResult.sidedSuccess(this.level.isClientSide);
        }
        final InteractionResult ang5 = super.mobInteract(bec, anf);
        if (ang5.consumesAction()) {
            return ang5;
        }
        final ItemStack bki6 = bec.getItemInHand(anf);
        if (bki6.getItem() == Items.SADDLE) {
            return bki6.interactLivingEntity(bec, this, anf);
        }
        return InteractionResult.PASS;
    }
    
    @Override
    public boolean isSaddleable() {
        return this.isAlive() && !this.isBaby();
    }
    
    @Override
    protected void dropEquipment() {
        super.dropEquipment();
        if (this.isSaddled()) {
            this.spawnAtLocation(Items.SADDLE);
        }
    }
    
    @Override
    public boolean isSaddled() {
        return this.steering.hasSaddle();
    }
    
    @Override
    public void equipSaddle(@Nullable final SoundSource acm) {
        this.steering.setSaddle(true);
        if (acm != null) {
            this.level.playSound(null, this, SoundEvents.PIG_SADDLE, acm, 0.5f, 1.0f);
        }
    }
    
    @Override
    public Vec3 getDismountLocationForPassenger(final LivingEntity aoy) {
        final Direction fz3 = this.getMotionDirection();
        if (fz3.getAxis() == Direction.Axis.Y) {
            return super.getDismountLocationForPassenger(aoy);
        }
        final int[][] arr4 = DismountHelper.offsetsForDirection(fz3);
        final BlockPos fu5 = this.blockPosition();
        final BlockPos.MutableBlockPos a6 = new BlockPos.MutableBlockPos();
        for (final Pose apj8 : aoy.getDismountPoses()) {
            final AABB deg9 = aoy.getLocalBoundsForPose(apj8);
            for (final int[] arr5 : arr4) {
                a6.set(fu5.getX() + arr5[0], fu5.getY(), fu5.getZ() + arr5[1]);
                final double double14 = this.level.getRelativeFloorHeight(a6);
                if (DismountHelper.isFloorValid(double14)) {
                    final Vec3 dem16 = Vec3.upFromBottomCenterOf(a6, double14);
                    if (DismountHelper.canDismountTo(this.level, aoy, deg9.move(dem16))) {
                        aoy.setPose(apj8);
                        return dem16;
                    }
                }
            }
        }
        return super.getDismountLocationForPassenger(aoy);
    }
    
    @Override
    public void thunderHit(final LightningBolt aox) {
        if (this.level.getDifficulty() != Difficulty.PEACEFUL) {
            final ZombifiedPiglin bcw3 = EntityType.ZOMBIFIED_PIGLIN.create(this.level);
            bcw3.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.GOLDEN_SWORD));
            bcw3.moveTo(this.getX(), this.getY(), this.getZ(), this.yRot, this.xRot);
            bcw3.setNoAi(this.isNoAi());
            bcw3.setBaby(this.isBaby());
            if (this.hasCustomName()) {
                bcw3.setCustomName(this.getCustomName());
                bcw3.setCustomNameVisible(this.isCustomNameVisible());
            }
            bcw3.setPersistenceRequired();
            this.level.addFreshEntity(bcw3);
            this.remove();
        }
        else {
            super.thunderHit(aox);
        }
    }
    
    @Override
    public void travel(final Vec3 dem) {
        this.travel(this, this.steering, dem);
    }
    
    @Override
    public float getSteeringSpeed() {
        return (float)this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 0.225f;
    }
    
    @Override
    public void travelWithInput(final Vec3 dem) {
        super.travel(dem);
    }
    
    @Override
    public boolean boost() {
        return this.steering.boost(this.getRandom());
    }
    
    @Override
    public Pig getBreedOffspring(final AgableMob aok) {
        return EntityType.PIG.create(this.level);
    }
    
    @Override
    public boolean isFood(final ItemStack bki) {
        return Pig.FOOD_ITEMS.test(bki);
    }
    
    @Override
    public Vec3 getLeashOffset() {
        return new Vec3(0.0, 0.6f * this.getEyeHeight(), this.getBbWidth() * 0.4f);
    }
    
    static {
        DATA_SADDLE_ID = SynchedEntityData.<Boolean>defineId(Pig.class, EntityDataSerializers.BOOLEAN);
        DATA_BOOST_TIME = SynchedEntityData.<Integer>defineId(Pig.class, EntityDataSerializers.INT);
        FOOD_ITEMS = Ingredient.of(Items.CARROT, Items.POTATO, Items.BEETROOT);
    }
}
