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

package com.hypixel.hytale.builtin.npccombatactionevaluator.evaluator.combatactions;

import com.hypixel.hytale.codec.codecs.EnumCodec;
import com.hypixel.hytale.assetstore.AssetKeyValidator;
import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
import com.hypixel.hytale.assetstore.codec.AssetCodec;
import com.hypixel.hytale.assetstore.codec.ContainedAssetCodec;
import com.hypixel.hytale.codec.validation.Validator;
import com.hypixel.hytale.codec.validation.Validators;
import com.hypixel.hytale.codec.KeyedCodec;
import javax.annotation.Nonnull;
import java.util.Arrays;
import com.hypixel.hytale.server.npc.valuestore.ValueStore;
import com.hypixel.hytale.builtin.npccombatactionevaluator.evaluator.CombatActionEvaluator;
import com.hypixel.hytale.server.npc.role.Role;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ArchetypeChunk;
import javax.annotation.Nullable;
import com.hypixel.hytale.assetstore.AssetRegistry;
import com.hypixel.hytale.assetstore.AssetExtraInfo;
import com.hypixel.hytale.assetstore.AssetStore;
import com.hypixel.hytale.codec.validation.ValidatorCache;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.assetstore.codec.AssetCodecMapCodec;
import com.hypixel.hytale.assetstore.map.IndexedLookupTableAssetMap;
import com.hypixel.hytale.assetstore.map.JsonAssetWithMap;
import com.hypixel.hytale.server.npc.decisionmaker.core.Option;

public abstract class CombatActionOption extends Option implements JsonAssetWithMap<String, IndexedLookupTableAssetMap<String, CombatActionOption>>
{
    public static final AssetCodecMapCodec<String, CombatActionOption> CODEC;
    public static final BuilderCodec<CombatActionOption> BASE_CODEC;
    public static final Codec<String> CHILD_ASSET_CODEC;
    public static final Codec<String[]> CHILD_ASSET_CODEC_ARRAY;
    public static final ValidatorCache<String> VALIDATOR_CACHE;
    private static AssetStore<String, CombatActionOption, IndexedLookupTableAssetMap<String, CombatActionOption>> ASSET_STORE;
    protected AssetExtraInfo.Data extraData;
    protected String id;
    protected Target actionTarget;
    protected double[] postExecuteDistanceRange;
    
    public static AssetStore<String, CombatActionOption, IndexedLookupTableAssetMap<String, CombatActionOption>> getAssetStore() {
        if (CombatActionOption.ASSET_STORE == null) {
            CombatActionOption.ASSET_STORE = AssetRegistry.getAssetStore(CombatActionOption.class);
        }
        return CombatActionOption.ASSET_STORE;
    }
    
    public static IndexedLookupTableAssetMap<String, CombatActionOption> getAssetMap() {
        return getAssetStore().getAssetMap();
    }
    
    protected CombatActionOption() {
    }
    
    @Override
    public String getId() {
        return this.id;
    }
    
    public Target getActionTarget() {
        return this.actionTarget;
    }
    
    @Nullable
    public double[] getPostExecuteDistanceRange() {
        return this.postExecuteDistanceRange;
    }
    
    public abstract void execute(final int p0, final ArchetypeChunk<EntityStore> p1, final CommandBuffer<EntityStore> p2, final Role p3, final CombatActionEvaluator p4, final ValueStore p5);
    
    public abstract boolean isBasicAttackAllowed(final int p0, final ArchetypeChunk<EntityStore> p1, final CommandBuffer<EntityStore> p2, final CombatActionEvaluator p3);
    
    public boolean cancelBasicAttackOnSelect() {
        return true;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "CombatActionOption{extraData=" + String.valueOf(this.extraData) + ", id='" + this.id + "', actionTarget=" + String.valueOf(this.actionTarget) + ", postExecuteDistanceRange=" + Arrays.toString(this.postExecuteDistanceRange) + "}" + super.toString();
    }
    
    @Nonnull
    public static CombatActionOption getNothingFor(final String id) {
        return new Nothing(id);
    }
    
    static {
        CODEC = new AssetCodecMapCodec<String, CombatActionOption>((Codec<String>)Codec.STRING, (t, k) -> t.id = k, t -> t.id, (t, data) -> t.extraData = data, t -> t.extraData);
        BASE_CODEC = BuilderCodec.abstractBuilder(CombatActionOption.class, Option.ABSTRACT_CODEC).appendInherited(new KeyedCodec<Target>("Target", Target.CODEC), (option, e) -> option.actionTarget = e, option -> option.actionTarget, (option, parent) -> option.actionTarget = parent.actionTarget).addValidator(Validators.nonNull()).documentation("The target type this action applies to.").add().appendInherited(new KeyedCodec("PostExecuteDistanceRange", Codec.DOUBLE_ARRAY), (option, o) -> option.postExecuteDistanceRange = o, option -> option.postExecuteDistanceRange, (option, parent) -> option.postExecuteDistanceRange = parent.postExecuteDistanceRange).addValidator(Validators.doubleArraySize(2)).addValidator(Validators.weaklyMonotonicSequentialDoubleArrayValidator()).documentation("An optional range the NPC will try to maintain from the target after executing the combat action.").add().build();
        CHILD_ASSET_CODEC = new ContainedAssetCodec<String, Object, Object>(CombatActionOption.class, CombatActionOption.CODEC);
        CHILD_ASSET_CODEC_ARRAY = new ArrayCodec<String>(CombatActionOption.CHILD_ASSET_CODEC, String[]::new);
        VALIDATOR_CACHE = new ValidatorCache<String>(new AssetKeyValidator<String>(CombatActionOption::getAssetStore));
        CombatActionOption.CODEC.register("State", StateCombatAction.class, StateCombatAction.CODEC);
        CombatActionOption.CODEC.register("Ability", AbilityCombatAction.class, AbilityCombatAction.CODEC);
        CombatActionOption.CODEC.register("SelectBasicAttackTarget", BasicAttackTargetCombatAction.class, BasicAttackTargetCombatAction.CODEC);
    }
    
    public enum Target
    {
        Self, 
        Hostile, 
        Friendly;
        
        public static final EnumCodec<Target> CODEC;
        
        static {
            CODEC = new EnumCodec<Target>(Target.class).documentKey(Target.Self, "Action targets self.").documentKey(Target.Hostile, "Action targets any hostile target.").documentKey(Target.Friendly, "Action targets any friendly target.");
        }
    }
    
    private static class Nothing extends CombatActionOption
    {
        private final String id;
        
        public Nothing(final String id) {
            this.id = id;
            this.actionTarget = Target.Self;
        }
        
        @Override
        public String getId() {
            return this.id;
        }
        
        @Override
        public void execute(final int index, final ArchetypeChunk<EntityStore> archetypeChunk, final CommandBuffer<EntityStore> commandBuffer, final Role role, final CombatActionEvaluator evaluator, final ValueStore valueStore) {
        }
        
        @Override
        public boolean isBasicAttackAllowed(final int selfIndex, final ArchetypeChunk<EntityStore> archetypeChunk, final CommandBuffer<EntityStore> commandBuffer, final CombatActionEvaluator evaluator) {
            return true;
        }
    }
}
