Implement BiomeZone

This commit is contained in:
dfsek
2020-09-10 02:33:58 -07:00
parent 98b1dc0e85
commit 7d7705464b
10 changed files with 134 additions and 69 deletions

View File

@@ -83,7 +83,7 @@
<dependency>
<groupId>org.polydev</groupId>
<artifactId>gaea</artifactId>
<version>1.1.3</version>
<version>1.3.0</version>
</dependency>
</dependencies>

View File

@@ -98,7 +98,6 @@ public class Terra extends JavaPlugin {
@Override
public @Nullable ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, @Nullable String id) {
new WorldConfig(worldName, this);
return new TerraChunkGenerator();
}
}

View File

@@ -20,6 +20,7 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
super(InterpolationType.TRILINEAR);
}
@Override
public ChunkData generateBase(@NotNull World world, @NotNull Random random, int chunkX, int chunkZ, FastNoise fastNoise) {
ChunkData chunk = createChunkData(world);
for(byte x = 0; x < 16; x++) {
@@ -29,34 +30,24 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
}
}
}
for(byte x = 0; x < 16; x++) {
for(byte z = 0; z < 16; z++) {
int paletteLevel = 0;
for(int y = world.getMaxHeight()-1; y > 0; y--) {
if(chunk.getType(x, y, z).isAir()){
paletteLevel = 0;
continue;
}
chunk.setBlock(x, y, z, TerraBiomeGrid.fromWorld(world).getBiome((chunkX << 4) + x, (chunkZ << 4) + z).getGenerator().getPalette().get(paletteLevel, random));
paletteLevel++;
}
}
}
return chunk;
}
@Override
public int getNoiseOctaves(World world) {
return 4;
}
@Override
public float getNoiseFrequency(World world) {
return 1f/96;
}
@Override
public List<GenerationPopulator> getGenerationPopulators(World world) {
return Collections.emptyList();
}
@Override
public org.polydev.gaea.biome.BiomeGrid getBiomeGrid(World world) {
return TerraBiomeGrid.fromWorld(world);
}

View File

@@ -0,0 +1,51 @@
package com.dfsek.terra.biome;
import com.dfsek.terra.config.WorldConfig;
import org.bukkit.World;
import org.polydev.gaea.biome.BiomeGrid;
import org.polydev.gaea.math.FastNoise;
import java.util.HashMap;
import java.util.Map;
public class BiomeZone {
private BiomeGrid[] grids;
private final World w;
private final FastNoise noise;
private static final Map<World, BiomeZone> zones = new HashMap<>();
public BiomeZone(World w, float freq) {
this.w = w;
this.noise = new FastNoise((int) w.getSeed()+2);
noise.setNoiseType(FastNoise.NoiseType.Value);
noise.setFrequency(freq);
setZones(WorldConfig.fromWorld(w).definedGrids);
zones.put(w, this);
}
public void setZones(BiomeGrid[] grids) {
if(grids.length != 16) throw new IllegalArgumentException("Illegal number of grids!");
this.grids = grids;
}
public BiomeGrid getGrid(int x, int z) {
return grids[normalize(noise.getValue(x, z))];
}
public static BiomeZone fromWorld(World w) {
if(zones.containsKey(w)) return zones.get(w);
else return new BiomeZone(w, WorldConfig.fromWorld(w).zoneFreq);
}
/**
* Takes a noise input and normalizes it to a value between 0 and 15 inclusive.
*
* @param i - The noise value to normalize.
* @return int - The normalized value.
*/
private static int normalize(double i) {
if(i > 0) i = Math.pow(i, 0.8125); // Redistribute
else i = -Math.pow(-i, 0.8125); // Redistribute
return Math.min((int) Math.floor((i+1)*8), 15);
}
}

View File

