// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.npc.movement.steeringforces;

import com.hypixel.hytale.server.core.modules.physics.util.PhysicsMath;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.npc.movement.Steering;

public class SteeringForceEvade extends SteeringForceWithTarget
{
    private double slowdownDistance;
    private double stopDistance;
    private double falloff;
    private double squaredSlowdownDistance;
    private double squaredStopDistance;
    private double distanceDelta;
    private float directionHint;
    private boolean adhereToDirectionHint;
    
    public SteeringForceEvade() {
        this(20.0, 25.0);
    }
    
    public SteeringForceEvade(final double slowdownDistance, final double stopDistance) {
        this.falloff = 3.0;
        this.setDistances(slowdownDistance, stopDistance);
    }
    
    public void setDistances(final double min, final double max) {
        this.slowdownDistance = min;
        this.stopDistance = max;
        this.squaredSlowdownDistance = min * min;
        this.squaredStopDistance = max * max;
        this.distanceDelta = max - min;
    }
    
    public void setDirectionHint(final float heading) {
        this.directionHint = heading;
    }
    
    public void setAdhereToDirectionHint(final boolean adhereToDirectionHint) {
        this.adhereToDirectionHint = adhereToDirectionHint;
    }
    
    @Override
    public boolean compute(@Nonnull final Steering output) {
        if (!super.compute(output)) {
            return false;
        }
        output.setTranslation(this.selfPosition).getTranslation().subtract(this.targetPosition);
        final double distanceSquared = output.getTranslation().squaredLength();
        if (distanceSquared >= this.squaredStopDistance) {
            output.clear();
            return false;
        }
        output.clearRotation();
        if (distanceSquared < 1.0E-6) {
            output.setTranslation(PhysicsMath.headingX(this.directionHint), 0.0, PhysicsMath.headingZ(this.directionHint));
            return true;
        }
        if (this.adhereToDirectionHint) {
            output.setTranslation(PhysicsMath.headingX(this.directionHint), 0.0, PhysicsMath.headingZ(this.directionHint));
        }
        if (distanceSquared < this.squaredSlowdownDistance || this.distanceDelta == 0.0) {
            output.getTranslation().normalize();
            return true;
        }
        final double scale = Math.pow((this.stopDistance - Math.sqrt(distanceSquared)) / this.distanceDelta, 1.0 / this.falloff);
        output.getTranslation().setLength(scale);
        return true;
    }
    
    public double getSlowdownDistance() {
        return this.slowdownDistance;
    }
    
    public void setSlowdownDistance(final double slowdownDistance) {
        this.setDistances(slowdownDistance, this.getStopDistance());
    }
    
    public double getStopDistance() {
        return this.stopDistance;
    }
    
    public void setStopDistance(final double stopDistance) {
        this.setDistances(this.getSlowdownDistance(), stopDistance);
        this.stopDistance = stopDistance;
    }
    
    public double getFalloff() {
        return this.falloff;
    }
    
    public void setFalloff(final double falloff) {
        this.falloff = falloff;
    }
}
