ChunkGenerator class

Пакет: com.hypixel.hytale.server.worldgen.chunk

Файл: com/hypixel/hytale/server/worldgen/chunk/ChunkGenerator.java

implements: IBenchmarkableWorldGen, ValidatableWorldGen, MetricProvider, IWorldMapProvider

Поля (71)

МодификаторыТипИмя
final int TINT_INTERPOLATION_RADIUS
Transform[] var10
long var10
Biome var10
int var10
InterpolatedBiomeCountList.BiomeCountResult var10
float var10
UniquePrefabContainer.UniquePrefabEntry[] var10
Random var11
double var11
ZoneBiomeResult var11
double var12
InterpolatedBiomeCountList.BiomeCountResult var12
double var13
var13
double var14
FadeContainer var15
UniquePrefabContainer.UniquePrefabEntry[] var15
double var16
ArrayList var2
int var2
var2
int var2
var2
double var2
ZonePatternGenerator var2
double var2
var2
var2
int var3
int var3
IntList var3
ArrayList var3
IntList var4
int var4
int var4
CoreDataCacheEntry var4
BitSet var4
long var5
ZoneBiomeResult var5
int var5
float var5
IntList var5
InterpolatedBiomeCountList var5
CoreDataCacheEntry var5
ZoneBiomeResult var5
int var6
int var6
int var6
int var6
double var6
InterpolatedBiomeCountList var6
CaveGenerator var6
Vector3i var7
long var7
ZonePatternGenerator var7
int var7
int var7
int var7
IntList var7
double var7
int var7
Vector3d var8
ZoneGeneratorResult var8
int var8
InterpolatedBiomeCountList.BiomeCountResult var8
Rotation3f var9
GeneratedChunk var9
ZoneGeneratorResult var9
float var9
Vector2i var9

Методы (32)

