From 114a9302bcab238555d4ef6097294703b90b1b46 Mon Sep 17 00:00:00 2001 From: dfsek Date: Tue, 29 Sep 2020 02:11:55 -0700 Subject: [PATCH] Implement structure biome config --- src/main/java/com/dfsek/terra/Terra.java | 3 +- .../com/dfsek/terra/config/ConfigUtil.java | 4 +- .../config/genconfig/AbstractBiomeConfig.java | 7 ++++ .../terra/config/genconfig/BiomeConfig.java | 18 ++++++++ .../config/genconfig/StructureConfig.java | 20 +++++++-- .../terra/generation/TerraChunkGenerator.java | 7 +--- .../generation/UserDefinedGenerator.java | 5 --- .../dfsek/terra/math/BaseHeightFunction.java | 29 ------------- .../terra/population/StructurePopulator.java | 41 +++++++++++-------- 9 files changed, 70 insertions(+), 64 deletions(-) delete mode 100644 src/main/java/com/dfsek/terra/math/BaseHeightFunction.java diff --git a/src/main/java/com/dfsek/terra/Terra.java b/src/main/java/com/dfsek/terra/Terra.java index 9765ea7a6..17cf02586 100644 --- a/src/main/java/com/dfsek/terra/Terra.java +++ b/src/main/java/com/dfsek/terra/Terra.java @@ -32,6 +32,7 @@ public class Terra extends JavaPlugin { @Override public void onEnable() { + instance = this; ConfigUtil.loadConfig(this); PluginCommand command = getCommand("terra"); @@ -47,7 +48,7 @@ public class Terra extends JavaPlugin { saveDefaultConfig(); config = getConfig(); Bukkit.getScheduler().scheduleAsyncRepeatingTask(this, TerraChunkGenerator::saveAll, ConfigUtil.dataSave, ConfigUtil.dataSave); - instance = this; + } public static void register(JavaPlugin plugin, Command pluginCommand, Commodore commodore) throws Exception { diff --git a/src/main/java/com/dfsek/terra/config/ConfigUtil.java b/src/main/java/com/dfsek/terra/config/ConfigUtil.java index 39bf7fe96..bc8069bd8 100644 --- a/src/main/java/com/dfsek/terra/config/ConfigUtil.java +++ b/src/main/java/com/dfsek/terra/config/ConfigUtil.java @@ -41,9 +41,9 @@ public class ConfigUtil { new ConfigLoader("flora").load(main, FloraConfig.class); - new ConfigLoader("abstract" + File.separator + "biomes").load(main, AbstractBiomeConfig.class); + new ConfigLoader("structures" + File.separator + "single").load(main, StructureConfig.class); - new ConfigLoader("structure" + File.separator + "single").load(main, StructureConfig.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. diff --git a/src/main/java/com/dfsek/terra/config/genconfig/AbstractBiomeConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/AbstractBiomeConfig.java index 70d9a025e..66e4fe6eb 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/AbstractBiomeConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/AbstractBiomeConfig.java @@ -48,6 +48,7 @@ public class AbstractBiomeConfig extends TerraConfigObject { private Map oreData; private Map treeData; private List> carvingData; + private List structureConfigs; public AbstractBiomeConfig(File file) throws IOException, InvalidConfigurationException { super(file); @@ -90,6 +91,8 @@ public class AbstractBiomeConfig extends TerraConfigObject { } } + if(contains("structures")) structureConfigs = getStringList("structures"); + biomes.put(biomeID, this); } @@ -177,4 +180,8 @@ public class AbstractBiomeConfig extends TerraConfigObject { public String getOceanPalette() { return oceanPalette; } + + public List getStructureConfigs() { + return structureConfigs; + } } diff --git a/src/main/java/com/dfsek/terra/config/genconfig/BiomeConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/BiomeConfig.java index 8d34f28d5..d197c8f9e 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/BiomeConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/BiomeConfig.java @@ -55,6 +55,7 @@ public class BiomeConfig extends TerraConfigObject { private FastNoise floraNoise; private Palette ocean; private int seaLevel; + private List structures; public BiomeConfig(File file) throws InvalidConfigurationException, IOException { super(file); @@ -335,6 +336,19 @@ public class BiomeConfig extends TerraConfigObject { Bukkit.getLogger().info("[Terra] Slabs: " + slabs.size()); } + // Structure stuff + structures = new ArrayList<>(); + List st = new ArrayList<>(); + if(abstractBiome != null && abstractBiome.getStructureConfigs() != null) st = abstractBiome.getStructureConfigs(); + if(contains("structures")) st = getStringList("structures"); + for(String s : st) { + try { + structures.add(Objects.requireNonNull(StructureConfig.fromID(s))); + } catch(NullPointerException e) { + throw new InvalidConfigurationException("No such structure " + s); + } + } + try { // Get UserDefinedBiome instance representing this config. this.biome = new UserDefinedBiome(vanillaBiome, dec, new UserDefinedGenerator(eq, Collections.emptyList(), paletteMap), biomeID); @@ -427,4 +441,8 @@ public class BiomeConfig extends TerraConfigObject { public int getSeaLevel() { return seaLevel; } + + public List getStructures() { + return structures; + } } diff --git a/src/main/java/com/dfsek/terra/config/genconfig/StructureConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/StructureConfig.java index 6c8786dc4..177c6da69 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/StructureConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/StructureConfig.java @@ -2,18 +2,23 @@ package com.dfsek.terra.config.genconfig; import com.dfsek.terra.Range; import com.dfsek.terra.Terra; +import com.dfsek.terra.config.ConfigUtil; import com.dfsek.terra.config.TerraConfigObject; import com.dfsek.terra.population.StructurePopulator; import com.dfsek.terra.structure.GaeaStructure; import com.dfsek.terra.structure.StructureSpawn; import com.dfsek.terra.structure.StructureSpawnRequirement; +import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import java.io.File; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; public class StructureConfig extends TerraConfigObject { + private static final Map configs = new HashMap<>(); private GaeaStructure structure; private StructureSpawn spawn; private String id; @@ -27,8 +32,12 @@ public class StructureConfig extends TerraConfigObject { @Override public void init() throws InvalidConfigurationException { try { - structure = GaeaStructure.load(new File(Terra.getInstance().getDataFolder() + File.separator + "config" + File.separator + "structures" + File.separator + "data", Objects.requireNonNull(getString("file")))); + File file = new File(Terra.getInstance().getDataFolder() + File.separator + "config" + File.separator + "structures" + File.separator + "data", Objects.requireNonNull(getString("file"))); + structure = GaeaStructure.load(file); } catch(IOException | NullPointerException e) { + if(ConfigUtil.debug) { + e.printStackTrace(); + } throw new InvalidConfigurationException("Unable to locate structure: " + getString("file")); } if(!contains("id")) throw new InvalidConfigurationException("No ID specified!"); @@ -37,10 +46,11 @@ public class StructureConfig extends TerraConfigObject { searchStart = new Range(getInt("spawn.start.min", 72), getInt("spawn.start.max", 72)); bound = new Range(getInt("spawn.bound.min", 48), getInt("spawn.bound.max", 72)); try { - type = StructurePopulator.SearchType.valueOf(getString("spawn,search", "DOWN")); + type = StructurePopulator.SearchType.valueOf(getString("spawn.search", "DOWN")); } catch(IllegalArgumentException e) { - throw new InvalidConfigurationException("Invalid search type, " + getString("spawn,search")); + throw new InvalidConfigurationException("Invalid search type, " + getString("spawn.search")); } + configs.put(id, this); } @Override @@ -63,4 +73,8 @@ public class StructureConfig extends TerraConfigObject { public Range getSearchStart() { return searchStart; } + + public static StructureConfig fromID(String id) { + return configs.get(id); + } } diff --git a/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java b/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java index d67270e35..c805b3d2c 100644 --- a/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java +++ b/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java @@ -120,12 +120,7 @@ public class TerraChunkGenerator extends GaeaChunkGenerator { @Override public @NotNull List getDefaultPopulators(@NotNull World world) { - try { - return Arrays.asList(new CavePopulator(), new StructurePopulator(), popMan); - } catch(IOException e) { - e.printStackTrace(); - throw new IllegalArgumentException(); - } + return Arrays.asList(new CavePopulator(), new StructurePopulator(), popMan); } @Override diff --git a/src/main/java/com/dfsek/terra/generation/UserDefinedGenerator.java b/src/main/java/com/dfsek/terra/generation/UserDefinedGenerator.java index a0c363497..648474c86 100644 --- a/src/main/java/com/dfsek/terra/generation/UserDefinedGenerator.java +++ b/src/main/java/com/dfsek/terra/generation/UserDefinedGenerator.java @@ -1,14 +1,10 @@ package com.dfsek.terra.generation; -import com.dfsek.terra.biome.TerraBiomeGrid; -import com.dfsek.terra.biome.UserDefinedBiome; -import com.dfsek.terra.biome.UserDefinedGrid; import com.dfsek.terra.math.NoiseFunction2; import com.dfsek.terra.math.NoiseFunction3; import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.polydev.gaea.biome.Generator; -import org.polydev.gaea.generation.GenerationPhase; import org.polydev.gaea.math.FastNoise; import org.polydev.gaea.math.parsii.eval.Expression; import org.polydev.gaea.math.parsii.eval.Parser; @@ -94,5 +90,4 @@ public class UserDefinedGenerator extends Generator { } return null; } - } diff --git a/src/main/java/com/dfsek/terra/math/BaseHeightFunction.java b/src/main/java/com/dfsek/terra/math/BaseHeightFunction.java deleted file mode 100644 index a709ef982..000000000 --- a/src/main/java/com/dfsek/terra/math/BaseHeightFunction.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.dfsek.terra.math; - -import org.polydev.gaea.math.FastNoise; -import org.polydev.gaea.math.parsii.eval.Expression; -import org.polydev.gaea.math.parsii.eval.Function; - -import java.util.List; - -public class BaseHeightFunction implements Function { - private FastNoise gen; - @Override - public int getNumberOfArguments() { - return 3; - } - - @Override - public double eval(List list) { - return gen.getSimplexFractal((float) list.get(0).evaluate(), (float) list.get(1).evaluate(), (float) list.get(2).evaluate()); - } - - public void setNoise(FastNoise gen) { - this.gen = gen; - } - - @Override - public boolean isNaturalFunction() { - return true; - } -} diff --git a/src/main/java/com/dfsek/terra/population/StructurePopulator.java b/src/main/java/com/dfsek/terra/population/StructurePopulator.java index 8b55d168e..d9cbc786b 100644 --- a/src/main/java/com/dfsek/terra/population/StructurePopulator.java +++ b/src/main/java/com/dfsek/terra/population/StructurePopulator.java @@ -2,6 +2,10 @@ package com.dfsek.terra.population; import com.dfsek.terra.Terra; import com.dfsek.terra.TerraProfiler; +import com.dfsek.terra.biome.TerraBiomeGrid; +import com.dfsek.terra.biome.UserDefinedBiome; +import com.dfsek.terra.config.genconfig.BiomeConfig; +import com.dfsek.terra.config.genconfig.StructureConfig; import com.dfsek.terra.structure.GaeaStructure; import com.dfsek.terra.structure.StructureSpawn; import com.dfsek.terra.structure.StructureSpawnRequirement; @@ -11,6 +15,7 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.generator.BlockPopulator; import org.jetbrains.annotations.NotNull; +import org.polydev.gaea.generation.GenerationPhase; import org.polydev.gaea.population.GaeaBlockPopulator; import org.polydev.gaea.profiler.ProfileFuture; @@ -23,33 +28,33 @@ import java.util.Random; import java.util.Set; public class StructurePopulator extends BlockPopulator { - StructureSpawn spawnTest = new StructureSpawn(75, 25); - GaeaStructure struc = GaeaStructure.load(new File(Terra.getInstance().getDataFolder() + File.separator + "export" + File.separator + "structures", "desert.tstructure")); - double horizontal = struc.getStructureInfo().getMaxHorizontal(); - - public StructurePopulator() throws IOException { - } @Override public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) { try(ProfileFuture ignored = TerraProfiler.fromWorld(world).measure("StructureTime")) { int cx = (chunk.getX() << 4); int cz = (chunk.getZ() << 4); - Location spawn = spawnTest.getNearestSpawn(cx+ 8, cz + 8, world.getSeed()).toLocation(world); - main: for(int y = 72; y > 0; y--) { - spawn.setY(y); - for(StructureSpawnRequirement s : struc.getSpawns()) { - if(!s.isValidSpawn(spawn)) continue main; - } - Bukkit.getLogger().info("Valid spawn at " + spawn); - if(Math.abs((cx+8)-spawn.getBlockX()) <= horizontal && Math.abs((cz+8)-spawn.getBlockZ()) <= horizontal) { - try(ProfileFuture ignore = TerraProfiler.fromWorld(world).measure("StructurePasteTime")) { - struc.paste(spawn, chunk, GaeaStructure.Rotation.fromDegrees(new Random(spawn.hashCode()).nextInt(4)*90), Collections.emptyList()); - break; + UserDefinedBiome b = (UserDefinedBiome) TerraBiomeGrid.fromWorld(world).getBiome(cx+ 8, cz + 8, GenerationPhase.POPULATE); + structure: for(StructureConfig conf : BiomeConfig.fromBiome(b).getStructures()) { + GaeaStructure struc = conf.getStructure(); + Location spawn = conf.getSpawn().getNearestSpawn(cx + 8, cz + 8, world.getSeed()).toLocation(world); + Random r2 = new Random(spawn.hashCode()); + main: for(int y = conf.getSearchStart().get(r2); y > 0; y--) { + if(y > conf.getBound().getMax() || y < conf.getBound().getMin()) continue structure; + spawn.setY(y); + for(StructureSpawnRequirement s : struc.getSpawns()) { + if(! s.isValidSpawn(spawn)) continue main; + } + double horizontal = struc.getStructureInfo().getMaxHorizontal(); + Bukkit.getLogger().info("Valid spawn at " + spawn); + if(Math.abs((cx + 8) - spawn.getBlockX()) <= horizontal && Math.abs((cz + 8) - spawn.getBlockZ()) <= horizontal) { + try(ProfileFuture ignore = TerraProfiler.fromWorld(world).measure("StructurePasteTime")) { + struc.paste(spawn, chunk, GaeaStructure.Rotation.fromDegrees(r2.nextInt(4) * 90), Collections.emptyList()); + break; + } } } } - } } public enum SearchType {