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
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)
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();
// Load settings from config.yml. This will check if there are any issues with it too.
loadSettings();
// Save biomes
this.saveResource("biomes.yml", false);
// Chunk generator
WorldRef wordRef = WorldRef.ofName(getSettings().getWorldName());
chunkGenerator = WorldGeneratorApi
@ -51,7 +53,7 @@ public class Boxed extends GameModeAddon {
.createCustomGenerator(wordRef, generator -> {
// Set the noise generator
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.setBiomeGenerator(new BoxedBiomeGenerator(this));
});
@ -153,7 +155,9 @@ public class Boxed extends GameModeAddon {
worldName2 = env.equals(World.Environment.THE_END) ? worldName2 + THE_END : worldName2;
World w = WorldCreator.name(worldName2).type(WorldType.FLAT).environment(env).generator(chunkGenerator2).createWorld();
// 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
if (w != null) {
if (getSettings().getSpawnLimitMonsters() > 0) {

View File

@ -1,6 +1,9 @@
package world.bentobox.boxed.generators;
import java.io.File;
import org.bukkit.block.Biome;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.util.noise.SimplexNoiseGenerator;
import nl.rutgerkok.worldgeneratorapi.BaseNoiseGenerator;
@ -16,39 +19,34 @@ public class BasicWorldGenerator implements BaseNoiseGenerator {
private final SimplexNoiseGenerator mainNoiseGenerator;
private final Boxed addon;
private final YamlConfiguration config;
public BasicWorldGenerator(Boxed addon, WorldRef world, long seed) {
this.addon = addon;
// Initialize the noise generator based on the world 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
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
int dist = addon.getSettings().getIslandDistance();
double height = 8;
scaledX = ((scaledX*4) % dist) / 4;
scaledZ = ((scaledZ*4) % dist) / 4;
Biome biome = biomeGenerator.getZoomedOutBiome(scaledX, scaledZ);
double noiseScaleHorizontal = addon.getSettings().getNoiseScaleHorizontal();
if (biome.equals(Biome.SNOWY_TAIGA)) {
noiseScaleHorizontal = noiseScaleHorizontal / 2;
} else if (biome.equals(Biome.MOUNTAINS)) {
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;
}
double noiseScaleHorizontal = config.getDouble("biomes." + biome.name() + ".scale", 10D);
double height = config.getDouble("biomes." + biome.name() + ".height", 8D);
double x = (((scaledX*4) % dist) / 4) / noiseScaleHorizontal;
double z = (((scaledZ*4) % dist) / 4) / noiseScaleHorizontal;
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;
buffer[y] = noise + heightOffset;
}

View File

@ -1,6 +1,14 @@
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.BlockFace;
import org.bukkit.util.Vector;
import nl.rutgerkok.worldgeneratorapi.BiomeGenerator;
@ -12,11 +20,78 @@ import world.bentobox.boxed.Boxed;
*/
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 int dist;
private final int offsetX;
private final int offsetZ;
public BoxedBiomeGenerator(Boxed boxed) {
this.addon = boxed;
dist = addon.getSettings().getIslandDistance();
@ -34,28 +109,31 @@ public class BoxedBiomeGenerator implements BiomeGenerator {
* 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);
double d = l.distance(s) / addon.getSettings().getIslandDistance();
if (d < 0.2) {
return Biome.PLAINS;
} else if (d < 0.3) {
return Biome.FOREST;
} else if (d < 0.33) {
return Biome.SNOWY_TAIGA;
} else if (d < 0.4) {
return Biome.DARK_FOREST;
} else if (d < 0.45) {
return Biome.MOUNTAINS;
} else if (d < 0.52) {
return Biome.DESERT;
double dis = l.distanceSquared(s);
double d = dis / (dist * dist);
Vector direction = s.subtract(l);
if (direction.getBlockX() <= 0 && direction.getBlockZ() <= 0) {
return getBiome(BlockFace.NORTH_WEST, d);
} else if (direction.getBlockX() > 0 && direction.getBlockZ() <= 0) {
return getBiome(BlockFace.NORTH_EAST, d);
} else if (direction.getBlockX() <= 0 && direction.getBlockZ() > 0) {
return getBiome(BlockFace.SOUTH_WEST, d);
}
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) {
long x = Math.round((double) v.getBlockX() / dist) * dist + offsetX;
long z = Math.round((double) v.getBlockZ() / dist) * dist + offsetZ;
return new Vector(x, v.getBlockY(), z);
int d = dist * 2;
long x = Math.round((double) v.getBlockX() / d) * d + offsetX;
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) {
backMap = new HashMap<>();
backMap.put(addon.getOverWorld(), Bukkit.getWorld(addon.getOverWorld().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.getNetherWorld(), Bukkit.getWorld(addon.getNetherWorld().getName() + "_bak"));
//backMap.put(addon.getEndWorld(), Bukkit.getWorld(addon.getEndWorld().getName() + "_bak"));
}
@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
NATURAL_SPAWNING_OUTSIDE_RANGE: true
BREAK_HOPPERS: false
FURNACE: false
FURNACE: true
LIQUIDS_FLOWING_OUT: true
ANVIL: false
MINECART: false
MINECART: true
FISH_SCOOPING: false
END_PORTAL: false
BREEDING: false
@ -131,7 +131,7 @@ world:
NAME_TAG: false
ENDERMAN_GRIEFING: true
CLEAN_SUPER_FLAT: false
TRADING: false
TRADING: true
EGGS: false
ITEM_DROP: true
NOTE_BLOCK: true
@ -160,11 +160,11 @@ world:
DYE: false
ITEM_FRAME: false
PLACE_BLOCKS: false
CRAFTING: false
CRAFTING: true
REMOVE_MOBS: true
ENCHANTING: true
SHEARING: false
BOAT: false
BOAT: true
BANK_ACCESS: false
BED: false
SPAWN_EGGS: false
@ -181,10 +181,10 @@ world:
MOUNT_INVENTORY: false
OFFLINE_REDSTONE: true
CHORUS_FRUIT: false
CONTAINER: false
CONTAINER: true
ITEM_FRAME_DAMAGE: false
JUKEBOX: false
POTION_THROWING: false
POTION_THROWING: true
SPAWNER_SPAWN_EGGS: false
# These are the default protection settings for new areas.
# The value is the minimum area rank required allowed to do the action