mirror of
https://github.com/BentoBoxWorld/Boxed.git
synced 2025-01-05 18:37:48 +01:00
Custom biomes and vanilla biomes mixed
This covers the overworld. Next is to do the nether.
This commit is contained in:
parent
c7880b355d
commit
4a675e0433
@ -22,10 +22,12 @@ import world.bentobox.bentobox.api.flags.Flag;
|
||||
import world.bentobox.bentobox.api.flags.Flag.Mode;
|
||||
import world.bentobox.bentobox.api.flags.Flag.Type;
|
||||
import world.bentobox.bentobox.managers.RanksManager;
|
||||
import world.bentobox.boxed.generators.AbstractBoxedChunkGenerator;
|
||||
import world.bentobox.boxed.generators.BoxedBiomeGenerator;
|
||||
import world.bentobox.boxed.generators.BoxedBlockPopulator;
|
||||
import world.bentobox.boxed.generators.BoxedChunkGenerator;
|
||||
import world.bentobox.boxed.generators.BoxedSeedChunkGenerator;
|
||||
import world.bentobox.boxed.generators.SeedBiomeGenerator;
|
||||
import world.bentobox.boxed.listeners.AdvancementListener;
|
||||
import world.bentobox.boxed.listeners.EnderPearlListener;
|
||||
|
||||
@ -48,13 +50,15 @@ public class Boxed extends GameModeAddon {
|
||||
private static final String SEED = "seed";
|
||||
private static final String NETHER = "_nether";
|
||||
private static final String THE_END = "_the_end";
|
||||
private static final String BASE = "_base";
|
||||
|
||||
// Settings
|
||||
private Settings settings;
|
||||
private BoxedChunkGenerator chunkGenerator;
|
||||
private AbstractBoxedChunkGenerator chunkGenerator;
|
||||
private final Config<Settings> configObject = new Config<>(this, Settings.class);
|
||||
private AdvancementsManager advManager;
|
||||
private BoxedChunkGenerator netherChunkGenerator;
|
||||
private AbstractBoxedChunkGenerator netherChunkGenerator;
|
||||
private World baseWorld;
|
||||
private World seedWorld;
|
||||
private World seedWorldNether;
|
||||
//private World seedWorldEnd;
|
||||
@ -146,22 +150,70 @@ public class Boxed extends GameModeAddon {
|
||||
|
||||
@Override
|
||||
public void createWorlds() {
|
||||
// Create seed world
|
||||
String worldName = settings.getWorldName().toLowerCase();
|
||||
// Create overworld
|
||||
createOverWorld(worldName);
|
||||
|
||||
// Make the nether if it does not exist
|
||||
if (settings.isNetherGenerate()) {
|
||||
createNether(worldName);
|
||||
}
|
||||
/*
|
||||
// Make the end if it does not exist
|
||||
if (settings.isEndGenerate()) {
|
||||
//TODO
|
||||
*/
|
||||
}
|
||||
|
||||
private void createNether(String worldName) {
|
||||
log("Creating Boxed Seed Nether world ...");
|
||||
seedWorldNether = WorldCreator
|
||||
.name(SEED + NETHER)
|
||||
.generator(new BoxedSeedChunkGenerator(this, Environment.NETHER))
|
||||
.environment(Environment.NETHER)
|
||||
.seed(getSettings().getSeed())
|
||||
.createWorld();
|
||||
seedWorldNether.setDifficulty(Difficulty.EASY); // No damage wanted in this world.
|
||||
|
||||
copyChunks(seedWorldNether, this.netherChunkGenerator);
|
||||
|
||||
if (getServer().getWorld(worldName + NETHER) == null) {
|
||||
log("Creating Boxed's Nether...");
|
||||
}
|
||||
netherWorld = getWorld(worldName, World.Environment.NETHER);
|
||||
}
|
||||
|
||||
private void createOverWorld(String worldName) {
|
||||
// Create vanilla seed world
|
||||
log("Creating Boxed Seed world ...");
|
||||
// This creates a vanilla base world with biomes
|
||||
AbstractBoxedChunkGenerator seedBaseGen = new BoxedSeedChunkGenerator(this, Environment.NORMAL);
|
||||
baseWorld = WorldCreator
|
||||
.name(SEED+BASE)
|
||||
.generator(seedBaseGen)
|
||||
.environment(Environment.NORMAL)
|
||||
.seed(getSettings().getSeed())
|
||||
.createWorld();
|
||||
baseWorld.setDifficulty(Difficulty.PEACEFUL);
|
||||
baseWorld.setSpawnLocation(settings.getSeedX(), 64, settings.getSeedZ());
|
||||
copyChunks(baseWorld, seedBaseGen);
|
||||
// Create seed world
|
||||
// This copies a base world with custom biomes
|
||||
log("Creating Boxed Biomed world ...");
|
||||
|
||||
seedWorld = WorldCreator
|
||||
.name(SEED)
|
||||
.generator(new BoxedSeedChunkGenerator(this, Environment.NORMAL))
|
||||
.generator(new BoxedSeedChunkGenerator(this, Environment.NORMAL, new SeedBiomeGenerator(this, seedBaseGen)))
|
||||
.environment(Environment.NORMAL)
|
||||
.seed(getSettings().getSeed())
|
||||
.createWorld();
|
||||
seedWorld.setDifficulty(Difficulty.EASY);
|
||||
copyChunks(seedWorld);
|
||||
|
||||
seedWorld.setSpawnLocation(settings.getSeedX(), 64, settings.getSeedZ());
|
||||
|
||||
copyChunks(seedWorld, chunkGenerator);
|
||||
|
||||
|
||||
// Unload seed world
|
||||
//Bukkit.getServer().unloadWorld("seed", false);
|
||||
String worldName = settings.getWorldName().toLowerCase();
|
||||
|
||||
if (getServer().getWorld(worldName) == null) {
|
||||
log("Creating Boxed world ...");
|
||||
@ -170,70 +222,20 @@ public class Boxed extends GameModeAddon {
|
||||
// Create the world if it does not exist
|
||||
islandWorld = getWorld(worldName, World.Environment.NORMAL);
|
||||
|
||||
// Make the nether if it does not exist
|
||||
if (settings.isNetherGenerate()) {
|
||||
log("Creating Boxed Seed Nether world ...");
|
||||
// Copy regions
|
||||
/*
|
||||
boolean newWorld = Bukkit.getWorld(SEED + NETHER) == null;
|
||||
if (newWorld) {
|
||||
// New world
|
||||
File root = new File(getDataFolder(), "../../../..");
|
||||
BentoBox.getInstance().logDebug("Absolute path " + root.getAbsolutePath());
|
||||
this.saveResource("worlds/seed_nether/DIM-1/region/r.18.18.mca", root, false, false);
|
||||
this.saveResource("worlds/seed_nether/DIM-1/region/r.18.19.mca", root, false, false);
|
||||
this.saveResource("worlds/seed_nether/DIM-1/region/r.18.20.mca", root, false, false);
|
||||
this.saveResource("worlds/seed_nether/DIM-1/region/r.19.18.mca", root, false, false);
|
||||
this.saveResource("worlds/seed_nether/DIM-1/region/r.19.19.mca", root, false, false);
|
||||
this.saveResource("worlds/seed_nether/DIM-1/region/r.19.20.mca", root, false, false);
|
||||
this.saveResource("worlds/seed_nether/DIM-1/region/r.20.18.mca", root, false, false);
|
||||
this.saveResource("worlds/seed_nether/DIM-1/region/r.20.19.mca", root, false, false);
|
||||
this.saveResource("worlds/seed_nether/DIM-1/region/r.20.20.mca", root, false, false);
|
||||
}*/
|
||||
|
||||
seedWorldNether = WorldCreator
|
||||
.name(SEED + NETHER)
|
||||
.generator(new BoxedSeedChunkGenerator(this, Environment.NETHER))
|
||||
.environment(Environment.NETHER)
|
||||
.seed(getSettings().getSeed())
|
||||
.createWorld();
|
||||
seedWorldNether.setDifficulty(Difficulty.EASY); // No damage wanted in this world.
|
||||
|
||||
|
||||
|
||||
|
||||
copyChunks(seedWorldNether);
|
||||
|
||||
if (getServer().getWorld(worldName + NETHER) == null) {
|
||||
log("Creating Boxed's Nether...");
|
||||
}
|
||||
netherWorld = getWorld(worldName, World.Environment.NETHER);
|
||||
}
|
||||
/*
|
||||
// Make the end if it does not exist
|
||||
if (settings.isEndGenerate()) {
|
||||
if (getServer().getWorld(worldName + THE_END) == null) {
|
||||
log("Creating Boxed's End World...");
|
||||
}
|
||||
endWorld = settings.isEndIslands() ? getWorld(worldName, World.Environment.THE_END) : getWorld(worldName, World.Environment.THE_END);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies chunks from the seed world so they can be pasted in the game world
|
||||
* @param seedWorld - source world
|
||||
* @param world - source world
|
||||
* @param gen - generator to store the chunks
|
||||
*/
|
||||
private void copyChunks(World seedWorld) {
|
||||
BoxedChunkGenerator gen;
|
||||
private void copyChunks(World world, AbstractBoxedChunkGenerator gen) {
|
||||
int startX = 0;
|
||||
int startZ = 0;
|
||||
if (seedWorld.getEnvironment().equals(Environment.NORMAL)) {
|
||||
gen = chunkGenerator;
|
||||
if (world.getEnvironment().equals(Environment.NORMAL)) {
|
||||
startX = this.settings.getSeedX() >> 4;
|
||||
startZ = this.settings.getSeedZ() >> 4;
|
||||
} else {
|
||||
gen = netherChunkGenerator;
|
||||
startX = this.settings.getNetherSeedX() >> 4;
|
||||
startZ = this.settings.getNetherSeedZ() >> 4;
|
||||
}
|
||||
@ -245,12 +247,12 @@ public class Boxed extends GameModeAddon {
|
||||
int last = 0;
|
||||
for (int x = -size; x <= size; x ++) {
|
||||
for (int z = -size; z <= size; z++) {
|
||||
gen.setChunk(x, z, seedWorld.getChunkAt(startX + x, startZ + z));
|
||||
gen.setChunk(x, z, world.getChunkAt(startX + x, startZ + z));
|
||||
count++;
|
||||
int p = (int) (count / percent * 100);
|
||||
if (p % 10 == 0 && p != last) {
|
||||
last = p;
|
||||
this.log("Storing seed chunks for " + seedWorld.getEnvironment() + " " + p + "% done");
|
||||
this.log("Storing seed chunks for " + world.getEnvironment() + " " + p + "% done");
|
||||
}
|
||||
|
||||
}
|
||||
@ -262,7 +264,7 @@ public class Boxed extends GameModeAddon {
|
||||
* @param env - nether, normal, or end
|
||||
* @return the chunkGenerator for the environment
|
||||
*/
|
||||
public BoxedChunkGenerator getChunkGenerator(Environment env) {
|
||||
public AbstractBoxedChunkGenerator getChunkGenerator(Environment env) {
|
||||
if (env.equals(Environment.NORMAL)) {
|
||||
return chunkGenerator;
|
||||
}
|
||||
|
@ -83,11 +83,10 @@ public abstract class AbstractBoxedBiomeProvider extends BiomeProvider {
|
||||
|
||||
@Override
|
||||
public Biome getBiome(WorldInfo worldInfo, int x, int y, int z) {
|
||||
int chunkX = (int)((double)x/16);
|
||||
int chunkZ = (int)((double)z/16);
|
||||
int size = (int)(dist / 16D); // Convert to chunk
|
||||
chunkX = BoxedChunkGenerator.repeatCalc(chunkX, size);
|
||||
chunkZ = BoxedChunkGenerator.repeatCalc(chunkZ, size);
|
||||
int chunkX = x >> 4;
|
||||
int chunkZ = z >> 4;
|
||||
chunkX = BoxedChunkGenerator.repeatCalc(chunkX);
|
||||
chunkZ = BoxedChunkGenerator.repeatCalc(chunkZ);
|
||||
ChunkSnapshot c = addon.getChunkGenerator(worldInfo.getEnvironment()).getChunk(chunkX, chunkZ);
|
||||
|
||||
if (c != null) {
|
||||
|
@ -0,0 +1,182 @@
|
||||
package world.bentobox.boxed.generators;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.ChunkSnapshot;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Banner;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.entity.AbstractHorse;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.ChestedHorse;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.generator.WorldInfo;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Attachable;
|
||||
import org.bukkit.material.Colorable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
import world.bentobox.bentobox.util.Pair;
|
||||
import world.bentobox.boxed.Boxed;
|
||||
|
||||
/**
|
||||
* Chunk generator for all environments
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractBoxedChunkGenerator extends ChunkGenerator {
|
||||
|
||||
protected final Boxed addon;
|
||||
protected static int size;
|
||||
protected Map<Pair<Integer, Integer>, ChunkStore> chunks = new HashMap<>();
|
||||
public record ChunkStore(ChunkSnapshot snapshot, List<EntityData> bpEnts, List<ChestData> chests) {};
|
||||
public record EntityData(Vector relativeLoc, BlueprintEntity entity) {};
|
||||
public record ChestData(Vector relativeLoc, BlueprintBlock chest) {};
|
||||
|
||||
//private final WorldRef wordRefNether;
|
||||
|
||||
public AbstractBoxedChunkGenerator(Boxed addon) {
|
||||
this.addon = addon;
|
||||
size = (int)(addon.getSettings().getIslandDistance() / 16D); // Size is chunks
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a chunk
|
||||
* @param z - chunk z coord
|
||||
* @param x - chunk x coord
|
||||
* @param chunk the chunk to set
|
||||
*/
|
||||
public void setChunk(int x, int z, Chunk chunk) {
|
||||
chunks.put(new Pair<>(x, z), new ChunkStore(chunk.getChunkSnapshot(false, true, false), getEnts(chunk), getChests(chunk)));
|
||||
}
|
||||
|
||||
protected abstract List<EntityData> getEnts(Chunk chunk);
|
||||
|
||||
protected abstract List<ChestData> getChests(Chunk chunk);
|
||||
|
||||
/**
|
||||
* @param x chunk x
|
||||
* @param z chunk z
|
||||
* @return chunk snapshot or null if there is none
|
||||
*/
|
||||
public ChunkSnapshot getChunk(int x, int z) {
|
||||
return chunks.get(new Pair<>(x, z)).snapshot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSpawn(World world, int x, int z)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateNoise(WorldInfo worldInfo, Random r, int chunkX, int chunkZ, ChunkData cd) {
|
||||
|
||||
int height = worldInfo.getMaxHeight();
|
||||
int minY = worldInfo.getMinHeight();
|
||||
int xx = repeatCalc(chunkX);
|
||||
int zz = repeatCalc(chunkZ);
|
||||
Pair<Integer, Integer> coords = new Pair<>(xx, zz);
|
||||
if (!chunks.containsKey(coords)) {
|
||||
// This should never be needed because islands should abut each other
|
||||
cd.setRegion(0, minY, 0, 16, 0, 16, Material.WATER);
|
||||
return;
|
||||
}
|
||||
// Copy the chunk
|
||||
ChunkSnapshot chunk = chunks.get(coords).snapshot;
|
||||
copyChunkVerbatim(cd, chunk, minY, height);
|
||||
|
||||
}
|
||||
|
||||
private void copyChunkVerbatim(ChunkData cd, ChunkSnapshot chunk, int minY, int height) {
|
||||
for (int x = 0; x < 16; x ++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = minY; y < height; y++) {
|
||||
cd.setBlock(x, y, z, chunk.getBlockData(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the repeating value for a given size
|
||||
* @param chunkCoord chunk coord
|
||||
* @return mapped chunk coord
|
||||
*/
|
||||
public static int repeatCalc(int chunkCoord) {
|
||||
int xx;
|
||||
if (chunkCoord > 0) {
|
||||
xx = Math.floorMod(chunkCoord + size, size*2) - size;
|
||||
} else {
|
||||
xx = Math.floorMod(chunkCoord - size, -size*2) + size;
|
||||
}
|
||||
return xx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the chunks
|
||||
*/
|
||||
public Map<Pair<Integer, Integer>, ChunkStore> getChunks() {
|
||||
return chunks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateNoise() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateSurface() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateCaves() {
|
||||
return false;
|
||||
//return this.addon.getSettings().isGenerateCaves();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateDecorations() {
|
||||
return false;
|
||||
//return this.addon.getSettings().isGenerateDecorations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateMobs() {
|
||||
return this.addon.getSettings().isGenerateMobs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateStructures() {
|
||||
return false;
|
||||
//return this.addon.getSettings().isAllowStructures();
|
||||
}
|
||||
|
||||
}
|
@ -33,9 +33,8 @@ public abstract class AbstractCopyBiomeProvider extends BiomeProvider {
|
||||
public Biome getBiome(WorldInfo worldInfo, int x, int y, int z) {
|
||||
int chunkX = (int)((double)x/16);
|
||||
int chunkZ = (int)((double)z/16);
|
||||
int size = (int)(dist / 16D); // Convert to chunk
|
||||
chunkX = BoxedChunkGenerator.repeatCalc(chunkX, size);
|
||||
chunkZ = BoxedChunkGenerator.repeatCalc(chunkZ, size);
|
||||
chunkX = BoxedChunkGenerator.repeatCalc(chunkX);
|
||||
chunkZ = BoxedChunkGenerator.repeatCalc(chunkZ);
|
||||
ChunkSnapshot c = addon.getChunkGenerator(worldInfo.getEnvironment()).getChunk(chunkX, chunkZ);
|
||||
|
||||
if (c != null) {
|
||||
|
@ -4,13 +4,16 @@ import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.bukkit.ChunkSnapshot;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.BlockFace;
|
||||
@ -18,9 +21,13 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.bukkit.generator.WorldInfo;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
|
||||
import com.google.common.base.Enums;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.util.Pair;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
import world.bentobox.boxed.Boxed;
|
||||
|
||||
/**
|
||||
@ -31,6 +38,7 @@ import world.bentobox.boxed.Boxed;
|
||||
public abstract class AbstractSeedBiomeProvider extends BiomeProvider {
|
||||
|
||||
private static final Map<Environment, String> ENV_MAP;
|
||||
private static final int DEPTH = 50;
|
||||
|
||||
static {
|
||||
Map<Environment, String> e = new EnumMap<>(Environment.class);
|
||||
@ -48,11 +56,13 @@ public abstract class AbstractSeedBiomeProvider extends BiomeProvider {
|
||||
private final int offsetX;
|
||||
private final int offsetZ;
|
||||
protected final Map<BlockFace, SortedMap<Double, Biome>> quadrants;
|
||||
private final AbstractBoxedChunkGenerator seedGen;
|
||||
|
||||
|
||||
protected AbstractSeedBiomeProvider(Boxed boxed, Environment env, Biome defaultBiome) {
|
||||
protected AbstractSeedBiomeProvider(Boxed boxed, Environment env, Biome defaultBiome, AbstractBoxedChunkGenerator seedGen) {
|
||||
this.addon = boxed;
|
||||
this.defaultBiome = defaultBiome;
|
||||
this.seedGen = seedGen;
|
||||
dist = addon.getSettings().getIslandDistance();
|
||||
offsetX = addon.getSettings().getIslandXOffset();
|
||||
offsetZ = addon.getSettings().getIslandZOffset();
|
||||
@ -75,34 +85,78 @@ public abstract class AbstractSeedBiomeProvider extends BiomeProvider {
|
||||
quadrants.put(BlockFace.SOUTH_WEST, southWest);
|
||||
}
|
||||
|
||||
private Biome getBiome(BlockFace dir, double d) {
|
||||
private Biome getQuadrantBiome(BlockFace dir, double d) {
|
||||
Entry<Double, Biome> en = ((TreeMap<Double, Biome>) quadrants.get(dir)).ceilingEntry(d);
|
||||
return en == null ? defaultBiome : en.getValue();
|
||||
return en == null ? null : en.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(WorldInfo worldInfo, int x, int y, int z) {
|
||||
return getMappedBiome(x,z);
|
||||
// Custom biomes are not 3D yet
|
||||
if (y < DEPTH) {
|
||||
Biome result = getVanillaBiome(worldInfo, x, y, z);
|
||||
return Objects.requireNonNull(result);
|
||||
}
|
||||
Biome result = getMappedBiome(x,z);
|
||||
if (result == null || result.equals(Biome.CUSTOM)) {
|
||||
result = getVanillaBiome(worldInfo, x, y, z);
|
||||
|
||||
}
|
||||
return Objects.requireNonNull(result);
|
||||
}
|
||||
|
||||
private @NonNull Biome getVanillaBiome(WorldInfo worldInfo, int x, int y, int z) {
|
||||
// Vanilla biomes
|
||||
int chunkX = BoxedChunkGenerator.repeatCalc(x >> 4);
|
||||
int chunkZ = BoxedChunkGenerator.repeatCalc(z >> 4);
|
||||
ChunkSnapshot snapshot = this.seedGen.getChunk(chunkX, chunkZ);
|
||||
if (snapshot == null) {
|
||||
return defaultBiome;
|
||||
}
|
||||
int xx = Math.floorMod(x, 16);
|
||||
int zz = Math.floorMod(z, 16);
|
||||
int yy = Math.max(Math.min(y * 4, worldInfo.getMaxHeight()), worldInfo.getMinHeight()); // To handle bug in Spigot
|
||||
|
||||
Biome b = snapshot.getBiome(xx, yy, zz);
|
||||
if (y > DEPTH )
|
||||
BentoBox.getInstance().logDebug("Returning vanilla biome " + b + " for " + worldInfo.getName() + " " + x + " " + y + " " + z);
|
||||
return Objects.requireNonNull(b);
|
||||
}
|
||||
|
||||
private Map<Pair<Integer, Integer>, Biome> biomeCache = new HashMap<>();
|
||||
/**
|
||||
* Get the mapped 2D biome at position x,z
|
||||
* @param x - block coord
|
||||
* @param z - block coord
|
||||
* @return Biome
|
||||
*/
|
||||
private Biome getMappedBiome(int x, int z) {
|
||||
/*
|
||||
* Biomes go around the island centers
|
||||
*
|
||||
*/
|
||||
Biome result = biomeCache.get((new Pair<Integer, Integer>(x,z)));
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
Vector s = new Vector(x, 0, z);
|
||||
Vector l = getClosestIsland(s);
|
||||
double dis = l.distanceSquared(s);
|
||||
double d = dis / (dist * dist);
|
||||
BentoBox.getInstance().logDebug("Closest island is " + Util.xyz(l));
|
||||
double dis = l.distance(s);
|
||||
double d = dis / dist; // Normalize
|
||||
Vector direction = s.subtract(l);
|
||||
if (direction.getBlockX() <= 0 && direction.getBlockZ() <= 0) {
|
||||
return getBiome(BlockFace.NORTH_WEST, d);
|
||||
result = getQuadrantBiome(BlockFace.NORTH_WEST, d);
|
||||
} else if (direction.getBlockX() > 0 && direction.getBlockZ() <= 0) {
|
||||
return getBiome(BlockFace.NORTH_EAST, d);
|
||||
result = getQuadrantBiome(BlockFace.NORTH_EAST, d);
|
||||
} else if (direction.getBlockX() <= 0 && direction.getBlockZ() > 0) {
|
||||
return getBiome(BlockFace.SOUTH_WEST, d);
|
||||
result = getQuadrantBiome(BlockFace.SOUTH_WEST, d);
|
||||
} else {
|
||||
result = getQuadrantBiome(BlockFace.SOUTH_EAST, d);
|
||||
}
|
||||
return getBiome(BlockFace.SOUTH_EAST, d);
|
||||
biomeCache.put(new Pair<Integer, Integer>(x,z), result);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -111,6 +165,11 @@ public abstract class AbstractSeedBiomeProvider extends BiomeProvider {
|
||||
return Arrays.stream(Biome.values()).filter(b -> !b.equals(Biome.CUSTOM)).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the island center closest to this vector
|
||||
* @param v - vector
|
||||
* @return island center vector (no y value)
|
||||
*/
|
||||
private Vector getClosestIsland(Vector v) {
|
||||
int d = dist * 2;
|
||||
long x = Math.round((double) v.getBlockX() / d) * d + offsetX;
|
||||
@ -129,8 +188,9 @@ public abstract class AbstractSeedBiomeProvider extends BiomeProvider {
|
||||
try {
|
||||
double d = Double.parseDouble(split[0]);
|
||||
Biome biome = Enums.getIfPresent(Biome.class, split[1].toUpperCase(Locale.ENGLISH)).orNull();
|
||||
if (biome == null && !split[1].toUpperCase(Locale.ENGLISH).equalsIgnoreCase("default")) {
|
||||
if (biome == null) {
|
||||
addon.logError(split[1].toUpperCase(Locale.ENGLISH) + " is an unknown biome on this server.");
|
||||
result.put(d, Biome.CUSTOM);
|
||||
} else {
|
||||
// A biome of null means that no alternative biome should be applied
|
||||
result.put(d, biome);
|
||||
|
@ -6,10 +6,8 @@ import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Banner;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.entity.Entity;
|
||||
@ -20,13 +18,12 @@ import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner;
|
||||
import world.bentobox.bentobox.util.Pair;
|
||||
import world.bentobox.boxed.Boxed;
|
||||
import world.bentobox.boxed.generators.BoxedChunkGenerator.ChestData;
|
||||
import world.bentobox.boxed.generators.BoxedChunkGenerator.ChunkStore;
|
||||
import world.bentobox.boxed.generators.AbstractBoxedChunkGenerator.ChestData;
|
||||
import world.bentobox.boxed.generators.AbstractBoxedChunkGenerator.ChunkStore;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
@ -35,14 +32,12 @@ import world.bentobox.boxed.generators.BoxedChunkGenerator.ChunkStore;
|
||||
public class BoxedBlockPopulator extends BlockPopulator {
|
||||
|
||||
private Boxed addon;
|
||||
private int size;
|
||||
|
||||
/**
|
||||
* @param addon
|
||||
*/
|
||||
public BoxedBlockPopulator(Boxed addon) {
|
||||
this.addon = addon;
|
||||
this.size = (int)(addon.getSettings().getIslandDistance() / 16D); // Size is chunks
|
||||
|
||||
}
|
||||
|
||||
@ -54,8 +49,8 @@ public class BoxedBlockPopulator extends BlockPopulator {
|
||||
World world = Bukkit.getWorld(worldInfo.getUID());
|
||||
int height = worldInfo.getMaxHeight();
|
||||
int minY = worldInfo.getMinHeight();
|
||||
int xx = BoxedChunkGenerator.repeatCalc(chunkX, size);
|
||||
int zz = BoxedChunkGenerator.repeatCalc(chunkZ, size);
|
||||
int xx = BoxedChunkGenerator.repeatCalc(chunkX);
|
||||
int zz = BoxedChunkGenerator.repeatCalc(chunkZ);
|
||||
Pair<Integer, Integer> coords = new Pair<>(xx, zz);
|
||||
if (chunks.containsKey(coords)) {
|
||||
//// BentoBox.getInstance().logDebug("Populating ");
|
||||
|
@ -43,26 +43,19 @@ import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
import world.bentobox.bentobox.util.Pair;
|
||||
import world.bentobox.boxed.Boxed;
|
||||
import world.bentobox.boxed.generators.AbstractBoxedChunkGenerator.ChestData;
|
||||
import world.bentobox.boxed.generators.AbstractBoxedChunkGenerator.ChunkStore;
|
||||
import world.bentobox.boxed.generators.AbstractBoxedChunkGenerator.EntityData;
|
||||
|
||||
/**
|
||||
* Chunk generator for all environments
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class BoxedChunkGenerator extends ChunkGenerator {
|
||||
|
||||
private final Boxed addon;
|
||||
private final int size;
|
||||
private Map<Pair<Integer, Integer>, ChunkStore> chunks = new HashMap<>();
|
||||
public record ChunkStore(ChunkSnapshot snapshot, List<EntityData> bpEnts, List<ChestData> chests) {};
|
||||
public record EntityData(Vector relativeLoc, BlueprintEntity entity) {};
|
||||
public record ChestData(Vector relativeLoc, BlueprintBlock chest) {};
|
||||
|
||||
//private final WorldRef wordRefNether;
|
||||
public class BoxedChunkGenerator extends AbstractBoxedChunkGenerator {
|
||||
|
||||
public BoxedChunkGenerator(Boxed addon) {
|
||||
this.addon = addon;
|
||||
this.size = (int)(addon.getSettings().getIslandDistance() / 16D); // Size is chunks
|
||||
super(addon);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -76,169 +69,22 @@ public class BoxedChunkGenerator extends ChunkGenerator {
|
||||
return world.getPopulators();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a chunk
|
||||
* @param z - chunk z coord
|
||||
* @param x - chunk x coord
|
||||
* @param chunk the chunk to set
|
||||
*/
|
||||
public void setChunk(int x, int z, Chunk chunk) {
|
||||
List<LivingEntity> ents = Arrays.stream(chunk.getEntities())
|
||||
@Override
|
||||
protected List<EntityData> getEnts(Chunk chunk) {
|
||||
return this.setEntities(Arrays.stream(chunk.getEntities())
|
||||
.filter(Objects::nonNull)
|
||||
.filter(e -> !(e instanceof Player))
|
||||
.filter(e -> e instanceof LivingEntity)
|
||||
.map(LivingEntity.class::cast)
|
||||
.toList();
|
||||
// Grab entities
|
||||
List<EntityData> bpEnts = this.setEntities(ents);
|
||||
// Grab tile entities
|
||||
List<ChestData> chests = Arrays.stream(chunk.getTileEntities()).map(t -> new ChestData(getLocInChunk(t.getLocation()), this.getBluePrintBlock(t.getBlock()))).toList();
|
||||
chunks.put(new Pair<>(x, z), new ChunkStore(chunk.getChunkSnapshot(false, true, false), bpEnts, chests));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x chunk x
|
||||
* @param z chunk z
|
||||
* @return chunk snapshot or null if there is none
|
||||
*/
|
||||
public ChunkSnapshot getChunk(int x, int z) {
|
||||
return chunks.get(new Pair<>(x, z)).snapshot;
|
||||
.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSpawn(World world, int x, int z)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateNoise(WorldInfo worldInfo, Random r, int chunkX, int chunkZ, ChunkData cd) {
|
||||
|
||||
int height = worldInfo.getMaxHeight();
|
||||
int minY = worldInfo.getMinHeight();
|
||||
int xx = repeatCalc(chunkX, size);
|
||||
int zz = repeatCalc(chunkZ, size);
|
||||
Pair<Integer, Integer> coords = new Pair<>(xx, zz);
|
||||
if (!chunks.containsKey(coords)) {
|
||||
// This should never be needed because islands should abut each other
|
||||
cd.setRegion(0, minY, 0, 16, 0, 16, Material.WATER);
|
||||
return;
|
||||
}
|
||||
// Copy the chunk
|
||||
ChunkSnapshot chunk = chunks.get(coords).snapshot;
|
||||
copyChunkVerbatim(cd, chunk, minY, height);
|
||||
|
||||
}
|
||||
|
||||
private void copyChunkVerbatim(ChunkData cd, ChunkSnapshot chunk, int minY, int height) {
|
||||
for (int x = 0; x < 16; x ++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = minY; y < height; y++) {
|
||||
cd.setBlock(x, y, z, chunk.getBlockData(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private void copyChunk(ChunkData cd, ChunkSnapshot chunk, int minY, int height) {
|
||||
for (int x = 0; x < 16; x ++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = minY; y < height; y++) {
|
||||
Material m = chunk.getBlockType(x, y, z);
|
||||
// Handle blocks that occur naturally in water
|
||||
if (isInWater(m)) {
|
||||
cd.setBlock(x, y, z, Material.WATER);
|
||||
} else {
|
||||
// Handle liquids and default blocks
|
||||
switch (m) {
|
||||
case WATER, LAVA, NETHERRACK, STONE, END_STONE -> cd.setBlock(x, y, z, m);
|
||||
default ->
|
||||
// Most other blocks
|
||||
cd.setBlock(x, y, z, isGround(m) ? Material.STONE : Material.AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* Calculates the repeating value for a given size
|
||||
* @param chunkCoord chunk coord
|
||||
* @param s size
|
||||
* @return mapped chunk coord
|
||||
*/
|
||||
public static int repeatCalc(int chunkCoord, int s) {
|
||||
int xx;
|
||||
if (chunkCoord > 0) {
|
||||
xx = Math.floorMod(chunkCoord + s, s*2) - s;
|
||||
} else {
|
||||
xx = Math.floorMod(chunkCoord - s, -s*2) + s;
|
||||
}
|
||||
return xx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the chunks
|
||||
*/
|
||||
public Map<Pair<Integer, Integer>, ChunkStore> getChunks() {
|
||||
return chunks;
|
||||
}
|
||||
/*
|
||||
private static boolean isInWater(Material m) {
|
||||
return switch (m) {
|
||||
// Underwater plants
|
||||
case KELP, KELP_PLANT, SEAGRASS, BUBBLE_COLUMN, BUBBLE_CORAL, BUBBLE_CORAL_BLOCK, BUBBLE_CORAL_FAN,
|
||||
BUBBLE_CORAL_WALL_FAN, DEAD_BRAIN_CORAL, DEAD_BRAIN_CORAL_BLOCK, DEAD_BRAIN_CORAL_FAN,
|
||||
DEAD_BRAIN_CORAL_WALL_FAN, DEAD_BUBBLE_CORAL, DEAD_BUBBLE_CORAL_BLOCK, DEAD_BUBBLE_CORAL_FAN,
|
||||
DEAD_BUBBLE_CORAL_WALL_FAN, DEAD_BUSH, DEAD_FIRE_CORAL, DEAD_FIRE_CORAL_BLOCK, DEAD_FIRE_CORAL_FAN,
|
||||
DEAD_FIRE_CORAL_WALL_FAN, DEAD_HORN_CORAL, DEAD_HORN_CORAL_BLOCK, DEAD_HORN_CORAL_FAN,
|
||||
DEAD_HORN_CORAL_WALL_FAN, DEAD_TUBE_CORAL, DEAD_TUBE_CORAL_BLOCK, DEAD_TUBE_CORAL_FAN,
|
||||
DEAD_TUBE_CORAL_WALL_FAN, FIRE_CORAL, FIRE_CORAL_BLOCK, FIRE_CORAL_FAN, FIRE_CORAL_WALL_FAN,
|
||||
HORN_CORAL, HORN_CORAL_BLOCK, HORN_CORAL_FAN, HORN_CORAL_WALL_FAN, TUBE_CORAL, TUBE_CORAL_BLOCK,
|
||||
TUBE_CORAL_FAN, TUBE_CORAL_WALL_FAN, TALL_SEAGRASS -> true;
|
||||
default -> false;
|
||||
};
|
||||
protected List<ChestData> getChests(Chunk chunk) {
|
||||
return Arrays.stream(chunk.getTileEntities()).map(t -> new ChestData(getLocInChunk(t.getLocation()), this.getBluePrintBlock(t.getBlock()))).toList();
|
||||
}
|
||||
|
||||
|
||||
private static boolean isGround(Material m) {
|
||||
if (m.isAir() || m.isBurnable() || !m.isSolid()) return false;
|
||||
return switch (m) {
|
||||
case ANDESITE, BEDROCK, CALCITE, CLAY, COAL_ORE, COARSE_DIRT, COBBLESTONE, COPPER_ORE, DEEPSLATE,
|
||||
DEEPSLATE_COAL_ORE, DEEPSLATE_COPPER_ORE, DEEPSLATE_DIAMOND_ORE, DEEPSLATE_EMERALD_ORE,
|
||||
DEEPSLATE_GOLD_ORE, DEEPSLATE_IRON_ORE, DEEPSLATE_LAPIS_ORE, DEEPSLATE_REDSTONE_ORE, DIAMOND_ORE,
|
||||
DIORITE, DIRT, DIRT_PATH, DRIPSTONE_BLOCK, EMERALD_ORE, END_STONE, FARMLAND, GLOWSTONE, GOLD_ORE,
|
||||
GRANITE, GRASS_BLOCK, IRON_ORE, MAGMA_BLOCK, MYCELIUM, NETHERITE_BLOCK, NETHERRACK, RED_SAND,
|
||||
RED_SANDSTONE, ROOTED_DIRT, SAND, SANDSTONE, SOUL_SAND, SOUL_SOIL, STONE, TERRACOTTA, AMETHYST_BLOCK,
|
||||
AMETHYST_CLUSTER, AMETHYST_SHARD, BASALT, BLACKSTONE, BLACK_CONCRETE, BLACK_GLAZED_TERRACOTTA,
|
||||
BLACK_TERRACOTTA, BLUE_CONCRETE, BLUE_GLAZED_TERRACOTTA, BLUE_TERRACOTTA, BONE_BLOCK, BROWN_CONCRETE,
|
||||
BROWN_GLAZED_TERRACOTTA, BROWN_TERRACOTTA, BUDDING_AMETHYST, CHISELED_DEEPSLATE,
|
||||
CHISELED_NETHER_BRICKS, CHISELED_POLISHED_BLACKSTONE, CHISELED_QUARTZ_BLOCK, CHISELED_RED_SANDSTONE,
|
||||
CHISELED_SANDSTONE, CHISELED_STONE_BRICKS, COAL_BLOCK, COBBLED_DEEPSLATE, CRYING_OBSIDIAN,
|
||||
CUT_RED_SANDSTONE, CUT_RED_SANDSTONE_SLAB, CUT_SANDSTONE, CUT_SANDSTONE_SLAB, CYAN_CONCRETE,
|
||||
CYAN_GLAZED_TERRACOTTA, CYAN_TERRACOTTA, DEEPSLATE_BRICKS, DIAMOND_BLOCK, ECHO_SHARD, EMERALD_BLOCK,
|
||||
GOLD_BLOCK, GRAVEL, GRAY_CONCRETE, GRAY_GLAZED_TERRACOTTA, GRAY_TERRACOTTA, GREEN_CONCRETE,
|
||||
GREEN_GLAZED_TERRACOTTA, GREEN_TERRACOTTA, INFESTED_CHISELED_STONE_BRICKS, INFESTED_COBBLESTONE,
|
||||
INFESTED_CRACKED_STONE_BRICKS, INFESTED_DEEPSLATE, INFESTED_MOSSY_STONE_BRICKS, INFESTED_STONE,
|
||||
INFESTED_STONE_BRICKS, LAPIS_ORE, LARGE_AMETHYST_BUD, LIGHT_BLUE_CONCRETE,
|
||||
LIGHT_BLUE_GLAZED_TERRACOTTA, LIGHT_BLUE_TERRACOTTA, LIGHT_GRAY_CONCRETE,
|
||||
LIGHT_GRAY_GLAZED_TERRACOTTA, LIGHT_GRAY_TERRACOTTA, LIME_CONCRETE, LIME_GLAZED_TERRACOTTA,
|
||||
LIME_TERRACOTTA, MAGENTA_CONCRETE, MAGENTA_GLAZED_TERRACOTTA, MAGENTA_TERRACOTTA, MOSSY_COBBLESTONE,
|
||||
MUD, NETHERITE_SCRAP, NETHER_GOLD_ORE, NETHER_QUARTZ_ORE, OBSIDIAN, ORANGE_CONCRETE,
|
||||
ORANGE_GLAZED_TERRACOTTA, ORANGE_TERRACOTTA, PACKED_MUD, PINK_CONCRETE, PINK_GLAZED_TERRACOTTA,
|
||||
PINK_TERRACOTTA, PODZOL, POLISHED_ANDESITE, POLISHED_BASALT, POLISHED_BLACKSTONE,
|
||||
POLISHED_DEEPSLATE, POLISHED_DIORITE, POLISHED_GRANITE, PURPLE_CONCRETE, PURPLE_GLAZED_TERRACOTTA,
|
||||
PURPLE_TERRACOTTA, PURPUR_BLOCK, QUARTZ_BLOCK, RAW_COPPER_BLOCK, RAW_GOLD_BLOCK, RAW_IRON_BLOCK,
|
||||
REDSTONE_BLOCK, REDSTONE_ORE, RED_CONCRETE, RED_GLAZED_TERRACOTTA, RED_TERRACOTTA, SMOOTH_BASALT,
|
||||
SMOOTH_QUARTZ, SMOOTH_RED_SANDSTONE, SMOOTH_SANDSTONE, SMOOTH_STONE, TUFF, WARPED_HYPHAE,
|
||||
WARPED_NYLIUM, WHITE_CONCRETE, WHITE_GLAZED_TERRACOTTA, WHITE_TERRACOTTA, YELLOW_CONCRETE,
|
||||
YELLOW_GLAZED_TERRACOTTA, YELLOW_TERRACOTTA -> true;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
*/
|
||||
private List<EntityData> setEntities(Collection<LivingEntity> entities) {
|
||||
List<EntityData> bpEnts = new ArrayList<>();
|
||||
for (LivingEntity entity: entities) {
|
||||
@ -350,39 +196,4 @@ public class BoxedChunkGenerator extends ChunkGenerator {
|
||||
return cs;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateNoise() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateSurface() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateCaves() {
|
||||
return false;
|
||||
//return this.addon.getSettings().isGenerateCaves();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateDecorations() {
|
||||
return false;
|
||||
//return this.addon.getSettings().isGenerateDecorations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateMobs() {
|
||||
return this.addon.getSettings().isGenerateMobs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateStructures() {
|
||||
return false;
|
||||
//return this.addon.getSettings().isAllowStructures();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package world.bentobox.boxed.generators;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
@ -12,24 +15,37 @@ import world.bentobox.boxed.Boxed;
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class BoxedSeedChunkGenerator extends ChunkGenerator {
|
||||
public class BoxedSeedChunkGenerator extends AbstractBoxedChunkGenerator {
|
||||
|
||||
private final BiomeProvider seedBiomeProvider;
|
||||
private final BiomeProvider biomeProvider;
|
||||
private final Environment env;
|
||||
|
||||
/**
|
||||
* @param env
|
||||
* @param seedBiomeProvider
|
||||
* @param boxed - addon
|
||||
* @param env - environment
|
||||
*/
|
||||
public BoxedSeedChunkGenerator(Boxed boxed, Environment env) {
|
||||
this.seedBiomeProvider = new SeedBiomeGenerator(boxed);
|
||||
super(boxed);
|
||||
this.biomeProvider = null;
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boxed - addon
|
||||
* @param env - environment
|
||||
* @param bp - biome provider
|
||||
*/
|
||||
public BoxedSeedChunkGenerator(Boxed boxed, Environment env, BiomeProvider bp) {
|
||||
super(boxed);
|
||||
this.biomeProvider = bp;
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeProvider getDefaultBiomeProvider(WorldInfo worldInfo) {
|
||||
return seedBiomeProvider;
|
||||
// If null then vanilla biomes are used
|
||||
return biomeProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -62,4 +78,16 @@ public class BoxedSeedChunkGenerator extends ChunkGenerator {
|
||||
public boolean shouldGenerateStructures() {
|
||||
return env.equals(Environment.NETHER); // We allow structures in the Nether
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<EntityData> getEnts(Chunk chunk) {
|
||||
// These won't be stored
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ChestData> getChests(Chunk chunk) {
|
||||
// These won't be stored
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package world.bentobox.boxed.generators;
|
||||
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
|
||||
import world.bentobox.boxed.Boxed;
|
||||
|
||||
@ -11,8 +12,8 @@ import world.bentobox.boxed.Boxed;
|
||||
*/
|
||||
public class SeedBiomeGenerator extends AbstractSeedBiomeProvider {
|
||||
|
||||
public SeedBiomeGenerator(Boxed boxed) {
|
||||
super(boxed, Environment.NORMAL, Biome.OCEAN);
|
||||
public SeedBiomeGenerator(Boxed boxed, AbstractBoxedChunkGenerator seedGen) {
|
||||
super(boxed, Environment.NORMAL, Biome.PLAINS, seedGen);
|
||||
}
|
||||
|
||||
}
|
@ -2,27 +2,25 @@
|
||||
distribution:
|
||||
overworld:
|
||||
north-east:
|
||||
- 0.05:PLAINS
|
||||
- 0.05:CUSTOM
|
||||
- 0.1:DESERT
|
||||
- 0.2:SAVANNA
|
||||
- 0.5:SPARSE_JUNGLE
|
||||
- 0.65:JUNGLE
|
||||
- 0.8:BAMBOO_JUNGLE
|
||||
- 1.0:MANGROVE_SWAMP
|
||||
- 2.0:CUSTOM
|
||||
south-east:
|
||||
- 0.05:PLAINS
|
||||
- 0.8:SUNFLOWER_PLAINS
|
||||
- 0.05:CUSTOM
|
||||
- 0.08:SUNFLOWER_PLAINS
|
||||
- 0.2:FLOWER_FOREST
|
||||
- 0.3:SAVANNA
|
||||
- 0.4:BEACH
|
||||
- 0.5:COLD_OCEAN
|
||||
- 0.5:CUSTOM
|
||||
north-west:
|
||||
- 0.05:PLAINS
|
||||
- 0.8:WARM_OCEAN
|
||||
- 1.5:COLD_OCEAN
|
||||
- 2.0:OCEAN
|
||||
- 2.0:CUSTOM
|
||||
south-west:
|
||||
- 0.04:PLAINS
|
||||
- 0.04:CUSTOM
|
||||
- 0.05:DARK_FOREST
|
||||
- 0.06:BIRCH_FOREST
|
||||
- 0.07:FOREST
|
||||
@ -34,9 +32,10 @@ distribution:
|
||||
- 0.7:TAIGA
|
||||
- 1.1:SNOWY_PLAINS
|
||||
- 2.1:SNOWY_TAIGA
|
||||
- 2.2:CUSTOM
|
||||
nether:
|
||||
north-east:
|
||||
- 0.03:NETHER_WASTES
|
||||
- 0.03:CUSTOM
|
||||
- 0.14:CRIMSON_FOREST
|
||||
- 0.26:NETHER_WASTES
|
||||
- 0.51:WARPED_FOREST
|
||||
@ -46,7 +45,7 @@ distribution:
|
||||
- 1.6:BASALT_DELTAS
|
||||
- 2.1:NETHER_WASTES
|
||||
south-east:
|
||||
- 0.03:NETHER_WASTES
|
||||
- 0.03:CUSTOM
|
||||
- 0.05:CRIMSON_FOREST
|
||||
- 0.23:NETHER_WASTES
|
||||
- 0.48:WARPED_FOREST
|
||||
@ -56,7 +55,7 @@ distribution:
|
||||
- 1.9:BASALT_DELTAS
|
||||
- 2.0:NETHER_WASTES
|
||||
north-west:
|
||||
- 0.03:NETHER_WASTES
|
||||
- 0.03:CUSTOM
|
||||
- 0.15:CRIMSON_FOREST
|
||||
- 0.20:NETHER_WASTES
|
||||
- 0.3:WARPED_FOREST
|
||||
@ -66,7 +65,7 @@ distribution:
|
||||
- 1.5:BASALT_DELTAS
|
||||
- 2.0:NETHER_WASTES
|
||||
south-west:
|
||||
- 0.03:NETHER_WASTES
|
||||
- 0.03:CUSTOM
|
||||
- 0.11:CRIMSON_FOREST
|
||||
- 0.22:NETHER_WASTES
|
||||
- 0.51:WARPED_FOREST
|
||||
|
Loading…
Reference in New Issue
Block a user