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

package com.hypixel.hytale.server.core.universe.world.connectedblocks;

import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import java.util.List;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockFlipType;
import com.hypixel.hytale.math.block.BlockUtil;
import com.hypixel.hytale.math.Axis;
import com.hypixel.hytale.math.util.ChunkUtil;
import it.unimi.dsi.fastutil.Pair;
import java.util.Optional;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.asset.type.buildertool.config.BlockTypeListAsset;
import java.util.Iterator;
import java.util.Set;
import com.hypixel.hytale.server.core.prefab.selection.mask.BlockPattern;
import java.util.HashSet;
import com.hypixel.hytale.math.vector.Vector3i;
import java.util.Map;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.RotationTuple;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.Rotation;
import javax.annotation.Nonnull;
import java.util.Random;
import com.hypixel.hytale.codec.builder.BuilderCodec;

public class CustomConnectedBlockPattern extends CustomTemplateConnectedBlockPattern
{
    public static final BuilderCodec<CustomConnectedBlockPattern> CODEC;
    @Nonnull
    private static final Random random;
    private boolean transformRulesToOrientation;
    private PatternRotationDefinition patternRotationDefinition;
    private ConnectedBlockPatternRule[] rulesToMatch;
    private Rotation yawToApplyAddReplacedBlockType;
    private boolean requireFaceTagsMatchingRoll;
    private boolean onlyOnUpdate;
    private boolean onlyOnPlacement;
    
    public CustomConnectedBlockPattern() {
        this.transformRulesToOrientation = true;
        this.patternRotationDefinition = PatternRotationDefinition.DEFAULT;
    }
    
    private static boolean checkPatternRuleAgainstBlockType(@Nonnull final CustomTemplateConnectedBlockRuleSet placedRuleset, @Nonnull final CustomConnectedBlockTemplateAsset template, @Nonnull final String block, @Nonnull final ConnectedBlockPatternRule rule, @Nonnull final String blockToTest, final RotationTuple rotationToCheckUnrotated, final int fillerToCheckUnrotated) {
        if (!rule.getFaceTags().getDirections().isEmpty()) {
            final BlockType checkingBlockType = BlockType.getAssetMap().getAsset(blockToTest);
            final ConnectedBlockRuleSet checkingRuleSet = checkingBlockType.getConnectedBlockRuleSet();
            if (!(checkingRuleSet instanceof CustomTemplateConnectedBlockRuleSet)) {
                return !rule.isInclude();
            }
            final CustomTemplateConnectedBlockRuleSet checkingConnectedBlockRuleSet = (CustomTemplateConnectedBlockRuleSet)checkingRuleSet;
            final int index = BlockType.getAssetMap().getIndex(blockToTest);
            final Set<String> shapeNames = checkingConnectedBlockRuleSet.getShapesForBlockType(index);
            final CustomConnectedBlockTemplateAsset checkingTemplateAsset = checkingConnectedBlockRuleSet.getShapeTemplateAsset();
            if (checkingTemplateAsset == null) {
                return !rule.isInclude();
            }
            for (final String shapeName : shapeNames) {
                if (!template.connectsToOtherMaterials && !placedRuleset.getShapeNameToBlockPatternMap().equals(checkingConnectedBlockRuleSet.getShapeNameToBlockPatternMap())) {
                    continue;
                }
                final ConnectedBlockShape blockToCheckConnectedBlockShape = checkingTemplateAsset.connectedBlockShapes.get(shapeName);
                final Map<Vector3i, HashSet<String>> ruleFaceTags = rule.getFaceTags().getBlockFaceTags();
                for (final Map.Entry<Vector3i, HashSet<String>> ruleFaceTag : ruleFaceTags.entrySet()) {
                    final Vector3i adjustedDirectionOfPattern = Rotation.rotate(ruleFaceTag.getKey().clone(), Rotation.None.subtract(rotationToCheckUnrotated.yaw()), Rotation.None);
                    for (final String faceTag : ruleFaceTag.getValue()) {
                        final boolean containsFaceTag = blockToCheckConnectedBlockShape.getFaceTags() != null && blockToCheckConnectedBlockShape.getFaceTags().contains(adjustedDirectionOfPattern, faceTag);
                        if (containsFaceTag) {
                            return rule.isInclude();
                        }
                    }
                }
            }
        }
        if (!rule.getShapeBlockTypeKeys().isEmpty()) {
            final BlockType checkingBlockType = BlockType.getAssetMap().getAsset(blockToTest);
            final ConnectedBlockRuleSet checkingRuleSet = checkingBlockType.getConnectedBlockRuleSet();
            if (!(checkingRuleSet instanceof CustomTemplateConnectedBlockRuleSet)) {
                return !rule.isInclude();
            }
            final CustomTemplateConnectedBlockRuleSet checkingConnectedBlockRuleSet = (CustomTemplateConnectedBlockRuleSet)checkingRuleSet;
            final int index = BlockType.getAssetMap().getIndex(blockToTest);
            final Set<String> shapeNames = checkingConnectedBlockRuleSet.getShapesForBlockType(index);
            for (final String shapeName2 : shapeNames) {
                if (!template.connectsToOtherMaterials && !placedRuleset.getShapeNameToBlockPatternMap().equals(checkingConnectedBlockRuleSet.getShapeNameToBlockPatternMap())) {
                    continue;
                }
                if (rule.getShapeBlockTypeKeys().contains(new BlockPattern.BlockEntry(shapeName2, rotationToCheckUnrotated.index(), fillerToCheckUnrotated))) {
                    return rule.isInclude();
                }
            }
        }
        if (!rule.getBlockTypes().isEmpty() && rule.getBlockTypes().contains(blockToTest)) {
            return rule.isInclude();
        }
        if (rule.getBlockTypeListAssets() != null) {
            for (final BlockTypeListAsset blockTypeListAsset : rule.getBlockTypeListAssets()) {
                if (blockTypeListAsset.getBlockTypeKeys().contains(blockToTest)) {
                    return rule.isInclude();
                }
            }
        }
        return !rule.isInclude();
    }
    
