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

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

import com.hypixel.hytale.server.npc.asset.builder.Builder;
import com.hypixel.hytale.server.npc.asset.builder.Feature;
import com.hypixel.hytale.server.npc.asset.builder.validators.StringNullOrNotEmptyValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleSingleValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.asset.FlockAssetExistsValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.AssetValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.StringValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.StringNotEmptyValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.IntArrayValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.IntSequenceValidator;
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.DoubleRangeValidator;
import com.google.gson.JsonElement;
import com.hypixel.hytale.server.npc.asset.builder.BuilderDescriptorState;
import com.hypixel.hytale.server.npc.corecomponents.lifecycle.ActionSpawn;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.npc.asset.builder.BuilderSupport;
import com.hypixel.hytale.server.npc.asset.builder.holder.DoubleHolder;
import com.hypixel.hytale.server.npc.asset.builder.holder.AssetHolder;
import com.hypixel.hytale.server.npc.asset.builder.holder.StringHolder;
import com.hypixel.hytale.server.npc.asset.builder.holder.NumberArrayHolder;
import com.hypixel.hytale.server.npc.asset.builder.holder.BooleanHolder;
import com.hypixel.hytale.server.npc.asset.builder.holder.FloatHolder;
import com.hypixel.hytale.server.npc.corecomponents.builders.BuilderActionBase;

public class BuilderActionSpawn extends BuilderActionBase
{
    public static final double[] DEFAULT_DISTANCE_RANGE;
    public static final int[] DEFAULT_COUNT_RANGE;
    public static final double[] DEFAULT_DELAY_RANGE;
    protected final FloatHolder spawnDirection;
    protected final FloatHolder spawnAngle;
    protected final BooleanHolder fanOut;
    protected final NumberArrayHolder distanceRange;
    protected final NumberArrayHolder countRange;
    protected final NumberArrayHolder delayRange;
    protected final StringHolder kind;
    protected final AssetHolder flock;
    protected final BooleanHolder launchAtTarget;
    protected final BooleanHolder pitchHigh;
    protected final DoubleHolder spread;
    protected final BooleanHolder joinFlock;
    protected final StringHolder spawnState;
    protected final StringHolder spawnSubState;
    
    public BuilderActionSpawn() {
        this.spawnDirection = new FloatHolder();
        this.spawnAngle = new FloatHolder();
        this.fanOut = new BooleanHolder();
        this.distanceRange = new NumberArrayHolder();
        this.countRange = new NumberArrayHolder();
        this.delayRange = new NumberArrayHolder();
        this.kind = new StringHolder();
        this.flock = new AssetHolder();
        this.launchAtTarget = new BooleanHolder();
        this.pitchHigh = new BooleanHolder();
        this.spread = new DoubleHolder();
        this.joinFlock = new BooleanHolder();
        this.spawnState = new StringHolder();
        this.spawnSubState = new StringHolder();
    }
    
    @Nonnull
    @Override
    public ActionSpawn build(@Nonnull final BuilderSupport builderSupport) {
        return new ActionSpawn(this, builderSupport);
    }
    
    @Nonnull
    @Override
    public String getShortDescription() {
        return "Spawn an NPC";
    }
    
    @Nonnull
    @Override
    public String getLongDescription() {
        return "Spawn an NPC";
    }
    
    @Nonnull
    @Override
    public BuilderDescriptorState getBuilderDescriptorState() {
        return BuilderDescriptorState.Experimental;
    }
    
