package net.minecraft.world.entity.ai.behavior;

import net.minecraft.world.entity.LivingEntity;
import java.util.List;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.server.level.ServerLevel;
import java.util.Map;
import net.minecraft.world.entity.ai.memory.WalkTarget;
import com.google.common.collect.ImmutableMap;
import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.Mob;

public class BackUpIfTooClose<E extends Mob> extends Behavior<E> {
    private final int tooCloseDistance;
    private final float strafeSpeed;
    
    public BackUpIfTooClose(final int integer, final float float2) {
        super(ImmutableMap.<MemoryModuleType<WalkTarget>, MemoryStatus>of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, (MemoryModuleType<WalkTarget>)MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED, (MemoryModuleType<WalkTarget>)MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_PRESENT, (MemoryModuleType<WalkTarget>)MemoryModuleType.VISIBLE_LIVING_ENTITIES, MemoryStatus.VALUE_PRESENT));
        this.tooCloseDistance = integer;
        this.strafeSpeed = float2;
    }
    
    @Override
    protected boolean checkExtraStartConditions(final ServerLevel zd, final E aoz) {
        return this.isTargetVisible(aoz) && this.isTargetTooClose(aoz);
    }
    
    @Override
    protected void start(final ServerLevel zd, final E aoz, final long long3) {
        aoz.getBrain().<EntityTracker>setMemory((MemoryModuleType<EntityTracker>)MemoryModuleType.LOOK_TARGET, new EntityTracker(this.getTarget(aoz), true));
        aoz.getMoveControl().strafe(-this.strafeSpeed, 0.0f);
        aoz.yRot = Mth.rotateIfNecessary(aoz.yRot, aoz.yHeadRot, 0.0f);
    }
    
    private boolean isTargetVisible(final E aoz) {
        return aoz.getBrain().<List<LivingEntity>>getMemory(MemoryModuleType.VISIBLE_LIVING_ENTITIES).get().contains(this.getTarget(aoz));
    }
    
    private boolean isTargetTooClose(final E aoz) {
        return this.getTarget(aoz).closerThan(aoz, this.tooCloseDistance);
    }
    
    private LivingEntity getTarget(final E aoz) {
        return aoz.getBrain().<LivingEntity>getMemory(MemoryModuleType.ATTACK_TARGET).get();
    }
}