    @Nonnull
    @Override
    public Optional<ConnectedBlocksUtil.ConnectedBlockResult> getConnectedBlockTypeKey(final String shapeName, @Nonnull final World world, @Nonnull final Vector3i coordinate, @Nonnull final CustomTemplateConnectedBlockRuleSet connectedBlockRuleset, @Nonnull final BlockType blockType, final int rotation, @Nonnull final Vector3i placementNormal, final boolean isPlacement) {
        if ((isPlacement && this.onlyOnUpdate) || (!isPlacement && this.onlyOnPlacement)) {
            return Optional.empty();
        }
        final CustomConnectedBlockTemplateAsset shapeTemplate = connectedBlockRuleset.getShapeTemplateAsset();
        if (shapeTemplate == null) {
            return Optional.empty();
        }
        Vector3i coordinateToTest = new Vector3i();
        final Rotation3D totalRotation = new Rotation3D(Rotation.None, Rotation.None, Rotation.None);
        final Rotation3D tempRotation = new Rotation3D(Rotation.None, Rotation.None, Rotation.None);
        final List<Pair<Rotation, PatternRotationDefinition.MirrorAxis>> rotations = this.patternRotationDefinition.getRotations();
        int i = 0;
    Label_0101:
        while (i < rotations.size()) {
            final Pair<Rotation, PatternRotationDefinition.MirrorAxis> patternTransform = rotations.get(i);
            totalRotation.assign(patternTransform.first(), Rotation.None, Rotation.None);
            if (this.transformRulesToOrientation) {
                final RotationTuple rotationTuple = RotationTuple.get(rotation);
                tempRotation.assign(rotationTuple.yaw(), rotationTuple.pitch(), rotationTuple.roll());
                totalRotation.add(tempRotation);
            }
            for (final ConnectedBlockPatternRule ruleToMatch : this.rulesToMatch) {
                coordinateToTest.assign(ruleToMatch.getRelativePosition());
                switch (patternTransform.second()) {
                    case X: {
                        coordinateToTest.setX(-coordinateToTest.getX());
                        break;
                    }
                    case Z: {
                        coordinateToTest.setZ(-coordinateToTest.getZ());
                        break;
                    }
                }
                Label_0694: {
                    if (ruleToMatch.getPlacementNormals() != null) {
                        for (final ConnectedBlockPatternRule.AdjacentSide normal : ruleToMatch.getPlacementNormals()) {
                            if (normal.relativePosition.equals(placementNormal)) {
                                break Label_0694;
                            }
                        }
                        return Optional.empty();
                    }
                    coordinateToTest = Rotation.rotate(coordinateToTest, totalRotation.rotationYaw, totalRotation.rotationPitch, totalRotation.rotationRoll);
                    coordinateToTest.add(coordinate);
                    final WorldChunk chunkIfLoaded = world.getChunkIfLoaded(ChunkUtil.indexChunkFromBlock(coordinateToTest.x, coordinateToTest.z));
                    if (chunkIfLoaded == null) {
                        return Optional.empty();
                    }
                    final String blockToCheckUnrotated = chunkIfLoaded.getBlockType(coordinateToTest).getId();
                    RotationTuple rotationToCheckUnrotated = chunkIfLoaded.getRotation(coordinateToTest.x, coordinateToTest.y, coordinateToTest.z);
                    tempRotation.assign(rotationToCheckUnrotated);
                    tempRotation.subtract(totalRotation);
                    int fillerToCheckUnrotated = chunkIfLoaded.getFiller(coordinateToTest.x, coordinateToTest.y, coordinateToTest.z);
                    fillerToCheckUnrotated = tempRotation.rotationPitch.subtract(rotationToCheckUnrotated.pitch()).rotateX(fillerToCheckUnrotated);
                    fillerToCheckUnrotated = tempRotation.rotationYaw.subtract(rotationToCheckUnrotated.yaw()).rotateY(fillerToCheckUnrotated);
                    fillerToCheckUnrotated = tempRotation.rotationRoll.subtract(rotationToCheckUnrotated.roll()).rotateY(fillerToCheckUnrotated);
                    rotationToCheckUnrotated = RotationTuple.of(tempRotation.rotationYaw, tempRotation.rotationPitch, tempRotation.rotationRoll);
                    final BlockType blockTypeToCheckUnrotated = BlockType.getAssetMap().getAsset(blockToCheckUnrotated);
                    if (patternTransform.second() != PatternRotationDefinition.MirrorAxis.NONE) {
                        final Rotation newYawMirrored = blockTypeToCheckUnrotated.getFlipType().flipYaw(rotationToCheckUnrotated.yaw(), (patternTransform.second() == PatternRotationDefinition.MirrorAxis.X) ? Axis.X : Axis.Z);
                        fillerToCheckUnrotated = newYawMirrored.subtract(rotationToCheckUnrotated.yaw()).rotateY(fillerToCheckUnrotated);
                        rotationToCheckUnrotated = RotationTuple.of(newYawMirrored, rotationToCheckUnrotated.pitch(), rotationToCheckUnrotated.roll());
                    }
                    final boolean patternMatches = checkPatternRuleAgainstBlockType(connectedBlockRuleset, shapeTemplate, blockType.getId(), ruleToMatch, blockToCheckUnrotated, rotationToCheckUnrotated, fillerToCheckUnrotated);
                    if (!patternMatches) {
                        ++i;
                        continue Label_0101;
                    }
                }
            }
            final BlockPattern resultBlockPattern = connectedBlockRuleset.getShapeNameToBlockPatternMap().get(shapeName);
            if (resultBlockPattern == null) {
                return Optional.empty();
            }
            CustomConnectedBlockPattern.random.setSeed(BlockUtil.pack(coordinate));
            final BlockPattern.BlockEntry resultBlockTypeKey = resultBlockPattern.nextBlockTypeKey(CustomConnectedBlockPattern.random);
            if (resultBlockTypeKey == null) {
                return Optional.empty();
            }
            final BlockType baseBlockTypeForFlip = BlockType.getAssetMap().getAsset(resultBlockTypeKey.blockTypeKey());
            if (baseBlockTypeForFlip == null) {
                return Optional.empty();
            }
            final BlockFlipType flipType = baseBlockTypeForFlip.getFlipType();
            RotationTuple resultRotation = RotationTuple.get(resultBlockTypeKey.rotation());
            resultRotation = RotationTuple.of(resultRotation.yaw().add(this.yawToApplyAddReplacedBlockType), resultRotation.pitch(), resultRotation.roll());
            if (patternTransform.second() != PatternRotationDefinition.MirrorAxis.NONE) {
                final Rotation newYawMirrored2 = flipType.flipYaw(resultRotation.yaw(), (patternTransform.second() == PatternRotationDefinition.MirrorAxis.X) ? Axis.X : Axis.Z);
                resultRotation = RotationTuple.of(newYawMirrored2, resultRotation.pitch(), resultRotation.roll());
            }
            resultRotation = RotationTuple.of(resultRotation.yaw().add(totalRotation.rotationYaw), resultRotation.pitch().add(totalRotation.rotationPitch), resultRotation.roll().add(totalRotation.rotationRoll));
            if (resultRotation.pitch().equals(Rotation.OneEighty) && flipType.equals(BlockFlipType.ORTHOGONAL)) {
                resultRotation = RotationTuple.of(resultRotation.yaw().subtract(Rotation.Ninety), resultRotation.pitch(), resultRotation.roll());
            }
            return Optional.of(new ConnectedBlocksUtil.ConnectedBlockResult(resultBlockTypeKey.blockTypeKey(), resultRotation.index()));
        }
        return Optional.empty();
    }
    