    @Nonnull
    @Override
    public BuilderActionSpawn readConfig(@Nonnull final JsonElement data) {
        this.getFloat(data, "SpawnDirection", this.spawnDirection, 0.0, DoubleRangeValidator.between(-180.0, 180.0), BuilderDescriptorState.Experimental, "Direction of spawn cone relative to view direction (in degrees)", null);
        this.getFloat(data, "SpawnAngle", this.spawnAngle, 360.0, DoubleRangeValidator.between(0.0, 360.0), BuilderDescriptorState.Experimental, "Cone width of spawn direction (in degrees)", null);
        this.getBoolean(data, "FanOut", this.fanOut, false, BuilderDescriptorState.Experimental, "Fan NPCs out equally over angle", null);
        this.getDoubleRange(data, "DistanceRange", this.distanceRange, BuilderActionSpawn.DEFAULT_DISTANCE_RANGE, DoubleSequenceValidator.fromExclToInclWeaklyMonotonic(0.0, 128.0), BuilderDescriptorState.Stable, "Distance from spawner to spawn", null);
        this.getIntRange(data, "CountRange", this.countRange, BuilderActionSpawn.DEFAULT_COUNT_RANGE, IntSequenceValidator.fromExclToInclWeaklyMonotonic(0, 100), BuilderDescriptorState.Stable, "Number of NPCs to spawn", null);
        this.getDoubleRange(data, "DelayRange", this.delayRange, BuilderActionSpawn.DEFAULT_DELAY_RANGE, DoubleSequenceValidator.betweenWeaklyMonotonic(0.0, Double.MAX_VALUE), BuilderDescriptorState.Stable, "Time between consecutive spawns in seconds", null);
        this.requireString(data, "Kind", this.kind, StringNotEmptyValidator.get(), BuilderDescriptorState.Experimental, "NPC role to spawn", null);
        this.getAsset(data, "Flock", this.flock, null, FlockAssetExistsValidator.withConfig(AssetValidator.CanBeEmpty), BuilderDescriptorState.Stable, "Flock definition to spawn", null);
        this.getBoolean(data, "LaunchAtTarget", this.launchAtTarget, false, BuilderDescriptorState.WorkInProgress, "Launch the spawned NPC at target position/entity", null);
        this.getBoolean(data, "PitchHigh", this.pitchHigh, true, BuilderDescriptorState.Stable, "If launching at a target, use high pitch", null);
        this.getDouble(data, "LaunchSpread", this.spread, 0.0, DoubleSingleValidator.greaterEqual0(), BuilderDescriptorState.Stable, "The radius of the circle centred on the target within which to spread thrown NPCs", null);
        this.getBoolean(data, "JoinFlock", this.joinFlock, false, BuilderDescriptorState.Stable, "Whether to join the parent NPC's flock", null);
        this.getString(data, "SpawnState", this.spawnState, null, StringNullOrNotEmptyValidator.get(), BuilderDescriptorState.Stable, "An optional state to set on the spawned NPC if it exists", null);
        this.getString(data, "SpawnSubState", this.spawnSubState, null, StringNullOrNotEmptyValidator.get(), BuilderDescriptorState.Stable, "An optional substate to set on the spawned NPC if it exists", null);
        this.requireFeatureIf(this.launchAtTarget, true, Feature.AnyPosition);
        return this;
    }
    
    public float getSpawnDirection(@Nonnull final BuilderSupport support) {
        final float spawnDirection = this.spawnDirection.get(support.getExecutionContext());
        return 0.017453292f * ((spawnDirection < 0.0f) ? (spawnDirection + 6.2831855f) : spawnDirection);
    }
    
    public float getSpawnAngle(@Nonnull final BuilderSupport support) {
        return 0.017453292f * this.spawnAngle.get(support.getExecutionContext());
    }
    
    public boolean isFanOut(@Nonnull final BuilderSupport support) {
        return this.fanOut.get(support.getExecutionContext());
    }
    
    public double[] getDistanceRange(@Nonnull final BuilderSupport support) {
        return this.distanceRange.get(support.getExecutionContext());
    }
    
    public String getKind(@Nonnull final BuilderSupport support) {
        return this.kind.get(support.getExecutionContext());
    }
    
    public String getFlock(@Nonnull final BuilderSupport support) {
        return this.flock.get(support.getExecutionContext());
    }
    
    public int[] getCountRange(@Nonnull final BuilderSupport support) {
        return this.countRange.getIntArray(support.getExecutionContext());
    }
    
    public double[] getDelayRange(@Nonnull final BuilderSupport support) {
        return this.delayRange.get(support.getExecutionContext());
    }
    
    public boolean isLaunchAtTarget(@Nonnull final BuilderSupport support) {
        return this.launchAtTarget.get(support.getExecutionContext());
    }
    
    public boolean isPitchHigh(@Nonnull final BuilderSupport support) {
        return this.pitchHigh.get(support.getExecutionContext());
    }
    
    public double getSpread(@Nonnull final BuilderSupport support) {
        return this.spread.get(support.getExecutionContext());
    }
    
    public boolean isJoinFlock(@Nonnull final BuilderSupport support) {
        return this.joinFlock.get(support.getExecutionContext());
    }
    
    public String getSpawnState(@Nonnull final BuilderSupport support) {
        return this.spawnState.get(support.getExecutionContext());
    }
    
    public String getSpawnSubState(@Nonnull final BuilderSupport support) {
        return this.spawnSubState.get(support.getExecutionContext());
    }
    
    static {
        DEFAULT_DISTANCE_RANGE = new double[] { 1.0, 1.0 };
        DEFAULT_COUNT_RANGE = new int[] { 5, 5 };
        DEFAULT_DELAY_RANGE = new double[] { 0.25, 0.25 };
    }
}
