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

package com.hypixel.hytale.builtin.instances.interactions;

import com.hypixel.hytale.codec.codecs.EnumCodec;
import com.hypixel.hytale.math.shape.Box;
import com.hypixel.hytale.assetstore.map.IndexedLookupTableAssetMap;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import com.hypixel.hytale.math.Axis;
import com.hypixel.hytale.server.core.asset.type.blockhitbox.BlockBoundingBoxes;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.RotationTuple;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import javax.annotation.Nullable;
import java.util.UUID;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.protocol.BlockPosition;
import com.hypixel.hytale.math.vector.Transform;
import com.hypixel.hytale.component.Archetype;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.CommandBuffer;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import com.hypixel.hytale.server.core.universe.world.World;
import java.util.concurrent.CompletableFuture;
import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.server.core.modules.block.BlockModule;
import com.hypixel.hytale.builtin.instances.blocks.InstanceBlock;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk;
import com.hypixel.hytale.math.util.ChunkUtil;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.universe.Universe;
import com.hypixel.hytale.builtin.instances.InstancesPlugin;
import com.hypixel.hytale.server.core.modules.entity.teleport.PendingTeleport;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.server.core.modules.entity.teleport.Teleport;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler;
import com.hypixel.hytale.server.core.entity.InteractionContext;
import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.protocol.WaitForDataFrom;
import javax.annotation.Nonnull;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.SimpleInstantInteraction;

public class TeleportInstanceInteraction extends SimpleInstantInteraction
{
    public static final BuilderCodec<TeleportInstanceInteraction> CODEC;
    private static final int SET_BLOCK_SETTINGS = 256;
    private String instanceName;
    private String instanceKey;
    private Vector3d positionOffset;
    private Vector3f rotation;
    @Nonnull
    private OriginSource originSource;
    private boolean personalReturnPoint;
    private boolean closeOnBlockRemove;
    private double removeBlockAfter;
    
    public TeleportInstanceInteraction() {
        this.originSource = OriginSource.PLAYER;
        this.personalReturnPoint = false;
        this.closeOnBlockRemove = true;
        this.removeBlockAfter = -1.0;
    }
    
    @Nonnull
    @Override
    public WaitForDataFrom getWaitForDataFrom() {
        return WaitForDataFrom.Server;
    }
    
