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

package com.hypixel.hytale.builtin.deployables.config;

import java.time.temporal.TemporalUnit;
import java.time.temporal.ChronoUnit;
import java.time.Instant;
import java.time.temporal.Temporal;
import java.time.Duration;
import com.hypixel.hytale.server.core.modules.time.TimeResource;
import java.util.Iterator;
import java.util.List;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.util.TargetUtil;
import java.util.function.Consumer;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.modules.entity.damage.DamageCause;
import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.modules.entity.DespawnComponent;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ArchetypeChunk;
import javax.annotation.Nonnull;
import com.hypixel.hytale.builtin.deployables.component.DeployableComponent;
import com.hypixel.hytale.codec.builder.BuilderCodec;

public class DeployableTrapConfig extends DeployableAoeConfig
{
    public static final BuilderCodec<DeployableTrapConfig> CODEC;
    protected float fuzeDuration;
    protected float activeDuration;
    protected boolean destroyOnTriggered;
    
    protected DeployableTrapConfig() {
        this.fuzeDuration = 0.0f;
        this.activeDuration = 1.0f;
        this.destroyOnTriggered = false;
    }
    
    @Override
    public void tick(@Nonnull final DeployableComponent deployableComponent, final float dt, final int index, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
        final Vector3d pos = archetypeChunk.getComponent(index, TransformComponent.getComponentType()).getPosition();
        final World world = store.getExternalData().getWorld();
        final Ref<EntityStore> entityRef = archetypeChunk.getReferenceTo(index);
        if (!deployableComponent.getOwner().isValid()) {
            world.execute(() -> {
                if (entityRef.isValid()) {
                    final DespawnComponent despawn = store.ensureAndGetComponent(entityRef, DespawnComponent.getComponentType());
                    final WorldTimeResource timeManager = commandBuffer.getResource(WorldTimeResource.getResourceType());
                    despawn.setDespawn(timeManager.getGameTime());
                }
            });
            return;
        }
        final float radius = this.getRadius(store, deployableComponent.getSpawnInstant());
        this.handleDebugGraphics(world, deployableComponent.getDebugColor(), pos, radius * 2.0f);
        switch (deployableComponent.getFlag(DeployableComponent.DeployableFlag.STATE)) {
            case 0: {
                deployableComponent.setFlag(DeployableComponent.DeployableFlag.STATE, 1);
                break;
            }
            case 1: {
                deployableComponent.setFlag(DeployableComponent.DeployableFlag.STATE, 2);
                DeployableConfig.playAnimation(store, entityRef, this, "Grow");
                break;
            }
            case 2: {
                if (radius >= this.endRadius) {
                    deployableComponent.setFlag(DeployableComponent.DeployableFlag.STATE, 3);
                    DeployableConfig.playAnimation(store, entityRef, this, "Looping");
                    break;
                }
                break;
            }
        }
        final Ref<EntityStore> trapRef = archetypeChunk.getReferenceTo(index);
        deployableComponent.setTimeSinceLastAttack(deployableComponent.getTimeSinceLastAttack() + dt);
        if (deployableComponent.getTimeSinceLastAttack() > this.damageInterval && this.isLive(store, deployableComponent)) {
            deployableComponent.setTimeSinceLastAttack(0.0f);
            this.handleDetection(store, commandBuffer, trapRef, deployableComponent, pos, radius, DamageCause.PHYSICAL);
        }
    }
    
    @Override
    protected void handleDetection(final Store<EntityStore> store, final CommandBuffer<EntityStore> commandBuffer, final Ref<EntityStore> deployableRef, final DeployableComponent deployableComponent, final Vector3d position, final float radius, final DamageCause damageCause) {
        final World world = store.getExternalData().getWorld();
        final Consumer<Ref<EntityStore>> consumer = new Consumer<Ref<EntityStore>>() {
            @Override
            public void accept(final Ref<EntityStore> entityStoreRef) {
                if (entityStoreRef == deployableRef) {
                    return;
                }
                if (store.getComponent(entityStoreRef, DeployableComponent.getComponentType()) != null) {
                    return;
                }
                DeployableTrapConfig.this.attackTarget(entityStoreRef, deployableRef, damageCause, commandBuffer);
                if (DeployableTrapConfig.this.destroyOnTriggered && deployableComponent.getFlag(DeployableComponent.DeployableFlag.TRIGGERED) == 0) {
                    DeployableTrapConfig.this.onTriggered(store, deployableRef);
                    deployableComponent.setFlag(DeployableComponent.DeployableFlag.TRIGGERED, 1);
                }
                DeployableTrapConfig.this.applyEffectToTarget(store, entityStoreRef);
            }
        };
        switch (this.shape) {
            case Sphere: {
                final List<Ref<EntityStore>> targetRefs = TargetUtil.getAllEntitiesInSphere(position, radius, store);
                for (final Ref<EntityStore> targetRef : targetRefs) {
                    consumer.accept(targetRef);
                }
                break;
            }
            case Cylinder: {
                final List<Ref<EntityStore>> targetRefs = TargetUtil.getAllEntitiesInCylinder(position, radius, this.height, store);
                for (final Ref<EntityStore> targetRef : targetRefs) {
                    consumer.accept(targetRef);
                }
                break;
            }
        }
    }
    