@@ -2,7 +2,9 @@ package com.dfsek.terra.biome;
import com.dfsek.terra.config.ConfigUtil;
import com.dfsek.terra.config.WorldConfig;
import org.bukkit.Location;
import org.bukkit.World;
import org.polydev.gaea.biome.Biome;
import org.polydev.gaea.biome.BiomeGrid;
import java.util.HashMap;
@@ -11,29 +13,27 @@ import java.util.Map;
public class TerraBiomeGrid extends BiomeGrid {
private static final Map<World, TerraBiomeGrid> grids = new HashMap<>();
private final UserDefinedBiome[][] grid;
private final World w;
public TerraBiomeGrid(World w) {
super(w, 1f/256, 1f/512);
this.w = w;
grid = new UserDefinedBiome[16][16];
load();
grids.put(w, this);
}
public void load() {
super.setGrid(WorldConfig.fromWorld(w).biomeGrid.getBiomeGrid());
}
public static TerraBiomeGrid fromWorld(World w) {
if(grids.containsKey(w)) return grids.get(w);
else return new TerraBiomeGrid(w);
}
public static void reloadAll() {
for(Map.Entry<World, TerraBiomeGrid> e : grids.entrySet()) {
e.getValue().load();
}
@Override
public Biome getBiome(int x, int z) {
return BiomeZone.fromWorld(w).getGrid(x, z).getBiome(x, z);
}
@Override
public Biome getBiome(Location l) {
return getBiome(l.getBlockX(), l.getBlockZ());
}
}

View File

@@ -71,7 +71,7 @@ public class UserDefinedGenerator extends BiomeTerrain {
* @return BlocPalette - The biome's palette.
*/
@Override
public BlockPalette getPalette() {
public BlockPalette getPalette(int y) {
return p;
}
}

View File

@@ -0,0 +1,12 @@
package com.dfsek.terra.biome;
import com.dfsek.terra.config.BiomeGridConfig;
import org.bukkit.World;
import org.polydev.gaea.biome.BiomeGrid;
public class UserDefinedGrid extends BiomeGrid {
public UserDefinedGrid(World w, float freq1, float freq2, BiomeGridConfig config) {
super(w, freq1, freq2);
super.setGrid(config.getBiomeGrid());
}
}

View File

@@ -1,6 +1,8 @@
package com.dfsek.terra.config;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.UserDefinedGrid;
import org.bukkit.World;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
@@ -11,13 +13,16 @@ import java.io.IOException;
import java.util.List;
public class BiomeGridConfig extends YamlConfiguration {
private UserDefinedGrid grid;
private String gridID;
private String friendlyName;
private boolean isEnabled = false;
private final UserDefinedBiome[][] grid = new UserDefinedBiome[16][16];
private World world;
private final UserDefinedBiome[][] gridRaw = new UserDefinedBiome[16][16];
public BiomeGridConfig(File file) throws IOException, InvalidConfigurationException {
public BiomeGridConfig(File file, World w) throws IOException, InvalidConfigurationException {
super();
this.world = w;
load(file);
}
@Override
@@ -28,7 +33,7 @@ public class BiomeGridConfig extends YamlConfiguration {
try {
for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) {
grid[x][z] = ConfigUtil.getBiome(((List<List<String>>) getList("grid")).get(x).get(z)).getBiome();
gridRaw[x][z] = ConfigUtil.getBiome(((List<List<String>>) getList("grid")).get(x).get(z)).getBiome();
}
}
} catch(ClassCastException e) {
@@ -38,6 +43,7 @@ public class BiomeGridConfig extends YamlConfiguration {
this.gridID = getString("id");
if(!contains("name")) throw new InvalidConfigurationException("Grid Name unspecified!");
this.friendlyName = getString("name");
this.grid = new UserDefinedGrid(world, 1f/256, 1f/512, this);// TODO: custom frequency
isEnabled = true;
}
@@ -46,7 +52,7 @@ public class BiomeGridConfig extends YamlConfiguration {
}
public UserDefinedBiome[][] getBiomeGrid() {
return grid;
return gridRaw;
}
public boolean isEnabled() {
@@ -56,4 +62,8 @@ public class BiomeGridConfig extends YamlConfiguration {
public String getGridID() {
return gridID;
}
public UserDefinedGrid getGrid() {
return grid;
}
}

View File

@@ -20,7 +20,7 @@ import java.util.stream.Stream;
public class ConfigUtil {
private static final Map<String, BiomeConfig> biomes = new HashMap<>();
private static final Map<String, BiomeGridConfig> biomeGrids = new HashMap<>();
private static final Map<String, PaletteConfig> palettes = new HashMap<>();
public static void loadConfig(JavaPlugin main) {
@@ -64,39 +64,16 @@ public class ConfigUtil {
e.printStackTrace();
}
try (Stream<Path> paths = Files.walk(Paths.get(main.getDataFolder() + File.separator + "grids"))) {
paths
.filter(path -> FilenameUtils.wildcardMatch(path.toFile().getName(), "*.yml"))
.forEach(path -> {
logger.info("Loading BiomeGrid from " + path.toString());
try {
BiomeGridConfig grid = new BiomeGridConfig(path.toFile());
biomeGrids.put(grid.getGridID(), grid);
logger.info("Friendly name: " + grid.getFriendlyName());
logger.info("ID: " + grid.getGridID());
} catch(IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
});
} catch(IOException e) {
e.printStackTrace();
}
WorldConfig.reloadAll();
TerraBiomeGrid.reloadAll();
}
public static BiomeConfig getBiome(String id) {
return biomes.get(id);
}
public static BiomeGridConfig getGrid(String id) {
return biomeGrids.get(id);
}
public static PaletteConfig getPalette(String id) {
return palettes.get(id);
}

View File

@@ -1,17 +1,16 @@
package com.dfsek.terra.config;
import com.dfsek.terra.Terra;
import com.dfsek.terra.biome.UserDefinedBiome;
import org.bukkit.Bukkit;
import com.dfsek.terra.biome.BiomeZone;
import com.dfsek.terra.biome.TerraBiomeGrid;
import com.dfsek.terra.biome.UserDefinedGrid;
import org.bukkit.World;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import org.polydev.gaea.commons.io.FileUtils;
import org.polydev.gaea.commons.io.FilenameUtils;
import org.polydev.gaea.math.parsii.tokenizer.ParseException;
import java.io.File;
import java.io.IOException;
@@ -19,38 +18,40 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
public class WorldConfig {
private static JavaPlugin main;
private static final Map<String, WorldConfig> configs = new HashMap<>();
public BiomeGridConfig biomeGrid;
private static final Map<World, WorldConfig> configs = new HashMap<>();
private final Map<String, BiomeGridConfig> biomeGrids = new HashMap<>();
public float zoneFreq = 1f/1536;
public UserDefinedGrid[] definedGrids = new UserDefinedGrid[16];
public WorldConfig(String name, JavaPlugin main) {
public WorldConfig(World w, JavaPlugin main) {
WorldConfig.main = main;
load(name);
load(w);
}
public static void reloadAll() {
for(Map.Entry<String, WorldConfig> e : configs.entrySet()) {
for(Map.Entry<World, WorldConfig> e : configs.entrySet()) {
e.getValue().load(e.getKey());
}
}
public static WorldConfig fromWorld(World w) {
return configs.getOrDefault(w.getName(), null);
if(configs.containsKey(w)) return configs.get(w);
return new WorldConfig(w, Terra.getInstance());
}
public void load(String w) {
public void load(World w) {
long start = System.nanoTime();
main.getLogger().info("Loading world configuration values for " + w + "...");
FileConfiguration config = new YamlConfiguration();
try {
File configFile = new File(main.getDataFolder() + File.separator + "worlds", w + ".yml");
File configFile = new File(main.getDataFolder() + File.separator + "worlds", w.getName() + ".yml");
if(! configFile.exists()) {
configFile.getParentFile().mkdirs();
main.getLogger().info("Configuration for world \"" + w + "\" not found. Copying default config.");
@@ -62,13 +63,37 @@ public class WorldConfig {
main.getLogger().severe("Unable to load configuration for world " + w + ".");
}
biomeGrid = ConfigUtil.getGrid(config.getStringList("grids").get(0));
try (Stream<Path> paths = Files.walk(Paths.get(main.getDataFolder() + File.separator + "grids"))) {
paths
.filter(path -> FilenameUtils.wildcardMatch(path.toFile().getName(), "*.yml"))
.forEach(path -> {
main.getLogger().info("Loading BiomeGrid from " + path.toString());
try {
BiomeGridConfig grid = new BiomeGridConfig(path.toFile(), w);
biomeGrids.put(grid.getGridID(), grid);
main.getLogger().info("Friendly name: " + grid.getFriendlyName());
main.getLogger().info("ID: " + grid.getGridID());
} catch(IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
});
} catch(IOException e) {
e.printStackTrace();
}
for(int i = 0; i < 16; i++) {
definedGrids[i] = biomeGrids.get(config.getStringList("grids").get(i)).getGrid();
}
configs.put(w, this);
main.getLogger().info("World load complete. Time elapsed: " + ((double) (System.nanoTime() - start)) / 1000000 + "ms");
}
}