Fix various biome abstraction issues

This commit is contained in:
dfsek 2020-09-23 02:47:43 -07:00
parent c4b0057f3e
commit b5efa7cd79
10 changed files with 40 additions and 29 deletions

View File

@ -15,7 +15,6 @@ import java.util.Objects;
public class BiomeZone { public class BiomeZone {
private BiomeGrid[] grids; private BiomeGrid[] grids;
private final World w;
private final FastNoise noise; private final FastNoise noise;
private static final Map<World, BiomeZone> zones = new HashMap<>(); private static final Map<World, BiomeZone> zones = new HashMap<>();
@Nullable @Nullable
@ -24,7 +23,6 @@ public class BiomeZone {
private final ImageLoader.Channel channel; private final ImageLoader.Channel channel;
private BiomeZone(World w) { private BiomeZone(World w) {
this.w = w;
this.noise = new FastNoise((int) w.getSeed()+2); this.noise = new FastNoise((int) w.getSeed()+2);
this.noise.setNoiseType(FastNoise.NoiseType.SimplexFractal); this.noise.setNoiseType(FastNoise.NoiseType.SimplexFractal);
this.noise.setFractalOctaves(4); this.noise.setFractalOctaves(4);
@ -57,4 +55,8 @@ public class BiomeZone {
if(zones.containsKey(w)) return zones.get(w); if(zones.containsKey(w)) return zones.get(w);
else return new BiomeZone(w); else return new BiomeZone(w);
} }
public static void invalidate() {
zones.clear();
}
} }

View File

@ -16,7 +16,7 @@ public class TerraBiomeGrid extends BiomeGrid {
private final World w; private final World w;
public TerraBiomeGrid(World w) { public TerraBiomeGrid(World w) {
super(w, 1f/256, 1f/512); super(w, WorldConfig.fromWorld(w).freq1, WorldConfig.fromWorld(w).freq2);
this.w = w; this.w = w;
grids.put(w, this); grids.put(w, this);
} }
@ -37,6 +37,10 @@ public class TerraBiomeGrid extends BiomeGrid {
return getBiome(l.getBlockX(), l.getBlockZ()); return getBiome(l.getBlockX(), l.getBlockZ());
} }
public static void invalidate() {
grids.clear();
}
public UserDefinedGrid getGrid(int x, int z) { public UserDefinedGrid getGrid(int x, int z) {
return (UserDefinedGrid) BiomeZone.fromWorld(w).getGrid(x, z); return (UserDefinedGrid) BiomeZone.fromWorld(w).getGrid(x, z);
} }

View File

@ -11,13 +11,14 @@ public class UserDefinedBiome implements Biome {
private final UserDefinedGenerator gen; private final UserDefinedGenerator gen;
private final UserDefinedDecorator decorator; private final UserDefinedDecorator decorator;
private final org.bukkit.block.Biome vanilla; private final org.bukkit.block.Biome vanilla;
private final String id;
public UserDefinedBiome(org.bukkit.block.Biome vanilla, UserDefinedDecorator dec, UserDefinedGenerator gen) { public UserDefinedBiome(org.bukkit.block.Biome vanilla, UserDefinedDecorator dec, UserDefinedGenerator gen, String id) {
this.vanilla = vanilla; this.vanilla = vanilla;
this.decorator = dec; this.decorator = dec;
this.gen = gen; this.gen = gen;
this.id = id;
} }
/** /**
@ -59,4 +60,8 @@ public class UserDefinedBiome implements Biome {
public Decorator getDecorator() { public Decorator getDecorator() {
return decorator; return decorator;
} }
public String getID() {
return id;
}
} }

View File

@ -14,16 +14,6 @@ public class UserDefinedGrid extends BiomeGrid {
private final boolean fromImage; private final boolean fromImage;
private final ImageLoader.Channel channelX; private final ImageLoader.Channel channelX;
private final ImageLoader.Channel channelZ; private final ImageLoader.Channel channelZ;
public UserDefinedGrid(World w, float freq1, float freq2, BiomeGridConfig config) {
super(w, freq1, freq2, config.getBiomeGrid().length, config.getBiomeGrid()[0].length);
super.setNormalType(NormalType.LOOKUP4096);
super.setGrid(config.getBiomeGrid());
WorldConfig c = WorldConfig.fromWorld(w);
imageLoader = c.imageLoader;
fromImage = c.fromImage;
channelX = c.biomeXChannel;
channelZ = c.biomeZChannel;
}
public UserDefinedGrid(World w, float freq1, float freq2, UserDefinedBiome[][] b) { public UserDefinedGrid(World w, float freq1, float freq2, UserDefinedBiome[][] b) {
super(w, freq1, freq2, b.length, b[0].length); super(w, freq1, freq2, b.length, b[0].length);
super.setNormalType(NormalType.LOOKUP4096); super.setNormalType(NormalType.LOOKUP4096);

View File

@ -36,8 +36,7 @@ public class UserDefinedCarver extends Carver {
@Override @Override
public boolean isChunkCarved(World w, int chunkX, int chunkZ, Random random) { public boolean isChunkCarved(World w, int chunkX, int chunkZ, Random random) {
UserDefinedBiome b = (UserDefinedBiome) TerraBiomeGrid.fromWorld(w).getBiome(chunkX << 4, chunkZ << 4); return random.nextInt(100) < BiomeConfig.fromBiome((UserDefinedBiome) TerraBiomeGrid.fromWorld(w).getBiome(chunkX << 4, chunkZ << 4)).getCarverChance(this);
return random.nextInt(100) < BiomeConfig.fromBiome(b).getCarverChance(this);
} }
private class UserDefinedWorm extends Worm { private class UserDefinedWorm extends Worm {

View File

@ -1,5 +1,6 @@
package com.dfsek.terra.config; package com.dfsek.terra.config;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.polydev.gaea.commons.io.FilenameUtils; import org.polydev.gaea.commons.io.FilenameUtils;
@ -9,7 +10,9 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -22,6 +25,7 @@ public class ConfigLoader {
public <T extends TerraConfigObject> void load(JavaPlugin main, Class<T> clazz) { public <T extends TerraConfigObject> void load(JavaPlugin main, Class<T> clazz) {
File folder = new File(main.getDataFolder() + File.separator + "config" + File.separator + path); File folder = new File(main.getDataFolder() + File.separator + "config" + File.separator + path);
folder.mkdirs(); folder.mkdirs();
List<String> ids = new ArrayList<>();
try (Stream<Path> paths = Files.walk(folder.toPath())) { try (Stream<Path> paths = Files.walk(folder.toPath())) {
paths paths
.filter(path -> FilenameUtils.wildcardMatch(path.toFile().getName(), "*.yml")) .filter(path -> FilenameUtils.wildcardMatch(path.toFile().getName(), "*.yml"))
@ -29,6 +33,8 @@ public class ConfigLoader {
try { try {
Constructor<T> c = clazz.getConstructor(File.class); Constructor<T> c = clazz.getConstructor(File.class);
T o = c.newInstance(path.toFile()); T o = c.newInstance(path.toFile());
if(ids.contains(o.getID())) Bukkit.getLogger().severe("Duplicate ID found in file: " + path.toString());
ids.add(o.getID());
main.getLogger().info("Loaded " + o.toString() + " from file " + path.toString()); main.getLogger().info("Loaded " + o.toString() + " from file " + path.toString());
} catch(IllegalAccessException | InstantiationException | NoSuchMethodException e) { } catch(IllegalAccessException | InstantiationException | NoSuchMethodException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -1,5 +1,7 @@
package com.dfsek.terra.config; package com.dfsek.terra.config;
import com.dfsek.terra.biome.BiomeZone;
import com.dfsek.terra.biome.TerraBiomeGrid;
import com.dfsek.terra.config.genconfig.AbstractBiomeConfig; import com.dfsek.terra.config.genconfig.AbstractBiomeConfig;
import com.dfsek.terra.config.genconfig.BiomeConfig; import com.dfsek.terra.config.genconfig.BiomeConfig;
import com.dfsek.terra.config.genconfig.BiomeGridConfig; import com.dfsek.terra.config.genconfig.BiomeGridConfig;
@ -29,6 +31,8 @@ public class ConfigUtil {
new ConfigLoader("abstract" + File.separator + "biomes").load(main, AbstractBiomeConfig.class); new ConfigLoader("abstract" + File.separator + "biomes").load(main, AbstractBiomeConfig.class);
TerraBiomeGrid.invalidate();
BiomeZone.invalidate(); // Invalidate BiomeZone and BiomeGrid caches to prevent old instances from being accessed.
new ConfigLoader("biomes").load(main, BiomeConfig.class); new ConfigLoader("biomes").load(main, BiomeConfig.class);
new ConfigLoader("grids").load(main, BiomeGridConfig.class); new ConfigLoader("grids").load(main, BiomeGridConfig.class);

View File

@ -30,7 +30,7 @@ public class WorldConfig {
public float freq2; public float freq2;
public int seaLevel; public int seaLevel;
public boolean fromImage; public boolean fromImage;
public UserDefinedGrid[] definedGrids = new UserDefinedGrid[32]; public UserDefinedGrid[] definedGrids;
public ImageLoader.Channel biomeXChannel; public ImageLoader.Channel biomeXChannel;
public ImageLoader.Channel biomeZChannel; public ImageLoader.Channel biomeZChannel;
public ImageLoader.Channel zoneChannel; public ImageLoader.Channel zoneChannel;
@ -102,6 +102,7 @@ public class WorldConfig {
// Load BiomeGrids from BiomeZone // Load BiomeGrids from BiomeZone
List<String> biomeList = config.getStringList("grids"); List<String> biomeList = config.getStringList("grids");
definedGrids = new UserDefinedGrid[biomeList.size()];
for(int i = 0; i < biomeList.size(); i++) { for(int i = 0; i < biomeList.size(); i++) {
String partName = biomeList.get(i); String partName = biomeList.get(i);
if(partName.startsWith("BIOME:")) { if(partName.startsWith("BIOME:")) {

View File

@ -188,14 +188,6 @@ public class BiomeConfig extends TerraConfigObject {
throw new InvalidConfigurationException("Invalid Vanilla biome: " + getString("vanilla")); throw new InvalidConfigurationException("Invalid Vanilla biome: " + getString("vanilla"));
} }
try {
// Get UserDefinedBiome instance representing this config.
this.biome = new UserDefinedBiome(vanillaBiome, dec, new UserDefinedGenerator(eq, Collections.emptyList(), paletteMap));
} catch(ParseException e) {
e.printStackTrace();
throw new IllegalArgumentException("Unable to parse noise equation!");
}
// Check if ores should be handled by super biome. // Check if ores should be handled by super biome.
if(extending && abstractBiome.getOres() != null && !contains("ores")) { if(extending && abstractBiome.getOres() != null && !contains("ores")) {
ores = abstractBiome.getOres(); ores = abstractBiome.getOres();
@ -212,8 +204,13 @@ public class BiomeConfig extends TerraConfigObject {
oreHeights = new HashMap<>(); oreHeights = new HashMap<>();
} }
try {
// Get UserDefinedBiome instance representing this config.
this.biome = new UserDefinedBiome(vanillaBiome, dec, new UserDefinedGenerator(eq, Collections.emptyList(), paletteMap), biomeID);
} catch(ParseException e) {
e.printStackTrace();
throw new IllegalArgumentException("Unable to parse noise equation!");
}
biomes.put(biomeID, this); biomes.put(biomeID, this);
} }
@ -245,6 +242,9 @@ public class BiomeConfig extends TerraConfigObject {
for(BiomeConfig biome : biomes.values()) { for(BiomeConfig biome : biomes.values()) {
if(biome.getBiome().equals(b)) return biome; if(biome.getBiome().equals(b)) return biome;
} }
for(BiomeConfig biome : biomes.values()) {
Bukkit.getLogger().info(biome.getID() + ":" + biome.hashCode() + " : " + b.getID() + ":" + b.hashCode());
}
throw new IllegalArgumentException("No BiomeConfig for provided biome."); throw new IllegalArgumentException("No BiomeConfig for provided biome.");
} }

View File

@ -83,7 +83,7 @@ public class BiomeGridConfig extends TerraConfigObject {
public UserDefinedGrid getGrid(World w) { public UserDefinedGrid getGrid(World w) {
WorldConfig c = WorldConfig.fromWorld(w); WorldConfig c = WorldConfig.fromWorld(w);
return new UserDefinedGrid(w, c.freq1, c.freq2, this); return new UserDefinedGrid(w, c.freq1, c.freq2, gridRaw);
} }
@Override @Override