mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-18 10:32:30 +00:00
Implement structure biome config
This commit is contained in:
parent
eb208ed9fe
commit
114a9302bc
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -48,6 +48,7 @@ public class AbstractBiomeConfig extends TerraConfigObject {
|
||||
private Map<String, Object> oreData;
|
||||
private Map<String, Object> treeData;
|
||||
private List<Map<?, ?>> carvingData;
|
||||
private List<String> 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<String> getStructureConfigs() {
|
||||
return structureConfigs;
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ public class BiomeConfig extends TerraConfigObject {
|
||||
private FastNoise floraNoise;
|
||||
private Palette<BlockData> ocean;
|
||||
private int seaLevel;
|
||||
private List<StructureConfig> 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<String> 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<StructureConfig> getStructures() {
|
||||
return structures;
|
||||
}
|
||||
}
|
||||
|
@ -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<String, StructureConfig> 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);
|
||||
}
|
||||
}
|
||||
|
@ -120,12 +120,7 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
|
||||
|
||||
@Override
|
||||
public @NotNull List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
|
||||
try {
|
||||
return Arrays.asList(new CavePopulator(), new StructurePopulator(), popMan);
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<Expression> 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;
|
||||
}
|
||||
}
|
@ -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--) {
|
||||
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(new Random(spawn.hashCode()).nextInt(4)*90), Collections.emptyList());
|
||||
struc.paste(spawn, chunk, GaeaStructure.Rotation.fromDegrees(r2.nextInt(4) * 90), Collections.emptyList());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
public enum SearchType {
|
||||
|
Loading…
x
Reference in New Issue
Block a user