PrefabStage class

Пакет: com.hypixel.hytale.builtin.adventure.farming.config.stages

Файл: com/hypixel/hytale/builtin/adventure/farming/config/stages/PrefabFarmingStageData.java

implements: IWeightedElement

Поля (5)

МодификаторыТипИмя
public static final Codec<PrefabFarmingStageData.PrefabStage> CODEC
public static final PrefabFarmingStageData.PrefabStage[] EMPTY_ARRAY
protected String path
Path var1
protected int weight

Методы (5)

МодификаторыВозвратСигнатура
abstract throw new IllegalStateExceptionthrow new IllegalStateException("Invalid prefab path: " + this.path)
public Path getResolvedPathpublic Path getResolvedPath()
public double getWeightpublic double getWeight()
if if(var1 == null)
public String toStringpublic String toString()

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.adventure.farming.config.stages;

class="kw">import com.hypixel.hytale.assetstore.AssetRegistry;
class="kw">import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
class="kw">import com.hypixel.hytale.builtin.adventure.farming.states.FarmingBlock;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
class="kw">import com.hypixel.hytale.codec.validation.Validators;
class="kw">import com.hypixel.hytale.common.map.IWeightedElement;
class="kw">import com.hypixel.hytale.common.map.IWeightedMap;
class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.util.FastRandom;
class="kw">import com.hypixel.hytale.math.util.HashUtil;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import com.hypixel.hytale.protocol.BlockMaterial;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.Rotation;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.RotationTuple;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.farming.FarmingStageData;
class="kw">import com.hypixel.hytale.server.core.codec.WeightedMapCodec;
class="kw">import com.hypixel.hytale.server.core.modules.block.BlockEntity;
class="kw">import com.hypixel.hytale.server.core.prefab.PrefabRotation;
class="kw">import com.hypixel.hytale.server.core.prefab.PrefabStore;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.buffer.PrefabBufferCall;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.buffer.PrefabBufferUtil;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.buffer.impl.IPrefabBuffer;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.AbstractCachedAccessor;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.BlockOperations;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.CachedAccessor;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockComponentSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.util.PrefabUtil;
class="kw">import java.nio.file.Path;
class="kw">import java.util.Arrays;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3i;

class="kw">public class PrefabFarmingStageData class="kw">extends FarmingStageData {
   @Nonnull
   class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   class="kw">public class="kw">static class="kw">final float MIN_VOLUME_PREFAB = 125.0F;
   class="kw">public class="kw">static class="kw">final float MAX_VOLUME_PREFAB = 1000.0F;
   class="kw">public class="kw">static class="kw">final float MIN_BROKEN_PARTICLE_RATE = 0.25F;
   class="kw">public class="kw">static class="kw">final float MAX_BROKEN_PARTICLE_RATE = 0.75F;
   @Nonnull
   class="kw">private class="kw">static class="kw">final String[] EMPTY_REPLACE_MASK = new String[0];
   @Nonnull
   class="kw">public class="kw">static class="kw">final BuilderCodec<PrefabFarmingStageData> CODEC = BuilderCodec.builder(
         PrefabFarmingStageData.class, PrefabFarmingStageData::new, FarmingStageData.BASE_CODEC
      )
      .append(
         new KeyedCodec<>("Prefabs", new WeightedMapCodec<>(PrefabFarmingStageData.PrefabStage.CODEC, PrefabFarmingStageData.PrefabStage.EMPTY_ARRAY)),
         (var0, var1) -> var0.prefabStages = var1,
         var0 -> var0.prefabStages
      )
      .add()
      .append(
         new KeyedCodec<>("ReplaceMaskTags", new ArrayCodec<>(Codec.STRING, String[]::new)),
         (var0, var1) -> var0.replaceMaskTags = var1,
         var0 -> var0.replaceMaskTags
      )
      .add()
      .append(
         new KeyedCodec<>("TolerateObstructionsBelowY", Codec.INTEGER),
         (var0, var1) -> var0.tolerateObstructionsBelowY = var1,
         var0 -> var0.tolerateObstructionsBelowY
      )
      .add()
      .append(
         new KeyedCodec<>("TolerateObstructionsAboveY", Codec.INTEGER),
         (var0, var1) -> var0.tolerateObstructionsAboveY = var1,
         var0 -> var0.tolerateObstructionsAboveY
      )
      .add()
      .afterDecode(PrefabFarmingStageData::processConfig)
      .build();
   class="kw">private class="kw">static class="kw">final AbstractCachedAccessor.Registry REGISTRY = new AbstractCachedAccessor.Registry();
   class="kw">private class="kw">static class="kw">final AbstractCachedAccessor.Key<BlockSection> BLOCK_SECTION = REGISTRY.forSection(BlockSection::getComponentType);
   class="kw">private class="kw">static class="kw">final AbstractCachedAccessor.Key<BlockComponentSection> BLOCK_COMPONENT_SECTION = REGISTRY.forSection(BlockComponentSection::getComponentType);
   class="kw">private class="kw">static class="kw">final AbstractCachedAccessor.InitFunction ACCESSOR = REGISTRY.threadLocal();
   class="kw">protected IWeightedMap<PrefabFarmingStageData.PrefabStage> prefabStages;
   class="kw">private String[] replaceMaskTags = EMPTY_REPLACE_MASK;
   class="kw">private int[] replaceMaskTagIndices;
   @Nullable
   class="kw">private Integer tolerateObstructionsBelowY;
   @Nullable
   class="kw">private Integer tolerateObstructionsAboveY;
   class="kw">private int belowToleranceMaxY = Integer.MIN_VALUE;
   class="kw">private int aboveToleranceMinY = Integer.MAX_VALUE;