    @Override
    protected void firstRun(@Nonnull final InteractionType type, @Nonnull final InteractionContext context, @Nonnull final CooldownHandler cooldownHandler) {
        final CommandBuffer<EntityStore> commandBuffer = context.getCommandBuffer();
        final Ref<EntityStore> ref = context.getEntity();
        final Player playerComponent = commandBuffer.getComponent(ref, Player.getComponentType());
        if (playerComponent == null || playerComponent.isWaitingForClientReady()) {
            return;
        }
        final Archetype<EntityStore> archetype = commandBuffer.getArchetype(ref);
        if (archetype.contains(Teleport.getComponentType()) || archetype.contains(PendingTeleport.getComponentType())) {
            return;
        }
        final World world = commandBuffer.getExternalData().getWorld();
        final InstancesPlugin module = InstancesPlugin.get();
        final Universe universe = Universe.get();
        CompletableFuture<World> targetWorldFuture = null;
        Transform returnPoint = null;
        World targetWorld;
        if (this.instanceKey != null) {
            targetWorld = universe.getWorld(this.instanceKey);
            if (targetWorld == null) {
                returnPoint = this.makeReturnPoint(ref, context, commandBuffer);
                targetWorldFuture = module.spawnInstance(this.instanceName, this.instanceKey, world, returnPoint);
            }
        }
        else {
            final BlockPosition targetBlock = context.getTargetBlock();
            if (targetBlock == null) {
                return;
            }
            final ChunkStore chunkStore = world.getChunkStore();
            final Ref<ChunkStore> chunkRef = chunkStore.getChunkReference(ChunkUtil.indexChunkFromBlock(targetBlock.x, targetBlock.z));
            if (chunkRef == null || !chunkRef.isValid()) {
                return;
            }
            final BlockComponentChunk blockComponentChunk = chunkStore.getStore().getComponent(chunkRef, BlockComponentChunk.getComponentType());
            assert blockComponentChunk != null;
            final int index = ChunkUtil.indexBlockInColumn(targetBlock.x, targetBlock.y, targetBlock.z);
            Ref<ChunkStore> blockRef = blockComponentChunk.getEntityReference(index);
            InstanceBlock instanceState;
            if (blockRef == null) {
                final Holder<ChunkStore> holder = ChunkStore.REGISTRY.newHolder();
                instanceState = holder.ensureAndGetComponent(InstanceBlock.getComponentType());
                holder.addComponent(BlockModule.BlockStateInfo.getComponentType(), new BlockModule.BlockStateInfo(index, chunkRef));
                blockRef = chunkStore.getStore().addEntity(holder, AddReason.SPAWN);
                instanceState.setCloseOnRemove(this.closeOnBlockRemove);
            }
            else {
                instanceState = chunkStore.getStore().getComponent(chunkRef, InstanceBlock.getComponentType());
            }
            if (blockRef == null) {
                return;
            }
            if (instanceState == null) {
                instanceState = chunkStore.getStore().ensureAndGetComponent(blockRef, InstanceBlock.getComponentType());
                instanceState.setCloseOnRemove(this.closeOnBlockRemove);
            }
            final UUID worldName = instanceState.getWorldUUID();
            targetWorldFuture = instanceState.getWorldFuture();
            targetWorld = ((worldName != null) ? universe.getWorld(worldName) : null);
            if (targetWorld == null && targetWorldFuture == null) {
                returnPoint = this.makeReturnPoint(ref, context, commandBuffer);
                targetWorldFuture = module.spawnInstance(this.instanceName, world, returnPoint);
                instanceState.setWorldFuture(targetWorldFuture);
                final Ref<ChunkStore> finalBlockRef = blockRef;
                final InstanceBlock finalInstanceState = instanceState;
                targetWorldFuture.thenAccept(instanceWorld -> {
                    if (!finalBlockRef.isValid()) {
                        return;
                    }
                    else {
                        finalInstanceState.setWorldFuture(null);
                        finalInstanceState.setWorldUUID(instanceWorld.getWorldConfig().getUuid());
                        blockComponentChunk.markNeedsSaving();
                        return;
                    }
                });
            }
        }
        if (targetWorldFuture != null) {
            final Transform personalReturnPoint = this.getPersonalReturnPoint(ref, context, returnPoint, commandBuffer);
            InstancesPlugin.teleportPlayerToLoadingInstance(ref, commandBuffer, targetWorldFuture, personalReturnPoint);
        }
        else if (targetWorld != null) {
            final Transform personalReturnPoint = this.getPersonalReturnPoint(ref, context, returnPoint, commandBuffer);
            InstancesPlugin.teleportPlayerToInstance(ref, commandBuffer, targetWorld, personalReturnPoint);
        }
        if (this.removeBlockAfter >= 0.0) {
            final BlockPosition targetBlock = context.getTargetBlock();
            if (targetBlock != null) {
                if (this.removeBlockAfter == 0.0) {
                    world.getChunk(ChunkUtil.indexChunkFromBlock(targetBlock.x, targetBlock.z)).setBlock(targetBlock.x, targetBlock.y, targetBlock.z, 0, 256);
                }
                else {
                    final int block = world.getBlock(targetBlock.x, targetBlock.y, targetBlock.z);
                    new CompletableFuture<Object>().completeOnTimeout(null, (long)(this.removeBlockAfter * 1.0E9), TimeUnit.NANOSECONDS).thenRunAsync(() -> {
                        if (world.getBlock(targetBlock.x, targetBlock.y, targetBlock.z) == block) {
                            world.getChunk(ChunkUtil.indexChunkFromBlock(targetBlock.x, targetBlock.z)).setBlock(targetBlock.x, targetBlock.y, targetBlock.z, 0, 256);
                        }
                    }, (Executor)world);
                }
            }
        }
    }
    
    @Nullable
    private Transform getPersonalReturnPoint(@Nonnull final Ref<EntityStore> playerRef, @Nonnull final InteractionContext context, @Nullable final Transform returnPoint, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        if (!this.personalReturnPoint) {
            return null;
        }
        if (returnPoint == null) {
            return this.makeReturnPoint(playerRef, context, componentAccessor);
        }
        return returnPoint;
    }
    