    static {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     2: invokedynamic   BootstrapMethod #0, get:()Ljava/util/function/Supplier;
        //     7: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    10: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    13: dup            
        //    14: ldc_w           "TransformRulesToOrientation"
        //    17: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
        //    20: iconst_0       
        //    21: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;Z)V
        //    24: invokedynamic   BootstrapMethod #1, accept:()Ljava/util/function/BiConsumer;
        //    29: invokedynamic   BootstrapMethod #2, apply:()Ljava/util/function/Function;
        //    34: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    37: ldc_w           "If the rules should be transformed to the current orientation of the block."
        //    40: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    43: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    46: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    49: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    52: dup            
        //    53: ldc_w           "YawToApplyAddReplacedBlockType"
        //    56: getstatic       com/hypixel/hytale/server/core/asset/type/blocktype/config/Rotation.CODEC:Lcom/hypixel/hytale/codec/Codec;
        //    59: iconst_0       
        //    60: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;Z)V
        //    63: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
        //    68: invokedynamic   BootstrapMethod #4, apply:()Ljava/util/function/Function;
        //    73: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    76: ldc_w           "Apply an additional Yaw to the resulting BlockType represented by this shape. This allows your replacement to be offset from your original placement"
        //    79: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    82: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    85: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    88: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    91: dup            
        //    92: ldc_w           "RequireFaceTagsMatchingRoll"
        //    95: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
        //    98: iconst_0       
        //    99: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;Z)V
        //   102: invokedynamic   BootstrapMethod #5, accept:()Ljava/util/function/BiConsumer;
        //   107: invokedynamic   BootstrapMethod #6, apply:()Ljava/util/function/Function;
        //   112: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   115: ldc_w           "Adds Roll comparison to face tag matching in patterns below"
        //   118: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   121: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   124: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   127: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   130: dup            
        //   131: ldc_w           "AllowedPatternTransformations"
        //   134: getstatic       com/hypixel/hytale/server/core/universe/world/connectedblocks/PatternRotationDefinition.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   137: iconst_0       
        //   138: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;Z)V
        //   141: invokedynamic   BootstrapMethod #7, accept:()Ljava/util/function/BiConsumer;
        //   146: invokedynamic   BootstrapMethod #8, apply:()Ljava/util/function/Function;
        //   151: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   154: ldc_w           "Will create additional generated patterns that are variants of this pattern, but rotated/mirrored/flipped to achieve different results. A common example of this is the Fence, which should its resulting shape based on the rotation of its pattern (fence corner rotates depending on which two sides have the corner fence shape)"
        //   157: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   160: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   163: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   166: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   169: dup            
        //   170: ldc_w           "RulesToMatch"
        //   173: new             Lcom/hypixel/hytale/codec/codecs/array/ArrayCodec;
        //   176: dup            
        //   177: getstatic       com/hypixel/hytale/server/core/universe/world/connectedblocks/ConnectedBlockPatternRule.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   180: invokedynamic   BootstrapMethod #9, apply:()Ljava/util/function/IntFunction;
        //   185: invokespecial   com/hypixel/hytale/codec/codecs/array/ArrayCodec.<init>:(Lcom/hypixel/hytale/codec/Codec;Ljava/util/function/IntFunction;)V
        //   188: iconst_1       
        //   189: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;Z)V
        //   192: invokedynamic   BootstrapMethod #10, accept:()Ljava/util/function/BiConsumer;
        //   197: invokedynamic   BootstrapMethod #11, apply:()Ljava/util/function/Function;
        //   202: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   205: ldc_w           "All rules must match in order for the pattern to match"
        //   208: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   211: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   214: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   217: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   220: dup            
        //   221: ldc_w           "OnlyOnPlacement"
        //   224: new             Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
        //   227: dup            
        //   228: invokespecial   com/hypixel/hytale/codec/codecs/simple/BooleanCodec.<init>:()V
        //   231: iconst_0       
        //   232: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;Z)V
        //   235: invokedynamic   BootstrapMethod #12, accept:()Ljava/util/function/BiConsumer;
        //   240: invokedynamic   BootstrapMethod #13, apply:()Ljava/util/function/Function;
        //   245: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   248: ldc_w           "If true, this pattern will only be checked when the block is first placed."
        //   251: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   254: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   257: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   260: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   263: dup            
        //   264: ldc_w           "OnlyOnUpdate"
        //   267: new             Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
        //   270: dup            
        //   271: invokespecial   com/hypixel/hytale/codec/codecs/simple/BooleanCodec.<init>:()V
        //   274: iconst_0       
        //   275: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;Z)V
        //   278: invokedynamic   BootstrapMethod #14, accept:()Ljava/util/function/BiConsumer;
        //   283: invokedynamic   BootstrapMethod #15, apply:()Ljava/util/function/Function;
        //   288: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   291: ldc_w           "If true, this pattern will only be checked when the block is updated by neighboring block changes."
        //   294: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.documentation:(Ljava/lang/String;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   297: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   300: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   303: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   306: putstatic       com/hypixel/hytale/server/core/universe/world/connectedblocks/CustomConnectedBlockPattern.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   309: new             Ljava/util/Random;
        //   312: dup            
        //   313: invokespecial   java/util/Random.<init>:()V
        //   316: putstatic       com/hypixel/hytale/server/core/universe/world/connectedblocks/CustomConnectedBlockPattern.random:Ljava/util/Random;
        //   319: 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.visitClassType(TypeSubstitutionVisitor.java:267)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:25)
        //     at com.strobel.assembler.metadata.TypeDefinition.accept(TypeDefinition.java:189)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:324)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2586)
        //     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: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: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.inferCall(TypeAnalysis.java:2483)
        //     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.inferCall(TypeAnalysis.java:2483)
        //     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:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     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.");
    }
}
