package net.minecraft.world.entity.monster.piglin;

import net.minecraft.util.TimeUtil;
import net.minecraft.world.entity.EntitySelector;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.util.RandomPos;
import java.util.UUID;
import net.minecraft.world.entity.ai.behavior.RunSometimes;
import net.minecraft.world.entity.ai.memory.WalkTarget;
import net.minecraft.world.item.ArmorMaterials;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.entity.Mob;
import net.minecraft.tags.Tag;
import net.minecraft.tags.ItemTags;
import java.util.Random;
import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
import java.util.Iterator;
import net.minecraft.world.entity.ai.behavior.BehaviorUtils;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.entity.player.Player;
import java.util.Collections;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.monster.hoglin.Hoglin;
import net.minecraft.sounds.SoundEvent;
import java.util.function.Consumer;
import net.minecraft.world.entity.ai.behavior.CopyMemoryWithExpiry;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.ai.behavior.RunIf;
import net.minecraft.world.entity.ai.behavior.SetWalkTargetFromLookTarget;
import net.minecraft.world.entity.ai.behavior.InteractWith;
import net.minecraft.world.entity.ai.behavior.RunOne;
import java.util.function.BiPredicate;
import net.minecraft.world.entity.ai.behavior.DismountOrSkipMounting;
import net.minecraft.world.entity.ai.behavior.Mount;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ai.behavior.SetWalkTargetAwayFrom;
import java.util.List;
import net.minecraft.world.entity.ai.behavior.DoNothing;
import net.minecraft.world.entity.ai.behavior.RandomStroll;
import com.mojang.datafixers.util.Pair;
import net.minecraft.world.entity.ai.behavior.GoToCelebrateLocation;
import net.minecraft.world.entity.ai.behavior.CrossbowAttack;
import net.minecraft.world.entity.ai.behavior.MeleeAttack;
import net.minecraft.world.entity.ai.behavior.SetWalkTargetFromAttackTargetIfTargetOutOfReach;
import java.util.function.Predicate;
import net.minecraft.world.entity.ai.behavior.BackUpIfTooClose;
import net.minecraft.world.entity.ai.behavior.StopAttackingIfTargetInvalid;
import net.minecraft.world.entity.ai.behavior.SetLookAndInteract;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import java.util.Optional;
import java.util.function.Function;
import net.minecraft.world.entity.ai.behavior.SetEntityLookTarget;
import net.minecraft.world.entity.ai.behavior.Behavior;
import com.google.common.collect.ImmutableList;
import net.minecraft.world.entity.ai.behavior.StopBeingAngryIfTargetDead;
import net.minecraft.world.entity.ai.behavior.StartCelebratingIfTargetDead;
import net.minecraft.world.entity.ai.behavior.InteractWithDoor;
import net.minecraft.world.entity.ai.behavior.MoveToTargetSink;
import net.minecraft.world.entity.ai.behavior.LookAtTargetSink;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import com.google.common.collect.ImmutableSet;
import net.minecraft.world.entity.schedule.Activity;
import net.minecraft.world.entity.ai.Brain;
import java.util.Set;
import net.minecraft.util.IntRange;
import net.minecraft.world.item.Item;

public class PiglinAi {
    public static final Item BARTERING_ITEM;
    private static final IntRange TIME_BETWEEN_HUNTS;
    private static final IntRange RIDE_START_INTERVAL;
    private static final IntRange RIDE_DURATION;
    private static final IntRange RETREAT_DURATION;
    private static final IntRange AVOID_ZOMBIFIED_DURATION;
    private static final IntRange BABY_AVOID_NEMESIS_DURATION;
    private static final Set<Item> FOOD_ITEMS;
    
    protected static Brain<?> makeBrain(final Piglin bdc, final Brain<Piglin> apr) {
        initCoreActivity(apr);
        initIdleActivity(apr);
        initAdmireItemActivity(apr);
        initFightActivity(bdc, apr);
        initCelebrateActivity(apr);
        initRetreatActivity(apr);
        initRideHoglinActivity(apr);
        apr.setCoreActivities(ImmutableSet.<Activity>of(Activity.CORE));
        apr.setDefaultActivity(Activity.IDLE);
        apr.useDefaultActivity();
        return apr;
    }
    
    protected static void initMemories(final Piglin bdc) {
        final int integer2 = PiglinAi.TIME_BETWEEN_HUNTS.randomValue(bdc.level.random);
        bdc.getBrain().<Boolean>setMemoryWithExpiry(MemoryModuleType.HUNTED_RECENTLY, true, integer2);
    }
    
    private static void initCoreActivity(final Brain<Piglin> apr) {
        apr.addActivity(Activity.CORE, 0, ImmutableList.of(new LookAtTargetSink(45, 90), new MoveToTargetSink(200), new InteractWithDoor(), babyAvoidNemesis(), avoidZombified(), new StopHoldingItemIfNoLongerAdmiring(), new StartAdmiringItemIfSeen(120), new StartCelebratingIfTargetDead(300, PiglinAi::wantsToDance), new StopBeingAngryIfTargetDead()));
    }
    