   class="kw">public PrefabFarmingStageData() {
   }

   class="kw">private class="kw">static double computeParticlesRate(@Nonnull IPrefabBuffer var0) {
      double var1 = var0.getMaxX() - var0.getMinX();
      double var3 = var0.getMaxY() - var0.getMinY();
      double var5 = var0.getMaxZ() - var0.getMinZ();
      double var7 = var1 * var3 * var5;
      double var9 = -5.7142857E-4F;
      double var11 = (var7 - 125.0) * -5.7142857E-4F;
      class="kw">return MathUtil.clamp(var11 + 0.75, 0.25, 0.75);
   }

   class="kw">private class="kw">static boolean isPrefabBlockIntact(
      @Nonnull CachedAccessor var0, int var1, int var2, int var3, int var4, int var5, int var6, int var7, int var8, @Nonnull PrefabRotation var9
   ) {
      int var10 = var9.getX(var4, var6) + var1;
      int var11 = var5 + var2;
      int var12 = var9.getZ(var4, var6) + var3;
      BlockType var13 = BlockType.getAssetMap().getAsset(var7);
      if (var13 != null && var13.getMaterial() != BlockMaterial.Empty) {
         BlockSection var14 = var0.getComponentSectionAtBlock(var10, var11, var12, BLOCK_SECTION);
         if (var14 == null) {
            class="kw">return false;
         }

         int var15 = var14.get(var10, var11, var12);
         if (var15 != var7) {
            class="kw">return false;
         }

         int var16 = var9.getRotation(var8);
         int var17 = var14.getRotationIndex(var10, var11, var12);
         class="kw">return var17 == var16;
      } else {
         class="kw">return true;
      }
   }

   class="kw">private boolean isPrefabIntact(
      @Nonnull IPrefabBuffer var1, @Nonnull CachedAccessor var2, int var3, int var4, int var5, @Nonnull PrefabRotation var6, @Nonnull FastRandom var7
   ) {
      class="kw">return var1.forEachRaw(IPrefabBuffer.iterateAllColumns(), (var6x, var7x, var8, var9, var10, var11, var12, var13, var14, var15) -> {
         if (var10 < 1.0F) {
            class="kw">return true;
         } else if (var14 != 0) {
            class="kw">return true;
         } else {
            class="kw">return this.isObstructionTolerated(var7x) ? true : isPrefabBlockIntact(var2, var3, var4, var5, var6x, var7x, var8, var9, var13, var6);
         }
      }, (var0, var1x, var2x, var3x, var4x, var5x) -> true, null, new PrefabBufferCall(var7, var6));
   }

   class="kw">private boolean isObstructionTolerated(int var1) {
      class="kw">return var1 <= this.belowToleranceMaxY || var1 >= this.aboveToleranceMinY;
   }

   @Override
   class="kw">public boolean consumesRemainingTime() {
      class="kw">return true;
   }

