package net.minecraft.world.entity.monster;

import java.util.EnumSet;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.ai.goal.RandomStrollGoal;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.entity.MobType;
import java.util.Random;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.InfestedBlock;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.damagesource.EntityDamageSource;
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.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.goal.MeleeAttackGoal;
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;

public class Silverfish extends Monster {
    private SilverfishWakeUpFriendsGoal friendsGoal;
    
    public Silverfish(final EntityType<? extends Silverfish> aoq, final Level bqb) {
        super(aoq, bqb);
    }
    
    @Override
    protected void registerGoals() {
        this.friendsGoal = new SilverfishWakeUpFriendsGoal(this);
        this.goalSelector.addGoal(1, new FloatGoal(this));
        this.goalSelector.addGoal(3, this.friendsGoal);
        this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0, false));
        this.goalSelector.addGoal(5, new SilverfishMergeWithStoneGoal(this));
        this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0]).setAlertOthers(new Class[0]));
        this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
    }
    
    @Override
    public double getMyRidingOffset() {
        return 0.1;
    }
    
    @Override
    protected float getStandingEyeHeight(final Pose apj, final EntityDimensions aon) {
        return 0.13f;
    }
    
    public static AttributeSupplier.Builder createAttributes() {
        return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 8.0).add(Attributes.MOVEMENT_SPEED, 0.25).add(Attributes.ATTACK_DAMAGE, 1.0);
    }
    
    @Override
    protected boolean isMovementNoisy() {
        return false;
    }
    
    @Override
    protected SoundEvent getAmbientSound() {
        return SoundEvents.SILVERFISH_AMBIENT;
    }
    
    @Override
    protected SoundEvent getHurtSound(final DamageSource anw) {
        return SoundEvents.SILVERFISH_HURT;
    }
    
    @Override
    protected SoundEvent getDeathSound() {
        return SoundEvents.SILVERFISH_DEATH;
    }
    
    @Override
    protected void playStepSound(final BlockPos fu, final BlockState cfj) {
        this.playSound(SoundEvents.SILVERFISH_STEP, 0.15f, 1.0f);
    }
    
    @Override
    public boolean hurt(final DamageSource anw, final float float2) {
        if (this.isInvulnerableTo(anw)) {
            return false;
        }
        if ((anw instanceof EntityDamageSource || anw == DamageSource.MAGIC) && this.friendsGoal != null) {
            this.friendsGoal.notifyHurt();
        }
        return super.hurt(anw, float2);
    }
    
    @Override
    public void tick() {
        this.yBodyRot = this.yRot;
        super.tick();
    }
    
    @Override
    public void setYBodyRot(final float float1) {
        super.setYBodyRot(this.yRot = float1);
    }
    
    @Override
    public float getWalkTargetValue(final BlockPos fu, final LevelReader bqd) {
        if (InfestedBlock.isCompatibleHostBlock(bqd.getBlockState(fu.below()))) {
            return 10.0f;
        }
        return super.getWalkTargetValue(fu, bqd);
    }
    
    public static boolean checkSliverfishSpawnRules(final EntityType<Silverfish> aoq, final LevelAccessor bqc, final MobSpawnType apb, final BlockPos fu, final Random random) {
        if (Monster.checkAnyLightMonsterSpawnRules(aoq, bqc, apb, fu, random)) {
            final Player bec6 = bqc.getNearestPlayer(fu.getX() + 0.5, fu.getY() + 0.5, fu.getZ() + 0.5, 5.0, true);
            return bec6 == null;
        }
        return false;
    }
    
    @Override
    public MobType getMobType() {
        return MobType.ARTHROPOD;
    }
    
    static class SilverfishWakeUpFriendsGoal extends Goal {
        private final Silverfish silverfish;
        private int lookForFriends;
        
        public SilverfishWakeUpFriendsGoal(final Silverfish bci) {
            this.silverfish = bci;
        }
        
        public void notifyHurt() {
            if (this.lookForFriends == 0) {
                this.lookForFriends = 20;
            }
        }
        
        @Override
        public boolean canUse() {
            return this.lookForFriends > 0;
        }
        
        @Override
        public void tick() {
            --this.lookForFriends;
            Label_0237: {
                if (this.lookForFriends <= 0) {
                    final Level bqb2 = this.silverfish.level;
                    final Random random3 = this.silverfish.getRandom();
                    final BlockPos fu4 = this.silverfish.blockPosition();
                    for (int integer5 = 0; integer5 <= 5 && integer5 >= -5; integer5 = ((integer5 <= 0) ? 1 : 0) - integer5) {
                        for (int integer6 = 0; integer6 <= 10 && integer6 >= -10; integer6 = ((integer6 <= 0) ? 1 : 0) - integer6) {
                            for (int integer7 = 0; integer7 <= 10 && integer7 >= -10; integer7 = ((integer7 <= 0) ? 1 : 0) - integer7) {
                                final BlockPos fu5 = fu4.offset(integer6, integer5, integer7);
                                final BlockState cfj9 = bqb2.getBlockState(fu5);
                                final Block bvr10 = cfj9.getBlock();
                                if (bvr10 instanceof InfestedBlock) {
                                    if (bqb2.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
                                        bqb2.destroyBlock(fu5, true, this.silverfish);
                                    }
                                    else {
                                        bqb2.setBlock(fu5, ((InfestedBlock)bvr10).getHostBlock().defaultBlockState(), 3);
                                    }
                                    if (random3.nextBoolean()) {
                                        break Label_0237;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    static class SilverfishMergeWithStoneGoal extends RandomStrollGoal {
        private Direction selectedDirection;
        private boolean doMerge;
        
        public SilverfishMergeWithStoneGoal(final Silverfish bci) {
            super(bci, 1.0, 10);
            this.setFlags(EnumSet.<Flag>of(Flag.MOVE));
        }
        
        @Override
        public boolean canUse() {
            if (this.mob.getTarget() != null) {
                return false;
            }
            if (!this.mob.getNavigation().isDone()) {
                return false;
            }
            final Random random2 = this.mob.getRandom();
            if (this.mob.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && random2.nextInt(10) == 0) {
                this.selectedDirection = Direction.getRandom(random2);
                final BlockPos fu3 = new BlockPos(this.mob.getX(), this.mob.getY() + 0.5, this.mob.getZ()).relative(this.selectedDirection);
                final BlockState cfj4 = this.mob.level.getBlockState(fu3);
                if (InfestedBlock.isCompatibleHostBlock(cfj4)) {
                    return this.doMerge = true;
                }
            }
            this.doMerge = false;
            return super.canUse();
        }
        
        @Override
        public boolean canContinueToUse() {
            return !this.doMerge && super.canContinueToUse();
        }
        
        @Override
        public void start() {
            if (!this.doMerge) {
                super.start();
                return;
            }
            final LevelAccessor bqc2 = this.mob.level;
            final BlockPos fu3 = new BlockPos(this.mob.getX(), this.mob.getY() + 0.5, this.mob.getZ()).relative(this.selectedDirection);
            final BlockState cfj4 = bqc2.getBlockState(fu3);
            if (InfestedBlock.isCompatibleHostBlock(cfj4)) {
                bqc2.setBlock(fu3, InfestedBlock.stateByHostBlock(cfj4.getBlock()), 3);
                this.mob.spawnAnim();
                this.mob.remove();
            }
        }
    }
}