МодификаторыВозвратСигнатура
abstract return new GeneratorChunkWorldMapreturn new GeneratorChunkWorldMap(this, this.executor)
abstract throw new SkipSentryExceptionthrow new SkipSentryException(var0)
for for(int var8 = -var6; var8 <= var6; var8++)
for for(int var9 = -var6; var9 <= var6; var9++)
abstract for for(int var6 = var4.size()
abstract for for(int var5 = var3.size()
abstract for for(int var9 = var7.size()
abstract for for(int var7 = var5.size()
abstract for for(int var8 = this.generateHighestThresholdDependent(var5)
abstract for for(int var9 = this.generateHighestThresholdDependent(var6)
public int generateHeightint generateHeight(int var1, int var2, int var3)
public int generateHeightBetweenint generateHeightBetween(int var1, int var2, int var3, @Nonnull IHeightThresholdInterpreter var4)
public int generateHighestThresholdDependentint generateHighestThresholdDependent(@Nonnull InterpolatedBiomeCountList var1)
public void generateInterpolatedBiomeCountAtvoid generateInterpolatedBiomeCountAt(int var1, int var2, int var3, @Nonnull InterpolatedBiomeCountList var4)
public double generateInterpolatedHeightNoisedouble generateInterpolatedHeightNoise(@Nonnull InterpolatedBiomeCountList var1)
static float generateInterpolatedThresholdfloat generateInterpolatedThreshold(int var0, int var1, int var2, int var3, @Nonnull InterpolatedBiomeCountList var4)
public int generateLowestThresholdDependentint generateLowestThresholdDependent(@Nonnull InterpolatedBiomeCountList var1)
public Path getDataFolderPath getDataFolder()
public int getHeightint getHeight(int var1, int var2, int var3)
static int getLargestFeatureChunkExtentsint getLargestFeatureChunkExtents(@Nonnull ZonePatternProvider var0, int var1)
static ChunkGeneratorResource getResourceChunkGeneratorResource getResource()
public ZoneBiomeResult getZoneBiomeResultAtZoneBiomeResult getZoneBiomeResultAt(int var1, int var2, int var3)
public ZonePatternProvider getZonePatternProviderZonePatternProvider getZonePatternProvider()
if if(var8 != 0 || var9 != 0)
if if(var10 <= var7)
if if(var7 > var2)
if if(var9 > var6 || var9 == 1.0)
if if(var10 > var7 || var10 == 1.0)
if if(var6 == null)
public boolean isChunkOutsideGeneratableAreaboolean isChunkOutsideGeneratableArea(int var1, int var2)
final void onExecutorShutdownvoid onExecutorShutdown()
public void putHeightvoid putHeight(int var1, int var2, int var3, int var4)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.worldgen.chunk;

class="kw">import com.hypixel.hytale.function.consumer.IntObjectConsumer;
class="kw">import com.hypixel.hytale.function.function.IntObjectFunction;
class="kw">import com.hypixel.hytale.logger.sentry.SkipSentryException;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import com.hypixel.hytale.math.vector.Rotation3f;
class="kw">import com.hypixel.hytale.math.vector.Transform;
class="kw">import com.hypixel.hytale.metrics.MetricProvider;
class="kw">import com.hypixel.hytale.metrics.MetricResults;
class="kw">import com.hypixel.hytale.procedurallib.condition.IHeightThresholdInterpreter;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.GeneratedChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.IBenchmarkableWorldGen;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.ValidatableWorldGen;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.WorldGenTimingsCollector;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldmap.IWorldMap;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldmap.WorldMapLoadException;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldmap.provider.IWorldMapProvider;
class="kw">import com.hypixel.hytale.server.worldgen.ChunkGeneratorResource;
class="kw">import com.hypixel.hytale.server.worldgen.benchmark.ChunkWorldgenBenchmark;
class="kw">import com.hypixel.hytale.server.worldgen.biome.Biome;
class="kw">import com.hypixel.hytale.server.worldgen.cache.CaveGeneratorCache;
class="kw">import com.hypixel.hytale.server.worldgen.cache.ChunkGeneratorCache;
class="kw">import com.hypixel.hytale.server.worldgen.cache.CoreDataCacheEntry;
class="kw">import com.hypixel.hytale.server.worldgen.cache.InterpolatedBiomeCountList;
class="kw">import com.hypixel.hytale.server.worldgen.cache.UniquePrefabCache;
class="kw">import com.hypixel.hytale.server.worldgen.cave.Cave;
class="kw">import com.hypixel.hytale.server.worldgen.cave.CaveGenerator;
class="kw">import com.hypixel.hytale.server.worldgen.cave.CaveType;
class="kw">import com.hypixel.hytale.server.worldgen.container.FadeContainer;
class="kw">import com.hypixel.hytale.server.worldgen.container.PrefabContainer;
class="kw">import com.hypixel.hytale.server.worldgen.container.UniquePrefabContainer;
class="kw">import com.hypixel.hytale.server.worldgen.map.GeneratorChunkWorldMap;
class="kw">import com.hypixel.hytale.server.worldgen.prefab.PrefabLoadingCache;
class="kw">import com.hypixel.hytale.server.worldgen.util.ArrayUtli;
class="kw">import com.hypixel.hytale.server.worldgen.util.ChunkThreadPoolExecutor;
class="kw">import com.hypixel.hytale.server.worldgen.util.ChunkWorkerThreadFactory;
class="kw">import com.hypixel.hytale.server.worldgen.util.LogUtil;
class="kw">import com.hypixel.hytale.server.worldgen.zone.Zone;
class="kw">import com.hypixel.hytale.server.worldgen.zone.ZoneGeneratorResult;
class="kw">import com.hypixel.hytale.server.worldgen.zone.ZonePatternGenerator;
class="kw">import com.hypixel.hytale.server.worldgen.zone.ZonePatternGeneratorCache;
class="kw">import com.hypixel.hytale.server.worldgen.zone.ZonePatternProvider;
class="kw">import it.unimi.dsi.fastutil.ints.IntList;
class="kw">import it.unimi.dsi.fastutil.longs.Long2FloatFunction;
class="kw">import java.nio.file.Path;
class="kw">import java.util.ArrayList;
class="kw">import java.util.Arrays;
class="kw">import java.util.BitSet;
class="kw">import java.util.Random;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.LinkedBlockingQueue;
class="kw">import java.util.concurrent.ThreadPoolExecutor;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.function.LongPredicate;
class="kw">import java.util.function.Supplier;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector2i;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3i;

class="kw">public class ChunkGenerator class="kw">implements IBenchmarkableWorldGen, ValidatableWorldGen, MetricProvider, IWorldMapProvider {
   class="kw">public class="kw">static class="kw">final int TINT_INTERPOLATION_RADIUS = 4;
   class="kw">private class="kw">static class="kw">final int CHUNK_BOUNDS_PADDING = 16;
   class="kw">private class="kw">static class="kw">final CompletableFuture<GeneratedChunk> NO_CHUNK = CompletableFuture.completedFuture(null);
   class="kw">private class="kw">static class="kw">final ThreadLocal<ChunkGeneratorResource> THREAD_LOCAL = ThreadLocal.withInitial(ChunkGeneratorResource::new);
   class="kw">public class="kw">static class="kw">final int POOL_SIZE = Math.max(2, MathUtil.fastCeil(Runtime.getRuntime().availableProcessors() * 0.75F));
   @Nonnull
   class="kw">private class="kw">final ThreadPoolExecutor executor;
   @Nonnull
   class="kw">private class="kw">final WorldGenTimingsCollector timings;
   class="kw">private class="kw">final ZonePatternProvider zonePatternProvider;
   class="kw">private class="kw">final ZonePatternGeneratorCache zonePatternGeneratorCache;
   @Nonnull
   class="kw">private class="kw">final ChunkGeneratorCache generatorCache;
   @Nonnull
   class="kw">private class="kw">final CaveGeneratorCache caveGeneratorCache;
   @Nonnull
   class="kw">private class="kw">final PrefabLoadingCache prefabLoadingCache;
   @Nonnull
   class="kw">private class="kw">final UniquePrefabCache uniquePrefabCache;
   @Nonnull
   class="kw">private class="kw">final ChunkWorldgenBenchmark benchmark;
   @Nonnull
   class="kw">private class="kw">final Supplier<GeneratedChunk> generatedChunkSupplier;
   class="kw">private class="kw">final Path dataFolder;
   class="kw">private class="kw">final int minChunkCoord;
   class="kw">private class="kw">final int maxChunkCoord;

   class="kw">public ChunkGenerator(ZonePatternProvider var1, Path var2) {
      this.dataFolder = var2;
      this.executor = new ChunkThreadPoolExecutor(
         POOL_SIZE,
         POOL_SIZE,
         60L,
         TimeUnit.SECONDS,
         new LinkedBlockingQueue<>(),
         new ChunkWorkerThreadFactory(this, "ChunkGenerator-%d-Worker-%d"),
         this::onExecutorShutdown
      );
      this.executor.allowCoreThreadTimeOut(true);
      this.timings = new WorldGenTimingsCollector(this.executor);
      this.zonePatternProvider = var1;
      this.zonePatternGeneratorCache = new ZonePatternGeneratorCache(var1);
      this.generatorCache = new ChunkGeneratorCache(
         this::generateZoneBiomeResultAt, this::generateInterpolatedBiomeCountAt, this::generateHeight, this::generateInterpolatedHeightNoise, 50000, 20L
      );
      this.caveGeneratorCache = new CaveGeneratorCache(this::generateCave, 5000, 30L);
      this.uniquePrefabCache = new UniquePrefabCache(this::generateUniquePrefabs, 50, 300L);
      this.prefabLoadingCache = new PrefabLoadingCache();
      this.generatedChunkSupplier = GeneratedChunk::new;
      this.benchmark = new ChunkWorldgenBenchmark();
      int var3 = getLargestFeatureChunkExtents(var1, 16);
      this.minChunkCoord = -67108864 + var3;
      this.maxChunkCoord = 67108863 - var3;
   }

   class="kw">public ZonePatternProvider getZonePatternProvider() {
      class="kw">return this.zonePatternProvider;
   }

   @Override
   class="kw">public WorldGenTimingsCollector getTimings() {
      class="kw">return this.timings;
   }

   @Nonnull
   @Override
   class="kw">public IWorldMap getGenerator(World var1) class="kw">throws WorldMapLoadException {
      class="kw">return new GeneratorChunkWorldMap(this, this.executor);
   }

   @Override
   class="kw">public Transform[] getSpawnPoints(int var1) {
      class="kw">return CompletableFuture.<Transform[]>supplyAsync(() -> {
         ArrayList var2 = new ArrayList<>();

         for (UniquePrefabContainer.UniquePrefabEntry var6 : this.getUniquePrefabs(var1)) {
            if (var6.isSpawnLocation()) {
               Vector3i var7 = var6.getPosition();
               Vector3d var8 = new Vector3d(var6.getSpawnOffset());
               Rotation3f var9 = new Rotation3f();
               var6.getRotation().rotate(var8);
               var9.addYaw(-var6.getRotation().getYaw());
               var2.add(new Transform(var8.add(var7.x, var7.y, var7.z).add(0.5, 0.0, 0.5), var9));
            }
         }

         if (var2.isEmpty()) {
            var2.add(new Transform(16.5, -1.0, 16.5));
         }

         Transform[] var10 = var2.toArray(Transform[]::new);
         Random var11 = getResource().random;
         var11.setSeed(var1 * 1494360372L);
         ArrayUtli.shuffleArray(var10, var11);
         class="kw">return var10;
      }, this.executor).join();
   }

   @Nonnull
   class="kw">public ChunkWorldgenBenchmark getBenchmark() {
      class="kw">return this.benchmark;
   }

   class="kw">public Path getDataFolder() {
      class="kw">return this.dataFolder;
   }

   @Nullable
   class="kw">public CoreDataCacheEntry getCoreData(int var1, int var2, int var3) {
      class="kw">return this.generatorCache.get(var1, var2, var3);
   }

   @Nonnull
   class="kw">public ZonePatternGenerator getZonePatternGenerator(int var1) {
      class="kw">return this.zonePatternGeneratorCache.get(var1);
   }

   class="kw">public ZoneBiomeResult getZoneBiomeResultAt(int var1, int var2, int var3) {
      class="kw">return this.generatorCache.getZoneBiomeResult(var1, var2, var3);
   }

   class="kw">public int getHeight(int var1, int var2, int var3) {
      class="kw">return this.generatorCache.getHeight(var1, var2, var3);
   }

   class="kw">public void putHeight(int var1, int var2, int var3, int var4) {
      this.generatorCache.putHeight(var1, var2, var3, var4);
   }

   @Nullable
   class="kw">public InterpolatedBiomeCountList getInterpolatedBiomeCountAt(int var1, int var2, int var3) {
      class="kw">return this.generatorCache.getBiomeCountResult(var1, var2, var3);
   }

   @Nullable
   class="kw">public Cave getCave(@Nonnull CaveType var1, int var2, int var3, int var4) {
      class="kw">return this.caveGeneratorCache.get(var1, var2, var3, var4);
   }

   @Nonnull
   class="kw">public CompletableFuture<Cave> getCaveAsync(@Nonnull CaveType var1, int var2, int var3, int var4) {
      class="kw">return CompletableFuture.supplyAsync(() -> this.getCave(var1, var2, var3, var4), this.executor);
   }

   @Nonnull
   class="kw">public PrefabLoadingCache getPrefabLoadingCache() {
      class="kw">return this.prefabLoadingCache;
   }

   @Nullable
   class="kw">public UniquePrefabContainer.UniquePrefabEntry[] getUniquePrefabs(int var1) {
      class="kw">return this.uniquePrefabCache.get(var1);
   }

   @Nonnull
   @Override
   class="kw">public CompletableFuture<GeneratedChunk> generate(int var1, long var2, int var4, int var5, @Nullable LongPredicate var6, Long2FloatFunction var7) {
      class="kw">return this.isChunkOutsideGeneratableArea(var4, var5) ? NO_CHUNK : CompletableFuture.<GeneratedChunk>supplyAsync(() -> {
         if (var6 != null && !var6.test(var2)) {
            class="kw">return null;
         }

         long var7 = -System.nanoTime();
         GeneratedChunk var9 = this.generatedChunkSupplier.get();
         var9.getBlockChunk().setCoordinates(var2, var4, var5);
         new ChunkGeneratorExecution(var1, this, var9).execute(var1);
         long var10 = System.nanoTime();
         double var12 = (var10 + var7) / 1.0E9;
         double var14 = this.timings.reportChunk(var10 + var7);
         if (var14 != this.timings.getWarmupValue()) {
            LogUtil.getLogger().at(Level.FINEST).log("Time taken: %s (avg: %s) (%s)", var12, var14, this.timings);
         } else {
            LogUtil.getLogger().at(Level.FINEST).log("Time taken: %s (warming up)", var12);
         }

         class="kw">return var9;
      }, this.executor).exceptionally(var0 -> {
         throw new SkipSentryException(var0);
      });
   }

   @Override
   class="kw">public void shutdown() {
      this.executor.shutdown();
   }

   @Nonnull
   class="kw">public ZoneBiomeResult generateZoneBiomeResultAt(int var1, int var2, int var3) {
      class="kw">return this.generateZoneBiomeResultAt(var1, var2, var3, new ZoneBiomeResult());
   }

   @Nonnull
   class="kw">public ZoneBiomeResult generateZoneBiomeResultAt(int var1, int var2, int var3, @Nonnull ZoneBiomeResult var4) {
      long var5 = -System.nanoTime();
      ZonePatternGenerator var7 = this.getZonePatternGenerator(var1);
      ZoneGeneratorResult var8 = var4.getZoneResult();
      ZoneGeneratorResult var9 = var7.generate(var1, var2, var3, var8 != null ? var8 : new ZoneGeneratorResult());
      Biome var10 = var9.getZone().biomePatternGenerator().generateBiomeAt(var9, var1, var2, var3);
      double var11 = var10.getHeightmapInterpreter().getContext(var1, var2, var3);
      double var13 = var10.getHeightmapNoise().get(var1, var2, var3);
      FadeContainer var15 = var10.getFadeContainer();
      if (var15.shouldFade()) {
         double var16 = var15.getTerrainFactor(var9);
         var13 = var13 * (1.0 - var16) + var15.getFadeHeightmap() * var16;
      }

      var4.setZoneResult(var9);
      var4.setBiome(var10);
      var4.setHeightThresholdContext(var11);
      var4.setHeightmapNoise(var13);
      this.timings.reportZoneBiomeResult(var5 + System.nanoTime());
      class="kw">return var4;
   }

   class="kw">public void generateInterpolatedBiomeCountAt(int var1, int var2, int var3, @Nonnull InterpolatedBiomeCountList var4) {
      ZoneBiomeResult var5 = this.getZoneBiomeResultAt(var1, var2, var3);
      var4.setCenter(var5);
      int var6 = var5.getBiome().getInterpolation().getRadius();
      int var7 = var6 * var6;

      for (int var8 = -var6; var8 <= var6; var8++) {
         for (int var9 = -var6; var9 <= var6; var9++) {
            if (var8 != 0 || var9 != 0) {
               int var10 = var8 * var8 + var9 * var9;
               if (var10 <= var7) {
                  ZoneBiomeResult var11 = this.getZoneBiomeResultAt(var1, var2 + var8, var3 + var9);
                  var4.add(var11, var10);
               }
            }
         }
      }

      if (var4.getBiomeIds().size() == 1) {
         InterpolatedBiomeCountList.BiomeCountResult var12 = var4.get(var5.getBiome());
         var12.heightNoise = var5.heightmapNoise;
         var12.count = 1;
      }
   }

   class="kw">public int generateLowestThresholdDependent(@Nonnull InterpolatedBiomeCountList var1) {
      int var2 = 320;
      IntList var4 = var1.getBiomeIds();
      int var5 = 0;

      for (int var6 = var4.size(); var5 < var6; var5++) {
         int var7 = var4.getInt(var5);
         int var3;
         if ((var3 = var1.get(var7).biome.getHeightmapInterpreter().getLowestNonOne()) < var2) {
            var2 = var3;
         }
      }

      class="kw">return var2;
   }

   class="kw">public int generateHighestThresholdDependent(@Nonnull InterpolatedBiomeCountList var1) {
      int var2 = -1;
      IntList var3 = var1.getBiomeIds();
      int var4 = 0;

      for (int var5 = var3.size(); var4 < var5; var4++) {
         int var6 = var3.getInt(var4);
         int var7 = var1.get(var6).biome.getHeightmapInterpreter().getHighestNonZero();
         if (var7 > var2) {
            var2 = var7;
         }
      }

      class="kw">return var2;
   }

   class="kw">public class="kw">static float generateInterpolatedThreshold(int var0, int var1, int var2, int var3, @Nonnull InterpolatedBiomeCountList var4) {
      float var5 = 0.0F;
      int var6 = 0;
      IntList var7 = var4.getBiomeIds();
      int var8 = 0;

      for (int var9 = var7.size(); var8 < var9; var8++) {
         InterpolatedBiomeCountList.BiomeCountResult var10 = var4.get(var7.getInt(var8));
         var5 += var10.biome.getHeightmapInterpreter().getThreshold(var0, var1, var2, var3, var10.heightThresholdContext) * var10.count;
         var6 += var10.count;
      }

      class="kw">return var5 / var6;
   }

   class="kw">public double generateInterpolatedHeightNoise(@Nonnull InterpolatedBiomeCountList var1) {
      double var2 = 0.0;
      int var4 = 0;
      IntList var5 = var1.getBiomeIds();
      int var6 = 0;

      for (int var7 = var5.size(); var6 < var7; var6++) {
         InterpolatedBiomeCountList.BiomeCountResult var8 = var1.get(var5.getInt(var6));
         var2 += var8.heightNoise * var8.count;
         var4 += var8.count;
      }

      class="kw">return var2 / var4;
   }

   class="kw">public int generateHeight(int var1, int var2, int var3) {
      CoreDataCacheEntry var4 = this.getCoreData(var1, var2, var3);
      this.generatorCache.ensureHeightNoise(var1, var2, var3, var4);
      InterpolatedBiomeCountList var5 = var4.biomeCountList;
      double var6 = var4.heightNoise;

      for (int var8 = this.generateHighestThresholdDependent(var5); var8 > 0; var8--) {
         float var9 = generateInterpolatedThreshold(var1, var2, var3, var8, var5);
         if (var9 > var6 || var9 == 1.0) {
            class="kw">return var8;
         }
      }

      class="kw">return 0;
   }

   class="kw">public int generateHeightBetween(int var1, int var2, int var3, @Nonnull IHeightThresholdInterpreter var4) {
      CoreDataCacheEntry var5 = this.getCoreData(var1, var2, var3);
      this.generatorCache.ensureHeightNoise(var1, var2, var3, var5);
      InterpolatedBiomeCountList var6 = var5.biomeCountList;
      double var7 = var5.heightNoise;

      for (int var9 = this.generateHighestThresholdDependent(var6); var9 > 0; var9--) {
         if (var4.isSpawnable(var9)) {
            float var10 = generateInterpolatedThreshold(var1, var2, var3, var9, var6);
            if (var10 > var7 || var10 == 1.0) {
               class="kw">return var9;
            }
         }
      }

      class="kw">return 0;
   }

   @Nullable
   class="kw">public Cave generateCave(@Nonnull CaveType var1, int var2, int var3, int var4) {
      ZoneBiomeResult var5 = this.getZoneBiomeResultAt(var2, var3, var4);
      CaveGenerator var6 = var5.zoneResult.getZone().caveGenerator();
      if (var6 == null) {
         class="kw">return null;
      }

      int var7 = this.getHeight(var2, var3, var4);
      class="kw">return var6.generate(var2, this, var1, var3, var7, var4);
   }

   @Nonnull
   class="kw">public UniquePrefabContainer.UniquePrefabEntry[] generateUniquePrefabs(int var1) {
      ZonePatternGenerator var2 = this.getZonePatternGenerator(var1);
      ArrayList var3 = new ArrayList<>();
      BitSet var4 = new BitSet(var2.getZones().length);

      for (Zone.Unique var8 : var2.getUniqueZones()) {
         Vector2i var9 = var8.getPosition();
         UniquePrefabContainer.UniquePrefabEntry[] var10 = var8.zone().uniquePrefabContainer().generate(var1, var9, this);
         var3.addAll(Arrays.asList(var10));
         var4.set(var8.zone().id());
      }

      for (Zone var14 : var2.getZones()) {
         if (!var4.get(var14.id())) {
            UniquePrefabContainer.UniquePrefabEntry[] var15 = var14.uniquePrefabContainer().generate(var1, (Vector2i)null, this);
            var3.addAll(Arrays.asList(var15));
         }
      }

      class="kw">return var3.toArray(UniquePrefabContainer.UniquePrefabEntry[]::new);
   }

   @Deprecated(forRemoval = true, since = "2026-06-16")
   @Nonnull
   class="kw">public CompletableFuture<Void> run(int var1, @Nonnull IntObjectConsumer<ChunkGenerator> var2) {
      class="kw">return CompletableFuture.runAsync(() -> var2.accept(var1, this), this.executor);
   }

   @Deprecated(forRemoval = true, since = "2026-06-16")
   @Nonnull
   class="kw">public <T> CompletableFuture<T> execute(int var1, @Nonnull IntObjectFunction<ChunkGenerator, T> var2) {
      class="kw">return CompletableFuture.supplyAsync(() -> var2.apply(var1, this), this.executor);
   }

   class="kw">protected class="kw">final void onExecutorShutdown() {
      this.prefabLoadingCache.clear();
   }

   class="kw">public class="kw">static ChunkGeneratorResource getResource() {
      class="kw">return THREAD_LOCAL.get();
   }

   class="kw">public boolean isChunkOutsideGeneratableArea(int var1, int var2) {
      class="kw">return var1 < this.minChunkCoord || var1 > this.maxChunkCoord || var2 < this.minChunkCoord || var2 > this.maxChunkCoord;
   }

   @Override
   class="kw">public boolean validate() {
      class="kw">return !ValidationUtil.isInvalid(this.zonePatternProvider, this.executor);
   }

   @Nonnull
   @Override
   class="kw">public MetricResults toMetricResults() {
      class="kw">return WorldGenTimingsCollector.METRICS_REGISTRY.toMetricResults(this.timings);
   }

   @Nonnull
   class="kw">public String toString(boolean var1, boolean var2) {
      class="kw">return "ChunkGenerator{timings="
         + (var1 ? this.timings : "-hidden-")
         + ", zonePatternProvider="
         + (var2 ? this.zonePatternProvider : "-hidden-")
         + ", generatorCache="
         + this.generatorCache
         + ", caveGeneratorCache="
         + this.caveGeneratorCache
         + ", uniquePrefabCache="
         + this.uniquePrefabCache
         + "}";
   }

   @Nonnull
   @Override
   class="kw">public String toString() {
      class="kw">return this.toString(true, true);
   }

   class="kw">private class="kw">static int getLargestFeatureChunkExtents(@Nonnull ZonePatternProvider var0, int var1) {
      double var2 = 0.0;

      for (Zone var7 : var0.getZones()) {
         if (var7.caveGenerator() != null) {
            for (CaveType var11 : var7.caveGenerator().getCaveTypes()) {
               var2 = Math.max(var2, var11.getMaximumSize());
            }
         }

         for (Biome var19 : var7.biomePatternGenerator().getBiomes()) {
            if (var19.getPrefabContainer() != null) {
               for (PrefabContainer.PrefabContainerEntry var15 : var19.getPrefabContainer().getEntries()) {
                  var2 = Math.max(var2, var15.getPrefabPatternGenerator().getMaxSize());
               }
            }
         }
      }

      class="kw">return ChunkUtil.chunkCoordinate(MathUtil.ceil(var2)) + var1;
   }
}