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

package com.hypixel.hytale.server.npc.corecomponents.movement.builders;

import com.hypixel.hytale.server.npc.asset.builder.Builder;
import com.hypixel.hytale.server.npc.asset.builder.validators.RelationalOperator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleRangeValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleArrayValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleSequenceValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleSingleValidator;
import com.google.gson.JsonElement;
import com.hypixel.hytale.server.npc.asset.builder.BuilderDescriptorState;
import com.hypixel.hytale.server.npc.corecomponents.movement.BodyMotionMoveAway;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.npc.asset.builder.BuilderSupport;
import com.hypixel.hytale.server.npc.asset.builder.holder.NumberArrayHolder;
import com.hypixel.hytale.server.npc.asset.builder.holder.DoubleHolder;

public class BuilderBodyMotionMoveAway extends BuilderBodyMotionFindWithTarget
{
    private static final double[] DEFAULT_HOLD_DIRECTION_DURATION_RANGE;
    protected final DoubleHolder slowdownDistance;
    protected final DoubleHolder stopDistance;
    protected final DoubleHolder falloff;
    protected final NumberArrayHolder holdDirectionDurationRange;
    protected final DoubleHolder changeDirectionViewSector;
    protected final DoubleHolder directionJitter;
    protected final DoubleHolder erraticDistance;
    protected final DoubleHolder erraticExtraJitter;
    protected final DoubleHolder erraticChangeDurationMultiplier;
    
    public BuilderBodyMotionMoveAway() {
        this.slowdownDistance = new DoubleHolder();
        this.stopDistance = new DoubleHolder();
        this.falloff = new DoubleHolder();
        this.holdDirectionDurationRange = new NumberArrayHolder();
        this.changeDirectionViewSector = new DoubleHolder();
        this.directionJitter = new DoubleHolder();
        this.erraticDistance = new DoubleHolder();
        this.erraticExtraJitter = new DoubleHolder();
        this.erraticChangeDurationMultiplier = new DoubleHolder();
    }
    
    @Nonnull
    @Override
    public BodyMotionMoveAway build(@Nonnull final BuilderSupport builderSupport) {
        return new BodyMotionMoveAway(this, builderSupport);
    }
    
    @Nonnull
    @Override
    public String getShortDescription() {
        return "Move away from target";
    }
    
    @Nonnull
    @Override
    public String getLongDescription() {
        return "Move away from a target using path finding or steering";
    }
    
    @Nonnull
    @Override
    public BuilderDescriptorState getBuilderDescriptorState() {
        return BuilderDescriptorState.Experimental;
    }
    
    @Nonnull
    @Override
    public BuilderBodyMotionMoveAway readConfig(@Nonnull final JsonElement data) {
        super.readConfig(data);
        this.getDouble(data, "SlowDownDistance", this.slowdownDistance, 8.0, DoubleSingleValidator.greater0(), BuilderDescriptorState.Stable, "Distance from target when NPC should start to slowdown", null);
        this.getDouble(data, "StopDistance", this.stopDistance, 10.0, DoubleSingleValidator.greater0(), BuilderDescriptorState.Stable, "Distance from target when NPC should halt", null);
        this.getDouble(data, "Falloff", this.falloff, 3.0, DoubleSingleValidator.greater0(), BuilderDescriptorState.Stable, "Rate how fast the slowdown should happen relative to distance", null);
        this.getDoubleRange(data, "HoldDirectionTimeRange", this.holdDirectionDurationRange, BuilderBodyMotionMoveAway.DEFAULT_HOLD_DIRECTION_DURATION_RANGE, DoubleSequenceValidator.betweenWeaklyMonotonic(0.0, Double.MAX_VALUE), BuilderDescriptorState.Stable, "How often to change heading", null);
        this.getDouble(data, "ChangeDirectionViewSector", this.changeDirectionViewSector, 230.0, DoubleRangeValidator.between(0.0, 360.0), BuilderDescriptorState.Stable, "The view sector the NPC uses to decide if it should switch direction", null);
        this.getDouble(data, "DirectionJitter", this.directionJitter, 45.0, DoubleRangeValidator.between(0.0, 180.0), BuilderDescriptorState.Stable, "How much jitter in degrees to add to the heading the NPC uses", null);
        this.getDouble(data, "ErraticDistance", this.erraticDistance, 4.0, DoubleSingleValidator.greater0(), BuilderDescriptorState.Stable, "If the player is closer than this distance, the NPC will behave more erratically using the additional jitter parameter", null);
        this.getDouble(data, "ErraticExtraJitter", this.erraticExtraJitter, 45.0, DoubleRangeValidator.between(0.0, 180.0), BuilderDescriptorState.Stable, "Extra jitter to add to the NPC heading on top of the standard when the target is too close", null);
        this.getDouble(data, "ErraticChangeDurationMultiplier", this.erraticChangeDurationMultiplier, 0.5, DoubleRangeValidator.fromExclToIncl(0.0, 1.0), BuilderDescriptorState.Stable, "A multiplier to decrease the duration between direction changes when the target is too close", null);
        this.validateDoubleRelation(this.slowdownDistance, RelationalOperator.LessEqual, this.stopDistance);
        return this;
    }
    
    public double getSlowdownDistance(@Nonnull final BuilderSupport support) {
        return this.slowdownDistance.get(support.getExecutionContext());
    }
    
    public double getStopDistance(@Nonnull final BuilderSupport support) {
        return this.stopDistance.get(support.getExecutionContext());
    }
    
    public double getFalloff(@Nonnull final BuilderSupport support) {
        return this.falloff.get(support.getExecutionContext());
    }
    
    public double[] getHoldDirectionDurationRange(@Nonnull final BuilderSupport support) {
        return this.holdDirectionDurationRange.get(support.getExecutionContext());
    }
    
    public float getChangeDirectionViewSectorRadians(@Nonnull final BuilderSupport support) {
        return (float)(this.changeDirectionViewSector.get(support.getExecutionContext()) * 0.01745329238474369);
    }
    
    public float getDirectionJitterRadians(@Nonnull final BuilderSupport support) {
        return (float)(this.directionJitter.get(support.getExecutionContext()) * 0.01745329238474369);
    }
    
    public double getErraticDistance(@Nonnull final BuilderSupport support) {
        return this.erraticDistance.get(support.getExecutionContext());
    }
    
    public float getErraticExtraJitterRadians(@Nonnull final BuilderSupport support) {
        return (float)(this.erraticExtraJitter.get(support.getExecutionContext()) * 0.01745329238474369);
    }
    
    public double getErraticChangeDurationMultiplier(@Nonnull final BuilderSupport support) {
        return this.erraticChangeDurationMultiplier.get(support.getExecutionContext());
    }
    
    static {
        DEFAULT_HOLD_DIRECTION_DURATION_RANGE = new double[] { 2.0, 5.0 };
    }
}