   class="kw">public IWeightedMap<PrefabFarmingStageData.PrefabStage> getPrefabStages() {
      class="kw">return this.prefabStages;
   }

   @Override
   class="kw">public void apply(
      @Nonnull ComponentAccessor<ChunkStore> var1,
      @Nonnull Ref<ChunkStore> var2,
      @Nonnull Ref<ChunkStore> var3,
      int var4,
      int var5,
      int var6,
      @Nullable FarmingStageData var7
   ) {
      FarmingBlock var8 = var1.getComponent(var3, FarmingBlock.getComponentType());
      if (var8 == null) {
         ((HytaleLogger.Api)LOGGER.at(Level.WARNING).atMostEvery(1, TimeUnit.MINUTES))
            .log("Missing farming block component when applying prefab farming stage at (%d, %d, %d)", var4, var5, var6);
      } else {
         BlockSection var9 = var1.getComponent(var2, BlockSection.getComponentType());
         int var10 = HashUtil.randomInt(var4, var5, var6, Rotation.VALUES.length);
         RotationTuple var11 = RotationTuple.of(Rotation.VALUES[var10], Rotation.None);
         ChunkSection var12 = var1.getComponent(var2, ChunkSection.getComponentType());
         if (var12 == null) {
            ((HytaleLogger.Api)LOGGER.at(Level.WARNING).atMostEvery(1, TimeUnit.MINUTES))
               .log("Missing chunk section component when applying prefab farming stage at (%d, %d, %d)", var4, var5, var6);
         } else {
            int var13 = ChunkUtil.worldCoordFromLocalCoord(var12.getX(), var4);
            int var14 = ChunkUtil.worldCoordFromLocalCoord(var12.getY(), var5);
            int var15 = ChunkUtil.worldCoordFromLocalCoord(var12.getZ(), var6);
            IPrefabBuffer var16 = this.getCachedPrefab(var13, var14, var15, var8.getGeneration());
            if (var8.getPreviousBlockType() == null) {
               var8.setPreviousBlockType(BlockType.getAssetMap().getAsset(var9.get(var4, var5, var6)).getId());
            }

            int var17 = var16.getMaxX() - var16.getMinX();
            int var18 = var16.getMaxY() - var16.getMinY();
            int var19 = var16.getMaxZ() - var16.getMinZ();
            World var20 = var1.getExternalData().getWorld();
            CachedAccessor var21 = ACCESSOR.getAtBlock(var1, var13, var14, var15, var17, var18, var19);
            FastRandom var22 = new FastRandom();
            PrefabRotation var23 = PrefabRotation.fromRotation(var11.yaw());
            BlockTypeAssetMap var24 = BlockType.getAssetMap();
            if (var7 class="kw">instanceof PrefabFarmingStageData var25) {
               IPrefabBuffer var26 = var25.getCachedPrefab(var13, var14, var15, var8.getGeneration() - 1);
               double var27 = computeParticlesRate(var16);
               var20.execute(
                  () -> {
                     boolean var14 = var25.isPrefabIntact(var26, var21, var13, var14, var15, var23, var22);
                     if (var14) {
                        boolean var15 = var16.compare(
                           (var5x, var6x, var7x, var8x, var9x, var10x, var11x, var12x, var13x, var14x, var15x, var16x, var17x, var18x) -> {
                              int var19 = var13 + var5x;
                              int var20 = var14 + var6x;
                              int var21 = var15 + var7x;
                              if (var8x == 0 || var8x == Integer.MIN_VALUE) {
                                 class="kw">return true;
                              }

                              if (this.isObstructionTolerated(var6x)) {
                                 class="kw">return true;
                              }

                              BlockSection var22 = var21.getComponentSectionAtBlock(var19, var20, var21, BLOCK_SECTION);
                              if (var22 == null) {
                                 class="kw">return false;
                              }

                              int var23 = var22.get(var19, var20, var21);
                              class="kw">return var23 == var13x ? true : !this.doesBlockObstruct(var8x, var23);
                           }, new PrefabBufferCall(var22, var23), var26
                        );
                        if (var15) {
                           var16.compare(
                              (var10x, var11x, var12x, var13x, var14x, var15x, var16x, var17x, var18x, var19x, var20x, var21x, var22x, var23x) -> {
                                 int var24 = var13 + var10x;
                                 int var25 = var14 + var11x;
                                 int var26 = var15 + var12x;
                                 BlockSection var27 = var21.getComponentSectionAtBlock(var24, var25, var26, BLOCK_SECTION);
                                 if (var27 == null) {
                                    class="kw">return true;
                                 }

                                 int var28 = 2;
                                 if (var22.nextDouble() > var27) {
                                    var28 |= 4;
                                 }

                                 int var29 = var27.get(var24, var25, var26);
                                 if (var13x != 0 && var13x != Integer.MIN_VALUE) {
                                    BlockType var33 = var24.getAsset(var13x);
                                    if (var33 == null) {
                                       ((HytaleLogger.Api)LOGGER.at(Level.WARNING).atMostEvery(1, TimeUnit.MINUTES))
                                          .log(
                                             "Invalid block ID %d in prefab at (%d, %d, %d) for farming stage at (%d, %d, %d)",
                                             var13x,
                                             var10x,
                                             var11x,
                                             var12x,
                                             var13,
                                             var14,
                                             var15
                                          );
                                       class="kw">return true;
                                    }

                                    if (var17x != 0) {
                                       class="kw">return true;
                                    }

                                    if ((var18x == 0 || var18x == Integer.MIN_VALUE) && !this.canReplace(var29, var24)) {
                                       class="kw">return true;
                                    }

                                    if (var18x != 0 && var18x != Integer.MIN_VALUE && var18x != var29 && !this.canReplace(var29, var24)) {
                                       class="kw">return true;
                                    }

                                    Ref var31 = var21.getSectionAtBlock(var24, var25, var26);
                                    if (var31 == null) {
                                       class="kw">return true;
                                    }

                                    BlockOperations.setBlock(var1.getExternalData(), var31, var24, var25, var26, var13x, var33, var16x, var17x, var28);
                                    if (var14x != null) {
                                       BlockComponentSection var32 = var21.getComponentSectionAtBlock(var24, var25, var26, BLOCK_COMPONENT_SECTION);
                                       if (var32 == null) {
                                          class="kw">return true;
                                       }

                                       BlockEntity.setBlockEntity(var1, var31, var32, var24, var25, var26, var33, var16x, var14x.clone());
                                    }
                                 } else if (var18x != 0 && var18x != Integer.MIN_VALUE && var29 == var18x) {
                                    Ref var30 = var21.getSectionAtBlock(var24, var25, var26);
                                    if (var30 == null) {
                                       class="kw">return true;
                                    }

                                    BlockOperations.setBlock(var1.getExternalData(), var30, var24, var25, var26, 0, BlockType.EMPTY, 0, 0, var28);
                                 }

                                 class="kw">return true;
                              },
                              new PrefabBufferCall(var22, var23),
                              var26
                           );
                        }
                     }
                  }
               );
            } else {
               super.apply(var1, var2, var3, var4, var5, var6, var7);
               var20.execute(
                  () -> {
                     boolean var10 = var16.forEachRaw(
                        IPrefabBuffer.iterateAllColumns(), (var6x, var7x, var8x, var9x, var10x, var11x, var12x, var13x, var14x, var15x) -> {
                           int var16 = var13 + var23.getX(var6x, var8x);
                           int var17 = var14 + var7x;
                           int var18 = var15 + var23.getZ(var6x, var8x);
                           if (var9x == 0 || var9x == Integer.MIN_VALUE) {
                              class="kw">return true;
                           }

                           if (this.isObstructionTolerated(var7x)) {
                              class="kw">return true;
                           }

                           BlockSection var19 = var21.getComponentSectionAtBlock(var16, var17, var18, BLOCK_SECTION);
                           if (var19 == null) {
                              class="kw">return false;
                           }

                           int var20 = var19.get(var16, var17, var18);
                           class="kw">return !this.doesBlockObstruct(var9x, var20);
                        }, (var0, var1x, var2x, var3x, var4x, var5x) -> true, null, new PrefabBufferCall(var22, var23)
                     );
                     if (var10) {
                        var16.forEach(
                           IPrefabBuffer.iterateAllColumns(),
                           (var7x, var8x, var9x, var10x, var11x, var12x, var13x, var14x, var15x, var16x, var17x) -> {
                              int var18 = var13 + var7x;
                              int var19 = var14 + var8x;
                              int var20 = var15 + var9x;
                              BlockSection var21 = var21.getComponentSectionAtBlock(var18, var19, var20, BLOCK_SECTION);
                              if (var21 != null) {
                                 if (var10x != 0 && var10x != Integer.MIN_VALUE) {
                                    BlockType var22 = var24.getAsset(var10x);
                                    if (var22 == null) {
                                       ((HytaleLogger.Api)LOGGER.at(Level.WARNING).atMostEvery(1, TimeUnit.MINUTES))
                                          .log(
                                             "Invalid block ID %d in prefab at (%d, %d, %d) for farming stage at (%d, %d, %d)",
                                             var10x,
                                             var7x,
                                             var8x,
                                             var9x,
                                             var13,
                                             var14,
                                             var15
                                          );
                                       class="kw">return;
                                    }

                                    if (var14x != 0) {
                                       class="kw">return;
                                    }

                                    int var23 = var21.get(var18, var19, var20);
                                    if (!this.canReplace(var23, var24)) {
                                       class="kw">return;
                                    }

                                    Ref var24 = var21.getSectionAtBlock(var18, var19, var20);
                                    if (var24 == null) {
                                       class="kw">return;
                                    }

                                    BlockOperations.setBlock(var1.getExternalData(), var24, var18, var19, var20, var10x, var22, var13x, var14x, 2);
                                    if (var11x != null) {
                                       BlockComponentSection var25 = var21.getComponentSectionAtBlock(var18, var19, var20, BLOCK_COMPONENT_SECTION);
                                       if (var25 == null) {
                                          class="kw">return;
                                       }

                                       BlockEntity.setBlockEntity(var1, var24, var25, var18, var19, var20, var22, var13x, var11x.clone());
                                    }
                                 }
                              }
                           },
                           null,
                           null,
                           new PrefabBufferCall(var22, var23)
                        );
                     }
                  }
               );
            }
         }
      }
   }