    private static void initIdleActivity(final Brain<Piglin> apr) {
        apr.addActivity(Activity.IDLE, 10, ImmutableList.of(new SetEntityLookTarget(PiglinAi::isPlayerHoldingLovedItem, 14.0f), new Behavior(Piglin::isAdult, PiglinAi::findNearestValidAttackTarget), new Behavior(Piglin::canHunt, new StartHuntingHoglin<>()), avoidRepellent(), babySometimesRideBabyHoglin(), createIdleLookBehaviors(), createIdleMovementBehaviors(), new SetLookAndInteract(EntityType.PLAYER, 4)));
    }
    
    private static void initFightActivity(final Piglin bdc, final Brain<Piglin> apr) {
        apr.addActivityAndRemoveMemoryWhenStopped(Activity.FIGHT, 10, ImmutableList.of(new StopAttackingIfTargetInvalid(aoy -> !isNearestValidAttackTarget(bdc, aoy)), new Behavior(PiglinAi::hasCrossbow, new BackUpIfTooClose<>(5, 0.75f)), new SetWalkTargetFromAttackTargetIfTargetOutOfReach(1.0f), new MeleeAttack(20), new CrossbowAttack(), new RememberIfHoglinWasKilled(), new Behavior(PiglinAi::isNearZombified, MemoryModuleType.ATTACK_TARGET)), MemoryModuleType.ATTACK_TARGET);
    }
    
    private static void initCelebrateActivity(final Brain<Piglin> apr) {
        apr.addActivityAndRemoveMemoryWhenStopped(Activity.CELEBRATE, 10, ImmutableList.of(avoidRepellent(), new SetEntityLookTarget(PiglinAi::isPlayerHoldingLovedItem, 14.0f), new Behavior(Piglin::isAdult, PiglinAi::findNearestValidAttackTarget), new Behavior(bdc -> !bdc.isDancing(), new GoToCelebrateLocation<>(2, 1.0f)), new Behavior(Piglin::isDancing, new GoToCelebrateLocation<>(4, 0.6f)), new Behavior(ImmutableList.of(Pair.of(new SetEntityLookTarget(EntityType.PIGLIN, 8.0f), 1), Pair.of(new RandomStroll(0.6f, 2, 1), 1), Pair.of(new DoNothing(10, 20), 1)))), MemoryModuleType.CELEBRATE_LOCATION);
    }
    
    private static void initAdmireItemActivity(final Brain<Piglin> apr) {
        apr.addActivityAndRemoveMemoryWhenStopped(Activity.ADMIRE_ITEM, 10, ImmutableList.of(new Behavior(PiglinAi::isNotHoldingLovedItemInOffHand, 1.0f, true, 9), new StopAdmiringIfItemTooFarAway(9)), MemoryModuleType.ADMIRING_ITEM);
    }
    
    private static void initRetreatActivity(final Brain<Piglin> apr) {
        apr.addActivityAndRemoveMemoryWhenStopped(Activity.AVOID, 10, ImmutableList.of(SetWalkTargetAwayFrom.entity(MemoryModuleType.AVOID_TARGET, 1.0f, 12, true), createIdleLookBehaviors(), createIdleMovementBehaviors(), new Behavior(PiglinAi::wantsToStopFleeing, MemoryModuleType.AVOID_TARGET)), MemoryModuleType.AVOID_TARGET);
    }
    
    private static void initRideHoglinActivity(final Brain<Piglin> apr) {
        apr.addActivityAndRemoveMemoryWhenStopped(Activity.RIDE, 10, ImmutableList.of(new Mount(0.8f), new SetEntityLookTarget(PiglinAi::isPlayerHoldingLovedItem, 8.0f), new Behavior(Entity::isPassenger, createIdleLookBehaviors()), new DismountOrSkipMounting(8, (BiPredicate<E, Entity>)PiglinAi::wantsToStopRiding)), MemoryModuleType.RIDE_TARGET);
    }
    
    private static RunOne<Piglin> createIdleLookBehaviors() {
        return new RunOne<Piglin>(ImmutableList.of(Pair.of(new SetEntityLookTarget(EntityType.PLAYER, 8.0f), 1), Pair.of(new SetEntityLookTarget(EntityType.PIGLIN, 8.0f), 1), Pair.of(new SetEntityLookTarget(8.0f), 1), Pair.of(new DoNothing(30, 60), 1)));
    }
    
    private static RunOne<Piglin> createIdleMovementBehaviors() {
        return new RunOne<Piglin>(ImmutableList.of(Pair.of(new RandomStroll(0.6f), 2), Pair.of(InteractWith.<LivingEntity>of(EntityType.PIGLIN, 8, MemoryModuleType.INTERACTION_TARGET, 0.6f, 2), 2), Pair.of(new RunIf(PiglinAi::doesntSeeAnyPlayerHoldingLovedItem, new SetWalkTargetFromLookTarget(0.6f, 3)), 2), Pair.of(new DoNothing(30, 60), 1)));
    }
    