    @Nonnull
    private Transform makeReturnPoint(@Nonnull final Ref<EntityStore> playerRef, @Nonnull final InteractionContext context, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        Transform transform = null;
        switch (this.originSource.ordinal()) {
            case 0: {
                final TransformComponent transformComponent = componentAccessor.getComponent(playerRef, TransformComponent.getComponentType());
                assert transformComponent != null;
                transform = transformComponent.getTransform().clone();
                transform.getPosition().add(this.positionOffset);
                transform.setRotation((this.rotation != null) ? this.rotation : Vector3f.NaN);
                break;
            }
            case 1: {
                final BlockPosition targetBlock = context.getTargetBlock();
                if (targetBlock == null) {
                    throw new IllegalArgumentException("Can't use OriginSource.BLOCK without a target block");
                }
                final World world = componentAccessor.getExternalData().getWorld();
                final WorldChunk chunk = world.getChunkIfInMemory(ChunkUtil.indexChunkFromBlock(targetBlock.x, targetBlock.z));
                if (chunk == null) {
                    throw new IllegalArgumentException("Missing chunk");
                }
                final BlockType blockType = chunk.getBlockType(targetBlock.x, targetBlock.y, targetBlock.z);
                final int rotationIndex = chunk.getRotationIndex(targetBlock.x, targetBlock.y, targetBlock.z);
                final RotationTuple rotationTuple = RotationTuple.get(rotationIndex);
                final IndexedLookupTableAssetMap<String, BlockBoundingBoxes> hitboxAssetMap = BlockBoundingBoxes.getAssetMap();
                final Box hitbox = hitboxAssetMap.getAsset(blockType.getHitboxTypeIndex()).get(rotationIndex).getBoundingBox();
                final Vector3d vector3d;
                final Vector3d position = vector3d = ((this.positionOffset != null) ? rotationTuple.rotate(this.positionOffset) : new Vector3d());
                vector3d.x += hitbox.middleX() + targetBlock.x;
                final Vector3d vector3d2 = position;
                vector3d2.y += hitbox.middleY() + targetBlock.y;
                final Vector3d vector3d3 = position;
                vector3d3.z += hitbox.middleZ() + targetBlock.z;
                Vector3f rotation = Vector3f.NaN;
                if (this.rotation != null) {
                    rotation = this.rotation.clone();
                    rotation.addRotationOnAxis(Axis.Y, rotationTuple.yaw().getDegrees());
                    rotation.addRotationOnAxis(Axis.X, rotationTuple.pitch().getDegrees());
                }
                transform = new Transform(position, rotation);
                break;
            }
        }
        return transform;
    }
    
