Added world generation settings for biomes

This commit is contained in:
tastybento 2021-02-20 10:19:05 -08:00
parent 60b9b227b8
commit 40147eeb2a
7 changed files with 378 additions and 50 deletions

View File

@ -1,9 +1,52 @@
# Boxed # Boxed
A game mode where you are boxed into a tiny space that only expands by completing advancements. A game mode where you are boxed into a tiny space that only expands by completing advancements.
** Warning this game mode is still in development and newer versions will not necessarily be compatible with older versions ***
## Required Plugin
Requires WorldGeneratorAPI plugin. [Download the correct one for your server here.](https://github.com/rutgerkok/WorldGeneratorApi/releases) Requires WorldGeneratorAPI plugin. [Download the correct one for your server here.](https://github.com/rutgerkok/WorldGeneratorApi/releases)
Recommended addons: ## Required Addons
* InvSwitcher - keeps advancements, inventory, etc. separate between worlds on a server
* Border - shows where the border is of the box and the maximum border
## How to install
### Quick Start
1. Place Boxed addon into the BentoBox addons folder along with InvSwitcher and Border.
2. Place the WorldGeneratorAPI plugin into your plugins folder.
3. Restart the server - new worlds will be created. There may be a delay.
4. Stop the server
5. Edit the Border addon's config.yml. It should have these settings:
```
# Use barrier blocks. If false, the border is indicated by particles only.
use-barrier-blocks: false
#
# Default border behavior
show-by-default: true
#
# Show max-protection range border. This is a visual border only and not a barrier.
show-max-border: true
```
6. Restart the server
7. Login
8. Type `/boxed` to start
* You will start by a tree.
* The only area you can operate on is your box that shows as a blue particle border.
* To make your box bigger, complete advancements.
* Check your progress with the Advancements screen, (L-key).
* Monsters can be hurt outside your box with weapons and potions.
* You can trade with villagers anywhere.
* Boats can be used anywhere.
* Items can be dropped and picked up anywhere.
* Workbenches can be used anywhere.
* The box owner can move the box using enderpearls thrown from within the box. Beware! It's a one-way trip.
* InvSwitcher - will keep advancements separate between worlds on a server
* Border - shows where the border is of the box

View File

@ -44,6 +44,8 @@ public class Boxed extends GameModeAddon {
saveDefaultConfig(); saveDefaultConfig();
// Load settings from config.yml. This will check if there are any issues with it too. // Load settings from config.yml. This will check if there are any issues with it too.
loadSettings(); loadSettings();
// Save biomes
this.saveResource("biomes.yml", false);
// Chunk generator // Chunk generator
WorldRef wordRef = WorldRef.ofName(getSettings().getWorldName()); WorldRef wordRef = WorldRef.ofName(getSettings().getWorldName());
chunkGenerator = WorldGeneratorApi chunkGenerator = WorldGeneratorApi
@ -51,7 +53,7 @@ public class Boxed extends GameModeAddon {
.createCustomGenerator(wordRef, generator -> { .createCustomGenerator(wordRef, generator -> {
// Set the noise generator // Set the noise generator
generator.setBaseNoiseGenerator(new BasicWorldGenerator(this, wordRef, getSettings().getSeed())); generator.setBaseNoiseGenerator(new BasicWorldGenerator(this, wordRef, getSettings().getSeed()));
generator.getWorldDecorator().withoutDefaultDecorations(DecorationType.SURFACE_STRUCTURES); //generator.getWorldDecorator().withoutDefaultDecorations(DecorationType.SURFACE_STRUCTURES);
generator.getWorldDecorator().withoutDefaultDecorations(DecorationType.STRONGHOLDS); generator.getWorldDecorator().withoutDefaultDecorations(DecorationType.STRONGHOLDS);
generator.setBiomeGenerator(new BoxedBiomeGenerator(this)); generator.setBiomeGenerator(new BoxedBiomeGenerator(this));
}); });
@ -153,7 +155,9 @@ public class Boxed extends GameModeAddon {
worldName2 = env.equals(World.Environment.THE_END) ? worldName2 + THE_END : worldName2; worldName2 = env.equals(World.Environment.THE_END) ? worldName2 + THE_END : worldName2;
World w = WorldCreator.name(worldName2).type(WorldType.FLAT).environment(env).generator(chunkGenerator2).createWorld(); World w = WorldCreator.name(worldName2).type(WorldType.FLAT).environment(env).generator(chunkGenerator2).createWorld();
// Backup world // Backup world
WorldCreator.name(worldName2 + "_bak").type(WorldType.FLAT).environment(env).generator(chunkGenerator2).createWorld(); if (env.equals(Environment.NORMAL)) {
WorldCreator.name(worldName2 + "_bak").type(WorldType.FLAT).environment(env).generator(chunkGenerator2).createWorld();
}
// Set spawn rates // Set spawn rates
if (w != null) { if (w != null) {
if (getSettings().getSpawnLimitMonsters() > 0) { if (getSettings().getSpawnLimitMonsters() > 0) {

View File

@ -1,6 +1,9 @@
package world.bentobox.boxed.generators; package world.bentobox.boxed.generators;
import java.io.File;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.util.noise.SimplexNoiseGenerator; import org.bukkit.util.noise.SimplexNoiseGenerator;
import nl.rutgerkok.worldgeneratorapi.BaseNoiseGenerator; import nl.rutgerkok.worldgeneratorapi.BaseNoiseGenerator;
@ -16,39 +19,34 @@ public class BasicWorldGenerator implements BaseNoiseGenerator {
private final SimplexNoiseGenerator mainNoiseGenerator; private final SimplexNoiseGenerator mainNoiseGenerator;
private final Boxed addon; private final Boxed addon;
private final YamlConfiguration config;
public BasicWorldGenerator(Boxed addon, WorldRef world, long seed) { public BasicWorldGenerator(Boxed addon, WorldRef world, long seed) {
this.addon = addon; this.addon = addon;
// Initialize the noise generator based on the world seed // Initialize the noise generator based on the world seed
this.mainNoiseGenerator = new SimplexNoiseGenerator(seed); this.mainNoiseGenerator = new SimplexNoiseGenerator(seed);
// Load the config
File biomeFile = new File(addon.getDataFolder(), "biomes.yml");
if (!biomeFile.exists()) {
addon.saveResource("biomes.yml", true);
}
config = YamlConfiguration.loadConfiguration(biomeFile);
} }
@Override @Override
public void getNoise(BiomeGenerator biomeGenerator, double[] buffer, int scaledX, int scaledZ) { public void getNoise(BiomeGenerator biomeGenerator, double[] buffer, int scaledX, int scaledZ) {
//addon.getPlugin().logDebug("1 Scaled x = " + scaledX + " scaled z = " + scaledZ);
// Repeat on an island boundary // Repeat on an island boundary
int dist = addon.getSettings().getIslandDistance(); int dist = addon.getSettings().getIslandDistance();
double height = 8;
scaledX = ((scaledX*4) % dist) / 4;
scaledZ = ((scaledZ*4) % dist) / 4;
Biome biome = biomeGenerator.getZoomedOutBiome(scaledX, scaledZ); Biome biome = biomeGenerator.getZoomedOutBiome(scaledX, scaledZ);
double noiseScaleHorizontal = addon.getSettings().getNoiseScaleHorizontal(); double noiseScaleHorizontal = config.getDouble("biomes." + biome.name() + ".scale", 10D);
if (biome.equals(Biome.SNOWY_TAIGA)) { double height = config.getDouble("biomes." + biome.name() + ".height", 8D);
noiseScaleHorizontal = noiseScaleHorizontal / 2; double x = (((scaledX*4) % dist) / 4) / noiseScaleHorizontal;
} else if (biome.equals(Biome.MOUNTAINS)) { double z = (((scaledZ*4) % dist) / 4) / noiseScaleHorizontal;
height = 10;
noiseScaleHorizontal = noiseScaleHorizontal / 4;
} else if (biome.equals(Biome.DESERT)) {
height = 9;
noiseScaleHorizontal = noiseScaleHorizontal * 1.5F;
} else if (biome.equals(Biome.BADLANDS)) {
height = 8.5;
noiseScaleHorizontal = noiseScaleHorizontal * 1.5F;
}
for (int y = 0; y < buffer.length; y++) { for (int y = 0; y < buffer.length; y++) {
double noise = this.mainNoiseGenerator.noise(scaledX / noiseScaleHorizontal, y, scaledZ / noiseScaleHorizontal); double noise = this.mainNoiseGenerator.noise(x, y, z);
double heightOffset = height - y; double heightOffset = height - y;
buffer[y] = noise + heightOffset; buffer[y] = noise + heightOffset;
} }

View File

@ -1,6 +1,14 @@
package world.bentobox.boxed.generators; package world.bentobox.boxed.generators;
import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.block.BlockFace;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import nl.rutgerkok.worldgeneratorapi.BiomeGenerator; import nl.rutgerkok.worldgeneratorapi.BiomeGenerator;
@ -12,11 +20,78 @@ import world.bentobox.boxed.Boxed;
*/ */
public class BoxedBiomeGenerator implements BiomeGenerator { public class BoxedBiomeGenerator implements BiomeGenerator {
private static final TreeMap<Double, Biome> NORTH_EAST = new TreeMap<>();
static {
NORTH_EAST.put(0.2, Biome.PLAINS);
NORTH_EAST.put(0.3, Biome.SAVANNA);
NORTH_EAST.put(0.4, Biome.JUNGLE_EDGE);
NORTH_EAST.put(0.5, Biome.JUNGLE);
NORTH_EAST.put(0.6, Biome.JUNGLE_HILLS);
NORTH_EAST.put(0.75, Biome.BAMBOO_JUNGLE_HILLS);
NORTH_EAST.put(0.8, Biome.BAMBOO_JUNGLE);
NORTH_EAST.put(0.9, Biome.BADLANDS_PLATEAU);
NORTH_EAST.put(1.0, Biome.BADLANDS);
NORTH_EAST.put(1.1, Biome.LUKEWARM_OCEAN);
NORTH_EAST.put(20.0, Biome.WARM_OCEAN);
}
private static final TreeMap<Double, Biome> SOUTH_EAST = new TreeMap<>();
static {
SOUTH_EAST.put(0.2, Biome.PLAINS);
SOUTH_EAST.put(0.3, Biome.SAVANNA);
SOUTH_EAST.put(0.4, Biome.DESERT);
SOUTH_EAST.put(0.5, Biome.SHATTERED_SAVANNA);
SOUTH_EAST.put(0.65, Biome.DESERT_HILLS);
SOUTH_EAST.put(0.7, Biome.GRAVELLY_MOUNTAINS);
SOUTH_EAST.put(0.9, Biome.BADLANDS_PLATEAU);
SOUTH_EAST.put(1.0, Biome.ERODED_BADLANDS);
SOUTH_EAST.put(1.1, Biome.MUSHROOM_FIELD_SHORE);
SOUTH_EAST.put(20.0, Biome.WARM_OCEAN);
}
private static final TreeMap<Double, Biome> NORTH_WEST = new TreeMap<>();
static {
NORTH_WEST.put(0.2, Biome.PLAINS);
NORTH_WEST.put(0.25, Biome.SUNFLOWER_PLAINS);
NORTH_WEST.put(0.3, Biome.FLOWER_FOREST);
NORTH_WEST.put(0.4, Biome.DARK_FOREST);
NORTH_WEST.put(0.5, Biome.SNOWY_TAIGA);
NORTH_WEST.put(0.65, Biome.SNOWY_TAIGA_HILLS);
NORTH_WEST.put(0.7, Biome.SNOWY_MOUNTAINS);
NORTH_WEST.put(0.9, Biome.MOUNTAIN_EDGE);
NORTH_WEST.put(1.1, Biome.BEACH);
NORTH_WEST.put(20.0, Biome.COLD_OCEAN);
}
private static final TreeMap<Double, Biome> SOUTH_WEST = new TreeMap<>();
static {
SOUTH_WEST.put(0.2, Biome.PLAINS);
SOUTH_WEST.put(0.25, Biome.SWAMP);
SOUTH_WEST.put(0.3, Biome.FOREST);
SOUTH_WEST.put(0.4, Biome.DARK_FOREST);
SOUTH_WEST.put(0.5, Biome.SNOWY_TAIGA);
SOUTH_WEST.put(0.65, Biome.SNOWY_TAIGA_HILLS);
SOUTH_WEST.put(0.7, Biome.SNOWY_MOUNTAINS);
SOUTH_WEST.put(0.9, Biome.MOUNTAIN_EDGE);
SOUTH_WEST.put(1.1, Biome.ICE_SPIKES);
SOUTH_WEST.put(20.0, Biome.COLD_OCEAN);
}
private static final Map<BlockFace, SortedMap<Double, Biome>> QUADRANTS;
static {
Map<BlockFace, SortedMap<Double, Biome>> q = new EnumMap<>(BlockFace.class);
q.put(BlockFace.NORTH_EAST, NORTH_EAST);
q.put(BlockFace.NORTH_WEST, NORTH_WEST);
q.put(BlockFace.SOUTH_EAST, SOUTH_EAST);
q.put(BlockFace.SOUTH_WEST, SOUTH_WEST);
QUADRANTS = Collections.unmodifiableMap(q);
}
private final Boxed addon; private final Boxed addon;
private final int dist; private final int dist;
private final int offsetX; private final int offsetX;
private final int offsetZ; private final int offsetZ;
public BoxedBiomeGenerator(Boxed boxed) { public BoxedBiomeGenerator(Boxed boxed) {
this.addon = boxed; this.addon = boxed;
dist = addon.getSettings().getIslandDistance(); dist = addon.getSettings().getIslandDistance();
@ -34,28 +109,31 @@ public class BoxedBiomeGenerator implements BiomeGenerator {
* Biomes go around the island centers * Biomes go around the island centers
* *
*/ */
Vector s = new Vector(x * 4, y * 4, z * 4); Vector s = new Vector(x * 4, 0, z * 4);
Vector l = getClosestIsland(s); Vector l = getClosestIsland(s);
double d = l.distance(s) / addon.getSettings().getIslandDistance(); double dis = l.distanceSquared(s);
if (d < 0.2) { double d = dis / (dist * dist);
return Biome.PLAINS; Vector direction = s.subtract(l);
} else if (d < 0.3) { if (direction.getBlockX() <= 0 && direction.getBlockZ() <= 0) {
return Biome.FOREST; return getBiome(BlockFace.NORTH_WEST, d);
} else if (d < 0.33) { } else if (direction.getBlockX() > 0 && direction.getBlockZ() <= 0) {
return Biome.SNOWY_TAIGA; return getBiome(BlockFace.NORTH_EAST, d);
} else if (d < 0.4) { } else if (direction.getBlockX() <= 0 && direction.getBlockZ() > 0) {
return Biome.DARK_FOREST; return getBiome(BlockFace.SOUTH_WEST, d);
} else if (d < 0.45) {
return Biome.MOUNTAINS;
} else if (d < 0.52) {
return Biome.DESERT;
} }
return Biome.BADLANDS; return getBiome(BlockFace.SOUTH_EAST, d);
}
private Biome getBiome(BlockFace dir, double d) {
Entry<Double, Biome> en = ((TreeMap<Double, Biome>) QUADRANTS.get(dir)).ceilingEntry(d);
return en == null ? Biome.OCEAN : en.getValue();
} }
public Vector getClosestIsland(Vector v) { public Vector getClosestIsland(Vector v) {
long x = Math.round((double) v.getBlockX() / dist) * dist + offsetX; int d = dist * 2;
long z = Math.round((double) v.getBlockZ() / dist) * dist + offsetZ; long x = Math.round((double) v.getBlockX() / d) * d + offsetX;
return new Vector(x, v.getBlockY(), z); long z = Math.round((double) v.getBlockZ() / d) * d + offsetZ;
return new Vector(x, 0, z);
} }
} }

View File

@ -24,8 +24,8 @@ public class DeleteGen extends ChunkGenerator {
public DeleteGen(Boxed addon) { public DeleteGen(Boxed addon) {
backMap = new HashMap<>(); backMap = new HashMap<>();
backMap.put(addon.getOverWorld(), Bukkit.getWorld(addon.getOverWorld().getName() + "_bak")); backMap.put(addon.getOverWorld(), Bukkit.getWorld(addon.getOverWorld().getName() + "_bak"));
backMap.put(addon.getNetherWorld(), Bukkit.getWorld(addon.getNetherWorld().getName() + "_bak")); //backMap.put(addon.getNetherWorld(), Bukkit.getWorld(addon.getNetherWorld().getName() + "_bak"));
backMap.put(addon.getEndWorld(), Bukkit.getWorld(addon.getEndWorld().getName() + "_bak")); //backMap.put(addon.getEndWorld(), Bukkit.getWorld(addon.getEndWorld().getName() + "_bak"));
} }
@Override @Override

View File

@ -0,0 +1,205 @@
biomes:
BADLANDS_PLATEAU:
height: 9
scale: 16
BADLANDS:
height: 8
scale: 10
BAMBOO_JUNGLE_HILLS:
height: 9
scale: 2.5
BAMBOO_JUNGLE:
height: 8
scale: 10
BEACH:
height: 7
scale: 16
BIRCH_FOREST_HILLS:
height: 9
scale: 2.5
BIRCH_FOREST:
height: 8
scale: 10
COLD_OCEAN:
height: 5
scale: 3.33
DARK_FOREST_HILLS:
height: 9
scale: 2.5
DARK_FOREST:
height: 8
scale: 10
DEEP_COLD_OCEAN:
height: 5
scale: 3.33
DEEP_FROZEN_OCEAN:
height: 5
scale: 3.33
DEEP_LUKEWARM_OCEAN:
height: 5
scale: 3.33
DEEP_OCEAN:
height: 5
scale: 3.33
DEEP_WARM_OCEAN:
height: 5
scale: 3.33
DESERT_HILLS:
height: 9
scale: 2.5
DESERT_LAKES:
height: 8
scale: 10
DESERT:
height: 8
scale: 15
ERODED_BADLANDS:
height: 8
scale: 17
FLOWER_FOREST:
height: 8
scale: 10
FOREST:
height: 8
scale: 10
FROZEN_OCEAN:
height: 5
scale: 3.33
FROZEN_RIVER:
height: 5
scale: 10
GIANT_SPRUCE_TAIGA_HILLS:
height: 9
scale: 2.5
GIANT_SPRUCE_TAIGA:
height: 8
scale: 10
GIANT_TREE_TAIGA_HILLS:
height: 9
scale: 2.5
GIANT_TREE_TAIGA:
height: 8
scale: 10
GRAVELLY_MOUNTAINS:
height: 10
scale: 2.5
ICE_SPIKES:
height: 8
scale: 20
JUNGLE_EDGE:
height: 8
scale: 10
JUNGLE_HILLS:
height: 9
scale: 2.5
JUNGLE:
height: 8
scale: 10
LUKEWARM_OCEAN:
height: 5
scale: 3.33
MODIFIED_BADLANDS_PLATEAU:
height: 9
scale: 16
MODIFIED_GRAVELLY_MOUNTAINS:
height: 10
scale: 2.5
MODIFIED_JUNGLE_EDGE:
height: 8
scale: 10
MODIFIED_JUNGLE:
height: 8
scale: 10
MODIFIED_WOODED_BADLANDS_PLATEAU:
height: 9
scale: 16
MOUNTAIN_EDGE:
height: 10
scale: 2.5
MOUNTAINS:
height: 10
scale: 2.5
MUSHROOM_FIELD_SHORE:
height: 5
scale: 10
MUSHROOM_FIELDS:
height: 8
scale: 10
OCEAN:
height: 5
scale: 3.33
PLAINS:
height: 8
scale: 10
RIVER:
height: 5
scale: 10
SAVANNA_PLATEAU:
height: 9
scale: 16
SAVANNA:
height: 8
scale: 10
SHATTERED_SAVANNA_PLATEAU:
height: 9
scale: 16
SHATTERED_SAVANNA:
height: 8
scale: 10
SNOWY_BEACH:
height: 7
scale: 16
SNOWY_MOUNTAINS:
height: 10
scale: 2.5
SNOWY_TAIGA_HILLS:
height: 9
scale: 2.5
SNOWY_TAIGA_MOUNTAINS:
height: 10
scale: 2.5
SNOWY_TAIGA:
height: 8
scale: 10
SNOWY_TUNDRA:
height: 8
scale: 10
STONE_SHORE:
height: 8
scale: 10
SUNFLOWER_PLAINS:
height: 8
scale: 10
SWAMP_HILLS:
height: 9
scale: 2.5
SWAMP:
height: 8
scale: 10
TAIGA_HILLS:
height: 9
scale: 2.5
TAIGA_MOUNTAINS:
height: 10
scale: 2.5
TAIGA:
height: 8
scale: 10
TALL_BIRCH_FOREST:
height: 8
scale: 10
TALL_BIRCH_HILLS:
height: 9
scale: 2.5
WARM_OCEAN:
height: 5
scale: 3.33
WOODED_BADLANDS_PLATEAU:
height: 9
scale: 16
WOODED_HILLS:
height: 9
scale: 2.5
WOODED_MOUNTAINS:
height: 10
scale: 2.5

View File

@ -105,10 +105,10 @@ world:
DOOR: true DOOR: true
NATURAL_SPAWNING_OUTSIDE_RANGE: true NATURAL_SPAWNING_OUTSIDE_RANGE: true
BREAK_HOPPERS: false BREAK_HOPPERS: false
FURNACE: false FURNACE: true
LIQUIDS_FLOWING_OUT: true LIQUIDS_FLOWING_OUT: true
ANVIL: false ANVIL: false
MINECART: false MINECART: true
FISH_SCOOPING: false FISH_SCOOPING: false
END_PORTAL: false END_PORTAL: false
BREEDING: false BREEDING: false
@ -131,7 +131,7 @@ world:
NAME_TAG: false NAME_TAG: false
ENDERMAN_GRIEFING: true ENDERMAN_GRIEFING: true
CLEAN_SUPER_FLAT: false CLEAN_SUPER_FLAT: false
TRADING: false TRADING: true
EGGS: false EGGS: false
ITEM_DROP: true ITEM_DROP: true
NOTE_BLOCK: true NOTE_BLOCK: true
@ -160,11 +160,11 @@ world:
DYE: false DYE: false
ITEM_FRAME: false ITEM_FRAME: false
PLACE_BLOCKS: false PLACE_BLOCKS: false
CRAFTING: false CRAFTING: true
REMOVE_MOBS: true REMOVE_MOBS: true
ENCHANTING: true ENCHANTING: true
SHEARING: false SHEARING: false
BOAT: false BOAT: true
BANK_ACCESS: false BANK_ACCESS: false
BED: false BED: false
SPAWN_EGGS: false SPAWN_EGGS: false
@ -181,10 +181,10 @@ world:
MOUNT_INVENTORY: false MOUNT_INVENTORY: false
OFFLINE_REDSTONE: true OFFLINE_REDSTONE: true
CHORUS_FRUIT: false CHORUS_FRUIT: false
CONTAINER: false CONTAINER: true
ITEM_FRAME_DAMAGE: false ITEM_FRAME_DAMAGE: false
JUKEBOX: false JUKEBOX: false
POTION_THROWING: false POTION_THROWING: true
SPAWNER_SPAWN_EGGS: false SPAWNER_SPAWN_EGGS: false
# These are the default protection settings for new areas. # These are the default protection settings for new areas.
# The value is the minimum area rank required allowed to do the action # The value is the minimum area rank required allowed to do the action