    private static SetWalkTargetAwayFrom<BlockPos> avoidRepellent() {
        return SetWalkTargetAwayFrom.pos(MemoryModuleType.NEAREST_REPELLENT, 1.0f, 8, false);
    }
    
    private static CopyMemoryWithExpiry<Piglin, LivingEntity> babyAvoidNemesis() {
        return new CopyMemoryWithExpiry<Piglin, LivingEntity>(Piglin::isBaby, MemoryModuleType.NEAREST_VISIBLE_NEMESIS, MemoryModuleType.AVOID_TARGET, PiglinAi.BABY_AVOID_NEMESIS_DURATION);
    }
    
    private static CopyMemoryWithExpiry<Piglin, LivingEntity> avoidZombified() {
        return new CopyMemoryWithExpiry<Piglin, LivingEntity>(PiglinAi::isNearZombified, MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED, MemoryModuleType.AVOID_TARGET, PiglinAi.AVOID_ZOMBIFIED_DURATION);
    }
    
    protected static void updateActivity(final Piglin bdc) {
        final Brain<Piglin> apr2 = bdc.getBrain();
        final Activity bfl3 = apr2.getActiveNonCoreActivity().orElse(null);
        apr2.setActiveActivityToFirstValid(ImmutableList.<Activity>of(Activity.ADMIRE_ITEM, Activity.FIGHT, Activity.AVOID, Activity.CELEBRATE, Activity.RIDE, Activity.IDLE));
        final Activity bfl4 = apr2.getActiveNonCoreActivity().orElse(null);
        if (bfl3 != bfl4) {
            getSoundForCurrentActivity(bdc).ifPresent(bdc::playSound);
        }
        bdc.setAggressive(apr2.hasMemoryValue(MemoryModuleType.ATTACK_TARGET));
        if (!apr2.hasMemoryValue(MemoryModuleType.RIDE_TARGET) && isBabyRidingBaby(bdc)) {
            bdc.stopRiding();
        }
        if (!apr2.hasMemoryValue(MemoryModuleType.CELEBRATE_LOCATION)) {
            apr2.<Boolean>eraseMemory(MemoryModuleType.DANCING);
        }
        bdc.setDancing(apr2.hasMemoryValue(MemoryModuleType.DANCING));
    }
    
    private static boolean isBabyRidingBaby(final Piglin bdc) {
        if (!bdc.isBaby()) {
            return false;
        }
        final Entity aom2 = bdc.getVehicle();
        return (aom2 instanceof Piglin && ((Piglin)aom2).isBaby()) || (aom2 instanceof Hoglin && ((Hoglin)aom2).isBaby());
    }
    
    protected static void pickUpItem(final Piglin bdc, final ItemEntity bbg) {
        stopWalking(bdc);
        ItemStack bki3;
        if (bbg.getItem().getItem() == Items.GOLD_NUGGET) {
            bdc.take(bbg, bbg.getItem().getCount());
            bki3 = bbg.getItem();
            bbg.remove();
        }
        else {
            bdc.take(bbg, 1);
            bki3 = removeOneItemFromItemEntity(bbg);
        }
        final Item bke4 = bki3.getItem();
        if (isLovedItem(bke4)) {
            holdInOffhand(bdc, bki3);
            admireGoldItem(bdc);
            return;
        }
        if (isFood(bke4) && !hasEatenRecently(bdc)) {
            eat(bdc);
            return;
        }
        final boolean boolean5 = bdc.equipItemIfPossible(bki3);
        if (boolean5) {
            return;
        }
        putInInventory(bdc, bki3);
    }
    
    private static void holdInOffhand(final Piglin bdc, final ItemStack bki) {
        if (isHoldingItemInOffHand(bdc)) {
            bdc.spawnAtLocation(bdc.getItemInHand(InteractionHand.OFF_HAND));
        }
        bdc.holdInOffHand(bki);
    }
    
    private static ItemStack removeOneItemFromItemEntity(final ItemEntity bbg) {
        final ItemStack bki2 = bbg.getItem();
        final ItemStack bki3 = bki2.split(1);
        if (bki2.isEmpty()) {
            bbg.remove();
        }
        else {
            bbg.setItem(bki2);
        }
        return bki3;
    }
    
    protected static void stopHoldingOffHandItem(final Piglin bdc, final boolean boolean2) {
        final ItemStack bki3 = bdc.getItemInHand(InteractionHand.OFF_HAND);
        bdc.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
        if (bdc.isAdult()) {
            final boolean boolean3 = isBarterCurrency(bki3.getItem());
            if (boolean2 && boolean3) {
                throwItems(bdc, getBarterResponseItems(bdc));
            }
            else if (!boolean3) {
                final boolean boolean4 = bdc.equipItemIfPossible(bki3);
                if (!boolean4) {
                    putInInventory(bdc, bki3);
                }
            }
        }
        else {
            final boolean boolean3 = bdc.equipItemIfPossible(bki3);
            if (!boolean3) {
                final ItemStack bki4 = bdc.getMainHandItem();
                if (isLovedItem(bki4.getItem())) {
                    putInInventory(bdc, bki4);
                }
                else {
                    throwItems(bdc, Collections.<ItemStack>singletonList(bki4));
                }
                bdc.holdInMainHand(bki3);
            }
        }
    }
    
