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

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

import com.hypixel.hytale.math.vector.Vector3d;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.npc.movement.Steering;

public class SteeringForcePursue extends SteeringForceWithTarget
{
    private double stopDistance;
    private double slowdownDistance;
    private double falloff;
    private double invFalloff;
    private double squaredStopDistance;
    private double squaredSlowdownDistance;
    private double distanceDelta;
    
    public SteeringForcePursue() {
        this(20.0, 25.0);
    }
    
    public SteeringForcePursue(final double stopDistance, final double slowdownDistance) {
        this.falloff = 3.0;
        this.invFalloff = 1.0 / this.falloff;
        this.setDistances(stopDistance, slowdownDistance);
    }
    
    public void setDistances(final double slowdown, final double stop) {
        this.stopDistance = stop;
        this.slowdownDistance = slowdown;
        this.squaredStopDistance = stop * stop;
        this.squaredSlowdownDistance = slowdown * slowdown;
        this.distanceDelta = slowdown - stop;
    }
    
    @Override
    public boolean compute(@Nonnull final Steering output) {
        if (!super.compute(output)) {
            return false;
        }
        output.setTranslation(this.targetPosition);
        final Vector3d translation = output.getTranslation();
        translation.subtract(this.selfPosition);
        final double distanceSquared = translation.squaredLength();
        if (distanceSquared <= this.squaredStopDistance) {
            output.clear();
            return false;
        }
        final double distance = Math.sqrt(distanceSquared);
        if (distanceSquared >= this.squaredSlowdownDistance) {
            translation.scale(1.0 / distance);
            output.clearRotation();
            return true;
        }
        final double scale = Math.pow((distance - this.stopDistance) / this.distanceDelta, this.invFalloff);
        translation.setLength(scale);
        output.clearRotation();
        return true;
    }
    
    public double getStopDistance() {
        return this.stopDistance;
    }
    
    public void setStopDistance(final double stopDistance) {
        this.setDistances(this.getSlowdownDistance(), stopDistance);
    }
    
    public double getSlowdownDistance() {
        return this.slowdownDistance;
    }
    
    public void setSlowdownDistance(final double slowdownDistance) {
        this.setDistances(slowdownDistance, this.getStopDistance());
    }
    
    public double getFalloff() {
        return this.falloff;
    }
    
    public void setFalloff(final double falloff) {
        this.falloff = falloff;
        this.invFalloff = 1.0 / falloff;
    }
}