   class="kw">private boolean doesBlockObstruct(int var1, int var2) {
      BlockTypeAssetMap var3 = BlockType.getAssetMap();
      BlockType var4 = var3.getAsset(var1);
      class="kw">return var4 != null && var4.getMaterial() != BlockMaterial.Empty ? !this.canReplace(var2, var3) : false;
   }

   class="kw">private boolean canReplace(int var1, @Nonnull BlockTypeAssetMap<String, BlockType> var2) {
      BlockType var3 = var2.getAsset(var1);
      if (var3 != null && var3.getMaterial() != BlockMaterial.Empty) {
         for (int var7 : this.replaceMaskTagIndices) {
            if (var2.getIndexesForTag(var7).contains(var1)) {
               class="kw">return true;
            }
         }

         class="kw">return false;
      } else {
         class="kw">return true;
      }
   }

   @Override
   class="kw">public void remove(@Nonnull ComponentAccessor<ChunkStore> var1, @Nonnull Ref<ChunkStore> var2, @Nonnull Ref<ChunkStore> var3, int var4, int var5, int var6) {
      super.remove(var1, var2, var3, var4, var5, var6);
      ChunkSection var7 = var1.getComponent(var2, ChunkSection.getComponentType());
      if (var7 == null) {
         ((HytaleLogger.Api)LOGGER.at(Level.WARNING).atMostEvery(1, TimeUnit.MINUTES))
            .log("Missing chunk section component when removing prefab farming stage at (%d, %d, %d)", var4, var5, var6);
      } else {
         int var8 = ChunkUtil.worldCoordFromLocalCoord(var7.getX(), var4);
         int var9 = ChunkUtil.worldCoordFromLocalCoord(var7.getY(), var5);
         int var10 = ChunkUtil.worldCoordFromLocalCoord(var7.getZ(), var6);
         FarmingBlock var11 = var1.getComponent(var3, FarmingBlock.getComponentType());
         if (var11 == null) {
            ((HytaleLogger.Api)LOGGER.at(Level.WARNING).atMostEvery(1, TimeUnit.MINUTES))
               .log("Missing farming block component when removing prefab farming stage at (%d, %d, %d)", var8, var9, var10);
         } else {
            IPrefabBuffer var12 = this.getCachedPrefab(var8, var9, var10, var11.getGeneration() - 1);
            BlockSection var13 = var1.getComponent(var2, BlockSection.getComponentType());
            if (var13 == null) {
               ((HytaleLogger.Api)LOGGER.at(Level.WARNING).atMostEvery(1, TimeUnit.MINUTES))
                  .log("Missing block section component when removing prefab farming stage at (%d, %d, %d)", var8, var9, var10);
            } else {
               RotationTuple var14 = var13.getRotation(var4, var5, var6);
               double var15 = computeParticlesRate(var12);
               World var17 = var1.getExternalData().getWorld();
               var17.execute(() -> {
                  int var8 = 1;
                  int var9 = 2;
                  PrefabUtil.remove(var12, var17, new Vector3i(var8, var9, var10), var14.yaw(), new FastRandom(), 1, 2, var15);
               });
            }
         }
      }
   }