    protected static void cancelAdmiring(final Piglin bdc) {
        if (isAdmiringItem(bdc) && !bdc.getOffhandItem().isEmpty()) {
            bdc.spawnAtLocation(bdc.getOffhandItem());
            bdc.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
        }
    }
    
    private static void putInInventory(final Piglin bdc, final ItemStack bki) {
        final ItemStack bki2 = bdc.addToInventory(bki);
        throwItemsTowardRandomPos(bdc, Collections.<ItemStack>singletonList(bki2));
    }
    
    private static void throwItems(final Piglin bdc, final List<ItemStack> list) {
        final Optional<Player> optional3 = bdc.getBrain().<Player>getMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER);
        if (optional3.isPresent()) {
            throwItemsTowardPlayer(bdc, optional3.get(), list);
        }
        else {
            throwItemsTowardRandomPos(bdc, list);
        }
    }
    
    private static void throwItemsTowardRandomPos(final Piglin bdc, final List<ItemStack> list) {
        throwItemsTowardPos(bdc, list, getRandomNearbyPos(bdc));
    }
    
    private static void throwItemsTowardPlayer(final Piglin bdc, final Player bec, final List<ItemStack> list) {
        throwItemsTowardPos(bdc, list, bec.position());
    }
    
    private static void throwItemsTowardPos(final Piglin bdc, final List<ItemStack> list, final Vec3 dem) {
        if (!list.isEmpty()) {
            bdc.swing(InteractionHand.OFF_HAND);
            for (final ItemStack bki5 : list) {
                BehaviorUtils.throwItem(bdc, bki5, dem.add(0.0, 1.0, 0.0));
            }
        }
    }
    
    private static List<ItemStack> getBarterResponseItems(final Piglin bdc) {
        final LootTable daw2 = bdc.level.getServer().getLootTables().get(BuiltInLootTables.PIGLIN_BARTERING);
        final List<ItemStack> list3 = daw2.getRandomItems(new LootContext.Builder((ServerLevel)bdc.level).<Entity>withParameter(LootContextParams.THIS_ENTITY, bdc).withRandom(bdc.level.random).create(LootContextParamSets.PIGLIN_BARTER));
        return list3;
    }
    
    private static boolean wantsToDance(final LivingEntity aoy1, final LivingEntity aoy2) {
        return aoy2.getType() == EntityType.HOGLIN && new Random(aoy1.level.getGameTime()).nextFloat() < 0.1f;
    }
    
    protected static boolean wantsToPickup(final Piglin bdc, final ItemStack bki) {
        final Item bke3 = bki.getItem();
        if (bke3.is(ItemTags.PIGLIN_REPELLENTS)) {
            return false;
        }
        if (isAdmiringDisabled(bdc) && bdc.getBrain().hasMemoryValue(MemoryModuleType.ATTACK_TARGET)) {
            return false;
        }
        if (isBarterCurrency(bke3)) {
            return isNotHoldingLovedItemInOffHand(bdc);
        }
        final boolean boolean4 = bdc.canAddToInventory(bki);
        if (bke3 == Items.GOLD_NUGGET) {
            return boolean4;
        }
        if (isFood(bke3)) {
            return !hasEatenRecently(bdc) && boolean4;
        }
        if (isLovedItem(bke3)) {
            return isNotHoldingLovedItemInOffHand(bdc) && boolean4;
        }
        return bdc.canReplaceCurrentItem(bki);
    }
    
    protected static boolean isLovedItem(final Item bke) {
        return bke.is(ItemTags.PIGLIN_LOVED);
    }
    
    private static boolean wantsToStopRiding(final Piglin bdc, final Entity aom) {
        if (aom instanceof Mob) {
            final Mob aoz3 = (Mob)aom;
            return !aoz3.isBaby() || !aoz3.isAlive() || wasHurtRecently(bdc) || wasHurtRecently(aoz3) || (aoz3 instanceof Piglin && aoz3.getVehicle() == null);
        }
        return false;
    }
    
    private static boolean isNearestValidAttackTarget(final Piglin bdc, final LivingEntity aoy) {
        return findNearestValidAttackTarget(bdc).filter(aoy2 -> aoy2 == aoy).isPresent();
    }
    
    private static boolean isNearZombified(final Piglin bdc) {
        final Brain<Piglin> apr2 = bdc.getBrain();
        if (apr2.hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED)) {
            final LivingEntity aoy3 = apr2.<LivingEntity>getMemory(MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED).get();
            return bdc.closerThan(aoy3, 6.0);
        }
        return false;
    }
    
    private static Optional<? extends LivingEntity> findNearestValidAttackTarget(final Piglin bdc) {
        final Brain<Piglin> apr2 = bdc.getBrain();
        if (isNearZombified(bdc)) {
            return Optional.empty();
        }
        final Optional<LivingEntity> optional3 = BehaviorUtils.getLivingEntityFromUUIDMemory(bdc, MemoryModuleType.ANGRY_AT);
        if (optional3.isPresent() && isAttackAllowed(optional3.get())) {
            return optional3;
        }
        if (apr2.hasMemoryValue(MemoryModuleType.UNIVERSAL_ANGER)) {
            final Optional<Player> optional4 = apr2.<Player>getMemory(MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER);
            if (optional4.isPresent()) {
                return optional4;
            }
        }
        final Optional<Mob> optional5 = apr2.<Mob>getMemory(MemoryModuleType.NEAREST_VISIBLE_NEMESIS);
        if (optional5.isPresent()) {
            return optional5;
        }
        final Optional<Player> optional6 = apr2.<Player>getMemory(MemoryModuleType.NEAREST_TARGETABLE_PLAYER_NOT_WEARING_GOLD);
        if (optional6.isPresent() && isAttackAllowed(optional6.get())) {
            return optional6;
        }
        return Optional.empty();
    }
    
    public static void angerNearbyPiglins(final Player bec, final boolean boolean2) {
        final List<Piglin> list3 = bec.level.<Piglin>getEntitiesOfClass(Piglin.class, bec.getBoundingBox().inflate(16.0));
        list3.stream().filter(PiglinAi::isIdle).filter(bdc -> !boolean2 || BehaviorUtils.canSee(bdc, bec)).forEach(bdc -> {
            if (bdc.level.getGameRules().getBoolean(GameRules.RULE_UNIVERSAL_ANGER)) {
                setAngerTargetToNearestTargetablePlayerIfFound(bdc, bec);
            }
            else {
                setAngerTarget(bdc, bec);
            }
        });
    }
    
    public static InteractionResult mobInteract(final Piglin bdc, final Player bec, final InteractionHand anf) {
        final ItemStack bki4 = bec.getItemInHand(anf);
        if (canAdmire(bdc, bki4)) {
            final ItemStack bki5 = bki4.split(1);
            holdInOffhand(bdc, bki5);
            admireGoldItem(bdc);
            stopWalking(bdc);
            return InteractionResult.CONSUME;
        }
        return InteractionResult.PASS;
    }
    
    protected static boolean canAdmire(final Piglin bdc, final ItemStack bki) {
        return !isAdmiringDisabled(bdc) && !isAdmiringItem(bdc) && bdc.isAdult() && isBarterCurrency(bki.getItem());
    }
    
    protected static void wasHurtBy(final Piglin bdc, final LivingEntity aoy) {
        if (aoy instanceof Piglin) {
            return;
        }
        if (isHoldingItemInOffHand(bdc)) {
            stopHoldingOffHandItem(bdc, false);
        }
        final Brain<Piglin> apr3 = bdc.getBrain();
        apr3.<BlockPos>eraseMemory(MemoryModuleType.CELEBRATE_LOCATION);
        apr3.<Boolean>eraseMemory(MemoryModuleType.DANCING);
        apr3.<Boolean>eraseMemory(MemoryModuleType.ADMIRING_ITEM);
        if (aoy instanceof Player) {
            apr3.<Boolean>setMemoryWithExpiry(MemoryModuleType.ADMIRING_DISABLED, true, 400L);
        }
        final Brain brain;
        getAvoidTarget(bdc).ifPresent(aoy3 -> {
            if (aoy3.getType() != aoy.getType()) {
                brain.eraseMemory(MemoryModuleType.AVOID_TARGET);
            }
            return;
        });
        if (bdc.isBaby()) {
            apr3.<LivingEntity>setMemoryWithExpiry(MemoryModuleType.AVOID_TARGET, aoy, 100L);
            if (isAttackAllowed(aoy)) {
                broadcastAngerTarget(bdc, aoy);
            }
            return;
        }
        if (aoy.getType() == EntityType.HOGLIN && hoglinsOutnumberPiglins(bdc)) {
            setAvoidTargetAndDontHuntForAWhile(bdc, aoy);
            broadcastRetreat(bdc, aoy);
            return;
        }
        maybeRetaliate(bdc, aoy);
    }
    
    private static void maybeRetaliate(final Piglin bdc, final LivingEntity aoy) {
        if (bdc.getBrain().isActive(Activity.AVOID)) {
            return;
        }
        if (!isAttackAllowed(aoy)) {
            return;
        }
        if (BehaviorUtils.isOtherTargetMuchFurtherAwayThanCurrentAttackTarget(bdc, aoy, 4.0)) {
            return;
        }
        if (aoy.getType() == EntityType.PLAYER && bdc.level.getGameRules().getBoolean(GameRules.RULE_UNIVERSAL_ANGER)) {
            setAngerTargetToNearestTargetablePlayerIfFound(bdc, aoy);
            broadcastUniversalAnger(bdc);
        }
        else {
            setAngerTarget(bdc, aoy);
            broadcastAngerTarget(bdc, aoy);
        }
    }
    
    public static Optional<SoundEvent> getSoundForCurrentActivity(final Piglin bdc) {
        return bdc.getBrain().getActiveNonCoreActivity().<SoundEvent>map(bfl -> getSoundForActivity(bdc, bfl));
    }
    
    private static SoundEvent getSoundForActivity(final Piglin bdc, final Activity bfl) {
        if (bfl == Activity.FIGHT) {
            return SoundEvents.PIGLIN_ANGRY;
        }
        if (bdc.isConverting()) {
            return SoundEvents.PIGLIN_RETREAT;
        }
        if (bfl == Activity.AVOID && isNearAvoidTarget(bdc)) {
            return SoundEvents.PIGLIN_RETREAT;
        }
        if (bfl == Activity.ADMIRE_ITEM) {
            return SoundEvents.PIGLIN_ADMIRING_ITEM;
        }
        if (bfl == Activity.CELEBRATE) {
            return SoundEvents.PIGLIN_CELEBRATE;
        }
        if (seesPlayerHoldingLovedItem(bdc)) {
            return SoundEvents.PIGLIN_JEALOUS;
        }
        if (isNearRepellent(bdc)) {
            return SoundEvents.PIGLIN_RETREAT;
        }
        return SoundEvents.PIGLIN_AMBIENT;
    }
    
    private static boolean isNearAvoidTarget(final Piglin bdc) {
        final Brain<Piglin> apr2 = bdc.getBrain();
        return apr2.hasMemoryValue(MemoryModuleType.AVOID_TARGET) && apr2.<LivingEntity>getMemory(MemoryModuleType.AVOID_TARGET).get().closerThan(bdc, 12.0);
    }
    
    protected static boolean hasAnyoneNearbyHuntedRecently(final Piglin bdc) {
        return bdc.getBrain().hasMemoryValue(MemoryModuleType.HUNTED_RECENTLY) || getVisibleAdultPiglins(bdc).stream().anyMatch(bdc -> bdc.getBrain().hasMemoryValue(MemoryModuleType.HUNTED_RECENTLY));
    }
    
    private static List<Piglin> getVisibleAdultPiglins(final Piglin bdc) {
        return bdc.getBrain().<List<Piglin>>getMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLINS).orElse(ImmutableList.of());
    }
    
    private static List<Piglin> getAdultPiglins(final Piglin bdc) {
        return bdc.getBrain().<List<Piglin>>getMemory(MemoryModuleType.NEAREST_ADULT_PIGLINS).orElse(ImmutableList.of());
    }
    
    public static boolean isWearingGold(final LivingEntity aoy) {
        final Iterable<ItemStack> iterable2 = aoy.getArmorSlots();
        for (final ItemStack bki4 : iterable2) {
            final Item bke5 = bki4.getItem();
            if (bke5 instanceof ArmorItem && ((ArmorItem)bke5).getMaterial() == ArmorMaterials.GOLD) {
                return true;
            }
        }
        return false;
    }
    
    private static void stopWalking(final Piglin bdc) {
        bdc.getBrain().<WalkTarget>eraseMemory(MemoryModuleType.WALK_TARGET);
        bdc.getNavigation().stop();
    }
    
    private static RunSometimes<Piglin> babySometimesRideBabyHoglin() {
        return new RunSometimes<Piglin>(new CopyMemoryWithExpiry(Piglin::isBaby, MemoryModuleType.NEAREST_VISIBLE_BABY_HOGLIN, (MemoryModuleType<Object>)MemoryModuleType.RIDE_TARGET, PiglinAi.RIDE_DURATION), PiglinAi.RIDE_START_INTERVAL);
    }
    
    protected static void broadcastAngerTarget(final Piglin bdc, final LivingEntity aoy) {
        getAdultPiglins(bdc).forEach(bdc -> {
            if (aoy.getType() != EntityType.HOGLIN || (bdc.canHunt() && ((Hoglin)aoy).canBeHunted())) {
                setAngerTargetIfCloserThanCurrent(bdc, aoy);
            }
        });
    }
    
    protected static void broadcastUniversalAnger(final Piglin bdc) {
        getAdultPiglins(bdc).forEach(bdc -> getNearestVisibleTargetablePlayer(bdc).ifPresent(bec -> setAngerTarget(bdc, bec)));
    }
    
    protected static void broadcastDontKillAnyMoreHoglinsForAWhile(final Piglin bdc) {
        getVisibleAdultPiglins(bdc).forEach(PiglinAi::dontKillAnyMoreHoglinsForAWhile);
    }
    
    protected static void setAngerTarget(final Piglin bdc, final LivingEntity aoy) {
        if (!isAttackAllowed(aoy)) {
            return;
        }
        bdc.getBrain().<Long>eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
        bdc.getBrain().<UUID>setMemoryWithExpiry(MemoryModuleType.ANGRY_AT, aoy.getUUID(), 600L);
        if (aoy.getType() == EntityType.HOGLIN) {
            dontKillAnyMoreHoglinsForAWhile(bdc);
        }
        if (aoy.getType() == EntityType.PLAYER && bdc.level.getGameRules().getBoolean(GameRules.RULE_UNIVERSAL_ANGER)) {
            bdc.getBrain().<Boolean>setMemoryWithExpiry(MemoryModuleType.UNIVERSAL_ANGER, true, 600L);
        }
    }
    
    private static void setAngerTargetToNearestTargetablePlayerIfFound(final Piglin bdc, final LivingEntity aoy) {
        final Optional<Player> optional3 = getNearestVisibleTargetablePlayer(bdc);
        if (optional3.isPresent()) {
            setAngerTarget(bdc, optional3.get());
        }
        else {
            setAngerTarget(bdc, aoy);
        }
    }
    
    private static void setAngerTargetIfCloserThanCurrent(final Piglin bdc, final LivingEntity aoy) {
        final Optional<LivingEntity> optional3 = getAngerTarget(bdc);
        final LivingEntity aoy2 = BehaviorUtils.getNearestTarget(bdc, optional3, aoy);
        if (optional3.isPresent() && optional3.get() == aoy2) {
            return;
        }
        setAngerTarget(bdc, aoy2);
    }
    
    private static Optional<LivingEntity> getAngerTarget(final Piglin bdc) {
        return BehaviorUtils.getLivingEntityFromUUIDMemory(bdc, MemoryModuleType.ANGRY_AT);
    }
    
    public static Optional<LivingEntity> getAvoidTarget(final Piglin bdc) {
        if (bdc.getBrain().hasMemoryValue(MemoryModuleType.AVOID_TARGET)) {
            return bdc.getBrain().<LivingEntity>getMemory(MemoryModuleType.AVOID_TARGET);
        }
        return Optional.<LivingEntity>empty();
    }
    
    public static Optional<Player> getNearestVisibleTargetablePlayer(final Piglin bdc) {
        if (bdc.getBrain().hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER)) {
            return bdc.getBrain().<Player>getMemory(MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER);
        }
        return Optional.<Player>empty();
    }
    
    private static void broadcastRetreat(final Piglin bdc, final LivingEntity aoy) {
        getVisibleAdultPiglins(bdc).forEach(bdc -> retreatFromNearestTarget(bdc, aoy));
    }
    
    private static void retreatFromNearestTarget(final Piglin bdc, final LivingEntity aoy) {
        final Brain<Piglin> apr3 = bdc.getBrain();
        LivingEntity aoy2 = aoy;
        aoy2 = BehaviorUtils.getNearestTarget(bdc, apr3.<LivingEntity>getMemory(MemoryModuleType.AVOID_TARGET), aoy2);
        aoy2 = BehaviorUtils.getNearestTarget(bdc, apr3.<LivingEntity>getMemory(MemoryModuleType.ATTACK_TARGET), aoy2);
        setAvoidTargetAndDontHuntForAWhile(bdc, aoy2);
    }
    
    private static boolean wantsToStopFleeing(final Piglin bdc) {
        final Brain<Piglin> apr2 = bdc.getBrain();
        if (!apr2.hasMemoryValue(MemoryModuleType.AVOID_TARGET)) {
            return true;
        }
        final LivingEntity aoy3 = apr2.<LivingEntity>getMemory(MemoryModuleType.AVOID_TARGET).get();
        final EntityType<?> aoq4 = aoy3.getType();
        if (aoq4 == EntityType.HOGLIN) {
            return piglinsEqualOrOutnumberHoglins(bdc);
        }
        return isZombified(aoq4) && !apr2.<LivingEntity>isMemoryValue(MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED, aoy3);
    }
    
    private static boolean piglinsEqualOrOutnumberHoglins(final Piglin bdc) {
        return !hoglinsOutnumberPiglins(bdc);
    }
    
    private static boolean hoglinsOutnumberPiglins(final Piglin bdc) {
        final int integer2 = bdc.getBrain().<Integer>getMemory(MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT).orElse(0) + 1;
        final int integer3 = bdc.getBrain().<Integer>getMemory(MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT).orElse(0);
        return integer3 > integer2;
    }
    
    private static void setAvoidTargetAndDontHuntForAWhile(final Piglin bdc, final LivingEntity aoy) {
        bdc.getBrain().<UUID>eraseMemory(MemoryModuleType.ANGRY_AT);
        bdc.getBrain().<LivingEntity>eraseMemory(MemoryModuleType.ATTACK_TARGET);
        bdc.getBrain().<WalkTarget>eraseMemory(MemoryModuleType.WALK_TARGET);
        bdc.getBrain().<LivingEntity>setMemoryWithExpiry(MemoryModuleType.AVOID_TARGET, aoy, PiglinAi.RETREAT_DURATION.randomValue(bdc.level.random));
        dontKillAnyMoreHoglinsForAWhile(bdc);
    }
    
    protected static void dontKillAnyMoreHoglinsForAWhile(final Piglin bdc) {
        bdc.getBrain().<Boolean>setMemoryWithExpiry(MemoryModuleType.HUNTED_RECENTLY, true, PiglinAi.TIME_BETWEEN_HUNTS.randomValue(bdc.level.random));
    }
    
    private static void eat(final Piglin bdc) {
        bdc.getBrain().<Boolean>setMemoryWithExpiry(MemoryModuleType.ATE_RECENTLY, true, 200L);
    }
    
    private static Vec3 getRandomNearbyPos(final Piglin bdc) {
        final Vec3 dem2 = RandomPos.getLandPos(bdc, 4, 2);
        return (dem2 == null) ? bdc.position() : dem2;
    }
    
    private static boolean hasEatenRecently(final Piglin bdc) {
        return bdc.getBrain().hasMemoryValue(MemoryModuleType.ATE_RECENTLY);
    }
    
    protected static boolean isIdle(final Piglin bdc) {
        return bdc.getBrain().isActive(Activity.IDLE);
    }
    
    private static boolean hasCrossbow(final LivingEntity aoy) {
        return aoy.isHolding(Items.CROSSBOW);
    }
    
    private static void admireGoldItem(final LivingEntity aoy) {
        aoy.getBrain().<Boolean>setMemoryWithExpiry(MemoryModuleType.ADMIRING_ITEM, true, 120L);
    }
    
    private static boolean isAdmiringItem(final Piglin bdc) {
        return bdc.getBrain().hasMemoryValue(MemoryModuleType.ADMIRING_ITEM);
    }
    
    private static boolean isBarterCurrency(final Item bke) {
        return bke == PiglinAi.BARTERING_ITEM;
    }
    
    private static boolean isFood(final Item bke) {
        return PiglinAi.FOOD_ITEMS.contains(bke);
    }
    
    private static boolean isAttackAllowed(final LivingEntity aoy) {
        return EntitySelector.ATTACK_ALLOWED.test(aoy);
    }
    
    private static boolean isNearRepellent(final Piglin bdc) {
        return bdc.getBrain().hasMemoryValue(MemoryModuleType.NEAREST_REPELLENT);
    }
    
    private static boolean seesPlayerHoldingLovedItem(final LivingEntity aoy) {
        return aoy.getBrain().hasMemoryValue(MemoryModuleType.NEAREST_PLAYER_HOLDING_WANTED_ITEM);
    }
    
    private static boolean doesntSeeAnyPlayerHoldingLovedItem(final LivingEntity aoy) {
        return !seesPlayerHoldingLovedItem(aoy);
    }
    
    public static boolean isPlayerHoldingLovedItem(final LivingEntity aoy) {
        return aoy.getType() == EntityType.PLAYER && aoy.isHolding(PiglinAi::isLovedItem);
    }
    
    private static boolean isAdmiringDisabled(final Piglin bdc) {
        return bdc.getBrain().hasMemoryValue(MemoryModuleType.ADMIRING_DISABLED);
    }
    
    private static boolean wasHurtRecently(final LivingEntity aoy) {
        return aoy.getBrain().hasMemoryValue(MemoryModuleType.HURT_BY);
    }
    
    private static boolean isHoldingItemInOffHand(final Piglin bdc) {
        return !bdc.getOffhandItem().isEmpty();
    }
    
    private static boolean isNotHoldingLovedItemInOffHand(final Piglin bdc) {
        return bdc.getOffhandItem().isEmpty() || !isLovedItem(bdc.getOffhandItem().getItem());
    }
    
    public static boolean isZombified(final EntityType aoq) {
        return aoq == EntityType.ZOMBIFIED_PIGLIN || aoq == EntityType.ZOGLIN;
    }
    
    static {
        BARTERING_ITEM = Items.GOLD_INGOT;
        TIME_BETWEEN_HUNTS = TimeUtil.rangeOfSeconds(30, 120);
        RIDE_START_INTERVAL = TimeUtil.rangeOfSeconds(10, 40);
        RIDE_DURATION = TimeUtil.rangeOfSeconds(10, 30);
        RETREAT_DURATION = TimeUtil.rangeOfSeconds(5, 20);
        AVOID_ZOMBIFIED_DURATION = TimeUtil.rangeOfSeconds(5, 7);
        BABY_AVOID_NEMESIS_DURATION = TimeUtil.rangeOfSeconds(5, 7);
        FOOD_ITEMS = ImmutableSet.<Item>of(Items.PORKCHOP, Items.COOKED_PORKCHOP);
    }
}
