mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-10-26 15:13:45 +01:00 
			
		
		
		
	Compare commits
	
		
			12 Commits
		
	
	
		
			fix/compon
			...
			feature/v7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 62f842eae5 | ||
|   | 76c2f0ff0b | ||
|   | 802edcba9f | ||
|   | 6187569086 | ||
|   | 94925323e8 | ||
|   | 666a60a1c7 | ||
|   | cdc8cdc497 | ||
|   | 307a1a6deb | ||
|   | 84c9bb0d92 | ||
|   | 1b08fc5419 | ||
|   | 9188c8c40d | ||
|   | 43150abb86 | 
| @@ -22,20 +22,30 @@ import com.plotsquared.bukkit.queue.GenChunk; | |||||||
| import com.plotsquared.bukkit.util.BukkitUtil; | import com.plotsquared.bukkit.util.BukkitUtil; | ||||||
| import com.plotsquared.bukkit.util.BukkitWorld; | import com.plotsquared.bukkit.util.BukkitWorld; | ||||||
| import com.plotsquared.core.PlotSquared; | import com.plotsquared.core.PlotSquared; | ||||||
|  | import com.plotsquared.core.generator.ClassicPlotWorld; | ||||||
| import com.plotsquared.core.generator.GeneratorWrapper; | import com.plotsquared.core.generator.GeneratorWrapper; | ||||||
| import com.plotsquared.core.generator.IndependentPlotGenerator; | import com.plotsquared.core.generator.IndependentPlotGenerator; | ||||||
| import com.plotsquared.core.generator.SingleWorldGenerator; | import com.plotsquared.core.generator.SingleWorldGenerator; | ||||||
| import com.plotsquared.core.location.ChunkWrapper; | import com.plotsquared.core.location.ChunkWrapper; | ||||||
|  | import com.plotsquared.core.location.UncheckedWorldLocation; | ||||||
| import com.plotsquared.core.plot.PlotArea; | import com.plotsquared.core.plot.PlotArea; | ||||||
| import com.plotsquared.core.plot.world.PlotAreaManager; | import com.plotsquared.core.plot.world.PlotAreaManager; | ||||||
| import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator; | import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator; | ||||||
| import com.plotsquared.core.util.ChunkManager; | import com.plotsquared.core.util.ChunkManager; | ||||||
|  | import com.sk89q.worldedit.bukkit.BukkitAdapter; | ||||||
| import com.sk89q.worldedit.math.BlockVector2; | import com.sk89q.worldedit.math.BlockVector2; | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.bukkit.HeightMap; | ||||||
| import org.bukkit.World; | import org.bukkit.World; | ||||||
| import org.bukkit.block.Biome; | import org.bukkit.block.Biome; | ||||||
|  | import org.bukkit.generator.BiomeProvider; | ||||||
| import org.bukkit.generator.BlockPopulator; | import org.bukkit.generator.BlockPopulator; | ||||||
| import org.bukkit.generator.ChunkGenerator; | import org.bukkit.generator.ChunkGenerator; | ||||||
|  | import org.bukkit.generator.WorldInfo; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.jetbrains.annotations.NotNull; | ||||||
|  | import org.jetbrains.annotations.Nullable; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @@ -44,6 +54,8 @@ import java.util.Set; | |||||||
|  |  | ||||||
| public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> { | public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> { | ||||||
|  |  | ||||||
|  |     private static final Logger LOGGER =  LogManager.getLogger("PlotSquared/" + BukkitPlotGenerator.class.getSimpleName()); | ||||||
|  |  | ||||||
|     @SuppressWarnings("unused") |     @SuppressWarnings("unused") | ||||||
|     public final boolean PAPER_ASYNC_SAFE = true; |     public final boolean PAPER_ASYNC_SAFE = true; | ||||||
|  |  | ||||||
| @@ -52,9 +64,15 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap | |||||||
|     private final ChunkGenerator platformGenerator; |     private final ChunkGenerator platformGenerator; | ||||||
|     private final boolean full; |     private final boolean full; | ||||||
|     private final String levelName; |     private final String levelName; | ||||||
|  |     private final boolean useNewGenerationMethods; | ||||||
|  |     private final BiomeProvider biomeProvider; | ||||||
|     private List<BlockPopulator> populators; |     private List<BlockPopulator> populators; | ||||||
|     private boolean loaded = false; |     private boolean loaded = false; | ||||||
|  |  | ||||||
|  |     private PlotArea lastPlotArea; | ||||||
|  |     private int lastChunkX = Integer.MIN_VALUE; | ||||||
|  |     private int lastChunkZ = Integer.MIN_VALUE; | ||||||
|  |  | ||||||
|     public BukkitPlotGenerator( |     public BukkitPlotGenerator( | ||||||
|             final @NonNull String name, |             final @NonNull String name, | ||||||
|             final @NonNull IndependentPlotGenerator generator, |             final @NonNull IndependentPlotGenerator generator, | ||||||
| @@ -72,18 +90,23 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap | |||||||
|             this.populators.add(new LegacyBlockStatePopulator(this.plotGenerator)); |             this.populators.add(new LegacyBlockStatePopulator(this.plotGenerator)); | ||||||
|         } |         } | ||||||
|         this.full = true; |         this.full = true; | ||||||
|  |         this.useNewGenerationMethods = PlotSquared.platform().serverVersion()[1] >= 17; | ||||||
|  |         this.biomeProvider = new BukkitPlotBiomeProvider(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public BukkitPlotGenerator(final String world, final ChunkGenerator cg, final @NonNull PlotAreaManager plotAreaManager) { |     public BukkitPlotGenerator(final String world, final ChunkGenerator cg, final @NonNull PlotAreaManager plotAreaManager) { | ||||||
|         if (cg instanceof BukkitPlotGenerator) { |         if (cg instanceof BukkitPlotGenerator) { | ||||||
|             throw new IllegalArgumentException("ChunkGenerator: " + cg.getClass().getName() |             throw new IllegalArgumentException("ChunkGenerator: " + cg | ||||||
|                     + " is already a BukkitPlotGenerator!"); |                     .getClass() | ||||||
|  |                     .getName() + " is already a BukkitPlotGenerator!"); | ||||||
|         } |         } | ||||||
|         this.plotAreaManager = plotAreaManager; |         this.plotAreaManager = plotAreaManager; | ||||||
|         this.levelName = world; |         this.levelName = world; | ||||||
|         this.full = false; |         this.full = false; | ||||||
|         this.platformGenerator = cg; |         this.platformGenerator = cg; | ||||||
|         this.plotGenerator = new DelegatePlotGenerator(cg, world); |         this.plotGenerator = new DelegatePlotGenerator(cg, world); | ||||||
|  |         this.useNewGenerationMethods = PlotSquared.platform().serverVersion()[1] >= 19; | ||||||
|  |         this.biomeProvider = null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -111,7 +134,7 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap | |||||||
|         try { |         try { | ||||||
|             checkLoaded(world); |             checkLoaded(world); | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             e.printStackTrace(); |             LOGGER.error("Error attempting to load world into PlotSquared.", e); | ||||||
|         } |         } | ||||||
|         ArrayList<BlockPopulator> toAdd = new ArrayList<>(); |         ArrayList<BlockPopulator> toAdd = new ArrayList<>(); | ||||||
|         List<BlockPopulator> existing = world.getPopulators(); |         List<BlockPopulator> existing = world.getPopulators(); | ||||||
| @@ -128,6 +151,7 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap | |||||||
|         return toAdd; |         return toAdd; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // Extracted to synchronized method for thread-safety, preventing multiple internal world load calls | ||||||
|     private synchronized void checkLoaded(@NonNull World world) { |     private synchronized void checkLoaded(@NonNull World world) { | ||||||
|         // Do not attempt to load configurations until WorldEdit has a platform ready. |         // Do not attempt to load configurations until WorldEdit has a platform ready. | ||||||
|         if (!PlotSquared.get().isWeInitialised()) { |         if (!PlotSquared.get().isWeInitialised()) { | ||||||
| @@ -153,7 +177,7 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @SuppressWarnings("deprecation") |     @SuppressWarnings("deprecation") // Kept for compatibility with <=1.17.1 | ||||||
|     private void setSpawnLimits(@NonNull World world, int limit) { |     private void setSpawnLimits(@NonNull World world, int limit) { | ||||||
|         world.setAmbientSpawnLimit(limit); |         world.setAmbientSpawnLimit(limit); | ||||||
|         world.setAnimalSpawnLimit(limit); |         world.setAnimalSpawnLimit(limit); | ||||||
| @@ -162,10 +186,112 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public @NonNull ChunkData generateChunkData( |     public void generateNoise( | ||||||
|             @NonNull World world, @NonNull Random random, int x, int z, |             @NotNull final WorldInfo worldInfo, | ||||||
|             @NonNull BiomeGrid biome |             @NotNull final Random random, | ||||||
|  |             final int chunkX, | ||||||
|  |             final int chunkZ, | ||||||
|  |             @NotNull final ChunkData chunkData | ||||||
|     ) { |     ) { | ||||||
|  |         if (this.platformGenerator != this) { | ||||||
|  |             this.platformGenerator.generateNoise(worldInfo, random, chunkX, chunkZ, chunkData); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         int minY = chunkData.getMinHeight(); | ||||||
|  |         int maxY = chunkData.getMaxHeight(); | ||||||
|  |         GenChunk result = new GenChunk(minY, maxY); | ||||||
|  |         // Set the chunk location | ||||||
|  |         result.setChunk(new ChunkWrapper(worldInfo.getName(), chunkX, chunkZ)); | ||||||
|  |         // Set the result data | ||||||
|  |         result.setChunkData(chunkData); | ||||||
|  |         result.result = null; | ||||||
|  |  | ||||||
|  |         // Catch any exceptions (as exceptions usually thrown) | ||||||
|  |         try { | ||||||
|  |             generate(BlockVector2.at(chunkX, chunkZ), worldInfo.getName(), result, false); | ||||||
|  |         } catch (Throwable e) { | ||||||
|  |             LOGGER.error("Error attempting to generate chunk.", e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void generateSurface( | ||||||
|  |             @NotNull final WorldInfo worldInfo, | ||||||
|  |             @NotNull final Random random, | ||||||
|  |             final int chunkX, | ||||||
|  |             final int chunkZ, | ||||||
|  |             @NotNull final ChunkData chunkData | ||||||
|  |     ) { | ||||||
|  |         if (platformGenerator != this) { | ||||||
|  |             platformGenerator.generateSurface(worldInfo, random, chunkX, chunkZ, chunkData); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void generateBedrock( | ||||||
|  |             @NotNull final WorldInfo worldInfo, | ||||||
|  |             @NotNull final Random random, | ||||||
|  |             final int chunkX, | ||||||
|  |             final int chunkZ, | ||||||
|  |             @NotNull final ChunkData chunkData | ||||||
|  |     ) { | ||||||
|  |         if (platformGenerator != this) { | ||||||
|  |             platformGenerator.generateBedrock(worldInfo, random, chunkX, chunkZ, chunkData); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void generateCaves( | ||||||
|  |             @NotNull final WorldInfo worldInfo, | ||||||
|  |             @NotNull final Random random, | ||||||
|  |             final int chunkX, | ||||||
|  |             final int chunkZ, | ||||||
|  |             @NotNull final ChunkData chunkData | ||||||
|  |     ) { | ||||||
|  |         if (platformGenerator != this) { | ||||||
|  |             platformGenerator.generateCaves(worldInfo, random, chunkX, chunkZ, chunkData); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public @Nullable BiomeProvider getDefaultBiomeProvider(@NotNull final WorldInfo worldInfo) { | ||||||
|  |         if (platformGenerator != this) { | ||||||
|  |             return platformGenerator.getDefaultBiomeProvider(worldInfo); | ||||||
|  |         } | ||||||
|  |         return biomeProvider; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int getBaseHeight( | ||||||
|  |             @NotNull final WorldInfo worldInfo, | ||||||
|  |             @NotNull final Random random, | ||||||
|  |             final int x, | ||||||
|  |             final int z, | ||||||
|  |             @NotNull final HeightMap heightMap | ||||||
|  |     ) { | ||||||
|  |         PlotArea area = getPlotArea(worldInfo.getName(), x, z); | ||||||
|  |         if (area instanceof ClassicPlotWorld cpw) { | ||||||
|  |             // Default to plot height being the heighest point before decoration (i.e. roads, walls etc.) | ||||||
|  |             return cpw.PLOT_HEIGHT; | ||||||
|  |         } | ||||||
|  |         return super.getBaseHeight(worldInfo, random, x, z, heightMap); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @SuppressWarnings("deprecation") // The entire method is deprecated, but kept for compatibility with <=1.16.2 | ||||||
|  |     @Override | ||||||
|  |     @Deprecated(since = "TODO") | ||||||
|  |     public @NonNull ChunkData generateChunkData( | ||||||
|  |             @NonNull World world, @NonNull Random random, int x, int z, @NonNull BiomeGrid biome | ||||||
|  |     ) { | ||||||
|  |         if (useNewGenerationMethods) { | ||||||
|  |             if (this.platformGenerator != this) { | ||||||
|  |                 return this.platformGenerator.generateChunkData(world, random, x, z, biome); | ||||||
|  |             } else { | ||||||
|  |                 // Return super as it will throw an exception caught by the server that will mean this method is no longer used. | ||||||
|  |                 return super.generateChunkData(world, random, x, z, biome); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|         int minY = BukkitWorld.getMinWorldHeight(world); |         int minY = BukkitWorld.getMinWorldHeight(world); | ||||||
|         int maxY = BukkitWorld.getMaxWorldHeight(world); |         int maxY = BukkitWorld.getMaxWorldHeight(world); | ||||||
|         GenChunk result = new GenChunk(minY, maxY); |         GenChunk result = new GenChunk(minY, maxY); | ||||||
| @@ -175,7 +301,6 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap | |||||||
|                     for (int chunkZ = 0; chunkZ < 16; chunkZ++) { |                     for (int chunkZ = 0; chunkZ < 16; chunkZ++) { | ||||||
|                         for (int y = minY; y < maxY; y++) { |                         for (int y = minY; y < maxY; y++) { | ||||||
|                             biome.setBiome(chunkX, y, chunkZ, Biome.PLAINS); |                             biome.setBiome(chunkX, y, chunkZ, Biome.PLAINS); | ||||||
|  |  | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -195,35 +320,32 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap | |||||||
|             if (this.platformGenerator != this) { |             if (this.platformGenerator != this) { | ||||||
|                 return this.platformGenerator.generateChunkData(world, random, x, z, biome); |                 return this.platformGenerator.generateChunkData(world, random, x, z, biome); | ||||||
|             } else { |             } else { | ||||||
|                 generate(BlockVector2.at(x, z), world, result); |                 generate(BlockVector2.at(x, z), world.getName(), result, true); | ||||||
|             } |             } | ||||||
|         } catch (Throwable e) { |         } catch (Throwable e) { | ||||||
|             e.printStackTrace(); |             LOGGER.error("Error attempting to load world into PlotSquared.", e); | ||||||
|         } |         } | ||||||
|         // Return the result data |         // Return the result data | ||||||
|         return result.getChunkData(); |         return result.getChunkData(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void generate(BlockVector2 loc, World world, ZeroedDelegateScopedQueueCoordinator result) { |     private void generate(BlockVector2 loc, String world, ZeroedDelegateScopedQueueCoordinator result, boolean biomes) { | ||||||
|         // Load if improperly loaded |         // Load if improperly loaded | ||||||
|         if (!this.loaded) { |         if (!this.loaded) { | ||||||
|             checkLoaded(world); |             synchronized (this) { | ||||||
|  |                 PlotSquared.get().loadWorld(world, this); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         // Process the chunk |         // Process the chunk | ||||||
|         if (ChunkManager.preProcessChunk(loc, result)) { |         if (ChunkManager.preProcessChunk(loc, result)) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         PlotArea area = this.plotAreaManager.getPlotArea(world.getName(), null); |         PlotArea area = getPlotArea(world, loc.getX(), loc.getZ()); | ||||||
|         if (area == null && (area = this.plotAreaManager.getPlotArea(this.levelName, null)) == null) { |  | ||||||
|             throw new IllegalStateException( |  | ||||||
|                     "Cannot regenerate chunk that does not belong to a plot area." + " Location: " + loc |  | ||||||
|                             + ", world: " + world); |  | ||||||
|         } |  | ||||||
|         try { |         try { | ||||||
|             this.plotGenerator.generateChunk(result, area); |             this.plotGenerator.generateChunk(result, area, biomes); | ||||||
|         } catch (Throwable e) { |         } catch (Throwable e) { | ||||||
|             // Recover from generator error |             // Recover from generator error | ||||||
|             e.printStackTrace(); |             LOGGER.error("Error attempting to generate chunk.", e); | ||||||
|         } |         } | ||||||
|         ChunkManager.postProcessChunk(loc, result); |         ChunkManager.postProcessChunk(loc, result); | ||||||
|     } |     } | ||||||
| @@ -277,4 +399,59 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap | |||||||
|         return this.levelName; |         return this.levelName; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private synchronized PlotArea getPlotArea(String name, int chunkX, int chunkZ) { | ||||||
|  |         // Load if improperly loaded | ||||||
|  |         if (!this.loaded) { | ||||||
|  |             PlotSquared.get().loadWorld(name, this); | ||||||
|  |             // Do not set loaded to true as we want to ensure spawn limits are set when "loading" is actually able to be | ||||||
|  |             // completed properly. | ||||||
|  |         } | ||||||
|  |         if (lastPlotArea != null && name.equals(this.levelName) && chunkX == lastChunkX && chunkZ == lastChunkZ) { | ||||||
|  |             return lastPlotArea; | ||||||
|  |         } | ||||||
|  |         PlotArea area = UncheckedWorldLocation.at(name, chunkX << 4, 0, chunkZ << 4).getPlotArea(); | ||||||
|  |         if (area == null) { | ||||||
|  |             throw new IllegalStateException(String.format("Cannot generate chunk that does not belong to a plot area. World: %s", | ||||||
|  |                     name | ||||||
|  |             )); | ||||||
|  |         } | ||||||
|  |         this.lastChunkX = chunkX; | ||||||
|  |         this.lastChunkZ = chunkZ; | ||||||
|  |         return this.lastPlotArea = area; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private PlotArea getPlotArea(String name) { | ||||||
|  |         final Set<PlotArea> areas = this.plotAreaManager.getPlotAreasSet(name); | ||||||
|  |         if (!areas.isEmpty()) { | ||||||
|  |             return areas.iterator().next(); | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Biome provider should never need to be accessed outside of this class. | ||||||
|  |      */ | ||||||
|  |     private final class BukkitPlotBiomeProvider extends BiomeProvider { | ||||||
|  |  | ||||||
|  |         private static final List<Biome> BIOMES; | ||||||
|  |  | ||||||
|  |         static { | ||||||
|  |             ArrayList<Biome> biomes = new ArrayList<>(List.of(Biome.values())); | ||||||
|  |             biomes.remove(Biome.CUSTOM); | ||||||
|  |             BIOMES = List.copyOf(biomes); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public @NotNull Biome getBiome(@NotNull final WorldInfo worldInfo, final int x, final int y, final int z) { | ||||||
|  |             PlotArea area = getPlotArea(worldInfo.getName(), x >> 4, z >> 4); | ||||||
|  |             return BukkitAdapter.adapt(plotGenerator.getBiome(area, x, y, z)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public @NotNull List<Biome> getBiomes(@NotNull final WorldInfo worldInfo) { | ||||||
|  |             return BIOMES; // Allow all biomes | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ import com.plotsquared.core.plot.PlotId; | |||||||
| import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator; | import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator; | ||||||
| import com.plotsquared.core.util.MathMan; | import com.plotsquared.core.util.MathMan; | ||||||
| import com.sk89q.worldedit.bukkit.BukkitAdapter; | import com.sk89q.worldedit.bukkit.BukkitAdapter; | ||||||
|  | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
| import org.bukkit.World; | import org.bukkit.World; | ||||||
| import org.bukkit.block.Biome; | import org.bukkit.block.Biome; | ||||||
| import org.bukkit.generator.BlockPopulator; | import org.bukkit.generator.BlockPopulator; | ||||||
| @@ -49,6 +50,11 @@ final class DelegatePlotGenerator extends IndependentPlotGenerator { | |||||||
|     public void initialize(PlotArea area) { |     public void initialize(PlotArea area) { | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public BiomeType getBiome(final PlotArea settings, final int x, final int y, final int z) { | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String getName() { |     public String getName() { | ||||||
|         return this.chunkGenerator.getClass().getName(); |         return this.chunkGenerator.getClass().getName(); | ||||||
| @@ -60,7 +66,7 @@ final class DelegatePlotGenerator extends IndependentPlotGenerator { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void generateChunk(final ZeroedDelegateScopedQueueCoordinator result, PlotArea settings) { |     public void generateChunk(final ZeroedDelegateScopedQueueCoordinator result, PlotArea settings, boolean biomes) { | ||||||
|         World world = BukkitUtil.getWorld(this.world); |         World world = BukkitUtil.getWorld(this.world); | ||||||
|         Location min = result.getMin(); |         Location min = result.getMin(); | ||||||
|         int chunkX = min.getX() >> 4; |         int chunkX = min.getX() >> 4; | ||||||
|   | |||||||
| @@ -786,7 +786,9 @@ public class PlotSquared { | |||||||
|         if (world.equals("CheckingPlotSquaredGenerator")) { |         if (world.equals("CheckingPlotSquaredGenerator")) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         this.getPlotAreaManager().addWorld(world); |         if (!this.getPlotAreaManager().addWorld(world)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|         Set<String> worlds; |         Set<String> worlds; | ||||||
|         if (this.worldConfiguration.contains("worlds")) { |         if (this.worldConfiguration.contains("worlds")) { | ||||||
|             worlds = this.worldConfiguration.getConfigurationSection("worlds").getKeys(false); |             worlds = this.worldConfiguration.getConfigurationSection("worlds").getKeys(false); | ||||||
|   | |||||||
| @@ -167,7 +167,7 @@ public class AugmentedUtils { | |||||||
|                             Location.at(world, blockX, area.getMinGenHeight(), blockZ), |                             Location.at(world, blockX, area.getMinGenHeight(), blockZ), | ||||||
|                             Location.at(world, blockX + 15, area.getMaxGenHeight(), blockZ + 15) |                             Location.at(world, blockX + 15, area.getMaxGenHeight(), blockZ + 15) | ||||||
|                     ); |                     ); | ||||||
|             generator.generateChunk(scoped, area); |             generator.generateChunk(scoped, area, true); | ||||||
|             generator.populateChunk(scoped, area); |             generator.populateChunk(scoped, area); | ||||||
|         } |         } | ||||||
|         if (enqueue) { |         if (enqueue) { | ||||||
|   | |||||||
| @@ -42,6 +42,8 @@ import com.sk89q.worldedit.world.block.BlockTypes; | |||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
| import org.checkerframework.checker.nullness.qual.Nullable; | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  |  | ||||||
|  | import java.util.EnumSet; | ||||||
|  |  | ||||||
| public class HybridGen extends IndependentPlotGenerator { | public class HybridGen extends IndependentPlotGenerator { | ||||||
|  |  | ||||||
|     private static final CuboidRegion CHUNK = new CuboidRegion(BlockVector3.ZERO, BlockVector3.at(15, 396, 15)); |     private static final CuboidRegion CHUNK = new CuboidRegion(BlockVector3.ZERO, BlockVector3.at(15, 396, 15)); | ||||||
| @@ -64,11 +66,11 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|             short relativeZ, |             short relativeZ, | ||||||
|             int x, |             int x, | ||||||
|             int z, |             int z, | ||||||
|             boolean isRoad, |             EnumSet<SchematicFeature> features | ||||||
|             boolean isPopulating |  | ||||||
|     ) { |     ) { | ||||||
|         int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT); |         int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT); | ||||||
|         if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad && Settings.Schematics.PASTE_ON_TOP)) { |         if ((features.contains(SchematicFeature.ROAD) && Settings.Schematics.PASTE_ROAD_ON_TOP) | ||||||
|  |                 || (!features.contains(SchematicFeature.ROAD) && Settings.Schematics.PASTE_ON_TOP)) { | ||||||
|             minY = world.SCHEM_Y; |             minY = world.SCHEM_Y; | ||||||
|         } else { |         } else { | ||||||
|             minY = world.getMinBuildHeight(); |             minY = world.getMinBuildHeight(); | ||||||
| @@ -77,12 +79,15 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         if (blocks != null) { |         if (blocks != null) { | ||||||
|             for (int y = 0; y < blocks.length; y++) { |             for (int y = 0; y < blocks.length; y++) { | ||||||
|                 if (blocks[y] != null) { |                 if (blocks[y] != null) { | ||||||
|                     if (!isPopulating || blocks[y].hasNbtData()) { |                     if (!features.contains(SchematicFeature.POPULATING) || blocks[y].hasNbtData()) { | ||||||
|                         result.setBlock(x, minY + y, z, blocks[y]); |                         result.setBlock(x, minY + y, z, blocks[y]); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         if (!features.contains(SchematicFeature.BIOMES)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|         BiomeType biome = world.G_SCH_B.get(MathMan.pair(relativeX, relativeZ)); |         BiomeType biome = world.G_SCH_B.get(MathMan.pair(relativeX, relativeZ)); | ||||||
|         if (biome != null) { |         if (biome != null) { | ||||||
|             result.setBiome(x, z, biome); |             result.setBiome(x, z, biome); | ||||||
| @@ -90,13 +95,15 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void generateChunk(@NonNull ZeroedDelegateScopedQueueCoordinator result, @NonNull PlotArea settings) { |     public void generateChunk(@NonNull ZeroedDelegateScopedQueueCoordinator result, @NonNull PlotArea settings, boolean biomes) { | ||||||
|         Preconditions.checkNotNull(result, "result cannot be null"); |         Preconditions.checkNotNull(result, "result cannot be null"); | ||||||
|         Preconditions.checkNotNull(settings, "settings cannot be null"); |         Preconditions.checkNotNull(settings, "settings cannot be null"); | ||||||
|  |  | ||||||
|         HybridPlotWorld hybridPlotWorld = (HybridPlotWorld) settings; |         HybridPlotWorld hybridPlotWorld = (HybridPlotWorld) settings; | ||||||
|         // Biome |         // Biome | ||||||
|  |         if (biomes) { | ||||||
|             result.fillBiome(hybridPlotWorld.getPlotBiome()); |             result.fillBiome(hybridPlotWorld.getPlotBiome()); | ||||||
|  |         } | ||||||
|         // Bedrock |         // Bedrock | ||||||
|         if (hybridPlotWorld.PLOT_BEDROCK) { |         if (hybridPlotWorld.PLOT_BEDROCK) { | ||||||
|             for (short x = 0; x < 16; x++) { |             for (short x = 0; x < 16; x++) { | ||||||
| @@ -105,26 +112,25 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         EnumSet<SchematicFeature> roadFeatures = EnumSet.of(SchematicFeature.ROAD); | ||||||
|  |         EnumSet<SchematicFeature> plotFeatures = EnumSet.noneOf(SchematicFeature.class); | ||||||
|  |         if (biomes) { | ||||||
|  |             roadFeatures.add(SchematicFeature.BIOMES); | ||||||
|  |             plotFeatures.add(SchematicFeature.BIOMES); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         // Coords |         // Coords | ||||||
|         Location min = result.getMin(); |         Location min = result.getMin(); | ||||||
|         int bx = min.getX() - hybridPlotWorld.ROAD_OFFSET_X; |         int bx = min.getX() - hybridPlotWorld.ROAD_OFFSET_X; | ||||||
|         int bz = min.getZ() - hybridPlotWorld.ROAD_OFFSET_Z; |         int bz = min.getZ() - hybridPlotWorld.ROAD_OFFSET_Z; | ||||||
|  |  | ||||||
|         // The relative X-coordinate (within the plot) of the minimum X coordinate |         // The relative X-coordinate (within the plot) of the minimum X coordinate | ||||||
|         // contained in the scoped queue |         // contained in the scoped queue | ||||||
|         short relativeOffsetX; |         short relativeOffsetX = (short) Math.floorMod(bx, hybridPlotWorld.SIZE); | ||||||
|         if (bx < 0) { |  | ||||||
|             relativeOffsetX = (short) (hybridPlotWorld.SIZE + (bx % hybridPlotWorld.SIZE)); |  | ||||||
|         } else { |  | ||||||
|             relativeOffsetX = (short) (bx % hybridPlotWorld.SIZE); |  | ||||||
|         } |  | ||||||
|         // The relative Z-coordinate (within the plot) of the minimum Z coordinate |         // The relative Z-coordinate (within the plot) of the minimum Z coordinate | ||||||
|         // contained in the scoped queue |         // contained in the scoped queue | ||||||
|         short relativeOffsetZ; |         short relativeOffsetZ = (short) Math.floorMod(bz, hybridPlotWorld.SIZE); | ||||||
|         if (bz < 0) { |  | ||||||
|             relativeOffsetZ = (short) (hybridPlotWorld.SIZE + (bz % hybridPlotWorld.SIZE)); |  | ||||||
|         } else { |  | ||||||
|             relativeOffsetZ = (short) (bz % hybridPlotWorld.SIZE); |  | ||||||
|         } |  | ||||||
|         // The X-coordinate of a given X coordinate, relative to the |         // The X-coordinate of a given X coordinate, relative to the | ||||||
|         // plot (Counting from the corner with the least positive |         // plot (Counting from the corner with the least positive | ||||||
|         // coordinates) |         // coordinates) | ||||||
| @@ -171,7 +177,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                         result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); |                         result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||||
|                     } |                     } | ||||||
|                     if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                     if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); |                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, roadFeatures); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } else if (insideWallX[x]) { |             } else if (insideWallX[x]) { | ||||||
| @@ -182,7 +188,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); |                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||||
|                         } |                         } | ||||||
|                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, roadFeatures); | ||||||
|                         } |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         // wall |                         // wall | ||||||
| @@ -194,7 +200,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern()); |                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern()); | ||||||
|                             } |                             } | ||||||
|                         } else { |                         } else { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, roadFeatures); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -206,7 +212,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); |                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||||
|                         } |                         } | ||||||
|                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, roadFeatures); | ||||||
|                         } |                         } | ||||||
|                     } else if (insideWallZ[z]) { |                     } else if (insideWallZ[z]) { | ||||||
|                         // wall |                         // wall | ||||||
| @@ -218,7 +224,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern()); |                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern()); | ||||||
|                             } |                             } | ||||||
|                         } else { |                         } else { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, roadFeatures); | ||||||
|                         } |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         // plot |                         // plot | ||||||
| @@ -227,7 +233,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                         } |                         } | ||||||
|                         result.setBlock(x, hybridPlotWorld.PLOT_HEIGHT, z, hybridPlotWorld.TOP_BLOCK.toPattern()); |                         result.setBlock(x, hybridPlotWorld.PLOT_HEIGHT, z, hybridPlotWorld.TOP_BLOCK.toPattern()); | ||||||
|                         if (hybridPlotWorld.PLOT_SCHEMATIC) { |                         if (hybridPlotWorld.PLOT_SCHEMATIC) { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, false, false); |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, plotFeatures); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -241,26 +247,21 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         if (!hybridPlotWorld.populationNeeded()) { |         if (!hybridPlotWorld.populationNeeded()) { | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |         EnumSet<SchematicFeature> roadFeatures = EnumSet.of(SchematicFeature.POPULATING, SchematicFeature.ROAD); | ||||||
|  |         EnumSet<SchematicFeature> plotFeatures = EnumSet.of(SchematicFeature.POPULATING); | ||||||
|  |  | ||||||
|         // Coords |         // Coords | ||||||
|         Location min = result.getMin(); |         Location min = result.getMin(); | ||||||
|         int bx = min.getX() - hybridPlotWorld.ROAD_OFFSET_X; |         int bx = min.getX() - hybridPlotWorld.ROAD_OFFSET_X; | ||||||
|         int bz = min.getZ() - hybridPlotWorld.ROAD_OFFSET_Z; |         int bz = min.getZ() - hybridPlotWorld.ROAD_OFFSET_Z; | ||||||
|  |  | ||||||
|         // The relative X-coordinate (within the plot) of the minimum X coordinate |         // The relative X-coordinate (within the plot) of the minimum X coordinate | ||||||
|         // contained in the scoped queue |         // contained in the scoped queue | ||||||
|         short relativeOffsetX; |         short relativeOffsetX = (short) Math.floorMod(bx, hybridPlotWorld.SIZE); | ||||||
|         if (bx < 0) { |  | ||||||
|             relativeOffsetX = (short) (hybridPlotWorld.SIZE + (bx % hybridPlotWorld.SIZE)); |  | ||||||
|         } else { |  | ||||||
|             relativeOffsetX = (short) (bx % hybridPlotWorld.SIZE); |  | ||||||
|         } |  | ||||||
|         // The relative Z-coordinate (within the plot) of the minimum Z coordinate |         // The relative Z-coordinate (within the plot) of the minimum Z coordinate | ||||||
|         // contained in the scoped queue |         // contained in the scoped queue | ||||||
|         short relativeOffsetZ; |         short relativeOffsetZ = (short) Math.floorMod(bz, hybridPlotWorld.SIZE); | ||||||
|         if (bz < 0) { |  | ||||||
|             relativeOffsetZ = (short) (hybridPlotWorld.SIZE + (bz % hybridPlotWorld.SIZE)); |  | ||||||
|         } else { |  | ||||||
|             relativeOffsetZ = (short) (bz % hybridPlotWorld.SIZE); |  | ||||||
|         } |  | ||||||
|         boolean allRoad = true; |         boolean allRoad = true; | ||||||
|         boolean overlap = false; |         boolean overlap = false; | ||||||
|  |  | ||||||
| @@ -313,17 +314,17 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|             if (insideRoadX[x] || insideWallX[x]) { |             if (insideRoadX[x] || insideWallX[x]) { | ||||||
|                 if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                 if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                     for (short z = 0; z < 16; z++) { |                     for (short z = 0; z < 16; z++) { | ||||||
|                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, true); |                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, roadFeatures); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|                 for (short z = 0; z < 16; z++) { |                 for (short z = 0; z < 16; z++) { | ||||||
|                     if (insideRoadZ[z] || insideWallZ[z]) { |                     if (insideRoadZ[z] || insideWallZ[z]) { | ||||||
|                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, true); |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, roadFeatures); | ||||||
|                         } |                         } | ||||||
|                     } else if (hybridPlotWorld.PLOT_SCHEMATIC) { |                     } else if (hybridPlotWorld.PLOT_SCHEMATIC) { | ||||||
|                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, false, true); |                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, plotFeatures); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -377,6 +378,27 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         // All initialization is done in the PlotArea class |         // All initialization is done in the PlotArea class | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public BiomeType getBiome(final PlotArea settings, final int worldX, final int worldY, final int worldZ) { | ||||||
|  |         HybridPlotWorld hybridPlotWorld = (HybridPlotWorld) settings; | ||||||
|  |         if (!hybridPlotWorld.PLOT_SCHEMATIC && !hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|  |             return hybridPlotWorld.getPlotBiome(); | ||||||
|  |         } | ||||||
|  |         int relativeX = worldX; | ||||||
|  |         int relativeZ = worldZ; | ||||||
|  |         if (hybridPlotWorld.ROAD_OFFSET_X != 0) { | ||||||
|  |             relativeX -= hybridPlotWorld.ROAD_OFFSET_X; | ||||||
|  |         } | ||||||
|  |         if (hybridPlotWorld.ROAD_OFFSET_Z != 0) { | ||||||
|  |             relativeZ -= hybridPlotWorld.ROAD_OFFSET_Z; | ||||||
|  |         } | ||||||
|  |         int size = hybridPlotWorld.PLOT_WIDTH + hybridPlotWorld.ROAD_WIDTH; | ||||||
|  |         relativeX = Math.floorMod(relativeX, size); | ||||||
|  |         relativeZ = Math.floorMod(relativeZ, size); | ||||||
|  |         BiomeType biome = hybridPlotWorld.G_SCH_B.get(MathMan.pair((short) relativeX, (short) relativeZ)); | ||||||
|  |         return biome == null ? hybridPlotWorld.getPlotBiome() : biome; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Wrapper to allow a WorldEdit {@link Entity} to effectively have a mutable location as the location in its NBT should be changed |      * Wrapper to allow a WorldEdit {@link Entity} to effectively have a mutable location as the location in its NBT should be changed | ||||||
|      * when set to the world. |      * when set to the world. | ||||||
| @@ -431,4 +453,10 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private enum SchematicFeature { | ||||||
|  |         BIOMES, | ||||||
|  |         ROAD, | ||||||
|  |         POPULATING | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -163,7 +163,7 @@ public class HybridUtils { | |||||||
|                 int relChunkZ = chunkPos.getZ() - cbz; |                 int relChunkZ = chunkPos.getZ() - cbz; | ||||||
|                 oldBlockQueue.setOffsetX(relChunkX << 4); |                 oldBlockQueue.setOffsetX(relChunkX << 4); | ||||||
|                 oldBlockQueue.setOffsetZ(relChunkZ << 4); |                 oldBlockQueue.setOffsetZ(relChunkZ << 4); | ||||||
|                 hpw.getGenerator().generateChunk(oldBlockQueue, hpw); |                 hpw.getGenerator().generateChunk(oldBlockQueue, hpw, false); | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|             final BlockState[][][] oldBlocks = oldBlockQueue.getBlockStates(); |             final BlockState[][][] oldBlocks = oldBlockQueue.getBlockStates(); | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ import com.plotsquared.core.plot.PlotArea; | |||||||
| import com.plotsquared.core.plot.PlotId; | import com.plotsquared.core.plot.PlotId; | ||||||
| import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator; | import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator; | ||||||
| import com.plotsquared.core.setup.PlotAreaBuilder; | import com.plotsquared.core.setup.PlotAreaBuilder; | ||||||
|  | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -42,10 +43,11 @@ public abstract class IndependentPlotGenerator { | |||||||
|     /** |     /** | ||||||
|      * Generate chunk block data |      * Generate chunk block data | ||||||
|      * |      * | ||||||
|      * @param result   queue |      * @param result   Queue to write to | ||||||
|      * @param settings PlotArea (settings) |      * @param settings PlotArea (settings) | ||||||
|  |      * @param biomes   If biomes should be generated | ||||||
|      */ |      */ | ||||||
|     public abstract void generateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea settings); |     public abstract void generateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea settings, boolean biomes); | ||||||
|  |  | ||||||
|     public boolean populateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea setting) { |     public boolean populateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea setting) { | ||||||
|         return false; |         return false; | ||||||
| @@ -91,6 +93,18 @@ public abstract class IndependentPlotGenerator { | |||||||
|         return (GeneratorWrapper<T>) PlotSquared.platform().wrapPlotGenerator(world, this); |         return (GeneratorWrapper<T>) PlotSquared.platform().wrapPlotGenerator(world, this); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the biome to be generated at a specific point | ||||||
|  |      * | ||||||
|  |      * @param settings PlotArea settings to provide biome | ||||||
|  |      * @param x       World x position | ||||||
|  |      * @param y       World y position | ||||||
|  |      * @param z       World z position | ||||||
|  |      * @return Biome type to be generated | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     public abstract BiomeType getBiome(PlotArea settings, int x, int y, int z); | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String toString() { |     public String toString() { | ||||||
|         return getName(); |         return getName(); | ||||||
|   | |||||||
| @@ -26,7 +26,9 @@ import com.plotsquared.core.plot.world.PlotAreaManager; | |||||||
| import com.plotsquared.core.plot.world.SinglePlotArea; | import com.plotsquared.core.plot.world.SinglePlotArea; | ||||||
| import com.plotsquared.core.plot.world.SinglePlotAreaManager; | import com.plotsquared.core.plot.world.SinglePlotAreaManager; | ||||||
| import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator; | import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator; | ||||||
|  | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
| import com.sk89q.worldedit.world.biome.BiomeTypes; | import com.sk89q.worldedit.world.biome.BiomeTypes; | ||||||
|  | import com.sk89q.worldedit.world.block.BlockState; | ||||||
| import com.sk89q.worldedit.world.block.BlockTypes; | import com.sk89q.worldedit.world.block.BlockTypes; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
| @@ -38,6 +40,9 @@ public class SingleWorldGenerator extends IndependentPlotGenerator { | |||||||
|     private static final Location dirt2 = Location.at("", 15, 2, 15); |     private static final Location dirt2 = Location.at("", 15, 2, 15); | ||||||
|     private static final Location grass1 = Location.at("", 0, 3, 0); |     private static final Location grass1 = Location.at("", 0, 3, 0); | ||||||
|     private static final Location grass2 = Location.at("", 15, 3, 15); |     private static final Location grass2 = Location.at("", 15, 3, 15); | ||||||
|  |     private static final BlockState BEDROCK = BlockTypes.BEDROCK.getDefaultState(); | ||||||
|  |     private static final BlockState DIRT = BlockTypes.DIRT.getDefaultState(); | ||||||
|  |     private static final BlockState GRASS_BLOCK = BlockTypes.GRASS_BLOCK.getDefaultState(); | ||||||
|  |  | ||||||
|     private final PlotAreaManager plotAreaManager; |     private final PlotAreaManager plotAreaManager; | ||||||
|  |  | ||||||
| @@ -52,20 +57,22 @@ public class SingleWorldGenerator extends IndependentPlotGenerator { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void generateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea settings) { |     public void generateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea settings, boolean biomes) { | ||||||
|         SinglePlotArea area = (SinglePlotArea) settings; |         SinglePlotArea area = (SinglePlotArea) settings; | ||||||
|         if (area.VOID) { |         if (area.VOID) { | ||||||
|             Location min = result.getMin(); |             Location min = result.getMin(); | ||||||
|             if (min.getX() == 0 && min.getZ() == 0) { |             if (min.getX() == 0 && min.getZ() == 0) { | ||||||
|                 result.setBlock(0, 0, 0, BlockTypes.BEDROCK.getDefaultState()); |                 result.setBlock(0, 0, 0, BEDROCK); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             result.setCuboid(bedrock1, bedrock2, BlockTypes.BEDROCK.getDefaultState()); |             result.setCuboid(bedrock1, bedrock2, BEDROCK); | ||||||
|             result.setCuboid(dirt1, dirt2, BlockTypes.DIRT.getDefaultState()); |             result.setCuboid(dirt1, dirt2, DIRT); | ||||||
|             result.setCuboid(grass1, grass2, BlockTypes.GRASS_BLOCK.getDefaultState()); |             result.setCuboid(grass1, grass2, GRASS_BLOCK); | ||||||
|         } |         } | ||||||
|  |         if (biomes) { | ||||||
|             result.fillBiome(BiomeTypes.PLAINS); |             result.fillBiome(BiomeTypes.PLAINS); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) { |     public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) { | ||||||
| @@ -76,4 +83,9 @@ public class SingleWorldGenerator extends IndependentPlotGenerator { | |||||||
|     public void initialize(PlotArea area) { |     public void initialize(PlotArea area) { | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public BiomeType getBiome(final PlotArea settings, final int x, final int y, final int z) { | ||||||
|  |         return BiomeTypes.PLAINS; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -110,11 +110,16 @@ public final class BlockBucket implements ConfigurationSerializable { | |||||||
|         if (isCompiled()) { |         if (isCompiled()) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         this.compiled = true; |         // Synchronized as BlockBuckets may require compilation asynchronously due to async chunk generation on Paper servers | ||||||
|  |         synchronized (this) { | ||||||
|  |             if (isCompiled()) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|             String string = this.input.toString(); |             String string = this.input.toString(); | ||||||
|             if (string.isEmpty()) { |             if (string.isEmpty()) { | ||||||
|                 this.single = null; |                 this.single = null; | ||||||
|                 this.pattern = null; |                 this.pattern = null; | ||||||
|  |                 this.compiled = true; | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             // Convert legacy format |             // Convert legacy format | ||||||
| @@ -135,6 +140,7 @@ public final class BlockBucket implements ConfigurationSerializable { | |||||||
|                     } |                     } | ||||||
|                     this.single = BlockUtil.get(string); |                     this.single = BlockUtil.get(string); | ||||||
|                     this.pattern = new BlockPattern(single); |                     this.pattern = new BlockPattern(single); | ||||||
|  |                     this.compiled = true; | ||||||
|                     return; |                     return; | ||||||
|                 } catch (Exception ignore) { |                 } catch (Exception ignore) { | ||||||
|                 } |                 } | ||||||
| @@ -158,6 +164,8 @@ public final class BlockBucket implements ConfigurationSerializable { | |||||||
|                 string = StringMan.join(blocksStr, ","); |                 string = StringMan.join(blocksStr, ","); | ||||||
|             } |             } | ||||||
|             pattern = PatternUtil.parse(null, string); |             pattern = PatternUtil.parse(null, string); | ||||||
|  |             this.compiled = true; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public boolean isCompiled() { |     public boolean isCompiled() { | ||||||
|   | |||||||
| @@ -137,15 +137,16 @@ public class DefaultPlotAreaManager implements PlotAreaManager { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void addWorld(final @NonNull String worldName) { |     public boolean addWorld(final @NonNull String worldName) { | ||||||
|         PlotWorld world = this.plotWorlds.get(worldName); |         PlotWorld world = this.plotWorlds.get(worldName); | ||||||
|         if (world != null) { |         if (world != null) { | ||||||
|             return; |             return false; | ||||||
|         } |         } | ||||||
|         // Create a new empty world. When a new area is added |         // Create a new empty world. When a new area is added | ||||||
|         // the world will be re-recreated with the correct type |         // the world will be re-recreated with the correct type | ||||||
|         world = new StandardPlotWorld(worldName, null); |         world = new StandardPlotWorld(worldName, null); | ||||||
|         this.plotWorlds.put(worldName, world); |         this.plotWorlds.put(worldName, world); | ||||||
|  |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
| @@ -110,8 +110,9 @@ public interface PlotAreaManager { | |||||||
|      * Add a world |      * Add a world | ||||||
|      * |      * | ||||||
|      * @param worldName Name of the world to add |      * @param worldName Name of the world to add | ||||||
|  |      * @return true if successful. False if world already existed | ||||||
|      */ |      */ | ||||||
|     void addWorld(@NonNull String worldName); |     boolean addWorld(@NonNull String worldName); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Remove a world |      * Remove a world | ||||||
|   | |||||||
| @@ -172,8 +172,8 @@ public class SinglePlotAreaManager extends DefaultPlotAreaManager { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void addWorld(final @NonNull String worldName) { |     public boolean addWorld(final @NonNull String worldName) { | ||||||
|         super.addWorld(worldName); |         return super.addWorld(worldName); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
| @@ -38,7 +38,6 @@ public abstract class ChunkManager { | |||||||
|     /** |     /** | ||||||
|      * @since TODO |      * @since TODO | ||||||
|      */ |      */ | ||||||
|     @Deprecated(forRemoval = true, since = "6.9.0") |  | ||||||
|     public static void setChunkInPlotArea( |     public static void setChunkInPlotArea( | ||||||
|             RunnableVal<ZeroedDelegateScopedQueueCoordinator> force, |             RunnableVal<ZeroedDelegateScopedQueueCoordinator> force, | ||||||
|             RunnableVal<ZeroedDelegateScopedQueueCoordinator> add, |             RunnableVal<ZeroedDelegateScopedQueueCoordinator> add, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user