    protected boolean isLive(@Nonnull final Store<EntityStore> store, @Nonnull final DeployableComponent comp) {
        if (comp.getFlag(DeployableComponent.DeployableFlag.LIVE) == 1) {
            return true;
        }
        if (this.fuzeDuration == 0.0f) {
            comp.setFlag(DeployableComponent.DeployableFlag.LIVE, 1);
            return true;
        }
        final Instant now = store.getResource(TimeResource.getResourceType()).getNow();
        final Instant spawnTime = comp.getSpawnInstant();
        final float timeDiff = Duration.between(spawnTime, now).toMillis() / 1000.0f;
        if (timeDiff >= this.fuzeDuration) {
            comp.setFlag(DeployableComponent.DeployableFlag.LIVE, 1);
            return true;
        }
        return false;
    }
    
    protected void onTriggered(@Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref) {
        final Instant now = store.getResource(TimeResource.getResourceType()).getNow();
        final DespawnComponent despawnComponent = store.getComponent(ref, DespawnComponent.getComponentType());
        despawnComponent.setDespawn(now.plus((long)this.activeDuration, (TemporalUnit)ChronoUnit.SECONDS));
    }
    
    @Override
    public String toString() {
        return "DeployableTrapConfig{}" + super.toString();
    }
    
    static {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     2: invokedynamic   BootstrapMethod #2, get:()Ljava/util/function/Supplier;
        //     7: getstatic       com/hypixel/hytale/builtin/deployables/config/DeployableAoeConfig.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //    10: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;Lcom/hypixel/hytale/codec/builder/BuilderCodec;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    13: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    16: dup            
        //    17: ldc_w           "FuzeDuration"
        //    20: getstatic       com/hypixel/hytale/codec/Codec.FLOAT:Lcom/hypixel/hytale/codec/codecs/simple/FloatCodec;
        //    23: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    26: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
        //    31: invokedynamic   BootstrapMethod #4, apply:()Ljava/util/function/Function;
        //    36: invokedynamic   BootstrapMethod #5, accept:()Ljava/util/function/BiConsumer;
        //    41: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    44: ldc_w           "The time it will take for the trap to become active"
        //    47: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    50: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    53: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    56: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    59: dup            
        //    60: ldc_w           "ActiveDuration"
        //    63: getstatic       com/hypixel/hytale/codec/Codec.FLOAT:Lcom/hypixel/hytale/codec/codecs/simple/FloatCodec;
        //    66: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    69: invokedynamic   BootstrapMethod #6, accept:()Ljava/util/function/BiConsumer;
        //    74: invokedynamic   BootstrapMethod #7, apply:()Ljava/util/function/Function;
        //    79: invokedynamic   BootstrapMethod #8, accept:()Ljava/util/function/BiConsumer;
        //    84: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    87: ldc_w           "The time the trap will stay alive after getting triggered"
        //    90: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    93: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    96: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    99: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   102: dup            
        //   103: ldc_w           "DestroyOnTriggered"
        //   106: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
        //   109: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   112: invokedynamic   BootstrapMethod #9, accept:()Ljava/util/function/BiConsumer;
        //   117: invokedynamic   BootstrapMethod #10, apply:()Ljava/util/function/Function;
        //   122: invokedynamic   BootstrapMethod #11, accept:()Ljava/util/function/BiConsumer;
        //   127: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   130: ldc_w           "Whether the trap will disappear when it's triggered by a players"
        //   133: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   136: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   139: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   142: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   145: putstatic       com/hypixel/hytale/builtin/deployables/config/DeployableTrapConfig.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   148: return         
        // 
        // The error that occurred was:
        // 
        // java.lang.UnsupportedOperationException: The requested operation is not supported.
        //     at com.strobel.util.ContractUtils.unsupported(ContractUtils.java:27)
        //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:284)
        //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:279)
        //     at com.strobel.assembler.metadata.TypeReference.makeGenericType(TypeReference.java:154)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:225)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:25)
        //     at com.strobel.assembler.metadata.ParameterizedType.accept(ParameterizedType.java:103)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:211)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:25)
        //     at com.strobel.assembler.metadata.ParameterizedType.accept(ParameterizedType.java:103)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:314)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2611)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1083)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:667)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:373)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:344)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:206)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
        //     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
        //     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
        //     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:129)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
}