   @Nonnull
   class="kw">private IPrefabBuffer getCachedPrefab(int var1, int var2, int var3, int var4) {
      class="kw">return PrefabBufferUtil.getCached(this.prefabStages.get(HashUtil.random(var1, var2, var3, var4)).getResolvedPath());
   }

   class="kw">private void processConfig() {
      this.replaceMaskTagIndices = new int[this.replaceMaskTags.length];

      for (int var1 = 0; var1 < this.replaceMaskTags.length; var1++) {
         this.replaceMaskTagIndices[var1] = AssetRegistry.getOrCreateTagIndex(this.replaceMaskTags[var1]);
      }

      this.belowToleranceMaxY = this.tolerateObstructionsBelowY != null ? this.tolerateObstructionsBelowY : Integer.MIN_VALUE;
      this.aboveToleranceMinY = this.tolerateObstructionsAboveY != null ? this.tolerateObstructionsAboveY : Integer.MAX_VALUE;
      if (this.belowToleranceMaxY >= this.aboveToleranceMinY) {
         LOGGER.at(Level.WARNING)
            .log(
               "Overlapping obstruction tolerance on prefab farming stage (TolerateObstructionsBelowY=%d >= TolerateObstructionsAboveY=%d); all obstructions will be tolerated",
               this.belowToleranceMaxY,
               this.aboveToleranceMinY
            );
      }
   }

