mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-22 05:06:44 +01:00
Move to new generation API
- Currently not working due to lack of biome-setting capability via BiomeProvider for flat worlds
This commit is contained in:
parent
43150abb86
commit
9188c8c40d
@ -29,28 +29,35 @@ import com.plotsquared.bukkit.queue.GenChunk;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.plotsquared.bukkit.util.BukkitWorld;
|
||||
import com.plotsquared.core.PlotSquared;
|
||||
import com.plotsquared.core.generator.ClassicPlotWorld;
|
||||
import com.plotsquared.core.generator.GeneratorWrapper;
|
||||
import com.plotsquared.core.generator.IndependentPlotGenerator;
|
||||
import com.plotsquared.core.generator.SingleWorldGenerator;
|
||||
import com.plotsquared.core.location.ChunkWrapper;
|
||||
import com.plotsquared.core.location.UncheckedWorldLocation;
|
||||
import com.plotsquared.core.plot.PlotArea;
|
||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||
import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator;
|
||||
import com.plotsquared.core.util.ChunkManager;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import org.bukkit.HeightMap;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.generator.WorldInfo;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class BukkitPlotGenerator extends ChunkGenerator
|
||||
implements GeneratorWrapper<ChunkGenerator> {
|
||||
public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final boolean PAPER_ASYNC_SAFE = true;
|
||||
@ -60,9 +67,15 @@ public class BukkitPlotGenerator extends ChunkGenerator
|
||||
private final ChunkGenerator platformGenerator;
|
||||
private final boolean full;
|
||||
private final String levelName;
|
||||
private final boolean useNewGenerationMethods;
|
||||
private final BiomeProvider biomeProvider;
|
||||
private List<BlockPopulator> populators;
|
||||
private boolean loaded = false;
|
||||
|
||||
private PlotArea lastPlotArea;
|
||||
private int lastChunkX = Integer.MIN_VALUE;
|
||||
private int lastChunkZ = Integer.MIN_VALUE;
|
||||
|
||||
public BukkitPlotGenerator(
|
||||
final @NonNull String name,
|
||||
final @NonNull IndependentPlotGenerator generator,
|
||||
@ -75,18 +88,23 @@ public class BukkitPlotGenerator extends ChunkGenerator
|
||||
this.populators = new ArrayList<>();
|
||||
this.populators.add(new BlockStatePopulator(this.plotGenerator, this.plotAreaManager));
|
||||
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) {
|
||||
if (cg instanceof BukkitPlotGenerator) {
|
||||
throw new IllegalArgumentException("ChunkGenerator: " + cg.getClass().getName()
|
||||
+ " is already a BukkitPlotGenerator!");
|
||||
throw new IllegalArgumentException("ChunkGenerator: " + cg
|
||||
.getClass()
|
||||
.getName() + " is already a BukkitPlotGenerator!");
|
||||
}
|
||||
this.plotAreaManager = plotAreaManager;
|
||||
this.levelName = world;
|
||||
this.full = false;
|
||||
this.platformGenerator = cg;
|
||||
this.plotGenerator = new DelegatePlotGenerator(cg, world);
|
||||
this.useNewGenerationMethods = PlotSquared.platform().serverVersion()[1] >= 17;
|
||||
this.biomeProvider = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -112,30 +130,7 @@ public class BukkitPlotGenerator extends ChunkGenerator
|
||||
@Override
|
||||
public @NonNull List<BlockPopulator> getDefaultPopulators(@NonNull World world) {
|
||||
try {
|
||||
if (!this.loaded) {
|
||||
String name = world.getName();
|
||||
PlotSquared.get().loadWorld(name, this);
|
||||
final Set<PlotArea> areas = this.plotAreaManager.getPlotAreasSet(name);
|
||||
if (!areas.isEmpty()) {
|
||||
PlotArea area = areas.iterator().next();
|
||||
if (!area.isMobSpawning()) {
|
||||
if (!area.isSpawnEggs()) {
|
||||
world.setSpawnFlags(false, false);
|
||||
}
|
||||
world.setAmbientSpawnLimit(0);
|
||||
world.setAnimalSpawnLimit(0);
|
||||
world.setMonsterSpawnLimit(0);
|
||||
world.setWaterAnimalSpawnLimit(0);
|
||||
} else {
|
||||
world.setSpawnFlags(true, true);
|
||||
world.setAmbientSpawnLimit(-1);
|
||||
world.setAnimalSpawnLimit(-1);
|
||||
world.setMonsterSpawnLimit(-1);
|
||||
world.setWaterAnimalSpawnLimit(-1);
|
||||
}
|
||||
}
|
||||
this.loaded = true;
|
||||
}
|
||||
checkLoaded(world);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -154,12 +149,138 @@ public class BukkitPlotGenerator extends ChunkGenerator
|
||||
return toAdd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull ChunkData generateChunkData(
|
||||
@NonNull World world, @NonNull Random random, int x, int z,
|
||||
@NonNull BiomeGrid biome
|
||||
) {
|
||||
// Extracted to synchronized method for thread-safety, preventing multiple internal world load calls
|
||||
private synchronized void checkLoaded(World world) {
|
||||
if (!this.loaded) {
|
||||
String name = world.getName();
|
||||
PlotSquared.get().loadWorld(name, this);
|
||||
final Set<PlotArea> areas = this.plotAreaManager.getPlotAreasSet(name);
|
||||
if (!areas.isEmpty()) {
|
||||
PlotArea area = areas.iterator().next();
|
||||
if (!area.isMobSpawning()) {
|
||||
if (!area.isSpawnEggs()) {
|
||||
world.setSpawnFlags(false, false);
|
||||
}
|
||||
setSpawnLimits(world, 0);
|
||||
} else {
|
||||
world.setSpawnFlags(true, true);
|
||||
setSpawnLimits(world, -1);
|
||||
}
|
||||
}
|
||||
this.loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // Kept for compatibility with <=1.17.1
|
||||
private void setSpawnLimits(World world, int spawnLimit) {
|
||||
world.setAmbientSpawnLimit(spawnLimit);
|
||||
world.setAnimalSpawnLimit(spawnLimit);
|
||||
world.setMonsterSpawnLimit(spawnLimit);
|
||||
world.setWaterAnimalSpawnLimit(spawnLimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateNoise(
|
||||
@NotNull final WorldInfo worldInfo,
|
||||
@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) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
// 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 maxY = BukkitWorld.getMaxWorldHeight(world);
|
||||
GenChunk result = new GenChunk(minY, maxY);
|
||||
@ -169,7 +290,6 @@ public class BukkitPlotGenerator extends ChunkGenerator
|
||||
for (int chunkZ = 0; chunkZ < 16; chunkZ++) {
|
||||
for (int y = minY; y < maxY; y++) {
|
||||
biome.setBiome(chunkX, y, chunkZ, Biome.PLAINS);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -189,7 +309,7 @@ public class BukkitPlotGenerator extends ChunkGenerator
|
||||
if (this.platformGenerator != this) {
|
||||
return this.platformGenerator.generateChunkData(world, random, x, z, biome);
|
||||
} else {
|
||||
generate(BlockVector2.at(x, z), world, result);
|
||||
generate(BlockVector2.at(x, z), world.getName(), result, true);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
@ -198,25 +318,14 @@ public class BukkitPlotGenerator extends ChunkGenerator
|
||||
return result.getChunkData();
|
||||
}
|
||||
|
||||
private void generate(BlockVector2 loc, World world, ZeroedDelegateScopedQueueCoordinator result) {
|
||||
// Load if improperly loaded
|
||||
if (!this.loaded) {
|
||||
String name = world.getName();
|
||||
PlotSquared.get().loadWorld(name, this);
|
||||
this.loaded = true;
|
||||
}
|
||||
private void generate(BlockVector2 loc, String world, ZeroedDelegateScopedQueueCoordinator result, boolean biomes) {
|
||||
// Process the chunk
|
||||
if (ChunkManager.preProcessChunk(loc, result)) {
|
||||
return;
|
||||
}
|
||||
PlotArea area = this.plotAreaManager.getPlotArea(world.getName(), null);
|
||||
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);
|
||||
}
|
||||
PlotArea area = getPlotArea(world, loc.getX(), loc.getZ());
|
||||
try {
|
||||
this.plotGenerator.generateChunk(result, area);
|
||||
this.plotGenerator.generateChunk(result, area, biomes);
|
||||
} catch (Throwable e) {
|
||||
// Recover from generator error
|
||||
e.printStackTrace();
|
||||
@ -273,4 +382,59 @@ public class BukkitPlotGenerator extends ChunkGenerator
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import com.plotsquared.core.plot.PlotId;
|
||||
import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator;
|
||||
import com.plotsquared.core.util.MathMan;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
@ -56,6 +57,11 @@ final class DelegatePlotGenerator extends IndependentPlotGenerator {
|
||||
public void initialize(PlotArea area) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(final PlotArea settings, final int x, final int y, final int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.chunkGenerator.getClass().getName();
|
||||
@ -67,7 +73,7 @@ final class DelegatePlotGenerator extends IndependentPlotGenerator {
|
||||
}
|
||||
|
||||
@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);
|
||||
Location min = result.getMin();
|
||||
int chunkX = min.getX() >> 4;
|
||||
|
@ -787,7 +787,9 @@ public class PlotSquared {
|
||||
if (world.equals("CheckingPlotSquaredGenerator")) {
|
||||
return;
|
||||
}
|
||||
this.getPlotAreaManager().addWorld(world);
|
||||
if (!this.getPlotAreaManager().addWorld(world)) {
|
||||
return;
|
||||
}
|
||||
Set<String> worlds;
|
||||
if (this.worldConfiguration.contains("worlds")) {
|
||||
worlds = this.worldConfiguration.getConfigurationSection("worlds").getKeys(false);
|
||||
|
@ -174,7 +174,7 @@ public class AugmentedUtils {
|
||||
Location.at(world, blockX, area.getMinGenHeight(), blockZ),
|
||||
Location.at(world, blockX + 15, area.getMaxGenHeight(), blockZ + 15)
|
||||
);
|
||||
generator.generateChunk(scoped, area);
|
||||
generator.generateChunk(scoped, area, true);
|
||||
generator.populateChunk(scoped, area);
|
||||
}
|
||||
if (enqueue) {
|
||||
|
@ -61,7 +61,8 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
short relativeZ,
|
||||
int x,
|
||||
int z,
|
||||
boolean isRoad
|
||||
boolean isRoad,
|
||||
boolean biomes
|
||||
) {
|
||||
int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT);
|
||||
if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad && Settings.Schematics.PASTE_ON_TOP)) {
|
||||
@ -77,6 +78,9 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!biomes) {
|
||||
return;
|
||||
}
|
||||
BiomeType biome = world.G_SCH_B.get(MathMan.pair(relativeX, relativeZ));
|
||||
if (biome != null) {
|
||||
result.setBiome(x, z, biome);
|
||||
@ -84,13 +88,15 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
}
|
||||
|
||||
@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(settings, "settings cannot be null");
|
||||
|
||||
HybridPlotWorld hybridPlotWorld = (HybridPlotWorld) settings;
|
||||
// Biome
|
||||
result.fillBiome(hybridPlotWorld.getPlotBiome());
|
||||
if (biomes) {
|
||||
result.fillBiome(hybridPlotWorld.getPlotBiome());
|
||||
}
|
||||
// Bedrock
|
||||
if (hybridPlotWorld.PLOT_BEDROCK) {
|
||||
for (short x = 0; x < 16; x++) {
|
||||
@ -132,10 +138,8 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
}
|
||||
relativeX[i] = v;
|
||||
if (hybridPlotWorld.ROAD_WIDTH != 0) {
|
||||
insideRoadX[i] =
|
||||
v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
insideWallX[i] =
|
||||
v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
insideRoadX[i] = v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
insideWallX[i] = v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
}
|
||||
}
|
||||
// The Z-coordinate of a given Z coordinate, relative to the
|
||||
@ -153,14 +157,12 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
}
|
||||
relativeZ[i] = v;
|
||||
if (hybridPlotWorld.ROAD_WIDTH != 0) {
|
||||
insideRoadZ[i] =
|
||||
v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
insideWallZ[i] =
|
||||
v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
insideRoadZ[i] = v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
insideWallZ[i] = v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
}
|
||||
}
|
||||
// generation
|
||||
int startY = hybridPlotWorld.getMinGenHeight() + (hybridPlotWorld.PLOT_BEDROCK ? 1: 0);
|
||||
int startY = hybridPlotWorld.getMinGenHeight() + (hybridPlotWorld.PLOT_BEDROCK ? 1 : 0);
|
||||
for (short x = 0; x < 16; x++) {
|
||||
if (insideRoadX[x]) {
|
||||
for (short z = 0; z < 16; z++) {
|
||||
@ -169,7 +171,7 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern());
|
||||
}
|
||||
if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true);
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, biomes);
|
||||
}
|
||||
}
|
||||
} else if (insideWallX[x]) {
|
||||
@ -180,9 +182,7 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern());
|
||||
}
|
||||
if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z,
|
||||
true
|
||||
);
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, biomes);
|
||||
}
|
||||
} else {
|
||||
// wall
|
||||
@ -191,14 +191,10 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
}
|
||||
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||
if (hybridPlotWorld.PLACE_TOP_BLOCK) {
|
||||
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 {
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z,
|
||||
true
|
||||
);
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, biomes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,9 +206,7 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern());
|
||||
}
|
||||
if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z,
|
||||
true
|
||||
);
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, biomes);
|
||||
}
|
||||
} else if (insideWallZ[z]) {
|
||||
// wall
|
||||
@ -221,27 +215,19 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
}
|
||||
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||
if (hybridPlotWorld.PLACE_TOP_BLOCK) {
|
||||
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 {
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z,
|
||||
true
|
||||
);
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, biomes);
|
||||
}
|
||||
} else {
|
||||
// plot
|
||||
for (int y = startY; y < hybridPlotWorld.PLOT_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hybridPlotWorld.MAIN_BLOCK.toPattern());
|
||||
}
|
||||
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) {
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z,
|
||||
false
|
||||
);
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, false, biomes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,4 +245,33 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
// 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;
|
||||
if (relativeX < 0) {
|
||||
relativeX = size + (relativeX % size);
|
||||
} else {
|
||||
relativeX = relativeX % size;
|
||||
}
|
||||
if (relativeZ < 0) {
|
||||
relativeZ = size + (relativeZ % size);
|
||||
} else {
|
||||
relativeZ = relativeZ % size;
|
||||
}
|
||||
BiomeType biome = hybridPlotWorld.G_SCH_B.get(MathMan.pair((short) relativeX, (short) relativeZ));
|
||||
return biome == null ? hybridPlotWorld.getPlotBiome() : biome;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ public class HybridUtils {
|
||||
int relChunkZ = chunkPos.getZ() - cbz;
|
||||
oldBlockQueue.setOffsetX(relChunkX << 4);
|
||||
oldBlockQueue.setOffsetZ(relChunkZ << 4);
|
||||
hpw.getGenerator().generateChunk(oldBlockQueue, hpw);
|
||||
hpw.getGenerator().generateChunk(oldBlockQueue, hpw, false);
|
||||
});
|
||||
|
||||
final BlockState[][][] oldBlocks = oldBlockQueue.getBlockStates();
|
||||
|
@ -30,6 +30,7 @@ import com.plotsquared.core.plot.PlotArea;
|
||||
import com.plotsquared.core.plot.PlotId;
|
||||
import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator;
|
||||
import com.plotsquared.core.setup.PlotAreaBuilder;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
@ -51,10 +52,11 @@ public abstract class IndependentPlotGenerator {
|
||||
* The PlotArea settings is the same one this was initialized with.
|
||||
* The PseudoRandom random is a fast random object.
|
||||
*
|
||||
* @param result queue
|
||||
* @param result Queue to write to
|
||||
* @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) {
|
||||
return false;
|
||||
@ -100,6 +102,18 @@ public abstract class IndependentPlotGenerator {
|
||||
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
|
||||
public String toString() {
|
||||
return getName();
|
||||
|
@ -33,7 +33,9 @@ import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||
import com.plotsquared.core.plot.world.SinglePlotArea;
|
||||
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
||||
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.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
@ -45,6 +47,9 @@ public class SingleWorldGenerator extends IndependentPlotGenerator {
|
||||
private static final Location dirt2 = Location.at("", 15, 2, 15);
|
||||
private static final Location grass1 = Location.at("", 0, 3, 0);
|
||||
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;
|
||||
|
||||
@ -59,19 +64,21 @@ public class SingleWorldGenerator extends IndependentPlotGenerator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea settings) {
|
||||
public void generateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea settings, boolean biomes) {
|
||||
SinglePlotArea area = (SinglePlotArea) settings;
|
||||
if (area.VOID) {
|
||||
Location min = result.getMin();
|
||||
if (min.getX() == 0 && min.getZ() == 0) {
|
||||
result.setBlock(0, 0, 0, BlockTypes.BEDROCK.getDefaultState());
|
||||
result.setBlock(0, 0, 0, BEDROCK);
|
||||
}
|
||||
} else {
|
||||
result.setCuboid(bedrock1, bedrock2, BlockTypes.BEDROCK.getDefaultState());
|
||||
result.setCuboid(dirt1, dirt2, BlockTypes.DIRT.getDefaultState());
|
||||
result.setCuboid(grass1, grass2, BlockTypes.GRASS_BLOCK.getDefaultState());
|
||||
result.setCuboid(bedrock1, bedrock2, BEDROCK);
|
||||
result.setCuboid(dirt1, dirt2, DIRT);
|
||||
result.setCuboid(grass1, grass2, GRASS_BLOCK);
|
||||
}
|
||||
if (biomes) {
|
||||
result.fillBiome(BiomeTypes.PLAINS);
|
||||
}
|
||||
result.fillBiome(BiomeTypes.PLAINS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -83,4 +90,9 @@ public class SingleWorldGenerator extends IndependentPlotGenerator {
|
||||
public void initialize(PlotArea area) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(final PlotArea settings, final int x, final int y, final int z) {
|
||||
return BiomeTypes.PLAINS;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,14 +41,14 @@ import org.khelekore.prtree.SimpleMBR;
|
||||
* An unmodifiable 6-tuple (world,x,y,z,yaw,pitch)
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public final class Location extends BlockLoc implements Comparable<Location> {
|
||||
public class Location extends BlockLoc implements Comparable<Location> {
|
||||
|
||||
private final float yaw;
|
||||
private final float pitch;
|
||||
private final BlockVector3 blockVector3;
|
||||
private final World<?> world;
|
||||
|
||||
private Location(
|
||||
protected Location(
|
||||
final @NonNull World<?> world, final @NonNull BlockVector3 blockVector3,
|
||||
final float yaw, final float pitch
|
||||
) {
|
||||
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* _____ _ _ _____ _
|
||||
* | __ \| | | | / ____| | |
|
||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||
* | |
|
||||
* |_|
|
||||
* PlotSquared plot management system for Minecraft
|
||||
* Copyright (C) 2014 - 2022 IntellectualSites
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.plotsquared.core.location;
|
||||
|
||||
import com.plotsquared.core.util.AnnotationHelper;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
* Used internally for generation to reference locations in worlds that "don't exist yet". There is no guarantee that the world
|
||||
* name provided by {@link UncheckedWorldLocation#getWorldName()} exists on the server.
|
||||
*/
|
||||
@AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.")
|
||||
public class UncheckedWorldLocation extends Location {
|
||||
|
||||
private final String worldName;
|
||||
|
||||
private UncheckedWorldLocation(
|
||||
final @NonNull String worldName, final int x, final int y, final int z
|
||||
) {
|
||||
super(World.nullWorld(), BlockVector3.at(x, y, z), 0f, 0f);
|
||||
this.worldName = worldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new location with yaw and pitch equal to 0
|
||||
*
|
||||
* @param world World
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @return New location
|
||||
*/
|
||||
public static @NonNull UncheckedWorldLocation at(
|
||||
final @NonNull String world, final int x, final int y, final int z
|
||||
) {
|
||||
return new UncheckedWorldLocation(world, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String getWorldName() {
|
||||
return this.worldName;
|
||||
}
|
||||
|
||||
}
|
@ -117,54 +117,60 @@ public final class BlockBucket implements ConfigurationSerializable {
|
||||
if (isCompiled()) {
|
||||
return;
|
||||
}
|
||||
this.compiled = true;
|
||||
String string = this.input.toString();
|
||||
if (string.isEmpty()) {
|
||||
this.single = null;
|
||||
this.pattern = null;
|
||||
return;
|
||||
}
|
||||
// Convert legacy format
|
||||
boolean legacy = false;
|
||||
String[] blocksStr = string.split(",(?![^\\(\\[]*[\\]\\)])");
|
||||
if (blocksStr.length == 1) {
|
||||
try {
|
||||
Matcher matcher = regex.matcher(string);
|
||||
// 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();
|
||||
if (string.isEmpty()) {
|
||||
this.single = null;
|
||||
this.pattern = null;
|
||||
return;
|
||||
}
|
||||
// Convert legacy format
|
||||
boolean legacy = false;
|
||||
String[] blocksStr = string.split(",(?![^\\(\\[]*[\\]\\)])");
|
||||
if (blocksStr.length == 1) {
|
||||
try {
|
||||
Matcher matcher = regex.matcher(string);
|
||||
if (matcher.find()) {
|
||||
String chanceStr = matcher.group("chance");
|
||||
String block = matcher.group("block");
|
||||
//noinspection PointlessNullCheck
|
||||
if (chanceStr != null && block != null && !MathMan.isInteger(block) && MathMan
|
||||
.isInteger(chanceStr)) {
|
||||
String namespace = matcher.group("namespace");
|
||||
string = (namespace == null ? "" : namespace + ":") + block;
|
||||
}
|
||||
}
|
||||
this.single = BlockUtil.get(string);
|
||||
this.pattern = new BlockPattern(single);
|
||||
return;
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < blocksStr.length; i++) {
|
||||
String entry = blocksStr[i];
|
||||
Matcher matcher = regex.matcher(entry);
|
||||
if (matcher.find()) {
|
||||
String chanceStr = matcher.group("chance");
|
||||
String block = matcher.group("block");
|
||||
//noinspection PointlessNullCheck
|
||||
if (chanceStr != null && block != null && !MathMan.isInteger(block) && MathMan
|
||||
.isInteger(chanceStr)) {
|
||||
String namespace = matcher.group("namespace");
|
||||
string = (namespace == null ? "" : namespace + ":") + block;
|
||||
if (chanceStr != null && MathMan.isInteger(chanceStr)) {
|
||||
String[] parts = entry.split(":");
|
||||
parts = Arrays.copyOf(parts, parts.length - 1);
|
||||
entry = chanceStr + "%" + StringMan.join(parts, ":");
|
||||
blocksStr[i] = entry;
|
||||
legacy = true;
|
||||
}
|
||||
}
|
||||
this.single = BlockUtil.get(string);
|
||||
this.pattern = new BlockPattern(single);
|
||||
return;
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < blocksStr.length; i++) {
|
||||
String entry = blocksStr[i];
|
||||
Matcher matcher = regex.matcher(entry);
|
||||
if (matcher.find()) {
|
||||
String chanceStr = matcher.group("chance");
|
||||
//noinspection PointlessNullCheck
|
||||
if (chanceStr != null && MathMan.isInteger(chanceStr)) {
|
||||
String[] parts = entry.split(":");
|
||||
parts = Arrays.copyOf(parts, parts.length - 1);
|
||||
entry = chanceStr + "%" + StringMan.join(parts, ":");
|
||||
blocksStr[i] = entry;
|
||||
legacy = true;
|
||||
}
|
||||
if (legacy) {
|
||||
string = StringMan.join(blocksStr, ",");
|
||||
}
|
||||
pattern = PatternUtil.parse(null, string);
|
||||
this.compiled = true;
|
||||
}
|
||||
if (legacy) {
|
||||
string = StringMan.join(blocksStr, ",");
|
||||
}
|
||||
pattern = PatternUtil.parse(null, string);
|
||||
}
|
||||
|
||||
public boolean isCompiled() {
|
||||
|
@ -144,15 +144,16 @@ public class DefaultPlotAreaManager implements PlotAreaManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWorld(final @NonNull String worldName) {
|
||||
public boolean addWorld(final @NonNull String worldName) {
|
||||
PlotWorld world = this.plotWorlds.get(worldName);
|
||||
if (world != null) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
// Create a new empty world. When a new area is added
|
||||
// the world will be re-recreated with the correct type
|
||||
world = new StandardPlotWorld(worldName, null);
|
||||
this.plotWorlds.put(worldName, world);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -117,8 +117,9 @@ public interface PlotAreaManager {
|
||||
* Add a world
|
||||
*
|
||||
* @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
|
||||
|
@ -179,8 +179,8 @@ public class SinglePlotAreaManager extends DefaultPlotAreaManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWorld(final @NonNull String worldName) {
|
||||
super.addWorld(worldName);
|
||||
public boolean addWorld(final @NonNull String worldName) {
|
||||
return super.addWorld(worldName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user