    static {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     2: invokevirtual   java/lang/Class.desiredAssertionStatus:()Z
        //     5: ifne            12
        //     8: iconst_1       
        //     9: goto            13
        //    12: iconst_0       
        //    13: putstatic       com/hypixel/hytale/builtin/instances/interactions/TeleportInstanceInteraction.$assertionsDisabled:Z
        //    16: ldc             Lcom/hypixel/hytale/builtin/instances/interactions/TeleportInstanceInteraction;.class
        //    18: invokedynamic   BootstrapMethod #2, get:()Ljava/util/function/Supplier;
        //    23: getstatic       com/hypixel/hytale/server/core/modules/interaction/interaction/config/SimpleInstantInteraction.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //    26: 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;
        //    29: ldc_w           "Teleports the **Player** to the named instance, creating it if required."
        //    32: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    35: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    38: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    41: dup            
        //    42: ldc_w           "InstanceName"
        //    45: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
        //    48: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    51: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
        //    56: invokedynamic   BootstrapMethod #4, apply:()Ljava/util/function/Function;
        //    61: invokedynamic   BootstrapMethod #5, accept:()Ljava/util/function/BiConsumer;
        //    66: 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;
        //    69: ldc_w           "The name of the **instance** to teleport to."
        //    72: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    75: invokestatic    com/hypixel/hytale/codec/validation/Validators.nonNull:()Lcom/hypixel/hytale/codec/validation/Validator;
        //    78: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.addValidator:(Lcom/hypixel/hytale/codec/validation/Validator;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    81: getstatic       com/hypixel/hytale/builtin/instances/InstanceValidator.INSTANCE:Lcom/hypixel/hytale/builtin/instances/InstanceValidator;
        //    84: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.addValidator:(Lcom/hypixel/hytale/codec/validation/Validator;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    87: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    90: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    93: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    96: dup            
        //    97: ldc_w           "InstanceKey"
        //   100: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
        //   103: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   106: invokedynamic   BootstrapMethod #6, accept:()Ljava/util/function/BiConsumer;
        //   111: invokedynamic   BootstrapMethod #7, apply:()Ljava/util/function/Function;
        //   116: invokedynamic   BootstrapMethod #8, accept:()Ljava/util/function/BiConsumer;
        //   121: 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;
        //   124: ldc_w           "The key to name the world. Random if not provided"
        //   127: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   130: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   133: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   136: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   139: dup            
        //   140: ldc_w           "PositionOffset"
        //   143: getstatic       com/hypixel/hytale/math/vector/Vector3d.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   146: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   149: invokedynamic   BootstrapMethod #9, accept:()Ljava/util/function/BiConsumer;
        //   154: invokedynamic   BootstrapMethod #10, apply:()Ljava/util/function/Function;
        //   159: invokedynamic   BootstrapMethod #11, accept:()Ljava/util/function/BiConsumer;
        //   164: 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;
        //   167: ldc_w           "The offset to apply to the return point.\n\nUsed to prevent repeated interactions when returning from the instance."
        //   170: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   173: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   176: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   179: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   182: dup            
        //   183: ldc_w           "Rotation"
        //   186: getstatic       com/hypixel/hytale/math/vector/Vector3f.ROTATION:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   189: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   192: invokedynamic   BootstrapMethod #12, accept:()Ljava/util/function/BiConsumer;
        //   197: invokedynamic   BootstrapMethod #13, apply:()Ljava/util/function/Function;
        //   202: invokedynamic   BootstrapMethod #14, accept:()Ljava/util/function/BiConsumer;
        //   207: 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;
        //   210: ldc_w           "The rotation to set the player to when returning from an instance."
        //   213: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   216: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   219: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   222: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   225: dup            
        //   226: ldc_w           "OriginSource"
        //   229: getstatic       com/hypixel/hytale/builtin/instances/interactions/TeleportInstanceInteraction$OriginSource.CODEC:Lcom/hypixel/hytale/codec/codecs/EnumCodec;
        //   232: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   235: invokedynamic   BootstrapMethod #15, accept:()Ljava/util/function/BiConsumer;
        //   240: invokedynamic   BootstrapMethod #16, apply:()Ljava/util/function/Function;
        //   245: invokedynamic   BootstrapMethod #17, accept:()Ljava/util/function/BiConsumer;
        //   250: 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;
        //   253: ldc_w           "The source to use for the return position.\n\nDefaults to the player's position."
        //   256: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   259: invokestatic    com/hypixel/hytale/codec/validation/Validators.nonNull:()Lcom/hypixel/hytale/codec/validation/Validator;
        //   262: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.addValidator:(Lcom/hypixel/hytale/codec/validation/Validator;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   265: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   268: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   271: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   274: dup            
        //   275: ldc_w           "PersonalReturnPoint"
        //   278: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
        //   281: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   284: invokedynamic   BootstrapMethod #18, accept:()Ljava/util/function/BiConsumer;
        //   289: invokedynamic   BootstrapMethod #19, apply:()Ljava/util/function/Function;
        //   294: invokedynamic   BootstrapMethod #20, accept:()Ljava/util/function/BiConsumer;
        //   299: 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;
        //   302: ldc_w           "Whether the player entering the instance will have their own return point\nset to the current location. Overriding the world's return point."
        //   305: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   308: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   311: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   314: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   317: dup            
        //   318: ldc_w           "CloseOnBlockRemove"
        //   321: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
        //   324: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   327: invokedynamic   BootstrapMethod #21, accept:()Ljava/util/function/BiConsumer;
        //   332: invokedynamic   BootstrapMethod #22, apply:()Ljava/util/function/Function;
        //   337: invokedynamic   BootstrapMethod #23, accept:()Ljava/util/function/BiConsumer;
        //   342: 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;
        //   345: ldc_w           "Whether to delete the instance when the portal block is removed."
        //   348: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   351: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   354: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   357: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   360: dup            
        //   361: ldc_w           "RemoveBlockAfter"
        //   364: getstatic       com/hypixel/hytale/codec/Codec.DOUBLE:Lcom/hypixel/hytale/codec/codecs/simple/DoubleCodec;
        //   367: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   370: invokedynamic   BootstrapMethod #24, accept:()Ljava/util/function/BiConsumer;
        //   375: invokedynamic   BootstrapMethod #25, apply:()Ljava/util/function/Function;
        //   380: invokedynamic   BootstrapMethod #26, accept:()Ljava/util/function/BiConsumer;
        //   385: 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;
        //   388: ldc_w           "The number of seconds to wait before removing the block that triggered\nthe interaction. A negative value disables this.\n\nThis is needed instead of using another interaction due to all interactions\nbeing stopped once teleporting to another world."
        //   391: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   394: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   397: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   400: invokedynamic   BootstrapMethod #27, accept:()Ljava/util/function/Consumer;
        //   405: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.afterDecode:(Ljava/util/function/Consumer;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   408: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   411: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   414: putstatic       com/hypixel/hytale/builtin/instances/interactions/TeleportInstanceInteraction.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   417: return         
        //    StackMapTable: 00 02 0C 40 01
        // 
        // 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: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.inferTypesForVariables(TypeAnalysis.java:593)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:405)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:109)
        //     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.");
    }
    
    private enum OriginSource
    {
        PLAYER, 
        BLOCK;
        
        @Nonnull
        public static EnumCodec<OriginSource> CODEC;
        
        static {
            OriginSource.CODEC = new EnumCodec<OriginSource>(OriginSource.class).documentKey(OriginSource.PLAYER, "The origin of operations will be based on the player's current position.").documentKey(OriginSource.BLOCK, "The origin of operations will be based on the middle of the block's hitbox.");
        }
    }
}