   @Nonnull
   @Override
   class="kw">public String toString() {
      class="kw">return "PrefabFarmingStageData{replaceMaskTags="
         + Arrays.toString(this.replaceMaskTags)
         + ", tolerateObstructionsBelowY="
         + this.tolerateObstructionsBelowY
         + ", tolerateObstructionsAboveY="
         + this.tolerateObstructionsAboveY
         + ", prefabStages="
         + this.prefabStages
         + "}";
   }

   class="kw">public class="kw">static class PrefabStage class="kw">implements IWeightedElement {
      @Nonnull
      class="kw">public class="kw">static class="kw">final PrefabFarmingStageData.PrefabStage[] EMPTY_ARRAY = new PrefabFarmingStageData.PrefabStage[0];
      @Nonnull
      class="kw">public class="kw">static class="kw">final Codec<PrefabFarmingStageData.PrefabStage> CODEC = BuilderCodec.builder(
            PrefabFarmingStageData.PrefabStage.class, PrefabFarmingStageData.PrefabStage::new
         )
         .append(new KeyedCodec<>("Weight", Codec.INTEGER), (var0, var1) -> var0.weight = var1, var0 -> var0.weight)
         .addValidator(Validators.greaterThanOrEqual(1))
         .add()
         .<String>append(new KeyedCodec<>("Path", Codec.STRING), (var0, var1) -> var0.path = var1, var0 -> var0.path)
         .addValidator(Validators.nonNull())
         .add()
         .build();
      class="kw">protected int weight = 1;
      class="kw">protected String path;

      class="kw">public PrefabStage() {
      }

      @Override
      class="kw">public double getWeight() {
         class="kw">return this.weight;
      }

      @Nonnull
      class="kw">public Path getResolvedPath() {
         Path var1 = PrefabStore.get().findAssetPrefabPath(this.path);
         if (var1 == null) {
            throw new IllegalStateException("Invalid prefab path: " + this.path);
         } else {
            class="kw">return var1;
         }
      }

      @Nonnull
      @Override
      class="kw">public String toString() {
         class="kw">return "PrefabStage{weight=" + this.weight + ", path='" + this.path + "'}";
      }
   }
}