mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 10:30:42 +00:00
Merge pull request #31 from PolyhedralDev/tectonic
Tectonic Implementation
This commit is contained in:
@@ -6,7 +6,7 @@ end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = false
|
||||
max_line_length = 120
|
||||
max_line_length = 140
|
||||
tab_width = 4
|
||||
ij_continuation_indent_size = 8
|
||||
ij_formatter_off_tag = @formatter:off
|
||||
|
||||
10
.idea/inspectionProfiles/Project_Default.xml
generated
10
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -6,6 +6,16 @@
|
||||
<language minSize="54" name="Java" />
|
||||
</Languages>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="FieldCanBeLocal" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="EXCLUDE_ANNOS">
|
||||
<value>
|
||||
<list size="1">
|
||||
<item index="0" class="java.lang.String" itemvalue="com.dfsek.tectonic.annotations.Value" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="IGNORE_FIELDS_USED_IN_MULTIPLE_METHODS" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="NonSerializableObjectPassedToObjectStream" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SerialVersionUIDNotStaticFinal" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SerializableHasSerialVersionUIDField" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
|
||||
5
.idea/jarRepositories.xml
generated
5
.idea/jarRepositories.xml
generated
@@ -81,5 +81,10 @@
|
||||
<option name="name" value="MavenLocal" />
|
||||
<option name="url" value="file:$MAVEN_REPOSITORY$/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven3" />
|
||||
<option name="name" value="maven3" />
|
||||
<option name="url" value="https://repo.codemc.org/repository/maven-releases" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
||||
5
.idea/misc.xml
generated
5
.idea/misc.xml
generated
@@ -4,8 +4,9 @@
|
||||
<entry_points version="2.0">
|
||||
<entry_point TYPE="field" FQNAME="com.dfsek.terra.util.StructureTypeEnum NETHER_FORTRESS" />
|
||||
</entry_points>
|
||||
<list size="1">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
|
||||
<list size="2">
|
||||
<item index="0" class="java.lang.String" itemvalue="com.dfsek.tectonic.annotations.Value" />
|
||||
<item index="1" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
|
||||
</list>
|
||||
</component>
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
|
||||
@@ -30,12 +30,12 @@ java {
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
val versionObj = Version("1", "5", "0", true)
|
||||
val versionObj = Version("2", "0", "0", true)
|
||||
|
||||
version = versionObj
|
||||
|
||||
dependencies {
|
||||
val gaeaVersion = "1.14.3"
|
||||
val gaeaVersion = "1.15.0"
|
||||
compileOnly(name = "Gaea-${gaeaVersion}", group = "")
|
||||
testImplementation(name = "Gaea-${gaeaVersion}", group = "")
|
||||
|
||||
@@ -49,13 +49,15 @@ dependencies {
|
||||
|
||||
compileOnly("com.googlecode.json-simple:json-simple:1.1")
|
||||
|
||||
implementation(name = "parsii-1.2.1", group = "")
|
||||
implementation("com.scireum:parsii:1.2.1")
|
||||
|
||||
compileOnly("org.spigotmc:spigot-api:1.16.2-R0.1-SNAPSHOT")
|
||||
implementation("io.papermc:paperlib:1.0.5")
|
||||
|
||||
implementation("net.jafama:jafama:2.3.2")
|
||||
|
||||
implementation(name = "Tectonic-1.0.2", group = "")
|
||||
|
||||
|
||||
// JUnit.
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0")
|
||||
@@ -107,6 +109,7 @@ tasks.named<ShadowJar>("shadowJar") {
|
||||
relocate("parsii", "com.dfsek.terra.lib.parsii")
|
||||
relocate("io.papermc.lib", "com.dfsek.terra.lib.paperlib")
|
||||
relocate("net.jafama", "com.dfsek.terra.lib.jafama")
|
||||
relocate("com.dfsek.tectonic", "com.dfsek.terra.lib.tectonic")
|
||||
minimize()
|
||||
}
|
||||
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
Binary file not shown.
BIN
lib/Gaea-1.15.0.jar
Normal file
BIN
lib/Gaea-1.15.0.jar
Normal file
Binary file not shown.
BIN
lib/Tectonic-1.0.2.jar
Normal file
BIN
lib/Tectonic-1.0.2.jar
Normal file
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
package com.dfsek.terra;
|
||||
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.base.PluginConfig;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Debug {
|
||||
@@ -11,18 +11,18 @@ public class Debug {
|
||||
}
|
||||
|
||||
public static void info(String message) {
|
||||
if(ConfigUtil.debug) main.getLogger().info(message);
|
||||
if(PluginConfig.isDebug()) main.getLogger().info(message);
|
||||
}
|
||||
|
||||
public static void warn(String message) {
|
||||
if(ConfigUtil.debug) main.getLogger().warning(message);
|
||||
if(PluginConfig.isDebug()) main.getLogger().warning(message);
|
||||
}
|
||||
|
||||
public static void error(String message) {
|
||||
if(ConfigUtil.debug) main.getLogger().severe(message);
|
||||
if(PluginConfig.isDebug()) main.getLogger().severe(message);
|
||||
}
|
||||
|
||||
public static void stack(Exception e) {
|
||||
if(ConfigUtil.debug) e.printStackTrace();
|
||||
if(PluginConfig.isDebug()) e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ package com.dfsek.terra;
|
||||
|
||||
import com.dfsek.terra.async.AsyncStructureFinder;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.genconfig.TreeConfig;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.generation.items.TerraStructure;
|
||||
import com.dfsek.terra.generation.items.tree.TerraTree;
|
||||
import com.dfsek.terra.registry.TreeRegistry;
|
||||
import com.dfsek.terra.util.StructureTypeEnum;
|
||||
import org.bukkit.Material;
|
||||
@@ -39,7 +39,7 @@ public class EventListener implements Listener {
|
||||
Debug.info("Detected Ender Signal...");
|
||||
TerraWorld tw = TerraWorld.getWorld(e.getEntity().getWorld());
|
||||
EnderSignal signal = (EnderSignal) entity;
|
||||
StructureConfig config = tw.getConfig().getLocatable().get(StructureTypeEnum.STRONGHOLD);
|
||||
TerraStructure config = tw.getConfig().getStructureLocatable(StructureTypeEnum.STRONGHOLD);
|
||||
if(config != null) {
|
||||
Debug.info("Overriding Ender Signal...");
|
||||
AsyncStructureFinder finder = new AsyncStructureFinder(tw.getGrid(), config, e.getLocation(), 0, 500, location -> {
|
||||
@@ -72,7 +72,7 @@ public class EventListener implements Listener {
|
||||
if(!TerraWorld.isTerraWorld(e.getWorld())) return;
|
||||
TerraWorld tw = TerraWorld.getWorld(e.getWorld());
|
||||
ConfigPack c = tw.getConfig();
|
||||
if(c.preventSaplingOverride) return;
|
||||
if(c.getTemplate().isDisableSaplings()) return;
|
||||
e.setCancelled(true);
|
||||
Block block = e.getLocation().getBlock();
|
||||
BlockData data = block.getBlockData();
|
||||
@@ -80,10 +80,10 @@ public class EventListener implements Listener {
|
||||
TreeRegistry registry = c.getTreeRegistry();
|
||||
Tree tree = registry.get(TreeType.fromBukkit(e.getSpecies()).toString());
|
||||
Debug.info("Overriding tree type: " + e.getSpecies());
|
||||
if(tree instanceof TreeConfig) {
|
||||
if(!((TreeConfig) tree).plantBlockCheck(e.getLocation(), new FastRandom())) {
|
||||
if(tree instanceof TerraTree) {
|
||||
if(!((TerraTree) tree).plantBlockCheck(e.getLocation().subtract(0, 1, 0), new FastRandom())) {
|
||||
block.setBlockData(data);
|
||||
}
|
||||
} else if(!tree.plant(e.getLocation(), new FastRandom(), Terra.getInstance())) block.setBlockData(data);
|
||||
} else if(!tree.plant(e.getLocation().subtract(0, 1, 0), new FastRandom(), Terra.getInstance())) block.setBlockData(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@ package com.dfsek.terra;
|
||||
|
||||
import com.dfsek.terra.command.TerraCommand;
|
||||
import com.dfsek.terra.command.structure.LocateCommand;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.base.PluginConfig;
|
||||
import com.dfsek.terra.config.base.WorldConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.generation.TerraChunkGenerator;
|
||||
import com.dfsek.terra.registry.ConfigRegistry;
|
||||
import com.dfsek.terra.util.PaperUtil;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -39,10 +40,17 @@ public class Terra extends GaeaPlugin {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
|
||||
saveDefaultConfig();
|
||||
|
||||
Metrics metrics = new Metrics(this, 9017);
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("worlds", TerraWorld::numWorlds));
|
||||
|
||||
Debug.setMain(this);
|
||||
ConfigUtil.loadConfig(this);
|
||||
PluginConfig.load(this);
|
||||
LangUtil.load(PluginConfig.getLanguage(), this); // Load language.
|
||||
TerraWorld.invalidate();
|
||||
ConfigRegistry.loadAll(this);
|
||||
|
||||
PluginCommand c = Objects.requireNonNull(getCommand("terra"));
|
||||
TerraCommand command = new TerraCommand(this);
|
||||
@@ -54,8 +62,9 @@ public class Terra extends GaeaPlugin {
|
||||
locatePl.setExecutor(locate);
|
||||
locatePl.setTabCompleter(locate);
|
||||
|
||||
saveDefaultConfig();
|
||||
Bukkit.getScheduler().scheduleAsyncRepeatingTask(this, TerraChunkGenerator::saveAll, ConfigUtil.dataSave, ConfigUtil.dataSave);
|
||||
|
||||
long save = PluginConfig.getDataSaveInterval();
|
||||
Bukkit.getScheduler().scheduleAsyncRepeatingTask(this, TerraChunkGenerator::saveAll, save, save);
|
||||
Bukkit.getPluginManager().registerEvents(new EventListener(this), this);
|
||||
PaperUtil.checkPaper(this);
|
||||
}
|
||||
@@ -71,7 +80,7 @@ public class Terra extends GaeaPlugin {
|
||||
|
||||
@Override
|
||||
public boolean isDebug() {
|
||||
return ConfigUtil.debug;
|
||||
return PluginConfig.isDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,8 +20,7 @@ public class TerraProfiler extends WorldProfiler {
|
||||
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "OreTime")
|
||||
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "CaveTime")
|
||||
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "StructureTime")
|
||||
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "ElevationTime")
|
||||
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "SnowTime");
|
||||
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "ElevationTime");
|
||||
}
|
||||
|
||||
public static TerraProfiler fromWorld(World w) {
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
package com.dfsek.terra;
|
||||
|
||||
import com.dfsek.terra.biome.BiomeZone;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.biome.grid.TerraBiomeGrid;
|
||||
import com.dfsek.terra.biome.grid.UserDefinedGrid;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.base.ConfigPackTemplate;
|
||||
import com.dfsek.terra.config.base.WorldConfig;
|
||||
import com.dfsek.terra.config.genconfig.BiomeGridConfig;
|
||||
import com.dfsek.terra.config.builder.biomegrid.BiomeGridBuilder;
|
||||
import com.dfsek.terra.generation.TerraChunkGenerator;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.polydev.gaea.biome.BiomeGrid;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class TerraWorld {
|
||||
private static final Map<World, TerraWorld> map = new HashMap<>();
|
||||
@@ -28,21 +27,18 @@ public class TerraWorld {
|
||||
safe = true;
|
||||
worldConfig = loaded.get(w.getName());
|
||||
config = worldConfig.getConfig();
|
||||
UserDefinedGrid[] definedGrids = new UserDefinedGrid[config.biomeList.size()];
|
||||
for(int i = 0; i < config.biomeList.size(); i++) {
|
||||
String partName = config.biomeList.get(i);
|
||||
|
||||
ConfigPackTemplate template = config.getTemplate();
|
||||
|
||||
int zoneSize = template.getGrids().size();
|
||||
|
||||
BiomeGrid[] definedGrids = new BiomeGrid[zoneSize];
|
||||
for(int i = 0; i < zoneSize; i++) {
|
||||
String partName = template.getGrids().get(i);
|
||||
try {
|
||||
if(partName.startsWith("BIOME:")) {
|
||||
UserDefinedBiome[][] temp = new UserDefinedBiome[1][1];
|
||||
UserDefinedBiome b = config.getBiomes().get(partName.substring(6)).getBiome();
|
||||
temp[0][0] = b;
|
||||
definedGrids[i] = new UserDefinedGrid(w, config.freq1, config.freq2, temp, worldConfig);
|
||||
Debug.info("Loaded single-biome grid " + partName);
|
||||
} else {
|
||||
BiomeGridConfig g = config.getBiomeGrid(partName);
|
||||
Debug.info("Loaded BiomeGrid " + g.getID());
|
||||
definedGrids[i] = g.getGrid(w, worldConfig);
|
||||
}
|
||||
BiomeGridBuilder g = config.getBiomeGrid(partName);
|
||||
BiomeGrid b = g.build(w, worldConfig);
|
||||
definedGrids[i] = b;
|
||||
} catch(NullPointerException e) {
|
||||
safe = false;
|
||||
Debug.stack(e);
|
||||
@@ -52,31 +48,8 @@ public class TerraWorld {
|
||||
Bukkit.getLogger().severe("Terrain will NOT generate properly at this point. Correct your config before using your server!");
|
||||
}
|
||||
}
|
||||
UserDefinedGrid erosion = null;
|
||||
if(config.erosionEnable) {
|
||||
try {
|
||||
if(config.erosionName.startsWith("BIOME:")) {
|
||||
UserDefinedBiome[][] temp = new UserDefinedBiome[1][1];
|
||||
UserDefinedBiome b = Objects.requireNonNull(config.getBiome(config.erosionName.substring(6)).getBiome());
|
||||
temp[0][0] = b;
|
||||
erosion = new UserDefinedGrid(w, config.freq1, config.freq2, temp, worldConfig);
|
||||
Debug.info("Loaded single-biome erosion grid " + config.erosionName);
|
||||
} else {
|
||||
BiomeGridConfig g = Objects.requireNonNull(config.getBiomeGrid(config.erosionName));
|
||||
Debug.info("Loaded BiomeGrid " + g.getID());
|
||||
erosion = g.getGrid(w, worldConfig);
|
||||
}
|
||||
} catch(NullPointerException e) {
|
||||
safe = false;
|
||||
Debug.stack(e);
|
||||
Bukkit.getLogger().severe("No such BiomeGrid (erosion): " + config.erosionName);
|
||||
Bukkit.getLogger().severe("Please check configuration files for errors. Configuration errors will have been reported during initialization.");
|
||||
Bukkit.getLogger().severe("ONLY report this to Terra if you are SURE your config is error-free.");
|
||||
Bukkit.getLogger().severe("Terrain will NOT generate properly at this point. Correct your config before using your server!");
|
||||
}
|
||||
}
|
||||
zone = new BiomeZone(w, worldConfig, definedGrids);
|
||||
grid = new TerraBiomeGrid(w, config.freq1, config.freq2, zone, config, erosion);
|
||||
grid = new TerraBiomeGrid(w, template.getGridFreqX(), template.getGridFreqZ(), zone, config);
|
||||
}
|
||||
|
||||
public static void loadWorld(WorldConfig w) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.async;
|
||||
|
||||
import com.dfsek.terra.biome.grid.TerraBiomeGrid;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.base.PluginConfig;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -28,11 +28,12 @@ public class AsyncBiomeFinder extends AsyncFeatureFinder<Biome> {
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid(int x, int z, Biome target) {
|
||||
return getGrid().getBiome(x * ConfigUtil.biomeSearchRes, z * ConfigUtil.biomeSearchRes, GenerationPhase.POST_GEN).equals(target);
|
||||
int res = PluginConfig.getBiomeSearchResolution();
|
||||
return getGrid().getBiome(x * res, z * res, GenerationPhase.POST_GEN).equals(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector finalizeVector(Vector orig) {
|
||||
return orig.multiply(ConfigUtil.biomeSearchRes);
|
||||
return orig.multiply(PluginConfig.getBiomeSearchResolution());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.dfsek.terra.async;
|
||||
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.biome.grid.TerraBiomeGrid;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.generation.items.TerraStructure;
|
||||
import com.dfsek.terra.structure.Rotation;
|
||||
import com.dfsek.terra.structure.Structure;
|
||||
import org.bukkit.Location;
|
||||
@@ -17,8 +17,8 @@ import java.util.function.Consumer;
|
||||
/**
|
||||
* Runnable to locate structures asynchronously
|
||||
*/
|
||||
public class AsyncStructureFinder extends AsyncFeatureFinder<StructureConfig> {
|
||||
public AsyncStructureFinder(TerraBiomeGrid grid, StructureConfig target, @NotNull Location origin, int startRadius, int maxRadius, Consumer<Vector> callback) {
|
||||
public class AsyncStructureFinder extends AsyncFeatureFinder<TerraStructure> {
|
||||
public AsyncStructureFinder(TerraBiomeGrid grid, TerraStructure target, @NotNull Location origin, int startRadius, int maxRadius, Consumer<Vector> callback) {
|
||||
super(grid, target, origin, startRadius, maxRadius, callback);
|
||||
setSearchSize(target.getSpawn().getWidth() + 2 * target.getSpawn().getSeparation());
|
||||
}
|
||||
@@ -30,15 +30,15 @@ public class AsyncStructureFinder extends AsyncFeatureFinder<StructureConfig> {
|
||||
* @param z Z coordinate
|
||||
* @return Whether location is a valid spawn for StructureConfig
|
||||
*/
|
||||
public boolean isValid(int x, int z, StructureConfig target) {
|
||||
public boolean isValid(int x, int z, TerraStructure target) {
|
||||
World world = getWorld();
|
||||
Location spawn = target.getSpawn().getChunkSpawn(x, z, world.getSeed()).toLocation(world);
|
||||
if(!((UserDefinedBiome) getGrid().getBiome(spawn)).getConfig().getStructures().contains(target))
|
||||
return false;
|
||||
Random r2 = new FastRandom(spawn.hashCode());
|
||||
Structure struc = target.getStructure(r2);
|
||||
Structure struc = target.getStructures().get(r2);
|
||||
Rotation rotation = Rotation.fromDegrees(r2.nextInt(4) * 90);
|
||||
for(int y = target.getSearchStart().get(r2); y > 0; y--) {
|
||||
for(int y = target.getSpawnStart().get(r2); y > 0; y--) {
|
||||
if(!target.getBound().isInRange(y)) return false;
|
||||
spawn.setY(y);
|
||||
if(!struc.checkSpawns(spawn, rotation)) continue;
|
||||
|
||||
@@ -26,7 +26,7 @@ public class BiomeZone {
|
||||
this.noise.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
this.noise.setFractalType(FastNoiseLite.FractalType.FBm);
|
||||
this.noise.setFractalOctaves(4);
|
||||
this.noise.setFrequency(wc.getConfig().zoneFreq);
|
||||
this.noise.setFrequency(1D / wc.getConfig().getTemplate().getZoneFreq());
|
||||
this.grids = grids;
|
||||
imageLoader = wc.imageLoader;
|
||||
useImage = wc.fromImage;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.dfsek.terra.biome;
|
||||
|
||||
import com.dfsek.terra.config.genconfig.biome.BiomeConfig;
|
||||
import com.dfsek.terra.config.genconfig.biome.GeneratorOptions;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.builder.GeneratorBuilder;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.generation.UserDefinedDecorator;
|
||||
import org.bukkit.World;
|
||||
import org.polydev.gaea.biome.Biome;
|
||||
@@ -15,21 +16,22 @@ import java.util.List;
|
||||
* Class representing a config-defined biome
|
||||
*/
|
||||
public class UserDefinedBiome implements Biome {
|
||||
private final GeneratorOptions gen;
|
||||
private final GeneratorBuilder gen;
|
||||
private final UserDefinedDecorator decorator;
|
||||
private final org.bukkit.block.Biome vanilla;
|
||||
private final String id;
|
||||
private final BiomeConfig config;
|
||||
private final boolean erode;
|
||||
private final BiomeTemplate config;
|
||||
private final ConfigPack pack;
|
||||
private UserDefinedBiome erode;
|
||||
|
||||
|
||||
public UserDefinedBiome(org.bukkit.block.Biome vanilla, UserDefinedDecorator dec, GeneratorOptions gen, boolean erode, BiomeConfig config) {
|
||||
public UserDefinedBiome(org.bukkit.block.Biome vanilla, UserDefinedDecorator dec, GeneratorBuilder gen, BiomeTemplate config, ConfigPack pack) {
|
||||
this.vanilla = vanilla;
|
||||
this.decorator = dec;
|
||||
this.gen = gen;
|
||||
this.id = config.getID();
|
||||
this.erode = erode;
|
||||
this.config = config;
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +51,7 @@ public class UserDefinedBiome implements Biome {
|
||||
*/
|
||||
@Override
|
||||
public Generator getGenerator() {
|
||||
return gen.getGenerator(0);
|
||||
return gen.build(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,16 +78,20 @@ public class UserDefinedBiome implements Biome {
|
||||
return id;
|
||||
}
|
||||
|
||||
public boolean isErodible() {
|
||||
public UserDefinedBiome getErode() {
|
||||
if(erode == null) {
|
||||
erode = (config.getErode() == null) ? this : pack.getBiome(config.getErode());
|
||||
}
|
||||
return erode;
|
||||
}
|
||||
|
||||
public BiomeConfig getConfig() {
|
||||
|
||||
public BiomeTemplate getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generator getGenerator(World w) {
|
||||
return gen.getGenerator(w.getSeed());
|
||||
return gen.build(w.getSeed());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.dfsek.terra.biome.grid;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.polydev.gaea.biome.Biome;
|
||||
import org.polydev.gaea.biome.BiomeGrid;
|
||||
import org.polydev.gaea.generation.GenerationPhase;
|
||||
|
||||
/**
|
||||
* BiomeGrid implementation that holds a single biome.
|
||||
*/
|
||||
public class SingleBiomeGrid extends BiomeGrid {
|
||||
private final Biome biome;
|
||||
|
||||
public SingleBiomeGrid(World w, Biome biome) {
|
||||
super(w, 0, 0, 1, 1);
|
||||
this.biome = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int z, GenerationPhase phase) {
|
||||
return biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(Location l) {
|
||||
return biome;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,8 @@ import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.biome.postprocessing.CoordinatePerturb;
|
||||
import com.dfsek.terra.biome.postprocessing.ErosionNoise;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.base.ConfigPackTemplate;
|
||||
import com.dfsek.terra.config.base.PluginConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.procgen.math.Vector2;
|
||||
import org.bukkit.Location;
|
||||
@@ -21,17 +22,16 @@ public class TerraBiomeGrid extends BiomeGrid {
|
||||
private final BiomeZone zone;
|
||||
private CoordinatePerturb perturb;
|
||||
private ErosionNoise erode;
|
||||
private UserDefinedGrid erosionGrid;
|
||||
|
||||
public TerraBiomeGrid(World w, double freq1, double freq2, BiomeZone zone, ConfigPack c, UserDefinedGrid erosion) {
|
||||
public TerraBiomeGrid(World w, double freq1, double freq2, BiomeZone zone, ConfigPack c) {
|
||||
super(w, freq1, freq2, 0, 0);
|
||||
if(c.biomeBlend) {
|
||||
perturb = new CoordinatePerturb(c.blendFreq, c.blendAmp, w.getSeed());
|
||||
ConfigPackTemplate t = c.getTemplate();
|
||||
if(c.getTemplate().isBlend()) {
|
||||
perturb = new CoordinatePerturb(t.getBlendFreq(), t.getBlendAmp(), w.getSeed());
|
||||
}
|
||||
this.zone = zone;
|
||||
if(c.erosionEnable) {
|
||||
erode = new ErosionNoise(c.erosionFreq, c.erosionThresh, c.erosionOctaves, w.getSeed());
|
||||
this.erosionGrid = erosion;
|
||||
if(c.getTemplate().isErode()) {
|
||||
erode = new ErosionNoise(t.getErodeFreq(), t.getErodeThresh(), t.getErodeOctaves(), w.getSeed());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class TerraBiomeGrid extends BiomeGrid {
|
||||
public Biome getBiome(int x, int z, GenerationPhase phase) {
|
||||
int xp = x;
|
||||
int zp = z;
|
||||
if(perturb != null && phase.equals(GenerationPhase.PALETTE_APPLY)) {
|
||||
if(perturb != null && (phase.equals(GenerationPhase.PALETTE_APPLY) || phase.equals(GenerationPhase.POPULATE))) {
|
||||
Vector2 perturbCoords = perturb.getShiftedCoords(x, z);
|
||||
xp = (int) perturbCoords.getX();
|
||||
zp = (int) perturbCoords.getZ();
|
||||
@@ -53,15 +53,13 @@ public class TerraBiomeGrid extends BiomeGrid {
|
||||
try {
|
||||
b = (UserDefinedBiome) zone.getGrid(xp, zp).getBiome(xp, zp, phase);
|
||||
} catch(NullPointerException e) {
|
||||
if(ConfigUtil.debug) e.printStackTrace();
|
||||
if(PluginConfig.isDebug()) e.printStackTrace();
|
||||
if(failNum % 256 == 0)
|
||||
LangUtil.log("error.severe-config", Level.SEVERE, String.valueOf(x), String.valueOf(z));
|
||||
failNum++;
|
||||
return null;
|
||||
}
|
||||
if(erode != null && b.isErodible() && erode.isEroded(xp, zp)) {
|
||||
return erosionGrid.getBiome(xp, zp, phase);
|
||||
}
|
||||
if(erode != null && erode.isEroded(xp, zp)) return b.getErode();
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.dfsek.terra.biome.grid;
|
||||
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.base.WorldConfig;
|
||||
import com.dfsek.terra.image.ImageLoader;
|
||||
import org.bukkit.Location;
|
||||
@@ -16,7 +15,7 @@ public class UserDefinedGrid extends BiomeGrid {
|
||||
private final ImageLoader.Channel channelX;
|
||||
private final ImageLoader.Channel channelZ;
|
||||
|
||||
public UserDefinedGrid(World w, double freq1, double freq2, UserDefinedBiome[][] b, WorldConfig c) {
|
||||
public UserDefinedGrid(World w, double freq1, double freq2, Biome[][] b, WorldConfig c) {
|
||||
super(w, freq1, freq2, b.length, b[0].length);
|
||||
super.setGrid(b);
|
||||
imageLoader = c.imageLoader;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.dfsek.terra.biome.palette;
|
||||
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
|
||||
public class PaletteHolder {
|
||||
private final Palette<BlockData>[] palettes;
|
||||
|
||||
protected PaletteHolder(Palette<BlockData>[] palettes) {
|
||||
this.palettes = palettes;
|
||||
}
|
||||
|
||||
public Palette<BlockData> getPalette(int y) {
|
||||
return palettes[y];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.dfsek.terra.biome.palette;
|
||||
|
||||
import com.dfsek.terra.util.DataUtil;
|
||||
import net.jafama.FastMath;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class PaletteHolderBuilder {
|
||||
private final TreeMap<Integer, Palette<BlockData>> paletteMap = new TreeMap<>();
|
||||
|
||||
public PaletteHolderBuilder add(int y, Palette<BlockData> palette) {
|
||||
paletteMap.put(y, palette);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
|
||||
public PaletteHolder build() {
|
||||
Palette<BlockData>[] palettes = new Palette[paletteMap.lastKey() + 1];
|
||||
for(int y = 0; y <= FastMath.max(paletteMap.lastKey(), 255); y++) {
|
||||
Palette<BlockData> d = DataUtil.BLANK_PALETTE;
|
||||
for(Map.Entry<Integer, Palette<BlockData>> e : paletteMap.entrySet()) {
|
||||
if(e.getKey() >= y) {
|
||||
d = e.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
palettes[y] = d;
|
||||
}
|
||||
return new PaletteHolder(palettes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.dfsek.terra.biome.palette;
|
||||
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
|
||||
public class PaletteLayer {
|
||||
private final ProbabilityCollection<BlockData> layer;
|
||||
private final int size;
|
||||
|
||||
public PaletteLayer(@NotNull ProbabilityCollection<BlockData> layer, int size) {
|
||||
this.layer = layer;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ProbabilityCollection<BlockData> getLayer() {
|
||||
return layer;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.dfsek.terra.biome.palette;
|
||||
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
|
||||
public class SinglePalette<E> extends Palette<E> {
|
||||
private final E item;
|
||||
|
||||
public SinglePalette(E item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int i, int i1, int i2) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import org.polydev.gaea.math.FastNoiseLite;
|
||||
public class CoordinatePerturb {
|
||||
private final FastNoiseLite perturbX;
|
||||
private final FastNoiseLite perturbZ;
|
||||
private final int amplitude;
|
||||
private final double amplitude;
|
||||
|
||||
/**
|
||||
* Create a CoordinatePerturb object with a given frequency, amplitude, and seed.
|
||||
@@ -18,7 +18,7 @@ public class CoordinatePerturb {
|
||||
* @param amplitude Offset amplitude
|
||||
* @param seed Noise seed
|
||||
*/
|
||||
public CoordinatePerturb(double frequency, int amplitude, long seed) {
|
||||
public CoordinatePerturb(double frequency, double amplitude, long seed) {
|
||||
perturbX = new FastNoiseLite((int) seed);
|
||||
perturbX.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
perturbX.setFrequency(frequency);
|
||||
|
||||
53
src/main/java/com/dfsek/terra/carving/CarverPalette.java
Normal file
53
src/main/java/com/dfsek/terra/carving/CarverPalette.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package com.dfsek.terra.carving;
|
||||
|
||||
import com.dfsek.terra.util.MaterialSet;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
|
||||
public class CarverPalette {
|
||||
private final boolean blacklist;
|
||||
private final MaterialSet replace;
|
||||
private final TreeMap<Integer, ProbabilityCollection<BlockData>> map = new TreeMap<>();
|
||||
private ProbabilityCollection<BlockData>[] layers;
|
||||
|
||||
public CarverPalette(MaterialSet replaceable, boolean blacklist) {
|
||||
this.blacklist = blacklist;
|
||||
this.replace = replaceable;
|
||||
}
|
||||
|
||||
public CarverPalette add(ProbabilityCollection<BlockData> collection, int y) {
|
||||
map.put(y, collection);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProbabilityCollection<BlockData> get(int y) {
|
||||
return layers[y];
|
||||
}
|
||||
|
||||
public boolean canReplace(Material material) {
|
||||
return blacklist != replace.contains(material);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the palette to an array.
|
||||
*/
|
||||
public void build() {
|
||||
int size = map.lastKey() + 1;
|
||||
layers = new ProbabilityCollection[size];
|
||||
for(int y = 0; y < size; y++) {
|
||||
ProbabilityCollection<BlockData> d = new ProbabilityCollection<BlockData>().add(Material.AIR.createBlockData(), 1); // Blank layer
|
||||
for(Map.Entry<Integer, ProbabilityCollection<BlockData>> e : map.entrySet()) {
|
||||
if(e.getKey() >= y) {
|
||||
d = e.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
layers[y] = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package com.dfsek.terra.carving;
|
||||
|
||||
import net.jafama.FastMath;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
import org.polydev.gaea.world.carving.Carver;
|
||||
import org.polydev.gaea.world.carving.CarvingData;
|
||||
import org.polydev.gaea.world.carving.Worm;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class SimplexCarver extends Carver {
|
||||
private final FastNoiseLite noise;
|
||||
private final FastNoiseLite height;
|
||||
private final FastNoiseLite column;
|
||||
private final FastNoiseLite hasCaves;
|
||||
private final double root2inverse = 1D / FastMath.sqrt(2);
|
||||
|
||||
public SimplexCarver(int minY, int maxY) {
|
||||
super(minY, maxY);
|
||||
noise = new FastNoiseLite(2403);
|
||||
noise.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
noise.setFractalType(FastNoiseLite.FractalType.FBm);
|
||||
noise.setFractalOctaves(3);
|
||||
noise.setFrequency(0.02f);
|
||||
|
||||
height = new FastNoiseLite(2404);
|
||||
height.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
height.setFrequency(0.01f);
|
||||
|
||||
column = new FastNoiseLite(2404);
|
||||
column.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
column.setFractalType(FastNoiseLite.FractalType.FBm);
|
||||
column.setFractalOctaves(5);
|
||||
column.setFrequency(0.05f);
|
||||
|
||||
hasCaves = new FastNoiseLite(2405);
|
||||
hasCaves.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
hasCaves.setFrequency(0.005f);
|
||||
}
|
||||
|
||||
private static double acot(double x) {
|
||||
return FastMath.PI / 2 - FastMath.atan(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CarvingData carve(int chunkX, int chunkZ, World w) {
|
||||
CarvingData c = new CarvingData(chunkX, chunkZ);
|
||||
int ox = chunkX << 4;
|
||||
int oz = chunkZ << 4;
|
||||
for(int x = ox; x < ox + 16; x++) {
|
||||
for(int z = oz; z < oz + 16; z++) {
|
||||
double heightNoise = height.getNoise(x, z);
|
||||
double mainNoise = noise.getNoise(x, z) * 2;
|
||||
double columnNoise = FastMath.pow(FastMath.max(column.getNoise(x, z), 0) * 2, 3);
|
||||
double hc = (acot(16 * (hasCaves.getNoise(x, z) - 0.2)) / FastMath.PI) - 0.1;
|
||||
CarvingData.CarvingType type = CarvingData.CarvingType.BOTTOM;
|
||||
double simplex = (FastMath.pow(mainNoise + root2inverse, 3) / 2 + columnNoise) * hc;
|
||||
for(int y = 0; y < 64; y++) {
|
||||
double finalNoise = (-0.05 * FastMath.abs(y - (heightNoise * 16 + 24)) + 1 - simplex) * hc;
|
||||
if(finalNoise > 0.5) {
|
||||
c.carve(x - ox, y, z - oz, type);
|
||||
double finalNoiseUp = (-0.05 * FastMath.abs((y + 1) - (heightNoise * 16 + 24)) + 1 - simplex) * hc;
|
||||
if(finalNoiseUp > 0.5) {
|
||||
type = CarvingData.CarvingType.CENTER;
|
||||
} else type = CarvingData.CarvingType.TOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Worm getWorm(long l, Vector vector) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkCarved(World world, int i, int i1, Random random) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2,47 +2,83 @@ package com.dfsek.terra.carving;
|
||||
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.biome.grid.TerraBiomeGrid;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
||||
import com.dfsek.terra.math.RandomFunction;
|
||||
import net.jafama.FastMath;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.polydev.gaea.biome.Biome;
|
||||
import org.polydev.gaea.generation.GenerationPhase;
|
||||
import org.polydev.gaea.math.MathUtil;
|
||||
import org.polydev.gaea.math.Range;
|
||||
import org.polydev.gaea.util.FastRandom;
|
||||
import org.polydev.gaea.util.GlueList;
|
||||
import org.polydev.gaea.world.carving.Carver;
|
||||
import org.polydev.gaea.world.carving.Worm;
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Parser;
|
||||
import parsii.eval.Scope;
|
||||
import parsii.eval.Variable;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class UserDefinedCarver extends Carver {
|
||||
private final double[] start; // 0, 1, 2 = x, y, z.
|
||||
private final double[] mutate; // 0, 1, 2 = x, y, z. 3 = radius.
|
||||
private final double[] radiusMultiplier;
|
||||
private final Range length;
|
||||
private final Range radius;
|
||||
private final int hash;
|
||||
private final int topCut;
|
||||
private final int bottomCut;
|
||||
private double step = 2;
|
||||
private Range recalc = new Range(8, 10);
|
||||
private double recalcMagnitude = 3;
|
||||
private final CarverTemplate config;
|
||||
private final Expression xRad;
|
||||
private final Expression yRad;
|
||||
private final Expression zRad;
|
||||
private final Variable lengthVar;
|
||||
private final Variable position;
|
||||
private final Variable seedVar;
|
||||
private final Range height;
|
||||
private final double sixtyFourSq = FastMath.pow(64, 2);
|
||||
|
||||
public UserDefinedCarver(Range height, Range radius, Range length, double[] start, double[] mutate, double[] radiusMultiplier, int hash, int topCut, int bottomCut) {
|
||||
public UserDefinedCarver(Range height, Range length, double[] start, double[] mutate, List<String> radii, Scope parent, int hash, int topCut, int bottomCut, CarverTemplate config) throws ParseException {
|
||||
super(height.getMin(), height.getMax());
|
||||
this.radius = radius;
|
||||
this.length = length;
|
||||
this.height = height;
|
||||
this.start = start;
|
||||
this.mutate = mutate;
|
||||
this.radiusMultiplier = radiusMultiplier;
|
||||
this.hash = hash;
|
||||
this.topCut = topCut;
|
||||
this.bottomCut = bottomCut;
|
||||
this.config = config;
|
||||
|
||||
Parser p = new Parser();
|
||||
|
||||
p.registerFunction("rand", new RandomFunction());
|
||||
|
||||
Scope s = new Scope().withParent(parent);
|
||||
|
||||
lengthVar = s.create("length");
|
||||
position = s.create("position");
|
||||
seedVar = s.create("seed");
|
||||
|
||||
|
||||
xRad = p.parse(radii.get(0), s);
|
||||
yRad = p.parse(radii.get(1), s);
|
||||
zRad = p.parse(radii.get(2), s);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Worm getWorm(long l, Vector vector) {
|
||||
Random r = new FastRandom(l + hash);
|
||||
return new UserDefinedWorm(length.get(r) / 2, r, vector, radius.getMax(), topCut, bottomCut);
|
||||
return new UserDefinedWorm(length.get(r) / 2, r, vector, topCut, bottomCut);
|
||||
}
|
||||
|
||||
public void setStep(double step) {
|
||||
@@ -53,35 +89,77 @@ public class UserDefinedCarver extends Carver {
|
||||
this.recalc = recalc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void carve(int chunkX, int chunkZ, World w, BiConsumer<Vector, CarvingType> consumer) {
|
||||
int carvingRadius = getCarvingRadius();
|
||||
TerraBiomeGrid grid = TerraWorld.getWorld(w).getGrid();
|
||||
for(int x = chunkX - carvingRadius; x <= chunkX + carvingRadius; x++) {
|
||||
z:
|
||||
for(int z = chunkZ - carvingRadius; z <= chunkZ + carvingRadius; z++) {
|
||||
if(isChunkCarved(w, x, z, new FastRandom(MathUtil.hashToLong(this.getClass().getName() + "_" + x + "&" + z)))) {
|
||||
long seed = MathUtil.getCarverChunkSeed(x, z, w.getSeed());
|
||||
seedVar.setValue(seed);
|
||||
Random r = new FastRandom(seed);
|
||||
Worm carving = getWorm(seed, new Vector((x << 4) + r.nextInt(16), height.get(r), (z << 4) + r.nextInt(16)));
|
||||
Vector origin = carving.getOrigin();
|
||||
List<Worm.WormPoint> points = new GlueList<>();
|
||||
for(int i = 0; i < carving.getLength(); i++) {
|
||||
carving.step();
|
||||
Biome biome = grid.getBiome(carving.getRunning().toLocation(w), GenerationPhase.POPULATE);
|
||||
if(!((UserDefinedBiome) biome).getConfig().getCarvers().containsKey(this)) { // Stop if we enter a biome this carver is not present in
|
||||
continue z;
|
||||
}
|
||||
if(FastMath.floorDiv(origin.getBlockX(), 16) != chunkX && FastMath.floorDiv(origin.getBlockZ(), 16) != chunkZ) { // Only carve in the current chunk.
|
||||
continue;
|
||||
}
|
||||
points.add(carving.getPoint());
|
||||
}
|
||||
points.forEach(point -> point.carve(chunkX, chunkZ, consumer));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setRecalcMagnitude(double recalcMagnitude) {
|
||||
this.recalcMagnitude = recalcMagnitude;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkCarved(World w, int chunkX, int chunkZ, Random random) {
|
||||
ConfigPack c = TerraWorld.getWorld(w).getConfig();
|
||||
return new FastRandom(random.nextLong() + hash).nextInt(100) < ((UserDefinedBiome) TerraWorld.getWorld(w).getGrid().getBiome(chunkX << 4, chunkZ << 4, GenerationPhase.POPULATE)).getConfig().getCarverChance(this);
|
||||
BiomeTemplate conf = ((UserDefinedBiome) TerraWorld.getWorld(w).getGrid().getBiome(chunkX << 4, chunkZ << 4, GenerationPhase.POPULATE)).getConfig();
|
||||
if(conf.getCarvers().get(this) != null) {
|
||||
return new FastRandom(random.nextLong() + hash).nextInt(100) < conf.getCarvers().get(this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public CarverTemplate getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
private class UserDefinedWorm extends Worm {
|
||||
private final Vector direction;
|
||||
private final int maxRad;
|
||||
private double runningRadius;
|
||||
private int steps;
|
||||
private int nextDirection = 0;
|
||||
private double[] currentRotation = new double[3];
|
||||
|
||||
public UserDefinedWorm(int length, Random r, Vector origin, int maxRad, int topCut, int bottomCut) {
|
||||
public UserDefinedWorm(int length, Random r, Vector origin, int topCut, int bottomCut) {
|
||||
super(length, r, origin);
|
||||
super.setTopCut(topCut);
|
||||
super.setBottomCut(bottomCut);
|
||||
runningRadius = radius.get(r);
|
||||
this.maxRad = maxRad;
|
||||
direction = new Vector((r.nextDouble() - 0.5D) * start[0], (r.nextDouble() - 0.5D) * start[1], (r.nextDouble() - 0.5D) * start[2]).normalize().multiply(step);
|
||||
position.setValue(0);
|
||||
lengthVar.setValue(length);
|
||||
setRadius(new int[] {(int) (xRad.evaluate()), (int) (yRad.evaluate()), (int) (zRad.evaluate())});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void step() {
|
||||
public WormPoint getPoint() {
|
||||
return new WormPoint(getRunning().clone(), getRadius(), config.getCutTop(), config.getCutBottom());
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void step() {
|
||||
if(steps == nextDirection) {
|
||||
direction.rotateAroundX(FastMath.toRadians((getRandom().nextGaussian()) * mutate[0] * recalcMagnitude));
|
||||
direction.rotateAroundY(FastMath.toRadians((getRandom().nextGaussian()) * mutate[1] * recalcMagnitude));
|
||||
@@ -92,9 +170,8 @@ public class UserDefinedCarver extends Carver {
|
||||
nextDirection += recalc.get(getRandom());
|
||||
}
|
||||
steps++;
|
||||
setRadius(new int[] {(int) (runningRadius * radiusMultiplier[0]), (int) (runningRadius * radiusMultiplier[1]), (int) (runningRadius * radiusMultiplier[2])});
|
||||
runningRadius += (getRandom().nextDouble() - 0.5) * mutate[3];
|
||||
runningRadius = FastMath.max(FastMath.min(runningRadius, maxRad), 1);
|
||||
position.setValue(steps);
|
||||
setRadius(new int[] {(int) (xRad.evaluate()), (int) (yRad.evaluate()), (int) (zRad.evaluate())});
|
||||
direction.rotateAroundX(FastMath.toRadians(currentRotation[0] * mutate[0]));
|
||||
direction.rotateAroundY(FastMath.toRadians(currentRotation[1] * mutate[1]));
|
||||
direction.rotateAroundZ(FastMath.toRadians(currentRotation[2] * mutate[2]));
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
package com.dfsek.terra.command;
|
||||
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.config.genconfig.OreConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import net.jafama.FastMath;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.polydev.gaea.command.WorldCommand;
|
||||
import org.polydev.gaea.util.FastRandom;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -24,6 +17,7 @@ public class OreCommand extends WorldCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World w) {
|
||||
/*
|
||||
Block bl = sender.getTargetBlockExact(25);
|
||||
if(args.length > 0) {
|
||||
OreConfig ore = TerraWorld.getWorld(w).getConfig().getOre(args[0]);
|
||||
@@ -40,7 +34,11 @@ public class OreCommand extends WorldCommand {
|
||||
} else {
|
||||
LangUtil.send("command.ore.main-menu", sender);
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
|
||||
|
||||
// TODO: implementation
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
56
src/main/java/com/dfsek/terra/command/PacksCommand.java
Normal file
56
src/main/java/com/dfsek/terra/command/PacksCommand.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package com.dfsek.terra.command;
|
||||
|
||||
import com.dfsek.terra.config.base.ConfigPackTemplate;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.registry.ConfigRegistry;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.polydev.gaea.command.Command;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class PacksCommand extends Command {
|
||||
public PacksCommand(Command parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "packs";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Command> getSubCommands() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull CommandSender commandSender, org.bukkit.command.@NotNull Command command, @NotNull String s, @NotNull String[] strings) {
|
||||
|
||||
ConfigRegistry registry = ConfigRegistry.getRegistry();
|
||||
|
||||
if(registry.entries().size() == 0) {
|
||||
LangUtil.send("command.packs.none", commandSender);
|
||||
return true;
|
||||
}
|
||||
|
||||
LangUtil.send("command.packs.main", commandSender);
|
||||
registry.entries().forEach(entry -> {
|
||||
ConfigPackTemplate template = entry.getTemplate();
|
||||
LangUtil.send("command.packs.pack", commandSender, template.getID(), template.getAuthor());
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int arguments() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompletions(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] strings) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
package com.dfsek.terra.command;
|
||||
|
||||
import com.dfsek.terra.Terra;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.config.base.PluginConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.registry.ConfigRegistry;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.polydev.gaea.command.Command;
|
||||
@@ -28,7 +29,10 @@ public class ReloadCommand extends Command implements DebugCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||
ConfigUtil.loadConfig(Terra.getInstance());
|
||||
PluginConfig.load(getMain());
|
||||
LangUtil.load(PluginConfig.getLanguage(), getMain()); // Load language.
|
||||
if(!ConfigRegistry.loadAll(getMain())) LangUtil.send("command.reload-error", sender);
|
||||
TerraWorld.invalidate();
|
||||
LangUtil.send("command.reload", sender);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ public class TerraCommand extends Command {
|
||||
new ImageCommand(this),
|
||||
new GeometryCommand(this),
|
||||
new FixChunkCommand(this),
|
||||
new VersionCommand(this));
|
||||
new VersionCommand(this),
|
||||
new PacksCommand(this));
|
||||
|
||||
public TerraCommand(GaeaPlugin main) {
|
||||
super(main);
|
||||
|
||||
@@ -3,11 +3,10 @@ package com.dfsek.terra.command.biome;
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.genconfig.biome.BiomeConfig;
|
||||
import com.dfsek.terra.config.genconfig.biome.BiomeSnowConfig;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.generation.TerraChunkGenerator;
|
||||
import com.dfsek.terra.generation.items.TerraStructure;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -30,60 +29,27 @@ public class BiomeInfoCommand extends WorldCommand {
|
||||
ConfigPack cfg = TerraWorld.getWorld(world).getConfig();
|
||||
UserDefinedBiome b;
|
||||
try {
|
||||
b = cfg.getBiome(id).getBiome();
|
||||
b = cfg.getBiome(id);
|
||||
} catch(IllegalArgumentException | NullPointerException e) {
|
||||
LangUtil.send("command.biome.invalid", sender, id);
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage("Biome info for \"" + b.getID() + "\".");
|
||||
sender.sendMessage("Vanilla biome: " + b.getVanillaBiome());
|
||||
sender.sendMessage("Erodible: " + b.isErodible());
|
||||
sender.sendMessage("Eroded by: " + b.getErode());
|
||||
|
||||
|
||||
BiomeConfig bio = b.getConfig();
|
||||
List<StructureConfig> structureConfigs = bio.getStructures();
|
||||
BiomeTemplate bio = b.getConfig();
|
||||
List<TerraStructure> structureConfigs = bio.getStructures();
|
||||
|
||||
if(structureConfigs.size() == 0) sender.sendMessage("No Structures");
|
||||
else {
|
||||
sender.sendMessage("-------Structures-------");
|
||||
for(StructureConfig c : structureConfigs) {
|
||||
sender.sendMessage(" - " + c.getID());
|
||||
for(TerraStructure c : structureConfigs) {
|
||||
sender.sendMessage(" - " + c.getTemplate().getID());
|
||||
}
|
||||
}
|
||||
|
||||
// Get snow info
|
||||
BiomeSnowConfig snowConfig = bio.getSnow();
|
||||
StringBuilder snowMessage = new StringBuilder("----------Snow----------\n");
|
||||
int comp = snowConfig.getSnowChance(0);
|
||||
int compHeight = 0;
|
||||
boolean changed = false;
|
||||
// Rebuild original snow data (rather than simply getting it, since it may have changed during initial assembly, if any overlaps occurred)
|
||||
for(int i = 0; i <= 255; i++) {
|
||||
int snow = snowConfig.getSnowChance(i);
|
||||
if(snow != comp) {
|
||||
changed = true;
|
||||
snowMessage.append("Y=")
|
||||
.append(compHeight)
|
||||
.append("-")
|
||||
.append(i)
|
||||
.append(": ")
|
||||
.append(comp)
|
||||
.append("% snow\n");
|
||||
comp = snow;
|
||||
compHeight = i;
|
||||
}
|
||||
}
|
||||
if(!changed) {
|
||||
snowMessage.append("Y=0")
|
||||
.append("-255")
|
||||
.append(": ")
|
||||
.append(comp)
|
||||
.append("% snow\n");
|
||||
}
|
||||
sender.sendMessage(snowMessage.toString());
|
||||
|
||||
sender.sendMessage("Do snow: " + snowConfig.doSnow());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.dfsek.terra.Terra;
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.async.AsyncBiomeFinder;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.base.PluginConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.generation.TerraChunkGenerator;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -39,12 +40,12 @@ public class BiomeLocateCommand extends WorldCommand {
|
||||
}
|
||||
UserDefinedBiome b;
|
||||
try {
|
||||
b = TerraWorld.getWorld(world).getConfig().getBiome(id).getBiome();
|
||||
b = TerraWorld.getWorld(world).getConfig().getBiome(id);
|
||||
} catch(IllegalArgumentException | NullPointerException e) {
|
||||
LangUtil.send("command.biome.invalid", sender, id);
|
||||
return true;
|
||||
}
|
||||
Bukkit.getScheduler().runTaskAsynchronously(Terra.getInstance(), new AsyncBiomeFinder(TerraWorld.getWorld(world).getGrid(), b, sender.getLocation(), 0, maxRadius, location -> {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(Terra.getInstance(), new AsyncBiomeFinder(TerraWorld.getWorld(world).getGrid(), b, sender.getLocation().clone().multiply((1D / PluginConfig.getBiomeSearchResolution())), 0, maxRadius, location -> {
|
||||
if(location != null) {
|
||||
LangUtil.send("command.biome.biome-found", sender, String.valueOf(location.getBlockX()), String.valueOf(location.getBlockZ()));
|
||||
if(tp) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.command.image.gui;
|
||||
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.base.PluginConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.image.ImageLoader;
|
||||
import org.bukkit.World;
|
||||
@@ -21,7 +21,7 @@ public class RawGUICommand extends WorldCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
|
||||
if(!ConfigUtil.debug) {
|
||||
if(!PluginConfig.isDebug()) {
|
||||
LangUtil.send("command.image.gui.debug", sender);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.command.image.gui;
|
||||
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.base.PluginConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.image.ImageLoader;
|
||||
import org.bukkit.World;
|
||||
@@ -21,7 +21,7 @@ public class StepGUICommand extends WorldCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
|
||||
if(!ConfigUtil.debug) {
|
||||
if(!PluginConfig.isDebug()) {
|
||||
LangUtil.send("command.image.gui.debug", sender);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package com.dfsek.terra.command.structure;
|
||||
import com.dfsek.terra.Terra;
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.async.AsyncStructureFinder;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.generation.TerraChunkGenerator;
|
||||
import com.dfsek.terra.generation.items.TerraStructure;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
@@ -38,7 +38,7 @@ public class LocateCommand extends WorldCommand {
|
||||
LangUtil.send("command.structure.invalid-radius", sender, args[1]);
|
||||
return true;
|
||||
}
|
||||
StructureConfig s;
|
||||
TerraStructure s;
|
||||
try {
|
||||
s = Objects.requireNonNull(TerraWorld.getWorld(world).getConfig().getStructure(id));
|
||||
} catch(IllegalArgumentException | NullPointerException e) {
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
package com.dfsek.terra.config;
|
||||
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ConfigLoader {
|
||||
public static <T extends TerraConfig> Map<String, T> load(Path file, ConfigPack config, Class<T> clazz) {
|
||||
long l = System.nanoTime();
|
||||
Map<String, T> configs = new HashMap<>();
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.toFile().mkdirs();
|
||||
List<String> ids = new ArrayList<>();
|
||||
try(Stream<Path> paths = Files.walk(file)) {
|
||||
paths.filter(path -> FilenameUtils.wildcardMatch(path.toFile().getName(), "*.yml"))
|
||||
.forEach(path -> {
|
||||
try {
|
||||
Constructor<T> c = clazz.getConstructor(File.class, ConfigPack.class);
|
||||
T o = c.newInstance(path.toFile(), config);
|
||||
if(ids.contains(o.getID()))
|
||||
LangUtil.log("config.error.duplicate", Level.SEVERE, path.toString());
|
||||
ids.add(o.getID());
|
||||
configs.put(o.getID(), o);
|
||||
LangUtil.log("config.loaded", Level.INFO, o.toString(), path.toString());
|
||||
} catch(IllegalAccessException | InstantiationException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
LangUtil.log("config.error.generic", Level.SEVERE, path.toString());
|
||||
} catch(IllegalArgumentException | InvocationTargetException e) {
|
||||
if(ConfigUtil.debug) e.printStackTrace();
|
||||
LangUtil.log("config.error.file", Level.SEVERE, path.toString(), e.getMessage());
|
||||
}
|
||||
});
|
||||
LangUtil.log("config.loaded-all", Level.INFO, String.valueOf(configs.size()), clazz.getSimpleName(), String.valueOf((System.nanoTime() - l) / 1000000D));
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return configs;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.dfsek.terra.config;
|
||||
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public abstract class TerraConfig extends YamlConfiguration {
|
||||
private final ConfigPack config;
|
||||
|
||||
public TerraConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||
load(file);
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public TerraConfig(InputStream stream, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||
load(new InputStreamReader(stream));
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public ConfigPack getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public abstract String getID();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.dfsek.terra.config;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class TerraConfigSection {
|
||||
private final TerraConfig parent;
|
||||
|
||||
public TerraConfigSection(@NotNull TerraConfig parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TerraConfig getParent() {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
@@ -1,322 +1,223 @@
|
||||
package com.dfsek.terra.config.base;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.Terra;
|
||||
import com.dfsek.tectonic.abstraction.AbstractConfigLoader;
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||
import com.dfsek.terra.config.ConfigLoader;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import com.dfsek.terra.config.genconfig.BiomeGridConfig;
|
||||
import com.dfsek.terra.config.genconfig.CarverConfig;
|
||||
import com.dfsek.terra.config.genconfig.FloraConfig;
|
||||
import com.dfsek.terra.config.genconfig.OreConfig;
|
||||
import com.dfsek.terra.config.genconfig.PaletteConfig;
|
||||
import com.dfsek.terra.config.genconfig.TreeConfig;
|
||||
import com.dfsek.terra.config.genconfig.biome.AbstractBiomeConfig;
|
||||
import com.dfsek.terra.config.genconfig.biome.BiomeConfig;
|
||||
import com.dfsek.terra.config.genconfig.noise.NoiseConfig;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.config.builder.biomegrid.BiomeGridBuilder;
|
||||
import com.dfsek.terra.config.exception.FileMissingException;
|
||||
import com.dfsek.terra.config.factories.BiomeFactory;
|
||||
import com.dfsek.terra.config.factories.BiomeGridFactory;
|
||||
import com.dfsek.terra.config.factories.CarverFactory;
|
||||
import com.dfsek.terra.config.factories.FloraFactory;
|
||||
import com.dfsek.terra.config.factories.OreFactory;
|
||||
import com.dfsek.terra.config.factories.PaletteFactory;
|
||||
import com.dfsek.terra.config.factories.StructureFactory;
|
||||
import com.dfsek.terra.config.factories.TerraFactory;
|
||||
import com.dfsek.terra.config.factories.TreeFactory;
|
||||
import com.dfsek.terra.config.files.FolderLoader;
|
||||
import com.dfsek.terra.config.files.Loader;
|
||||
import com.dfsek.terra.config.files.ZIPLoader;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.config.loaders.LootTableLoader;
|
||||
import com.dfsek.terra.config.loaders.StructureLoader;
|
||||
import com.dfsek.terra.config.templates.AbstractableTemplate;
|
||||
import com.dfsek.terra.config.templates.BiomeGridTemplate;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
||||
import com.dfsek.terra.config.templates.FloraTemplate;
|
||||
import com.dfsek.terra.config.templates.OreTemplate;
|
||||
import com.dfsek.terra.config.templates.PaletteTemplate;
|
||||
import com.dfsek.terra.config.templates.StructureTemplate;
|
||||
import com.dfsek.terra.config.templates.TreeTemplate;
|
||||
import com.dfsek.terra.generation.items.TerraStructure;
|
||||
import com.dfsek.terra.generation.items.ores.Ore;
|
||||
import com.dfsek.terra.registry.BiomeGridRegistry;
|
||||
import com.dfsek.terra.registry.BiomeRegistry;
|
||||
import com.dfsek.terra.registry.CarverRegistry;
|
||||
import com.dfsek.terra.registry.FloraRegistry;
|
||||
import com.dfsek.terra.registry.OreRegistry;
|
||||
import com.dfsek.terra.registry.PaletteRegistry;
|
||||
import com.dfsek.terra.registry.StructureRegistry;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
import com.dfsek.terra.registry.TreeRegistry;
|
||||
import com.dfsek.terra.structure.Structure;
|
||||
import com.dfsek.terra.util.ConfigUtil;
|
||||
import com.dfsek.terra.util.StructureTypeEnum;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.polydev.gaea.biome.Biome;
|
||||
import org.polydev.gaea.structures.loot.LootTable;
|
||||
import org.polydev.gaea.tree.Tree;
|
||||
import org.polydev.gaea.world.Flora;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import parsii.eval.Scope;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* Represents a Terra configuration pack.
|
||||
*/
|
||||
public class ConfigPack extends YamlConfiguration {
|
||||
private static final Map<String, ConfigPack> configs = new HashMap<>();
|
||||
public final List<String> biomeList;
|
||||
public final double zoneFreq;
|
||||
public final double freq1;
|
||||
public final double freq2;
|
||||
public final double erosionFreq;
|
||||
public final double erosionThresh;
|
||||
public final boolean erosionEnable;
|
||||
public final int erosionOctaves;
|
||||
public final String erosionName;
|
||||
public final int blendAmp;
|
||||
public final boolean biomeBlend;
|
||||
public final double blendFreq;
|
||||
public final boolean vanillaCaves;
|
||||
public final boolean vanillaStructures;
|
||||
public final boolean vanillaDecoration;
|
||||
public final boolean vanillaMobs;
|
||||
public final boolean preventSaplingOverride;
|
||||
|
||||
private final Map<StructureTypeEnum, StructureConfig> locatable = new HashMap<>();
|
||||
private final Map<String, OreConfig> ores;
|
||||
private final Map<String, PaletteConfig> palettes;
|
||||
private final Map<String, CarverConfig> carvers;
|
||||
private final Map<String, StructureConfig> structures;
|
||||
private final Map<String, AbstractBiomeConfig> abstractBiomes;
|
||||
private final Map<String, BiomeConfig> biomes;
|
||||
private final Map<String, BiomeGridConfig> grids;
|
||||
private final TreeRegistry treeRegistry = new TreeRegistry();
|
||||
public class ConfigPack {
|
||||
private final ConfigPackTemplate template = new ConfigPackTemplate();
|
||||
private final BiomeRegistry biomeRegistry = new BiomeRegistry();
|
||||
private final BiomeGridRegistry biomeGridRegistry = new BiomeGridRegistry(biomeRegistry);
|
||||
private final StructureRegistry structureRegistry = new StructureRegistry();
|
||||
private final CarverRegistry carverRegistry = new CarverRegistry();
|
||||
private final PaletteRegistry paletteRegistry = new PaletteRegistry();
|
||||
private final FloraRegistry floraRegistry = new FloraRegistry();
|
||||
private final Set<StructureConfig> allStructures = new HashSet<>();
|
||||
private final Map<String, NoiseConfig> noiseBuilders = new HashMap<>();
|
||||
private final Scope vScope;
|
||||
private final File dataFolder;
|
||||
private final String id;
|
||||
private final OreRegistry oreRegistry = new OreRegistry();
|
||||
private final TreeRegistry treeRegistry = new TreeRegistry();
|
||||
|
||||
public ConfigPack(File file) throws IOException, InvalidConfigurationException {
|
||||
private final AbstractConfigLoader abstractConfigLoader = new AbstractConfigLoader();
|
||||
private final ConfigLoader selfLoader = new ConfigLoader();
|
||||
private final Scope varScope = new Scope();
|
||||
|
||||
private final Map<StructureTypeEnum, TerraStructure> structureMap = new HashMap<>();
|
||||
|
||||
{
|
||||
abstractConfigLoader
|
||||
.registerLoader(Palette.class, paletteRegistry)
|
||||
.registerLoader(Biome.class, biomeRegistry)
|
||||
.registerLoader(UserDefinedCarver.class, carverRegistry)
|
||||
.registerLoader(Flora.class, floraRegistry)
|
||||
.registerLoader(Ore.class, oreRegistry)
|
||||
.registerLoader(Tree.class, treeRegistry)
|
||||
.registerLoader(TerraStructure.class, structureRegistry);
|
||||
ConfigUtil.registerAllLoaders(abstractConfigLoader);
|
||||
ConfigUtil.registerAllLoaders(selfLoader);
|
||||
}
|
||||
|
||||
public ConfigPack(File folder) throws ConfigException {
|
||||
long l = System.nanoTime();
|
||||
load(new File(file, "pack.yml"));
|
||||
dataFolder = file;
|
||||
|
||||
if(!contains("id")) throw new ConfigException("No ID specified!", "null");
|
||||
this.id = getString("id");
|
||||
File pack = new File(folder, "pack.yml");
|
||||
|
||||
Map<String, Object> noise = Objects.requireNonNull(getConfigurationSection("noise")).getValues(false);
|
||||
for(Map.Entry<String, Object> entry : noise.entrySet()) {
|
||||
NoiseConfig noiseConfig = new NoiseConfig((ConfigurationSection) entry.getValue());
|
||||
noiseBuilders.put(entry.getKey(), noiseConfig);
|
||||
Debug.info("Loaded noise function " + entry.getKey() + " with type " + noiseConfig.getBuilder().getType());
|
||||
}
|
||||
|
||||
ores = ConfigLoader.load(new File(file, "ores").toPath(), this, OreConfig.class);
|
||||
|
||||
palettes = ConfigLoader.load(new File(file, "palettes").toPath(), this, PaletteConfig.class);
|
||||
|
||||
carvers = ConfigLoader.load(new File(file, "carving").toPath(), this, CarverConfig.class);
|
||||
|
||||
Map<String, FloraConfig> flora = ConfigLoader.load(new File(file, "flora").toPath(), this, FloraConfig.class);
|
||||
for(Map.Entry<String, FloraConfig> entry : flora.entrySet()) {
|
||||
if(floraRegistry.add(entry.getKey(), entry.getValue()))
|
||||
Debug.info("Overriding Gaea flora: " + entry.getKey());
|
||||
}
|
||||
|
||||
structures = ConfigLoader.load(new File(file, "structures").toPath(), this, StructureConfig.class);
|
||||
|
||||
Map<String, TreeConfig> trees = ConfigLoader.load(new File(file, "trees").toPath(), this, TreeConfig.class);
|
||||
|
||||
for(Map.Entry<String, TreeConfig> entry : trees.entrySet()) {
|
||||
if(treeRegistry.add(entry.getKey(), entry.getValue()))
|
||||
Debug.info("Overriding Vanilla tree: " + entry.getKey());
|
||||
}
|
||||
|
||||
vScope = new Scope();
|
||||
if(contains("variables")) {
|
||||
Map<String, Object> vars = Objects.requireNonNull(getConfigurationSection("variables")).getValues(false);
|
||||
for(Map.Entry<String, Object> entry : vars.entrySet()) {
|
||||
try {
|
||||
vScope.getVariable(entry.getKey()).setValue(Double.parseDouble(entry.getValue().toString()));
|
||||
Debug.info("Registered variable " + entry.getKey() + " with value " + entry.getValue());
|
||||
} catch(ClassCastException | NumberFormatException e) {
|
||||
Debug.stack(e);
|
||||
throw new ConfigException("Variable value " + entry.getValue().toString() + " could not be parsed to a double.", getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstractBiomes = ConfigLoader.load(new File(file, "abstract" + File.separator + "biomes").toPath(), this, AbstractBiomeConfig.class);
|
||||
|
||||
biomes = ConfigLoader.load(new File(file, "biomes").toPath(), this, BiomeConfig.class);
|
||||
|
||||
grids = ConfigLoader.load(new File(file, "grids").toPath(), this, BiomeGridConfig.class);
|
||||
|
||||
zoneFreq = 1f / getInt("frequencies.zone", 1536);
|
||||
freq1 = 1f / getInt("frequencies.grid-x", 256);
|
||||
freq2 = 1f / getInt("frequencies.grid-z", 512);
|
||||
|
||||
biomeBlend = getBoolean("blend.enable", false);
|
||||
blendAmp = getInt("blend.amplitude", 8);
|
||||
blendFreq = getDouble("blend.frequency", 0.01);
|
||||
|
||||
erosionEnable = getBoolean("erode.enable", false);
|
||||
erosionFreq = getDouble("erode.frequency", 0.01);
|
||||
erosionThresh = getDouble("erode.threshold", 0.04);
|
||||
erosionOctaves = getInt("erode.octaves", 3);
|
||||
|
||||
erosionName = getString("erode.grid");
|
||||
|
||||
vanillaCaves = getBoolean("vanilla.caves", false);
|
||||
vanillaStructures = getBoolean("vanilla.structures", false);
|
||||
vanillaDecoration = getBoolean("vanilla.decorations", false);
|
||||
vanillaMobs = getBoolean("vanilla.mobs", false);
|
||||
|
||||
preventSaplingOverride = getBoolean("prevent-sapling-override", false);
|
||||
|
||||
if(vanillaMobs || vanillaDecoration || vanillaStructures || vanillaCaves) {
|
||||
Terra.getInstance().getLogger().warning("WARNING: Vanilla features have been enabled! These features may not work properly, and are not officially supported! Use at your own risk!");
|
||||
}
|
||||
|
||||
// Load BiomeGrids from BiomeZone
|
||||
biomeList = getStringList("grids");
|
||||
|
||||
for(String biome : biomeList) {
|
||||
if(getBiomeGrid(biome) == null) {
|
||||
if(biome.startsWith("BIOME:") && biomes.containsKey(biome.substring(6))) continue;
|
||||
throw new ConfigException("No such BiomeGrid: " + biome, getID());
|
||||
}
|
||||
}
|
||||
|
||||
configs.put(id, this);
|
||||
|
||||
for(BiomeConfig b : getBiomes().values()) {
|
||||
allStructures.addAll(b.getStructures());
|
||||
}
|
||||
|
||||
ConfigurationSection st = getConfigurationSection("locatable");
|
||||
if(st != null) {
|
||||
Map<String, Object> strucLocatable = st.getValues(false);
|
||||
for(Map.Entry<String, Object> e : strucLocatable.entrySet()) {
|
||||
StructureConfig c = getStructure((String) e.getValue());
|
||||
if(c == null) throw new NotFoundException("Structure", (String) e.getValue(), getID());
|
||||
try {
|
||||
locatable.put(StructureTypeEnum.valueOf(e.getKey()), c);
|
||||
} catch(IllegalArgumentException ex) {
|
||||
throw new NotFoundException("Structure Type", e.getKey(), getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LangUtil.log("config-pack.loaded", Level.INFO, getID(), String.valueOf((System.nanoTime() - l) / 1000000D));
|
||||
}
|
||||
|
||||
public static synchronized void loadAll(JavaPlugin main) {
|
||||
configs.clear();
|
||||
File file = new File(main.getDataFolder(), "packs");
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.mkdirs();
|
||||
List<Path> subfolder;
|
||||
try {
|
||||
subfolder = Files.walk(file.toPath(), 1)
|
||||
.filter(Files::isDirectory)
|
||||
.collect(Collectors.toList());
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
selfLoader.load(template, new FileInputStream(pack));
|
||||
} catch(FileNotFoundException e) {
|
||||
throw new FileMissingException("No pack.yml file found in " + folder.getAbsolutePath(), e);
|
||||
}
|
||||
subfolder.remove(0);
|
||||
for(Path folder : subfolder) {
|
||||
ConfigPack config;
|
||||
|
||||
load(new FolderLoader(folder.toPath()), l);
|
||||
}
|
||||
|
||||
public ConfigPack(ZipFile file) throws ConfigException {
|
||||
long l = System.nanoTime();
|
||||
|
||||
InputStream stream = null;
|
||||
|
||||
try {
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if(entry.getName().equals("pack.yml")) stream = file.getInputStream(entry);
|
||||
}
|
||||
} catch(IOException e) {
|
||||
throw new LoadException("Unable to load pack.yml from ZIP file", e);
|
||||
}
|
||||
if(stream == null) throw new FileMissingException("No pack.yml file found in " + file.getName());
|
||||
|
||||
selfLoader.load(template, stream);
|
||||
|
||||
load(new ZIPLoader(file), l);
|
||||
}
|
||||
|
||||
private void load(Loader loader, long start) throws ConfigException {
|
||||
for(Map.Entry<String, Double> var : template.getVariables().entrySet()) {
|
||||
varScope.create(var.getKey()).setValue(var.getValue());
|
||||
}
|
||||
abstractConfigLoader.registerLoader(Structure.class, new StructureLoader(loader))
|
||||
.registerLoader(LootTable.class, new LootTableLoader(loader)); // These loaders need access to the Loader instance to get files.
|
||||
loader
|
||||
.open("palettes").then(streams -> buildAll(new PaletteFactory(), paletteRegistry, abstractConfigLoader.load(streams, PaletteTemplate::new))).close()
|
||||
.open("ores").then(streams -> buildAll(new OreFactory(), oreRegistry, abstractConfigLoader.load(streams, OreTemplate::new))).close()
|
||||
.open("flora").then(streams -> buildAll(new FloraFactory(), floraRegistry, abstractConfigLoader.load(streams, FloraTemplate::new))).close()
|
||||
.open("carving").then(streams -> buildAll(new CarverFactory(this), carverRegistry, abstractConfigLoader.load(streams, CarverTemplate::new))).close()
|
||||
.open("structures/trees").then(streams -> buildAll(new TreeFactory(), treeRegistry, abstractConfigLoader.load(streams, TreeTemplate::new))).close()
|
||||
.open("structures/single").then(streams -> buildAll(new StructureFactory(), structureRegistry, abstractConfigLoader.load(streams, StructureTemplate::new))).close()
|
||||
.open("biomes").then(streams -> buildAll(new BiomeFactory(this), biomeRegistry, abstractConfigLoader.load(streams, () -> new BiomeTemplate(this)))).close()
|
||||
.open("grids").then(streams -> buildAll(new BiomeGridFactory(), biomeGridRegistry, abstractConfigLoader.load(streams, BiomeGridTemplate::new))).close();
|
||||
for(UserDefinedBiome b : biomeRegistry.entries()) {
|
||||
try {
|
||||
config = new ConfigPack(folder.toFile());
|
||||
if(configs.containsKey(config.getID())) {
|
||||
//Bukkit.getLogger().severe("Duplicate Config Pack ID: \"" + config.getID() + "\"");
|
||||
continue;
|
||||
}
|
||||
configs.put(config.getID(), config);
|
||||
} catch(IOException | InvalidConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
Objects.requireNonNull(b.getErode()); // Throws NPE if it cannot load erosion biomes.
|
||||
} catch(NullPointerException e) {
|
||||
throw new LoadException("Invalid erosion biome defined in biome \"" + b.getID() + "\"", e);
|
||||
}
|
||||
}
|
||||
template.getStructureLocatables().forEach((type, name) -> structureMap.put(Objects.requireNonNull(type), Objects.requireNonNull(structureRegistry.get(name))));
|
||||
|
||||
LangUtil.log("config-pack.loaded", Level.INFO, template.getID(), String.valueOf((System.nanoTime() - start) / 1000000D), template.getAuthor(), template.getVersion());
|
||||
}
|
||||
|
||||
public static synchronized ConfigPack fromID(String id) {
|
||||
return configs.get(id);
|
||||
private <C extends AbstractableTemplate, O> void buildAll(TerraFactory<C, O> factory, TerraRegistry<O> registry, List<C> configTemplates) throws LoadException {
|
||||
for(C template : configTemplates) registry.add(template.getID(), factory.build(template));
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
public UserDefinedBiome getBiome(String id) {
|
||||
return biomeRegistry.get(id);
|
||||
}
|
||||
|
||||
public Scope getVariableScope() {
|
||||
return vScope;
|
||||
}
|
||||
|
||||
public Map<String, BiomeConfig> getBiomes() {
|
||||
return biomes;
|
||||
}
|
||||
|
||||
public StructureConfig getStructure(String id) {
|
||||
return structures.get(id);
|
||||
}
|
||||
|
||||
public BiomeGridConfig getBiomeGrid(String id) {
|
||||
return grids.get(id);
|
||||
}
|
||||
|
||||
public Map<String, NoiseConfig> getNoiseBuilders() {
|
||||
return noiseBuilders;
|
||||
}
|
||||
|
||||
public Map<StructureTypeEnum, StructureConfig> getLocatable() {
|
||||
return locatable;
|
||||
}
|
||||
|
||||
public Map<String, AbstractBiomeConfig> getAbstractBiomes() {
|
||||
return abstractBiomes;
|
||||
}
|
||||
|
||||
public Map<String, CarverConfig> getCarvers() {
|
||||
return carvers;
|
||||
}
|
||||
|
||||
public Set<StructureConfig> getAllStructures() {
|
||||
return allStructures;
|
||||
}
|
||||
|
||||
public File getDataFolder() {
|
||||
return dataFolder;
|
||||
}
|
||||
|
||||
public BiomeConfig getBiome(String id) {
|
||||
return biomes.get(id);
|
||||
}
|
||||
|
||||
public CarverConfig getCarver(String id) {
|
||||
return carvers.get(id);
|
||||
}
|
||||
|
||||
public CarverConfig getCarver(UserDefinedCarver c) {
|
||||
for(CarverConfig co : carvers.values()) {
|
||||
if(co.getCarver().equals(c)) return co;
|
||||
}
|
||||
throw new IllegalArgumentException("Unable to find carver!");
|
||||
}
|
||||
|
||||
public PaletteConfig getPalette(String id) {
|
||||
return palettes.get(id);
|
||||
}
|
||||
|
||||
public OreConfig getOre(String id) {
|
||||
return ores.get(id);
|
||||
public BiomeGridBuilder getBiomeGrid(String id) {
|
||||
return biomeGridRegistry.get(id);
|
||||
}
|
||||
|
||||
public List<String> getBiomeIDs() {
|
||||
List<String> fill = new ArrayList<>();
|
||||
for(BiomeConfig b : biomes.values()) {
|
||||
fill.add(b.getID());
|
||||
}
|
||||
return fill;
|
||||
List<String> biomeIDs = new ArrayList<>();
|
||||
biomeRegistry.forEach(biome -> biomeIDs.add(biome.getID()));
|
||||
return biomeIDs;
|
||||
}
|
||||
|
||||
public TerraStructure getStructure(String id) {
|
||||
return structureRegistry.get(id);
|
||||
}
|
||||
|
||||
public Set<TerraStructure> getStructures() {
|
||||
return structureRegistry.entries();
|
||||
}
|
||||
|
||||
public Collection<UserDefinedCarver> getCarvers() {
|
||||
return carverRegistry.entries();
|
||||
}
|
||||
|
||||
public UserDefinedCarver getCarver(String id) {
|
||||
return carverRegistry.get(id);
|
||||
}
|
||||
|
||||
public List<String> getStructureIDs() {
|
||||
List<String> fill = new ArrayList<>();
|
||||
for(StructureConfig s : structures.values()) {
|
||||
fill.add(s.getID());
|
||||
}
|
||||
return fill;
|
||||
}
|
||||
|
||||
public FloraRegistry getFloraRegistry() {
|
||||
return floraRegistry;
|
||||
List<String> ids = new ArrayList<>();
|
||||
structureRegistry.forEach(structure -> ids.add(structure.getTemplate().getID()));
|
||||
return ids;
|
||||
}
|
||||
|
||||
public TreeRegistry getTreeRegistry() {
|
||||
return treeRegistry;
|
||||
}
|
||||
|
||||
public ConfigPackTemplate getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public Scope getVarScope() {
|
||||
return varScope;
|
||||
}
|
||||
|
||||
public TerraStructure getStructureLocatable(StructureTypeEnum type) {
|
||||
return structureMap.get(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
package com.dfsek.terra.config.base;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.generation.config.NoiseBuilder;
|
||||
import com.dfsek.terra.util.StructureTypeEnum;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public class ConfigPackTemplate implements ConfigTemplate {
|
||||
@Value("id")
|
||||
private String id;
|
||||
|
||||
@Value("noise")
|
||||
private Map<String, NoiseBuilder> noiseBuilderMap;
|
||||
|
||||
@Value("variables")
|
||||
@Default
|
||||
private Map<String, Double> variables = new HashMap<>();
|
||||
|
||||
@Value("locatable")
|
||||
@Default
|
||||
private Map<StructureTypeEnum, String> structureLocatables = new HashMap<>();
|
||||
|
||||
@Value("grids")
|
||||
private List<String> grids;
|
||||
|
||||
@Value("frequencies.grid-x")
|
||||
@Default
|
||||
private int gridFreqX = 4096;
|
||||
|
||||
@Value("frequencies.grid-z")
|
||||
@Default
|
||||
private int gridFreqZ = 4096;
|
||||
|
||||
@Value("frequencies.zone")
|
||||
@Default
|
||||
private int zoneFreq = 2048;
|
||||
|
||||
@Value("blend.enable")
|
||||
@Default
|
||||
private boolean blend = false;
|
||||
|
||||
@Value("blend.frequency")
|
||||
@Default
|
||||
private double blendFreq = 0.1;
|
||||
|
||||
@Value("blend.amplitude")
|
||||
@Default
|
||||
private double blendAmp = 4.0D;
|
||||
|
||||
@Value("erode.enable")
|
||||
@Default
|
||||
private boolean erode = false;
|
||||
|
||||
@Value("erode.frequency")
|
||||
@Default
|
||||
private double erodeFreq = 0.001D;
|
||||
|
||||
@Value("erode.threshold")
|
||||
@Default
|
||||
private double erodeThresh = 0.0015D;
|
||||
|
||||
@Value("erode.octaves")
|
||||
@Default
|
||||
private int erodeOctaves = 5;
|
||||
|
||||
@Value("vanilla.mobs")
|
||||
@Default
|
||||
private boolean vanillaMobs = true;
|
||||
|
||||
@Value("vanilla.caves")
|
||||
@Default
|
||||
private boolean vanillaCaves = false;
|
||||
|
||||
@Value("vanilla.decorations")
|
||||
@Default
|
||||
private boolean vanillaDecorations = false;
|
||||
|
||||
@Value("vanilla.structures")
|
||||
@Default
|
||||
private boolean vanillaStructures = false;
|
||||
|
||||
@Value("author")
|
||||
@Default
|
||||
private String author = "Anon Y. Mous";
|
||||
|
||||
@Value("disable.sapling")
|
||||
@Default
|
||||
private boolean disableSaplings = false;
|
||||
|
||||
@Value("version")
|
||||
@Default
|
||||
private String version = "0.1.0";
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public boolean isDisableSaplings() {
|
||||
return disableSaplings;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public boolean vanillaMobs() {
|
||||
return vanillaMobs;
|
||||
}
|
||||
|
||||
public boolean vanillaCaves() {
|
||||
return vanillaCaves;
|
||||
}
|
||||
|
||||
public boolean vanillaDecorations() {
|
||||
return vanillaDecorations;
|
||||
}
|
||||
|
||||
public boolean vanillaStructures() {
|
||||
return vanillaStructures;
|
||||
}
|
||||
|
||||
public Map<String, NoiseBuilder> getNoiseBuilderMap() {
|
||||
return noiseBuilderMap;
|
||||
}
|
||||
|
||||
public Map<String, Double> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
|
||||
public Map<StructureTypeEnum, String> getStructureLocatables() {
|
||||
return structureLocatables;
|
||||
}
|
||||
|
||||
public List<String> getGrids() {
|
||||
return grids;
|
||||
}
|
||||
|
||||
public int getGridFreqX() {
|
||||
return gridFreqX;
|
||||
}
|
||||
|
||||
public int getGridFreqZ() {
|
||||
return gridFreqZ;
|
||||
}
|
||||
|
||||
public int getZoneFreq() {
|
||||
return zoneFreq;
|
||||
}
|
||||
|
||||
public boolean isBlend() {
|
||||
return blend;
|
||||
}
|
||||
|
||||
public double getBlendFreq() {
|
||||
return blendFreq;
|
||||
}
|
||||
|
||||
public double getBlendAmp() {
|
||||
return blendAmp;
|
||||
}
|
||||
|
||||
public boolean isErode() {
|
||||
return erode;
|
||||
}
|
||||
|
||||
public double getErodeFreq() {
|
||||
return erodeFreq;
|
||||
}
|
||||
|
||||
public double getErodeThresh() {
|
||||
return erodeThresh;
|
||||
}
|
||||
|
||||
public int getErodeOctaves() {
|
||||
return erodeOctaves;
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
package com.dfsek.terra.config.base;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.Terra;
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.util.TagUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.polydev.gaea.util.JarUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.time.Duration;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public final class ConfigUtil {
|
||||
public static boolean debug;
|
||||
public static long dataSave; // Period of population data saving, in ticks.
|
||||
public static boolean masterDisableCaves;
|
||||
public static int biomeSearchRes;
|
||||
public static int cacheSize;
|
||||
|
||||
public static void loadConfig(JavaPlugin main) {
|
||||
main.saveDefaultConfig();
|
||||
main.reloadConfig();
|
||||
FileConfiguration config = main.getConfig();
|
||||
LangUtil.load(config.getString("language", "en_us"), main);
|
||||
|
||||
debug = config.getBoolean("debug", false);
|
||||
dataSave = Duration.parse(Objects.requireNonNull(config.getString("data-save", "PT6M"))).toMillis() / 20L;
|
||||
masterDisableCaves = config.getBoolean("master-disable.caves", false);
|
||||
biomeSearchRes = config.getInt("biome-search-resolution", 4);
|
||||
cacheSize = config.getInt("cache-size", 384);
|
||||
|
||||
if(config.getBoolean("dump-default", true)) {
|
||||
try(JarFile jar = new JarFile(new File(Terra.class.getProtectionDomain().getCodeSource().getLocation().toURI()))) {
|
||||
JarUtil.copyResourcesToDirectory(jar, "packs", new File(main.getDataFolder(), "packs").toString());
|
||||
} catch(IOException | URISyntaxException e) {
|
||||
Debug.error("Failed to dump default config files!");
|
||||
e.printStackTrace();
|
||||
Debug.error("Report this to Terra!");
|
||||
}
|
||||
}
|
||||
|
||||
Logger logger = main.getLogger();
|
||||
logger.info("Loading config values");
|
||||
|
||||
ConfigPack.loadAll(main);
|
||||
TerraWorld.invalidate();
|
||||
}
|
||||
|
||||
public static Set<Material> toBlockData(List<String> list, String phase, String id) throws InvalidConfigurationException {
|
||||
Set<Material> bl = EnumSet.noneOf(Material.class);
|
||||
for(String s : list) {
|
||||
try {
|
||||
if(s.startsWith("#")) {
|
||||
Debug.info("Loading Tag " + s);
|
||||
Set<Material> tag = TagUtil.getTag(s.substring(1));
|
||||
for(Material m : tag) {
|
||||
if(bl.contains(m)) {
|
||||
Bukkit.getLogger().warning("Duplicate material in " + phase + " list: " + m); // Check for duplicates in this tag
|
||||
}
|
||||
}
|
||||
bl.addAll(tag);
|
||||
} else {
|
||||
if(bl.contains(Bukkit.createBlockData(s).getMaterial()))
|
||||
Bukkit.getLogger().warning("Duplicate material in " + phase + " list: " + s);
|
||||
bl.add(Bukkit.createBlockData(s).getMaterial());
|
||||
}
|
||||
} catch(NullPointerException | IllegalArgumentException e) {
|
||||
throw new ConfigException("Could not load BlockData data for \"" + s + "\"", id);
|
||||
}
|
||||
}
|
||||
return bl;
|
||||
}
|
||||
}
|
||||
94
src/main/java/com/dfsek/terra/config/base/PluginConfig.java
Normal file
94
src/main/java/com/dfsek/terra/config/base/PluginConfig.java
Normal file
@@ -0,0 +1,94 @@
|
||||
package com.dfsek.terra.config.base;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.Terra;
|
||||
import org.polydev.gaea.GaeaPlugin;
|
||||
import org.polydev.gaea.util.JarUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.time.Duration;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public class PluginConfig implements ConfigTemplate {
|
||||
private static final PluginConfig singleton = new PluginConfig();
|
||||
private static boolean loaded = false;
|
||||
|
||||
@Value("debug")
|
||||
@Default
|
||||
private boolean debug = false;
|
||||
|
||||
@Value("language")
|
||||
@Default
|
||||
private String language = "en_us";
|
||||
|
||||
@Value("data-save")
|
||||
@Default
|
||||
private Duration dataSave = Duration.parse("PT6M");
|
||||
|
||||
@Value("biome-search-resolution")
|
||||
@Default
|
||||
private int biomeSearch = 4;
|
||||
|
||||
@Value("cache-size")
|
||||
@Default
|
||||
private int cacheSize = 384;
|
||||
|
||||
@Value("dump-default")
|
||||
@Default
|
||||
private boolean dumpDefaultConfig = true;
|
||||
|
||||
private PluginConfig() {
|
||||
}
|
||||
|
||||
public static void load(GaeaPlugin main) {
|
||||
Logger logger = main.getLogger();
|
||||
logger.info("Loading config values");
|
||||
try(FileInputStream file = new FileInputStream(new File(main.getDataFolder(), "config.yml"))) {
|
||||
ConfigLoader loader = new ConfigLoader();
|
||||
loader.load(singleton, file);
|
||||
if(singleton.dumpDefaultConfig && !loaded) { // Don't dump default config if already loaded.
|
||||
try(JarFile jar = new JarFile(new File(Terra.class.getProtectionDomain().getCodeSource().getLocation().toURI()))) {
|
||||
JarUtil.copyResourcesToDirectory(jar, "packs", new File(main.getDataFolder(), "packs").toString());
|
||||
} catch(IOException | URISyntaxException e) {
|
||||
Debug.error("Failed to dump default config files!");
|
||||
e.printStackTrace();
|
||||
Debug.error("Report this to Terra!");
|
||||
}
|
||||
}
|
||||
loaded = true;
|
||||
} catch(ConfigException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
logger.info("Debug: " + isDebug());
|
||||
}
|
||||
|
||||
public static String getLanguage() {
|
||||
return singleton.language;
|
||||
}
|
||||
|
||||
public static boolean isDebug() {
|
||||
return singleton.debug;
|
||||
}
|
||||
|
||||
public static long getDataSaveInterval() {
|
||||
return singleton.dataSave.toMillis() / 20L;
|
||||
}
|
||||
|
||||
public static int getBiomeSearchResolution() {
|
||||
return singleton.biomeSearch;
|
||||
}
|
||||
|
||||
public static int getCacheSize() {
|
||||
return singleton.cacheSize;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.dfsek.terra.config.base;
|
||||
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.image.ImageLoader;
|
||||
import com.dfsek.terra.registry.ConfigRegistry;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
@@ -16,7 +17,7 @@ import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class WorldConfig {
|
||||
public class WorldConfig implements ConfigTemplate {
|
||||
private final String worldID;
|
||||
private final String configID;
|
||||
private final GaeaPlugin main;
|
||||
@@ -42,8 +43,6 @@ public class WorldConfig {
|
||||
FileConfiguration config = new YamlConfiguration();
|
||||
Debug.info("Loading config " + configID + " for world " + worldID);
|
||||
try { // Load/create world config file
|
||||
if(configID == null || configID.isEmpty())
|
||||
throw new ConfigException("Config pack unspecified in bukkit.yml!", worldID);
|
||||
File configFile = new File(main.getDataFolder() + File.separator + "worlds", worldID + ".yml");
|
||||
if(!configFile.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
@@ -56,10 +55,7 @@ public class WorldConfig {
|
||||
// Get values from config.
|
||||
fromImage = config.getBoolean("image.enable", false);
|
||||
|
||||
tConfig = ConfigPack.fromID(configID);
|
||||
|
||||
if(tConfig == null)
|
||||
throw new ConfigException("No such config pack: \"" + configID + "\". This pack either does not exist, or failed to load due to configuration errors.", worldID);
|
||||
tConfig = ConfigRegistry.getRegistry().get(configID);
|
||||
|
||||
// Load image stuff
|
||||
try {
|
||||
@@ -84,7 +80,7 @@ public class WorldConfig {
|
||||
} catch(IllegalArgumentException | NullPointerException e) {
|
||||
throw new InvalidConfigurationException(e.getCause());
|
||||
}
|
||||
Bukkit.getLogger().log(Level.INFO, "Loaded {0} BiomeGrids from list.", tConfig.biomeList.size());
|
||||
Bukkit.getLogger().log(Level.INFO, "Loaded {0} BiomeGrids from list.", tConfig.getTemplate().getGrids().size());
|
||||
} catch(IOException | InvalidConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
LangUtil.log("world-config.error", Level.SEVERE, worldID);
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.dfsek.terra.config.builder;
|
||||
|
||||
import com.dfsek.terra.biome.palette.PaletteHolder;
|
||||
import com.dfsek.terra.generation.config.NoiseBuilder;
|
||||
import com.dfsek.terra.generation.config.WorldGenerator;
|
||||
import parsii.eval.Scope;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class GeneratorBuilder {
|
||||
private final Map<Long, WorldGenerator> gens = new HashMap<>();
|
||||
|
||||
private String noiseEquation;
|
||||
|
||||
private String elevationEquation;
|
||||
|
||||
private Scope varScope;
|
||||
|
||||
private Map<String, NoiseBuilder> noiseBuilderMap;
|
||||
|
||||
private PaletteHolder palettes;
|
||||
|
||||
private PaletteHolder slantPalettes;
|
||||
|
||||
private boolean preventInterpolation;
|
||||
|
||||
private boolean interpolateElevation;
|
||||
|
||||
public WorldGenerator build(long seed) {
|
||||
return gens.computeIfAbsent(seed, k -> new WorldGenerator(seed, noiseEquation, elevationEquation, varScope, noiseBuilderMap, palettes, slantPalettes, preventInterpolation, interpolateElevation));
|
||||
}
|
||||
|
||||
public String getNoiseEquation() {
|
||||
return noiseEquation;
|
||||
}
|
||||
|
||||
public void setNoiseEquation(String noiseEquation) {
|
||||
this.noiseEquation = noiseEquation;
|
||||
}
|
||||
|
||||
public String getElevationEquation() {
|
||||
return elevationEquation;
|
||||
}
|
||||
|
||||
public void setElevationEquation(String elevationEquation) {
|
||||
this.elevationEquation = elevationEquation;
|
||||
}
|
||||
|
||||
public Scope getVarScope() {
|
||||
return varScope;
|
||||
}
|
||||
|
||||
public void setVarScope(Scope varScope) {
|
||||
this.varScope = varScope;
|
||||
}
|
||||
|
||||
public Map<String, NoiseBuilder> getNoiseBuilderMap() {
|
||||
return noiseBuilderMap;
|
||||
}
|
||||
|
||||
public void setNoiseBuilderMap(Map<String, NoiseBuilder> noiseBuilderMap) {
|
||||
this.noiseBuilderMap = noiseBuilderMap;
|
||||
}
|
||||
|
||||
public PaletteHolder getPalettes() {
|
||||
return palettes;
|
||||
}
|
||||
|
||||
public void setPalettes(PaletteHolder palettes) {
|
||||
this.palettes = palettes;
|
||||
}
|
||||
|
||||
public PaletteHolder getSlantPalettes() {
|
||||
return slantPalettes;
|
||||
}
|
||||
|
||||
public void setSlantPalettes(PaletteHolder slantPalettes) {
|
||||
this.slantPalettes = slantPalettes;
|
||||
}
|
||||
|
||||
public boolean isPreventInterpolation() {
|
||||
return preventInterpolation;
|
||||
}
|
||||
|
||||
public void setPreventInterpolation(boolean preventInterpolation) {
|
||||
this.preventInterpolation = preventInterpolation;
|
||||
}
|
||||
|
||||
public void setInterpolateElevation(boolean interpolateElevation) {
|
||||
this.interpolateElevation = interpolateElevation;
|
||||
}
|
||||
|
||||
public boolean interpolateElevation() {
|
||||
return interpolateElevation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.dfsek.terra.config.builder.biomegrid;
|
||||
|
||||
import com.dfsek.terra.config.base.WorldConfig;
|
||||
import org.bukkit.World;
|
||||
import org.polydev.gaea.biome.BiomeGrid;
|
||||
|
||||
public interface BiomeGridBuilder {
|
||||
BiomeGrid build(World world, WorldConfig config);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.dfsek.terra.config.builder.biomegrid;
|
||||
|
||||
import com.dfsek.terra.biome.grid.SingleBiomeGrid;
|
||||
import com.dfsek.terra.config.base.WorldConfig;
|
||||
import org.bukkit.World;
|
||||
import org.polydev.gaea.biome.Biome;
|
||||
|
||||
public class SingleGridBuilder implements BiomeGridBuilder {
|
||||
private final Biome biome;
|
||||
|
||||
public SingleGridBuilder(Biome biome) {
|
||||
this.biome = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleBiomeGrid build(World world, WorldConfig config) {
|
||||
return new SingleBiomeGrid(world, biome);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.dfsek.terra.config.builder.biomegrid;
|
||||
|
||||
import com.dfsek.terra.biome.grid.UserDefinedGrid;
|
||||
import com.dfsek.terra.config.base.WorldConfig;
|
||||
import org.bukkit.World;
|
||||
import org.polydev.gaea.biome.Biome;
|
||||
|
||||
public class UserDefinedGridBuilder implements BiomeGridBuilder {
|
||||
private double xFreq;
|
||||
private double zFreq;
|
||||
|
||||
private Biome[][] biomes;
|
||||
|
||||
@Override
|
||||
public UserDefinedGrid build(World world, WorldConfig config) {
|
||||
return new UserDefinedGrid(world, 1D / xFreq, 1D / zFreq, biomes, config);
|
||||
}
|
||||
|
||||
public double getXFreq() {
|
||||
return xFreq;
|
||||
}
|
||||
|
||||
public void setXFreq(double xFreq) {
|
||||
this.xFreq = xFreq;
|
||||
}
|
||||
|
||||
public double getZFreq() {
|
||||
return zFreq;
|
||||
}
|
||||
|
||||
public void setZFreq(double zFreq) {
|
||||
this.zFreq = zFreq;
|
||||
}
|
||||
|
||||
public Biome[][] getBiomes() {
|
||||
return biomes;
|
||||
}
|
||||
|
||||
public void setBiomes(Biome[][] biomes) {
|
||||
this.biomes = biomes;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.dfsek.terra.config.exception;
|
||||
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
|
||||
/**
|
||||
* Thrown when a config item is not valid.
|
||||
*/
|
||||
public class ConfigException extends InvalidConfigurationException {
|
||||
private static final long serialVersionUID = -4342864317005935979L;
|
||||
private final String message;
|
||||
private final String id;
|
||||
|
||||
public ConfigException(String message, String id) {
|
||||
this.message = message;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
String ex = getStackTrace()[0].getClassName();
|
||||
return "Configuration error for " + ex.substring(ex.lastIndexOf(".") + 1) + " with ID \"" + id + "\": \n\n" + message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.dfsek.terra.config.exception;
|
||||
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
|
||||
public class FileMissingException extends ConfigException {
|
||||
private static final long serialVersionUID = 4489395640246760802L;
|
||||
|
||||
public FileMissingException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public FileMissingException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.dfsek.terra.config.exception;
|
||||
|
||||
/**
|
||||
* Thrown when a required config item is not found.
|
||||
*/
|
||||
public class NotFoundException extends ConfigException {
|
||||
private static final long serialVersionUID = -3763471113262357426L;
|
||||
|
||||
public NotFoundException(String item, String itemName, String id) {
|
||||
super(item + " \"" + itemName + "\" cannot be found!", id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.builder.GeneratorBuilder;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.generation.UserDefinedDecorator;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
|
||||
public class BiomeFactory implements TerraFactory<BiomeTemplate, UserDefinedBiome> {
|
||||
private final ConfigPack pack;
|
||||
|
||||
public BiomeFactory(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDefinedBiome build(BiomeTemplate template) {
|
||||
UserDefinedDecorator decorator = new UserDefinedDecorator(new ProbabilityCollection<>(), new ProbabilityCollection<>(), 0, 0);
|
||||
GeneratorBuilder generatorBuilder = new GeneratorBuilder();
|
||||
generatorBuilder.setElevationEquation(template.getElevationEquation());
|
||||
generatorBuilder.setNoiseEquation(template.getNoiseEquation());
|
||||
generatorBuilder.setNoiseBuilderMap(template.getPack().getTemplate().getNoiseBuilderMap());
|
||||
generatorBuilder.setPalettes(template.getPalette());
|
||||
generatorBuilder.setSlantPalettes(template.getSlantPalette());
|
||||
generatorBuilder.setVarScope(pack.getVarScope());
|
||||
generatorBuilder.setInterpolateElevation(template.interpolateElevation());
|
||||
|
||||
|
||||
return new UserDefinedBiome(template.getVanilla(), decorator, generatorBuilder, template, pack);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.builder.biomegrid.BiomeGridBuilder;
|
||||
import com.dfsek.terra.config.builder.biomegrid.UserDefinedGridBuilder;
|
||||
import com.dfsek.terra.config.templates.BiomeGridTemplate;
|
||||
import org.polydev.gaea.biome.Biome;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BiomeGridFactory implements TerraFactory<BiomeGridTemplate, BiomeGridBuilder> {
|
||||
|
||||
@Override
|
||||
public UserDefinedGridBuilder build(BiomeGridTemplate config) {
|
||||
|
||||
UserDefinedGridBuilder holder = new UserDefinedGridBuilder();
|
||||
holder.setXFreq(config.getXFreq());
|
||||
holder.setZFreq(config.getZFreq());
|
||||
|
||||
int xSize = config.getGrid().size();
|
||||
int zSize = config.getGrid().get(0).size();
|
||||
|
||||
Biome[][] biomes = new UserDefinedBiome[xSize][zSize];
|
||||
|
||||
for(int x = 0; x < xSize; x++) {
|
||||
List<Biome> layer = config.getGrid().get(x);
|
||||
if(!(layer.size() == zSize)) throw new IllegalArgumentException();
|
||||
for(int z = 0; z < zSize; z++) {
|
||||
biomes[x][z] = layer.get(z);
|
||||
}
|
||||
}
|
||||
holder.setBiomes(biomes);
|
||||
|
||||
return holder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class CarverFactory implements TerraFactory<CarverTemplate, UserDefinedCarver> {
|
||||
private final ConfigPack pack;
|
||||
|
||||
public CarverFactory(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDefinedCarver build(CarverTemplate config) throws LoadException {
|
||||
double[] start = new double[] {config.getStartX(), config.getStartY(), config.getStartZ()};
|
||||
double[] mutate = new double[] {config.getMutateX(), config.getMutateY(), config.getMutateZ()};
|
||||
List<String> radius = Arrays.asList(config.getRadMX(), config.getRadMY(), config.getRadMZ());
|
||||
int hash = config.getID().hashCode();
|
||||
UserDefinedCarver carver;
|
||||
try {
|
||||
carver = new UserDefinedCarver(config.getHeight(), config.getLength(), start, mutate, radius, pack.getVarScope(), hash, config.getCutTop(), config.getCutBottom(), config);
|
||||
} catch(ParseException e) {
|
||||
throw new LoadException("Unable to parse radius equations", e);
|
||||
}
|
||||
carver.setRecalc(config.getRecalc());
|
||||
carver.setRecalcMagnitude(config.getRecaclulateMagnitude());
|
||||
return carver;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.terra.biome.palette.PaletteLayer;
|
||||
import com.dfsek.terra.config.templates.FloraTemplate;
|
||||
import com.dfsek.terra.generation.items.flora.TerraFlora;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.polydev.gaea.util.FastRandom;
|
||||
import org.polydev.gaea.world.Flora;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import org.polydev.gaea.world.palette.RandomPalette;
|
||||
|
||||
public class FloraFactory implements TerraFactory<FloraTemplate, Flora> {
|
||||
@Override
|
||||
public TerraFlora build(FloraTemplate config) {
|
||||
Palette<BlockData> palette = new RandomPalette<>(new FastRandom(2403));
|
||||
for(PaletteLayer layer : config.getFloraPalette()) {
|
||||
palette.add(layer.getLayer(), layer.getSize());
|
||||
}
|
||||
return new TerraFlora(palette, config.doPhysics(), config.isCeiling(), config.getIrrigable(), config.getSpawnable(), config.getReplaceable(), config.getMaxPlacements(), config.getSearch(), config.isSpawnBlacklist(), config.getIrrigableOffset());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.terra.config.templates.OreTemplate;
|
||||
import com.dfsek.terra.generation.items.ores.DeformedSphereOre;
|
||||
import com.dfsek.terra.generation.items.ores.Ore;
|
||||
import com.dfsek.terra.generation.items.ores.VanillaOre;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
public class OreFactory implements TerraFactory<OreTemplate, Ore> {
|
||||
@Override
|
||||
public Ore build(OreTemplate config) {
|
||||
BlockData m = config.getMaterial();
|
||||
switch(config.getType()) {
|
||||
case SPHERE:
|
||||
return new DeformedSphereOre(m, config.getReplaceable(), config.doPhysics(), config.getDeform(), config.getDeformFrequency(), config.getSize());
|
||||
case VANILLA:
|
||||
return new VanillaOre(m, config.getReplaceable(), config.doPhysics(), config.getSize());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.terra.biome.palette.PaletteLayer;
|
||||
import com.dfsek.terra.config.templates.PaletteTemplate;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
import org.polydev.gaea.util.FastRandom;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import org.polydev.gaea.world.palette.RandomPalette;
|
||||
import org.polydev.gaea.world.palette.SimplexPalette;
|
||||
|
||||
public class PaletteFactory implements TerraFactory<PaletteTemplate, Palette<BlockData>> {
|
||||
@Override
|
||||
public Palette<BlockData> build(PaletteTemplate config) {
|
||||
Palette<BlockData> palette;
|
||||
if(config.isSimplex()) {
|
||||
FastNoiseLite noise = new FastNoiseLite((int) config.getSeed());
|
||||
noise.setFrequency(config.getFrequency());
|
||||
palette = new SimplexPalette<>(noise);
|
||||
} else palette = new RandomPalette<>(new FastRandom(config.getSeed()));
|
||||
|
||||
for(PaletteLayer layer : config.getPalette()) {
|
||||
palette.add(layer.getLayer(), layer.getSize());
|
||||
}
|
||||
return palette;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.terra.config.templates.StructureTemplate;
|
||||
import com.dfsek.terra.generation.items.TerraStructure;
|
||||
|
||||
public class StructureFactory implements TerraFactory<StructureTemplate, TerraStructure> {
|
||||
@Override
|
||||
public TerraStructure build(StructureTemplate config) throws LoadException {
|
||||
return new TerraStructure(config.getStructures(), config.getBound(), config.getY(), config.getSpawn(), config.getLoot(), config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
|
||||
public interface TerraFactory<C extends ConfigTemplate, O> {
|
||||
O build(C config) throws LoadException;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.terra.config.templates.TreeTemplate;
|
||||
import com.dfsek.terra.generation.items.tree.TerraTree;
|
||||
import org.polydev.gaea.tree.Tree;
|
||||
|
||||
public class TreeFactory implements TerraFactory<TreeTemplate, Tree> {
|
||||
@Override
|
||||
public Tree build(TreeTemplate config) throws LoadException {
|
||||
return new TerraTree(config.getSpawnable(), config.getyOffset(), config.getStructures());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.dfsek.terra.config.files;
|
||||
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ExceptionalConsumer<T> {
|
||||
void accept(T t) throws ConfigException;
|
||||
}
|
||||
43
src/main/java/com/dfsek/terra/config/files/FolderLoader.java
Normal file
43
src/main/java/com/dfsek/terra/config/files/FolderLoader.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package com.dfsek.terra.config.files;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Load all {@code *.yml} files from a {@link java.nio.file.Path}.
|
||||
*/
|
||||
public class FolderLoader extends Loader {
|
||||
private final Path path;
|
||||
|
||||
public FolderLoader(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream get(String singleFile) throws IOException {
|
||||
return new FileInputStream(new File(path.toFile(), singleFile));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load(String directory) {
|
||||
File newPath = new File(path.toFile(), directory);
|
||||
newPath.mkdirs();
|
||||
try(Stream<Path> paths = Files.walk(newPath.toPath())) {
|
||||
paths.filter(Files::isRegularFile).filter(file -> file.toString().toLowerCase().endsWith(".yml")).forEach(file -> {
|
||||
try {
|
||||
streams.add(new FileInputStream(file.toFile()));
|
||||
} catch(FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
58
src/main/java/com/dfsek/terra/config/files/Loader.java
Normal file
58
src/main/java/com/dfsek/terra/config/files/Loader.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package com.dfsek.terra.config.files;
|
||||
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Loader {
|
||||
protected final List<InputStream> streams = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Do something with the InputStreams.
|
||||
*
|
||||
* @param consumer Something to do with the streams.
|
||||
*/
|
||||
public Loader then(ExceptionalConsumer<List<InputStream>> consumer) throws ConfigException {
|
||||
consumer.accept(streams);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single file from this Loader.
|
||||
*
|
||||
* @param singleFile File to get
|
||||
* @return InputStream from file.
|
||||
*/
|
||||
public abstract InputStream get(String singleFile) throws IOException;
|
||||
|
||||
/**
|
||||
* Open a subdirectory.
|
||||
*
|
||||
* @param directory Directory to open
|
||||
*/
|
||||
public Loader open(String directory) {
|
||||
if(streams.size() != 0) throw new IllegalStateException("Attempted to load new directory before closing existing InputStreams");
|
||||
load(directory);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected abstract void load(String directory);
|
||||
|
||||
/**
|
||||
* Close all InputStreams opened.
|
||||
*/
|
||||
public Loader close() {
|
||||
streams.forEach(input -> {
|
||||
try {
|
||||
input.close();
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
streams.clear();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
40
src/main/java/com/dfsek/terra/config/files/ZIPLoader.java
Normal file
40
src/main/java/com/dfsek/terra/config/files/ZIPLoader.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package com.dfsek.terra.config.files;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class ZIPLoader extends Loader {
|
||||
private final ZipFile file;
|
||||
|
||||
public ZIPLoader(ZipFile file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream get(String singleFile) throws IOException {
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if(!entry.isDirectory() && entry.getName().equals(singleFile)) return file.getInputStream(entry);
|
||||
}
|
||||
throw new IllegalArgumentException("No such file: " + singleFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load(String directory) {
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if(!entry.isDirectory() && entry.getName().startsWith(directory) && entry.getName().endsWith(".yml")) {
|
||||
try {
|
||||
streams.add(file.getInputStream(entry));
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.biome.grid.UserDefinedGrid;
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.base.WorldConfig;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BiomeGridConfig extends TerraConfig {
|
||||
private final String gridID;
|
||||
private final UserDefinedBiome[][] gridRaw;
|
||||
private final int sizeX;
|
||||
private final int sizeZ;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public BiomeGridConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||
super(file, config);
|
||||
load(file);
|
||||
if(!contains("id")) throw new ConfigException("Grid ID unspecified!", "null");
|
||||
this.gridID = getString("id");
|
||||
if(!contains("grid")) throw new ConfigException("Grid key not found!", getID());
|
||||
this.sizeX = Objects.requireNonNull(getList("grid")).size();
|
||||
this.sizeZ = ((List<List<String>>) Objects.requireNonNull(getList("grid"))).get(0).size();
|
||||
gridRaw = new UserDefinedBiome[sizeX][sizeZ];
|
||||
try {
|
||||
for(int x = 0; x < sizeX; x++) {
|
||||
for(int z = 0; z < sizeZ; z++) {
|
||||
try {
|
||||
gridRaw[x][z] = config.getBiome(((List<List<String>>) Objects.requireNonNull(getList("grid"))).get(x).get(z)).getBiome();
|
||||
} catch(NullPointerException e) {
|
||||
throw new NotFoundException("Biome", ((List<List<String>>) Objects.requireNonNull(getList("grid"))).get(x).get(z), getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(ClassCastException | NullPointerException e) {
|
||||
throw new ConfigException("Malformed grid! Ensure all dimensions are correct.", getID());
|
||||
}
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return gridID;
|
||||
}
|
||||
|
||||
public UserDefinedBiome[][] getBiomeGrid() {
|
||||
return gridRaw;
|
||||
}
|
||||
|
||||
public UserDefinedGrid getGrid(World w, WorldConfig wc) {
|
||||
ConfigPack c = wc.getConfig();
|
||||
return new UserDefinedGrid(w, c.freq1, c.freq2, gridRaw, wc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BiomeGrid with ID " + getID() + ", dimensions " + getSizeX() + ":" + getSizeZ();
|
||||
}
|
||||
|
||||
public int getSizeX() {
|
||||
return sizeX;
|
||||
}
|
||||
|
||||
public int getSizeZ() {
|
||||
return sizeZ;
|
||||
}
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
import org.polydev.gaea.math.Range;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class CarverConfig extends TerraConfig {
|
||||
private final UserDefinedCarver carver;
|
||||
private final String id;
|
||||
private final Set<Material> replaceableInner;
|
||||
private final Set<Material> replaceableOuter;
|
||||
private final Set<Material> replaceableTop;
|
||||
private final Set<Material> replaceableBottom;
|
||||
private final Set<Material> update;
|
||||
private final Map<Material, Set<Material>> shift;
|
||||
private final Map<Integer, ProbabilityCollection<BlockData>> inner;
|
||||
private final Map<Integer, ProbabilityCollection<BlockData>> outer;
|
||||
private final Map<Integer, ProbabilityCollection<BlockData>> top;
|
||||
private final Map<Integer, ProbabilityCollection<BlockData>> bottom;
|
||||
private final boolean replaceIsBlacklistInner;
|
||||
private final boolean replaceIsBlacklistOuter;
|
||||
private final boolean replaceIsBlacklistTop;
|
||||
private final boolean replaceIsBlacklistBottom;
|
||||
private final boolean updateOcean;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public CarverConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||
super(file, config);
|
||||
load(file);
|
||||
if(!contains("id")) throw new ConfigException("No ID specified for Carver!", "null");
|
||||
id = Objects.requireNonNull(getString("id"));
|
||||
|
||||
inner = getBlocks("palette.inner.layers");
|
||||
|
||||
outer = getBlocks("palette.outer.layers");
|
||||
|
||||
top = getBlocks("palette.top.layers");
|
||||
|
||||
bottom = getBlocks("palette.bottom.layers");
|
||||
|
||||
replaceableInner = ConfigUtil.toBlockData(getStringList("palette.inner.replace"), "replaceable inner", getID());
|
||||
|
||||
replaceableOuter = ConfigUtil.toBlockData(getStringList("palette.outer.replace"), "replaceable outer", getID());
|
||||
|
||||
replaceableTop = ConfigUtil.toBlockData(getStringList("palette.top.replace"), "replaceable top", getID());
|
||||
|
||||
replaceableBottom = ConfigUtil.toBlockData(getStringList("palette.bottom.replace"), "replaceable bottom", getID());
|
||||
|
||||
update = ConfigUtil.toBlockData(getStringList("update"), "update", getID());
|
||||
|
||||
updateOcean = getBoolean("update-liquids", false);
|
||||
|
||||
double step = getDouble("step", 2);
|
||||
Range recalc = new Range(getInt("recalculate-direction.min", 8), getInt("recalculate-direction.max", 12));
|
||||
double rm = getDouble("recalculate-magnitude", 4);
|
||||
shift = new HashMap<>();
|
||||
for(Map.Entry<String, Object> e : Objects.requireNonNull(getConfigurationSection("shift")).getValues(false).entrySet()) {
|
||||
Set<Material> l = EnumSet.noneOf(Material.class);
|
||||
for(String s : (List<String>) e.getValue()) {
|
||||
l.add(Bukkit.createBlockData(s).getMaterial());
|
||||
Debug.info("Added " + s + " to shift-able blocks");
|
||||
}
|
||||
shift.put(Bukkit.createBlockData(e.getKey()).getMaterial(), l);
|
||||
Debug.info("Added " + e.getKey() + " as master block");
|
||||
}
|
||||
|
||||
replaceIsBlacklistInner = getBoolean("palette.inner.replace-blacklist", false);
|
||||
replaceIsBlacklistOuter = getBoolean("palette.outer.replace-blacklist", false);
|
||||
replaceIsBlacklistTop = getBoolean("palette.top.replace-blacklist", false);
|
||||
replaceIsBlacklistBottom = getBoolean("palette.bottom.replace-blacklist", false);
|
||||
|
||||
double[] start = new double[] {getDouble("start.x"), getDouble("start.y"), getDouble("start.z")};
|
||||
double[] mutate = new double[] {getDouble("mutate.x"), getDouble("mutate.y"), getDouble("mutate.z"), getDouble("mutate.radius")};
|
||||
double[] radiusMultiplier = new double[] {getDouble("start.radius.multiply.x"), getDouble("start.radius.multiply.y"), getDouble("start.radius.multiply.z")};
|
||||
Range length = new Range(getInt("length.min"), getInt("length.max"));
|
||||
Range radius = new Range(getInt("start.radius.min"), getInt("start.radius.max"));
|
||||
Range height = new Range(getInt("start.height.min"), getInt("start.height.max"));
|
||||
|
||||
carver = new UserDefinedCarver(height, radius, length, start, mutate, radiusMultiplier, id.hashCode(), getInt("cut.top", 0), getInt("cut.bottom", 0));
|
||||
carver.setStep(step);
|
||||
carver.setRecalc(recalc);
|
||||
carver.setRecalcMagnitude(rm);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<Integer, ProbabilityCollection<BlockData>> getBlocks(String key) throws InvalidConfigurationException {
|
||||
if(!contains(key)) throw new ConfigException("Missing Carver Palette!", getID());
|
||||
Map<Integer, ProbabilityCollection<BlockData>> result = new TreeMap<>();
|
||||
for(Map<?, ?> m : getMapList(key)) {
|
||||
try {
|
||||
ProbabilityCollection<BlockData> layer = new ProbabilityCollection<>();
|
||||
for(Map.Entry<String, Integer> type : ((Map<String, Integer>) m.get("materials")).entrySet()) {
|
||||
layer.add(Bukkit.createBlockData(type.getKey()), type.getValue());
|
||||
Debug.info("Added " + type.getKey() + " with probability " + type.getValue());
|
||||
}
|
||||
result.put((Integer) m.get("y"), layer);
|
||||
Debug.info("Added at level " + m.get("y"));
|
||||
} catch(ClassCastException e) {
|
||||
throw new ConfigException("Unable to parse Carver Palette configuration! Check YAML syntax:" + e.getMessage(), getID());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public UserDefinedCarver getCarver() {
|
||||
return carver;
|
||||
}
|
||||
|
||||
public Map<Material, Set<Material>> getShiftedBlocks() {
|
||||
return shift;
|
||||
}
|
||||
|
||||
public Set<Material> getUpdateBlocks() {
|
||||
return update;
|
||||
}
|
||||
|
||||
public boolean isReplaceableInner(Material m) {
|
||||
if(replaceIsBlacklistInner) {
|
||||
return !replaceableInner.contains(m);
|
||||
}
|
||||
return replaceableInner.contains(m);
|
||||
}
|
||||
|
||||
public boolean isReplaceableOuter(Material m) {
|
||||
if(replaceIsBlacklistOuter) {
|
||||
return !replaceableOuter.contains(m);
|
||||
}
|
||||
return replaceableOuter.contains(m);
|
||||
}
|
||||
|
||||
public boolean isReplaceableTop(Material m) {
|
||||
if(replaceIsBlacklistTop) {
|
||||
return !replaceableTop.contains(m);
|
||||
}
|
||||
return replaceableTop.contains(m);
|
||||
}
|
||||
|
||||
public boolean isReplaceableBottom(Material m) {
|
||||
if(replaceIsBlacklistBottom) {
|
||||
return !replaceableBottom.contains(m);
|
||||
}
|
||||
return replaceableBottom.contains(m);
|
||||
}
|
||||
|
||||
public ProbabilityCollection<BlockData> getPaletteInner(int y) {
|
||||
for(Map.Entry<Integer, ProbabilityCollection<BlockData>> e : inner.entrySet()) {
|
||||
if(e.getKey() >= y) return e.getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ProbabilityCollection<BlockData> getPaletteOuter(int y) {
|
||||
for(Map.Entry<Integer, ProbabilityCollection<BlockData>> e : outer.entrySet()) {
|
||||
if(e.getKey() >= y) return e.getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ProbabilityCollection<BlockData> getPaletteBottom(int y) {
|
||||
for(Map.Entry<Integer, ProbabilityCollection<BlockData>> e : bottom.entrySet()) {
|
||||
if(e.getKey() >= y) return e.getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ProbabilityCollection<BlockData> getPaletteTop(int y) {
|
||||
for(Map.Entry<Integer, ProbabilityCollection<BlockData>> e : top.entrySet()) {
|
||||
if(e.getKey() >= y) return e.getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean shouldUpdateOcean() {
|
||||
return updateOcean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Carver with ID " + getID();
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import net.jafama.FastMath;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.polydev.gaea.math.Range;
|
||||
import org.polydev.gaea.util.FastRandom;
|
||||
import org.polydev.gaea.world.Flora;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import org.polydev.gaea.world.palette.RandomPalette;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class FloraConfig extends TerraConfig implements Flora {
|
||||
private final Palette<BlockData> floraPalette;
|
||||
private final String id;
|
||||
private final boolean physics;
|
||||
private final boolean ceiling;
|
||||
|
||||
private final Set<Material> irrigable;
|
||||
|
||||
private final Set<Material> spawnable;
|
||||
private final Set<Material> replaceable;
|
||||
|
||||
public FloraConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||
super(file, config);
|
||||
load(file);
|
||||
if(!contains("id")) throw new ConfigException("Flora ID unspecified!", "null");
|
||||
this.id = getString("id");
|
||||
if(!contains("layers")) throw new ConfigException("No blocks defined in custom flora!", getID());
|
||||
if(!contains("spawnable")) throw new ConfigException("Flora spawnable blocks unspecified!", getID());
|
||||
|
||||
spawnable = ConfigUtil.toBlockData(getStringList("spawnable"), "spawnable", getID());
|
||||
replaceable = ConfigUtil.toBlockData(getStringList("replaceable"), "replaceable", getID());
|
||||
|
||||
if(contains("irrigable")) {
|
||||
irrigable = ConfigUtil.toBlockData(getStringList("irrigable"), "irrigable", getID());
|
||||
} else irrigable = null;
|
||||
|
||||
physics = getBoolean("physics", false);
|
||||
ceiling = getBoolean("ceiling", false);
|
||||
|
||||
Palette<BlockData> p = new RandomPalette<>(new FastRandom(getInt("seed", 4)));
|
||||
|
||||
floraPalette = PaletteConfig.getPalette(getMapList("layers"), p);
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Block> getValidSpawnsAt(Chunk chunk, int x, int z, Range range) {
|
||||
int size = floraPalette.getSize();
|
||||
Block current = chunk.getBlock(x, range.getMin(), z);
|
||||
List<Block> blocks = new ArrayList<>();
|
||||
for(int y : range) {
|
||||
if(y > 255 || y < 0) continue;
|
||||
current = current.getRelative(BlockFace.UP);
|
||||
if(spawnable.contains(current.getType()) && isIrrigated(current) && valid(size, current)) {
|
||||
blocks.add(current);
|
||||
}
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
private boolean valid(int size, Block block) {
|
||||
for(int i = 0; i < size; i++) { // Down if ceiling, up if floor
|
||||
if(block.getY() + 1 > 255 || block.getY() < 0) return false;
|
||||
block = block.getRelative(ceiling ? BlockFace.DOWN : BlockFace.UP);
|
||||
if(!replaceable.contains(block.getType())) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isIrrigated(Block b) {
|
||||
if(irrigable == null) return true;
|
||||
return irrigable.contains(b.getRelative(BlockFace.NORTH).getType())
|
||||
|| irrigable.contains(b.getRelative(BlockFace.SOUTH).getType())
|
||||
|| irrigable.contains(b.getRelative(BlockFace.EAST).getType())
|
||||
|| irrigable.contains(b.getRelative(BlockFace.WEST).getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean plant(Location location) {
|
||||
int size = floraPalette.getSize();
|
||||
int c = ceiling ? -1 : 1;
|
||||
for(int i = 0; FastMath.abs(i) < size; i += c) { // Down if ceiling, up if floor
|
||||
int lvl = (FastMath.abs(i));
|
||||
location.clone().add(0, i + c, 0).getBlock().setBlockData(floraPalette.get((ceiling ? lvl : size - lvl - 1), location.getBlockX(), location.getBlockZ()), physics);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Flora with name ID " + getID();
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import net.jafama.FastMath;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
import org.polydev.gaea.population.ChunkCoordinate;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class OreConfig extends TerraConfig {
|
||||
private final BlockData oreData;
|
||||
private final int min;
|
||||
private final int max;
|
||||
private final double deform;
|
||||
private final double deformFrequency;
|
||||
private final String id;
|
||||
private final boolean update;
|
||||
Set<Material> replaceable;
|
||||
|
||||
public OreConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||
super(file, config);
|
||||
if(!contains("id")) throw new ConfigException("Ore ID not found!", "null");
|
||||
this.id = getString("id");
|
||||
if(!contains("material")) throw new ConfigException("Ore material not found!", getID());
|
||||
if(!contains("deform")) throw new ConfigException("Ore vein deformation not found!", getID());
|
||||
if(!contains("replace")) throw new ConfigException("Ore replaceable materials not found!", getID());
|
||||
min = getInt("radius.min", 1);
|
||||
max = getInt("radius.max", 1);
|
||||
deform = getDouble("deform", 0.75);
|
||||
deformFrequency = getDouble("deform-frequency", 0.1);
|
||||
update = getBoolean("update", false);
|
||||
|
||||
replaceable = ConfigUtil.toBlockData(getStringList("replace"), "replaceable", getID());
|
||||
|
||||
try {
|
||||
oreData = Bukkit.createBlockData(Objects.requireNonNull(getString("material")));
|
||||
} catch(NullPointerException | IllegalArgumentException e) {
|
||||
throw new ConfigException("Invalid ore material: " + getString("material"), getID());
|
||||
}
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void doVein(Vector l, Chunk chunk, Random r) {
|
||||
FastNoiseLite ore = new FastNoiseLite(r.nextInt());
|
||||
ore.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
ore.setFrequency(deformFrequency);
|
||||
int rad = randomInRange(r);
|
||||
Map<ChunkCoordinate, Chunk> chunks = new HashMap<>(); // Cache chunks to prevent re-loading chunks every time one is needed.
|
||||
chunks.put(new ChunkCoordinate(chunk), chunk);
|
||||
Vector orig = new Vector(l.getBlockX() + (chunk.getX() << 4), l.getBlockY(), l.getBlockZ() + (chunk.getZ() << 4));
|
||||
for(int x = -rad; x <= rad; x++) {
|
||||
for(int y = -rad; y <= rad; y++) {
|
||||
for(int z = -rad; z <= rad; z++) {
|
||||
Vector oreLoc = orig.clone().add(new Vector(x, y, z));
|
||||
Vector source = l.clone().add(new Vector(x, y, z));
|
||||
if(oreLoc.getBlockY() > 255 || oreLoc.getBlockY() < 0) continue;
|
||||
if(source.distance(l) < (rad + 0.5) * ((ore.getNoise(x, y, z) + 1) * deform)) {
|
||||
ChunkCoordinate coord = new ChunkCoordinate(FastMath.floorDiv(oreLoc.getBlockX(), 16), FastMath.floorDiv(oreLoc.getBlockZ(), 16), chunk.getWorld().getUID());
|
||||
Block b = chunks.computeIfAbsent(coord, k -> chunk.getWorld().getChunkAt(oreLoc.toLocation(chunk.getWorld())))
|
||||
.getBlock(FastMath.floorMod(source.getBlockX(), 16), source.getBlockY(), FastMath.floorMod(source.getBlockZ(), 16)); // Chunk caching conditional computation
|
||||
if(replaceable.contains(b.getType()) && b.getLocation().getY() >= 0)
|
||||
b.setBlockData(oreData, update);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int randomInRange(Random r) {
|
||||
return r.nextInt(max - min + 1) + min;
|
||||
}
|
||||
|
||||
public void doVeinSingle(Vector l, Chunk chunk, Random r) {
|
||||
FastNoiseLite ore = new FastNoiseLite(r.nextInt());
|
||||
ore.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
ore.setFrequency(deformFrequency);
|
||||
int rad = randomInRange(r);
|
||||
for(int x = -rad; x <= rad; x++) {
|
||||
for(int y = -rad; y <= rad; y++) {
|
||||
for(int z = -rad; z <= rad; z++) {
|
||||
Vector oreLoc = l.clone().add(new Vector(x, y, z));
|
||||
if(oreLoc.getBlockX() > 15 || oreLoc.getBlockZ() > 15 || oreLoc.getBlockY() > 255 || oreLoc.getBlockX() < 0 || oreLoc.getBlockZ() < 0 || oreLoc.getBlockY() < 0)
|
||||
continue;
|
||||
if(oreLoc.distance(l) < (rad + 0.5) * ((ore.getNoise(x, y, z) + 1) * deform)) {
|
||||
Block b = chunk.getBlock(oreLoc.getBlockX(), oreLoc.getBlockY(), oreLoc.getBlockZ());
|
||||
if(replaceable.contains(b.getType()) && b.getLocation().getY() >= 0)
|
||||
b.setBlockData(oreData, update);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Ore with ID " + getID();
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
import org.polydev.gaea.util.FastRandom;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import org.polydev.gaea.world.palette.RandomPalette;
|
||||
import org.polydev.gaea.world.palette.SimplexPalette;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PaletteConfig extends TerraConfig {
|
||||
private final Palette<BlockData> palette;
|
||||
private final String paletteID;
|
||||
private boolean useNoise = false;
|
||||
|
||||
public PaletteConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||
super(file, config);
|
||||
if(!contains("id")) throw new ConfigException("Palette ID unspecified!", "null");
|
||||
this.paletteID = getString("id");
|
||||
Palette<BlockData> pal;
|
||||
if(getBoolean("simplex", false)) {
|
||||
useNoise = true;
|
||||
FastNoiseLite pNoise = new FastNoiseLite(getInt("seed", 2403));
|
||||
pNoise.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
pNoise.setFractalOctaves(4);
|
||||
pNoise.setFrequency(getDouble("frequency", 0.02));
|
||||
pal = new SimplexPalette<>(pNoise);
|
||||
} else pal = new RandomPalette<>(new FastRandom(getInt("seed", 2403)));
|
||||
palette = getPalette(getMapList("layers"), pal);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static Palette<BlockData> getPalette(List<Map<?, ?>> maps, Palette<BlockData> p) throws InvalidConfigurationException {
|
||||
for(Map<?, ?> m : maps) {
|
||||
try {
|
||||
ProbabilityCollection<BlockData> layer = new ProbabilityCollection<>();
|
||||
List<Map<?, ?>> map = (List<Map<?, ?>>) m.get("materials");
|
||||
if(map.size() > 1) {
|
||||
for(Map<?, ?> entry : map) {
|
||||
for(Map.Entry<?, ?> type : entry.entrySet()) {
|
||||
layer.add(Bukkit.createBlockData((String) type.getKey()), (Integer) type.getValue());
|
||||
}
|
||||
}
|
||||
p.add(layer, (Integer) m.get("layers"));
|
||||
} else {
|
||||
Debug.info("One-block palette layer!");
|
||||
String data = "null";
|
||||
for(Map.Entry<?, ?> e : map.get(0).entrySet()) {
|
||||
data = (String) e.getKey();
|
||||
}
|
||||
p.add(Bukkit.createBlockData(data), (Integer) m.get("layers"));
|
||||
}
|
||||
} catch(ClassCastException e) {
|
||||
throw new InvalidConfigurationException("SEVERE configuration error for Palette: \n\n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Palette with ID " + getID() + " with " + getPalette().getSize() + " layers, using Simplex: " + useNoise;
|
||||
}
|
||||
|
||||
public Palette<BlockData> getPalette() {
|
||||
return palette;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return paletteID;
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import com.dfsek.terra.procgen.math.Vector2;
|
||||
import com.dfsek.terra.structure.Rotation;
|
||||
import com.dfsek.terra.structure.Structure;
|
||||
import com.dfsek.terra.structure.StructureContainedBlock;
|
||||
import com.dfsek.terra.structure.StructureInfo;
|
||||
import com.dfsek.terra.util.structure.RotationUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
import org.polydev.gaea.tree.Tree;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class TreeConfig extends TerraConfig implements Tree {
|
||||
private final Set<Material> spawnable;
|
||||
private final String id;
|
||||
private final int yOffset;
|
||||
private final ProbabilityCollection<Structure> structure = new ProbabilityCollection<>();
|
||||
|
||||
public TreeConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||
super(file, config);
|
||||
spawnable = ConfigUtil.toBlockData(getStringList("spawnable"), "spawnable", getID());
|
||||
if(!contains("id")) throw new ConfigException("No ID specified!", "null");
|
||||
id = getString("id");
|
||||
if(!contains("files")) throw new ConfigException("No files specified!", getID());
|
||||
yOffset = getInt("y-offset", 0);
|
||||
try {
|
||||
for(Map.Entry<String, Object> e : Objects.requireNonNull(getConfigurationSection("files")).getValues(false).entrySet()) {
|
||||
try {
|
||||
File structureFile = new File(config.getDataFolder() + File.separator + "trees" + File.separator + "data", e.getKey() + ".tstructure");
|
||||
structure.add(Structure.load(structureFile), (Integer) e.getValue());
|
||||
} catch(FileNotFoundException ex) {
|
||||
Debug.stack(ex);
|
||||
throw new NotFoundException("Tree Structure File", e.getKey(), getID());
|
||||
} catch(ClassCastException ex) {
|
||||
Debug.stack(ex);
|
||||
throw new ConfigException("Unable to parse Tree configuration! Check YAML syntax.", getID());
|
||||
}
|
||||
}
|
||||
} catch(IOException | NullPointerException e) {
|
||||
if(ConfigUtil.debug) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new NotFoundException("Tree Structure", getString("file"), getID());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean plant(Location location, Random random, JavaPlugin javaPlugin) {
|
||||
location.subtract(0, 1, 0);
|
||||
Location mut = location.clone().subtract(0, yOffset, 0);
|
||||
if(!spawnable.contains(location.getBlock().getType())) return false;
|
||||
Structure struc = structure.get(random);
|
||||
Rotation rotation = Rotation.fromDegrees(random.nextInt(4) * 90);
|
||||
if(!struc.checkSpawns(mut, rotation)) return false;
|
||||
struc.paste(mut, rotation);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean plantBlockCheck(Location location, Random random) {
|
||||
location.subtract(0, 1, 0);
|
||||
Location mut = location.clone().subtract(0, yOffset, 0);
|
||||
if(!spawnable.contains(location.getBlock().getType())) return false;
|
||||
Structure struc = structure.get(random);
|
||||
Rotation rotation = Rotation.fromDegrees(random.nextInt(4) * 90);
|
||||
StructureInfo info = struc.getStructureInfo();
|
||||
for(StructureContainedBlock spawn : struc.getSpawns()) {
|
||||
Vector2 rot = RotationUtil.getRotatedCoords(new Vector2(spawn.getX() - info.getCenterX(), spawn.getZ() - info.getCenterZ()), rotation);
|
||||
int x = (int) rot.getX();
|
||||
int z = (int) rot.getZ();
|
||||
switch(spawn.getRequirement()) {
|
||||
case AIR:
|
||||
if(!mut.clone().add(x, spawn.getY() - 1, z).getBlock().isPassable()) return false;
|
||||
break;
|
||||
case LAND:
|
||||
if(!mut.clone().add(x, spawn.getY() - 1, z).getBlock().getType().isSolid()) return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
struc.paste(mut, rotation);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.biome;
|
||||
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class AbstractBiomeConfig extends TerraConfig {
|
||||
private final String biomeID;
|
||||
private final String equation;
|
||||
private final int seaLevel;
|
||||
private BiomeSlabConfig slabs;
|
||||
private List<String> structureConfigs;
|
||||
private BiomePaletteConfig palette;
|
||||
private BiomeFloraConfig flora;
|
||||
private BiomeCarverConfig carving;
|
||||
private BiomeTreeConfig trees;
|
||||
private BiomeOreConfig ores;
|
||||
private BiomeOceanConfig ocean;
|
||||
private BiomeSnowConfig snow;
|
||||
|
||||
public AbstractBiomeConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||
super(file, config);
|
||||
load(file);
|
||||
if(!contains("id")) throw new ConfigException("Abstract Biome ID unspecified!", "null");
|
||||
this.biomeID = getString("id");
|
||||
|
||||
equation = getString("noise-equation");
|
||||
seaLevel = getInt("ocean.level", 62);
|
||||
|
||||
if(contains("carving")) carving = new BiomeCarverConfig(this);
|
||||
|
||||
if(contains("palette")) palette = new BiomePaletteConfig(this, "palette");
|
||||
|
||||
if(contains("flora")) flora = new BiomeFloraConfig(this);
|
||||
|
||||
if(contains("trees")) trees = new BiomeTreeConfig(this);
|
||||
|
||||
if(contains("ores")) ores = new BiomeOreConfig(this);
|
||||
|
||||
if(contains("ocean")) ocean = new BiomeOceanConfig(this);
|
||||
|
||||
if(contains("slabs") && getBoolean("slabs.enable", false)) slabs = new BiomeSlabConfig(this);
|
||||
|
||||
if(contains("structures")) structureConfigs = getStringList("structures");
|
||||
|
||||
if(contains("snow")) snow = new BiomeSnowConfig(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return biomeID;
|
||||
}
|
||||
|
||||
public String getEquation() {
|
||||
return equation;
|
||||
}
|
||||
|
||||
public BiomePaletteConfig getPaletteData() {
|
||||
return palette;
|
||||
}
|
||||
|
||||
public BiomeFloraConfig getFlora() {
|
||||
return flora;
|
||||
}
|
||||
|
||||
public BiomeCarverConfig getCarving() {
|
||||
return carving;
|
||||
}
|
||||
|
||||
public BiomeTreeConfig getTrees() {
|
||||
return trees;
|
||||
}
|
||||
|
||||
public BiomeOreConfig getOres() {
|
||||
return ores;
|
||||
}
|
||||
|
||||
public BiomeSlabConfig getSlabs() {
|
||||
return slabs;
|
||||
}
|
||||
|
||||
public BiomeOceanConfig getOcean() {
|
||||
return ocean;
|
||||
}
|
||||
|
||||
public int getSeaLevel() {
|
||||
return seaLevel;
|
||||
}
|
||||
|
||||
public List<String> getStructureConfigs() {
|
||||
return structureConfigs;
|
||||
}
|
||||
|
||||
public BiomeSnowConfig getSnow() {
|
||||
return snow;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.biome;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.TerraConfigSection;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import com.dfsek.terra.config.genconfig.CarverConfig;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class BiomeCarverConfig extends TerraConfigSection {
|
||||
private final Map<CarverConfig, Integer> carvers = new HashMap<>();
|
||||
|
||||
public BiomeCarverConfig(TerraConfig parent) throws InvalidConfigurationException {
|
||||
super(parent);
|
||||
ConfigurationSection configurationSection = parent.getConfigurationSection("carving");
|
||||
|
||||
Map<String, Object> cfg;
|
||||
if(configurationSection != null) {
|
||||
cfg = configurationSection.getValues(false);
|
||||
} else return;
|
||||
if(cfg.size() == 0) return;
|
||||
for(Map.Entry<String, Object> entry : cfg.entrySet()) {
|
||||
try {
|
||||
CarverConfig c = parent.getConfig().getCarver(entry.getKey());
|
||||
if(c == null) throw new NotFoundException("Carver", entry.getKey(), parent.getID());
|
||||
Debug.info("Got carver " + c + ". Adding with weight " + entry.getValue());
|
||||
carvers.put(c, (Integer) entry.getValue());
|
||||
} catch(ClassCastException ex) {
|
||||
throw new ConfigException("Unable to parse Carver configuration! Check YAML syntax.", parent.getID());
|
||||
} catch(NullPointerException ex) {
|
||||
throw new NotFoundException("carver", entry.getKey(), parent.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<CarverConfig, Integer> getCarvers() {
|
||||
return carvers;
|
||||
}
|
||||
}
|
||||
@@ -1,237 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.biome;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.generation.UserDefinedDecorator;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.polydev.gaea.math.Range;
|
||||
import org.polydev.gaea.tree.Tree;
|
||||
import org.polydev.gaea.world.Flora;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class BiomeConfig extends TerraConfig {
|
||||
|
||||
private final UserDefinedBiome biome;
|
||||
private final String biomeID;
|
||||
private final BiomeOreConfig ore;
|
||||
private final BiomeCarverConfig carver;
|
||||
private final BiomeFloraConfig flora;
|
||||
private final BiomeTreeConfig tree;
|
||||
private final BiomeOceanConfig ocean;
|
||||
private final BiomeSlabConfig slab;
|
||||
private final BiomeSnowConfig snow;
|
||||
private final List<StructureConfig> structures;
|
||||
private final ConfigPack config;
|
||||
private final double ySlantOffsetTop;
|
||||
private final double ySlantOffsetBottom;
|
||||
|
||||
private String eq;
|
||||
|
||||
public BiomeConfig(File file, ConfigPack config) throws InvalidConfigurationException, IOException {
|
||||
super(file, config);
|
||||
load(file);
|
||||
this.config = config;
|
||||
if(!contains("id")) throw new ConfigException("Biome ID unspecified!", "null");
|
||||
this.biomeID = getString("id");
|
||||
|
||||
AbstractBiomeConfig abstractBiome = null;
|
||||
// Whether an abstract biome is to be extended. Default to false.
|
||||
boolean extending = false;
|
||||
// Check if biome extends an abstract biome, load abstract biome if so.
|
||||
if(contains("extends")) {
|
||||
try {
|
||||
abstractBiome = config.getAbstractBiomes().get(getString("extends"));
|
||||
if(abstractBiome == null) throw new NotFoundException("Abstract Biome", getString("extends"), getID());
|
||||
extending = true;
|
||||
Debug.info("Extending biome " + getString("extends"));
|
||||
} catch(NullPointerException e) {
|
||||
throw new NotFoundException("Abstract Biome", getString("extends"), getID());
|
||||
}
|
||||
}
|
||||
|
||||
// Get various simple values using getOrDefault config methods.
|
||||
try {
|
||||
eq = getString("noise-equation", Objects.requireNonNull(abstractBiome).getEquation());
|
||||
} catch(NullPointerException e) {
|
||||
eq = getString("noise-equation", null);
|
||||
}
|
||||
|
||||
BiomePaletteConfig palette;
|
||||
// Check if biome is extending abstract biome, only use abstract biome's palette if palette is NOT defined for current biome.
|
||||
if(extending && abstractBiome.getPaletteData() != null && !contains("palette")) {
|
||||
palette = abstractBiome.getPaletteData();
|
||||
Debug.info("Using super palette");
|
||||
} else palette = new BiomePaletteConfig(this, "palette");
|
||||
|
||||
// Palette must not be null
|
||||
if(palette.getPaletteMap() == null)
|
||||
throw new ConfigException("No Palette specified in biome or super biome.", getID());
|
||||
|
||||
// Check if carving should be handled by super biome.
|
||||
if(extending && abstractBiome.getCarving() != null && !contains("carving")) {
|
||||
carver = abstractBiome.getCarving();
|
||||
Debug.info("Using super carvers");
|
||||
} else carver = new BiomeCarverConfig(this);
|
||||
|
||||
// Check if flora should be handled by super biome.
|
||||
if(extending && abstractBiome.getFlora() != null && !contains("flora")) {
|
||||
flora = abstractBiome.getFlora();
|
||||
Debug.info("Using super flora (" + flora.getFlora().size() + " entries, " + flora.getFloraChance() + " % chance)");
|
||||
} else flora = new BiomeFloraConfig(this);
|
||||
|
||||
// Check if trees should be handled by super biome.
|
||||
if(extending && abstractBiome.getTrees() != null && !contains("trees")) {
|
||||
tree = abstractBiome.getTrees();
|
||||
Debug.info("Using super trees");
|
||||
} else tree = new BiomeTreeConfig(this);
|
||||
|
||||
// Check if ores should be handled by super biome.
|
||||
if(extending && abstractBiome.getOres() != null && !contains("ores")) {
|
||||
ore = abstractBiome.getOres();
|
||||
Debug.info("Using super ores");
|
||||
} else ore = new BiomeOreConfig(this);
|
||||
|
||||
// Get slab stuff
|
||||
if(extending && abstractBiome.getSlabs() != null && !contains("slabs")) {
|
||||
slab = abstractBiome.getSlabs();
|
||||
Debug.info("Using super slabs");
|
||||
} else slab = new BiomeSlabConfig(this);
|
||||
|
||||
// Get ocean stuff
|
||||
if(extending && abstractBiome.getOcean() != null) {
|
||||
ocean = abstractBiome.getOcean();
|
||||
Debug.info("Using super ocean");
|
||||
} else ocean = new BiomeOceanConfig(this);
|
||||
|
||||
// Get ocean stuff
|
||||
if(extending && abstractBiome.getSnow() != null) {
|
||||
snow = abstractBiome.getSnow();
|
||||
Debug.info("Using super snow");
|
||||
} else snow = new BiomeSnowConfig(this);
|
||||
|
||||
// Get slant stuff
|
||||
TreeMap<Integer, Palette<BlockData>> slant = new TreeMap<>();
|
||||
if(contains("slant")) {
|
||||
String slantS = getString("slant.palette");
|
||||
slant = new BiomePaletteConfig(this, "slant.palette").getPaletteMap();
|
||||
Debug.info("Using slant palette: " + slantS);
|
||||
if(slant == null) throw new NotFoundException("Slant Palette", slantS, getID());
|
||||
}
|
||||
ySlantOffsetTop = getDouble("slant.y-offset.top", 0.25);
|
||||
ySlantOffsetBottom = getDouble("slant.y-offset.bottom", 0.25);
|
||||
|
||||
//Make sure equation is non-null
|
||||
if(eq == null || eq.isEmpty())
|
||||
throw new ConfigException("Could not find noise equation! Biomes must include a noise equation, or extend an abstract biome with one.", getID());
|
||||
|
||||
// Create decorator for this config.
|
||||
UserDefinedDecorator dec = new UserDefinedDecorator(flora.getFlora(), tree.getTrees(), flora.getFloraChance(), tree.getTreeDensity());
|
||||
|
||||
// Get Vanilla biome, throw exception if it is invalid/unspecified.
|
||||
org.bukkit.block.Biome vanillaBiome;
|
||||
try {
|
||||
if(!contains("vanilla")) throw new ConfigException("Vanilla Biome unspecified!", getID());
|
||||
vanillaBiome = org.bukkit.block.Biome.valueOf(getString("vanilla"));
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new ConfigException("Invalid Vanilla biome: \"" + getString("vanilla") + "\"", getID());
|
||||
}
|
||||
|
||||
// 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(config.getStructure(s)));
|
||||
} catch(NullPointerException e) {
|
||||
throw new NotFoundException("Structure", s, getID());
|
||||
}
|
||||
}
|
||||
|
||||
String elevation = getString("elevation.equation", null);
|
||||
boolean doElevationInterpolation = getBoolean("elevation.interpolation", true);
|
||||
|
||||
try {
|
||||
// Get UserDefinedBiome instance representing this config.
|
||||
GeneratorOptions gen = new GeneratorOptions(eq, elevation, config.getVariableScope(), palette.getPaletteMap(), slant, config.getNoiseBuilders(), getBoolean("prevent-smooth", false), doElevationInterpolation);
|
||||
this.biome = new UserDefinedBiome(vanillaBiome, dec, gen, getBoolean("erodible", false), this);
|
||||
} catch(ParseException e) {
|
||||
e.printStackTrace();
|
||||
throw new ConfigException("Unable to parse noise equation!", getID());
|
||||
}
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return biomeID;
|
||||
}
|
||||
|
||||
public UserDefinedBiome getBiome() {
|
||||
return biome;
|
||||
}
|
||||
|
||||
public BiomeOreConfig getOres() {
|
||||
return ore;
|
||||
}
|
||||
|
||||
public Range getFloraHeights(Flora f) {
|
||||
return flora.getFloraHeights().computeIfAbsent(f, input -> new Range(-1, -1));
|
||||
}
|
||||
|
||||
public double getYSlantOffsetTop() {
|
||||
return ySlantOffsetTop;
|
||||
}
|
||||
|
||||
public double getYSlantOffsetBottom() {
|
||||
return ySlantOffsetBottom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Biome with ID " + getID() + " and noise equation " + eq;
|
||||
}
|
||||
|
||||
public int getCarverChance(UserDefinedCarver c) {
|
||||
return carver.getCarvers().getOrDefault(config.getCarver(c), 0);
|
||||
}
|
||||
|
||||
public BiomeSlabConfig getSlabs() {
|
||||
return slab;
|
||||
}
|
||||
|
||||
public BiomeOceanConfig getOcean() {
|
||||
return ocean;
|
||||
}
|
||||
|
||||
public BiomeFloraConfig getFlora() {
|
||||
return flora;
|
||||
}
|
||||
|
||||
public List<StructureConfig> getStructures() {
|
||||
return structures;
|
||||
}
|
||||
|
||||
public Range getTreeRange(Tree t) {
|
||||
return tree.getTreeHeights().getOrDefault(t, new Range(-1, -1));
|
||||
}
|
||||
|
||||
public BiomeSnowConfig getSnow() {
|
||||
return snow;
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.biome;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.TerraConfigSection;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
import org.polydev.gaea.math.Range;
|
||||
import org.polydev.gaea.world.Flora;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BiomeFloraConfig extends TerraConfigSection {
|
||||
private final ProbabilityCollection<Flora> floras = new ProbabilityCollection<>();
|
||||
private final Map<Flora, Range> floraHeights = new HashMap<>();
|
||||
private int floraAttempts;
|
||||
private int floraChance;
|
||||
private boolean floraSimplex;
|
||||
private FastNoiseLite floraNoise;
|
||||
|
||||
public BiomeFloraConfig(TerraConfig parent) throws InvalidConfigurationException {
|
||||
super(parent);
|
||||
ConfigurationSection cfg = parent.getConfigurationSection("flora.items");
|
||||
if(cfg == null) return;
|
||||
floraSimplex = parent.getBoolean("flora.simplex.enable", false);
|
||||
floraAttempts = parent.getInt("flora.attempts", 1);
|
||||
floraChance = parent.getInt("flora.chance", 0);
|
||||
double floraFreq = parent.getDouble("flora.simplex.frequency", 0.1);
|
||||
int floraSeed = parent.getInt("flora.simplex.seed", 2403);
|
||||
if(floraSimplex) {
|
||||
floraNoise = new FastNoiseLite(floraSeed);
|
||||
floraNoise.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
floraNoise.setFrequency(floraFreq);
|
||||
}
|
||||
|
||||
for(Map.Entry<String, Object> e : cfg.getValues(false).entrySet()) {
|
||||
try {
|
||||
Map<?, ?> val = ((ConfigurationSection) e.getValue()).getValues(false);
|
||||
Map<?, ?> y = ((ConfigurationSection) val.get("y")).getValues(false);
|
||||
Flora flora;
|
||||
try {
|
||||
flora = Objects.requireNonNull(parent.getConfig().getFloraRegistry().get(e.getKey()));
|
||||
} catch(NullPointerException ex) {
|
||||
throw new NotFoundException("Flora", e.getKey(), parent.getID());
|
||||
}
|
||||
floras.add(flora, (Integer) val.get("weight"));
|
||||
floraHeights.put(flora, new Range((Integer) y.get("min"), (Integer) y.get("max")));
|
||||
} catch(ClassCastException ex) {
|
||||
Debug.stack(ex);
|
||||
throw new ConfigException("Unable to parse Flora configuration! Check YAML syntax.", parent.getID());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ProbabilityCollection<Flora> getFlora() {
|
||||
return floras;
|
||||
}
|
||||
|
||||
public Map<Flora, Range> getFloraHeights() {
|
||||
return floraHeights;
|
||||
}
|
||||
|
||||
public FastNoiseLite getFloraNoise() {
|
||||
return floraNoise;
|
||||
}
|
||||
|
||||
public int getFloraAttempts() {
|
||||
return floraAttempts;
|
||||
}
|
||||
|
||||
public boolean isFloraSimplex() {
|
||||
return floraSimplex;
|
||||
}
|
||||
|
||||
public int getFloraChance() {
|
||||
return floraChance;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.biome;
|
||||
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.TerraConfigSection;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
import org.polydev.gaea.util.FastRandom;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import org.polydev.gaea.world.palette.RandomPalette;
|
||||
|
||||
public class BiomeOceanConfig extends TerraConfigSection {
|
||||
private static final Palette<BlockData> oceanDefault = new RandomPalette<BlockData>(new FastRandom(0)).add(Material.WATER.createBlockData(), 1);
|
||||
private final Palette<BlockData> ocean;
|
||||
private final int seaLevel;
|
||||
|
||||
public BiomeOceanConfig(@NotNull TerraConfig parent) throws InvalidConfigurationException {
|
||||
super(parent);
|
||||
seaLevel = parent.getInt("ocean.level", 62);
|
||||
String oceanN = parent.getString("ocean.palette");
|
||||
if(oceanN != null) {
|
||||
if(oceanN.startsWith("BLOCK:")) {
|
||||
try {
|
||||
ocean = new RandomPalette<BlockData>(new FastRandom(0)).add(new ProbabilityCollection<BlockData>().add(Bukkit.createBlockData(oceanN.substring(6)), 1), 1);
|
||||
} catch(IllegalArgumentException ex) {
|
||||
throw new ConfigException("BlockData \"" + oceanN + "\" is invalid! (Ocean Palette)", parent.getID());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
ocean = parent.getConfig().getPalette(oceanN).getPalette();
|
||||
} catch(NullPointerException ex) {
|
||||
throw new NotFoundException("Palette", oceanN, parent.getID());
|
||||
}
|
||||
}
|
||||
} else ocean = oceanDefault;
|
||||
}
|
||||
|
||||
public Palette<BlockData> getOcean() {
|
||||
return ocean;
|
||||
}
|
||||
|
||||
public int getSeaLevel() {
|
||||
return seaLevel;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.biome;
|
||||
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.TerraConfigSection;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import com.dfsek.terra.config.genconfig.OreConfig;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.polydev.gaea.math.Range;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class BiomeOreConfig extends TerraConfigSection {
|
||||
private final Map<OreConfig, Range> ores = new HashMap<>();
|
||||
private final Map<OreConfig, Range> oreHeights = new HashMap<>();
|
||||
|
||||
public BiomeOreConfig(TerraConfig parent) throws InvalidConfigurationException {
|
||||
super(parent);
|
||||
ConfigurationSection c = parent.getConfigurationSection("ores");
|
||||
if(c == null) return;
|
||||
Map<String, Object> cfg = c.getValues(false);
|
||||
try {
|
||||
for(Map.Entry<String, Object> m : cfg.entrySet()) {
|
||||
OreConfig ore = parent.getConfig().getOre(m.getKey());
|
||||
if(ore == null) throw new NotFoundException("Ore", m.getKey(), parent.getID());
|
||||
ores.put(ore, new Range(((ConfigurationSection) m.getValue()).getInt("min"), ((ConfigurationSection) m.getValue()).getInt("max")));
|
||||
oreHeights.put(ore, new Range(((ConfigurationSection) m.getValue()).getInt("min-height"), ((ConfigurationSection) m.getValue()).getInt("max-height")));
|
||||
}
|
||||
} catch(ClassCastException e) {
|
||||
if(ConfigUtil.debug) e.printStackTrace();
|
||||
throw new ConfigException("Unable to parse Flora configuration! Check YAML syntax.", parent.getID());
|
||||
}
|
||||
}
|
||||
|
||||
public Map<OreConfig, Range> getOres() {
|
||||
return ores;
|
||||
}
|
||||
|
||||
public Map<OreConfig, Range> getOreHeights() {
|
||||
return oreHeights;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.biome;
|
||||
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.TerraConfigSection;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
import org.polydev.gaea.util.FastRandom;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import org.polydev.gaea.world.palette.RandomPalette;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class BiomePaletteConfig extends TerraConfigSection {
|
||||
private TreeMap<Integer, Palette<BlockData>> paletteMap;
|
||||
|
||||
public BiomePaletteConfig(TerraConfig parent, String key) throws InvalidConfigurationException {
|
||||
super(parent);
|
||||
List<Map<?, ?>> cfg = parent.getMapList(key);
|
||||
if(cfg.size() == 0) return;
|
||||
paletteMap = new TreeMap<>();
|
||||
for(Map<?, ?> e : cfg) {
|
||||
for(Map.Entry<?, ?> entry : e.entrySet()) {
|
||||
try {
|
||||
if(((String) entry.getKey()).startsWith("BLOCK:")) {
|
||||
try {
|
||||
paletteMap.put((Integer) entry.getValue(), new RandomPalette<BlockData>(new FastRandom(0)).add(new ProbabilityCollection<BlockData>().add(Bukkit.createBlockData(((String) entry.getKey()).substring(6)), 1), 1));
|
||||
} catch(IllegalArgumentException ex) {
|
||||
throw new ConfigException("BlockData " + entry.getKey() + " is invalid! (Palettes)", parent.getID());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
paletteMap.put((Integer) entry.getValue(), parent.getConfig().getPalette((String) entry.getKey()).getPalette());
|
||||
} catch(NullPointerException ex) {
|
||||
throw new NotFoundException("Palette", (String) entry.getKey(), parent.getID());
|
||||
}
|
||||
}
|
||||
} catch(ClassCastException ex) {
|
||||
throw new ConfigException("Unable to parse Palette configuration! Check YAML syntax.", parent.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TreeMap<Integer, Palette<BlockData>> getPaletteMap() {
|
||||
return paletteMap;
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.biome;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.TerraConfigSection;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
import org.polydev.gaea.util.FastRandom;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import org.polydev.gaea.world.palette.RandomPalette;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BiomeSlabConfig extends TerraConfigSection {
|
||||
private final Map<Material, Palette<BlockData>> slabs;
|
||||
private final Map<Material, Palette<BlockData>> stairs;
|
||||
private final double slabThreshold;
|
||||
|
||||
public BiomeSlabConfig(@NotNull TerraConfig parent) throws InvalidConfigurationException {
|
||||
super(parent);
|
||||
slabThreshold = parent.getDouble("slabs.threshold", 0.1D);
|
||||
slabs = getSlabPalettes(parent.getMapList("slabs.palettes"));
|
||||
if(parent.contains("slabs.stair-palettes") && parent.getBoolean("slabs.use-stairs-if-available", false)) {
|
||||
stairs = getSlabPalettes(parent.getMapList("slabs.stair-palettes"));
|
||||
} else stairs = new HashMap<>();
|
||||
}
|
||||
|
||||
protected Map<Material, Palette<BlockData>> getSlabPalettes(List<Map<?, ?>> paletteConfigSection) throws InvalidConfigurationException {
|
||||
Map<Material, Palette<BlockData>> paletteMap = new EnumMap<>(Material.class);
|
||||
|
||||
for(Map<?, ?> e : paletteConfigSection) {
|
||||
for(Map.Entry<?, ?> entry : e.entrySet()) {
|
||||
try {
|
||||
if(((String) entry.getValue()).startsWith("BLOCK:")) {
|
||||
try {
|
||||
Debug.info("Adding slab palette with single material " + entry.getKey());
|
||||
paletteMap.put(Bukkit.createBlockData((String) entry.getKey()).getMaterial(), new RandomPalette<BlockData>(new FastRandom(0)).add(new ProbabilityCollection<BlockData>().add(Bukkit.createBlockData(((String) entry.getValue()).substring(6)), 1), 1));
|
||||
} catch(IllegalArgumentException ex) {
|
||||
throw new ConfigException("Invalid BlockData in slab configuration: " + ex.getMessage(), getParent().getConfig().getID());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
Palette<BlockData> p = getParent().getConfig().getPalette((String) entry.getValue()).getPalette();
|
||||
if(p.getSize() != 1)
|
||||
throw new InvalidConfigurationException("Slab palette must hold only one layer. Palette " + entry.getValue() + " is too large/small");
|
||||
paletteMap.put(Bukkit.createBlockData((String) entry.getKey()).getMaterial(), p);
|
||||
} catch(NullPointerException ex) {
|
||||
throw new NotFoundException("Slab Palette", (String) entry.getValue(), getParent().getConfig().getID());
|
||||
}
|
||||
}
|
||||
} catch(ClassCastException ex) {
|
||||
throw new ConfigException("Unable to parse Slab Palette configuration! Check YAML syntax.", getParent().getConfig().getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
Debug.info("Adding " + paletteMap.size() + " slab palettes...");
|
||||
return paletteMap;
|
||||
}
|
||||
|
||||
public Map<Material, Palette<BlockData>> getStairs() {
|
||||
return stairs;
|
||||
}
|
||||
|
||||
public Map<Material, Palette<BlockData>> getSlabs() {
|
||||
return slabs;
|
||||
}
|
||||
|
||||
public double getSlabThreshold() {
|
||||
return slabThreshold;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.biome;
|
||||
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.TerraConfigSection;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.polydev.gaea.math.Range;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BiomeSnowConfig extends TerraConfigSection {
|
||||
private final int[] snowHeights;
|
||||
private final boolean physics;
|
||||
private boolean doSnow = false;
|
||||
|
||||
public BiomeSnowConfig(TerraConfig parent) throws InvalidConfigurationException {
|
||||
super(parent);
|
||||
snowHeights = new int[256];
|
||||
List<Map<?, ?>> maps = parent.getMapList("snow");
|
||||
this.physics = getParent().getBoolean("snow-physics", false);
|
||||
if(maps.size() == 0) return;
|
||||
try {
|
||||
for(Map<?, ?> e : maps) {
|
||||
Range r = new Range((Integer) e.get("min"), (Integer) e.get("max"));
|
||||
int chance = (Integer) e.get("chance");
|
||||
for(int y : r) {
|
||||
if(chance > 0) doSnow = true;
|
||||
snowHeights[y] = chance;
|
||||
}
|
||||
}
|
||||
} catch(ClassCastException e) {
|
||||
if(ConfigUtil.debug) e.printStackTrace();
|
||||
throw new ConfigException("Unable to parse Snow configuration! Check YAML syntax.", parent.getID());
|
||||
}
|
||||
}
|
||||
|
||||
public int getSnowChance(int y) {
|
||||
return snowHeights[y];
|
||||
}
|
||||
|
||||
public boolean doSnow() {
|
||||
return doSnow;
|
||||
}
|
||||
|
||||
public boolean doPhysics() {
|
||||
return physics;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.biome;
|
||||
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.TerraConfigSection;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
import org.polydev.gaea.math.Range;
|
||||
import org.polydev.gaea.tree.Tree;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BiomeTreeConfig extends TerraConfigSection {
|
||||
private final ProbabilityCollection<Tree> trees = new ProbabilityCollection<>();
|
||||
private final Map<Tree, Range> treeHeights = new HashMap<>();
|
||||
private int treeDensity;
|
||||
|
||||
public BiomeTreeConfig(TerraConfig parent) throws InvalidConfigurationException {
|
||||
super(parent);
|
||||
ConfigurationSection c = parent.getConfigurationSection("trees.items");
|
||||
if(c == null) return;
|
||||
Map<String, Object> cfg = c.getValues(false);
|
||||
if(cfg.size() == 0) return;
|
||||
treeDensity = parent.getInt("trees.density", 0);
|
||||
|
||||
for(Map.Entry<String, Object> e : cfg.entrySet()) {
|
||||
try {
|
||||
Map<?, ?> val = ((ConfigurationSection) e.getValue()).getValues(false);
|
||||
Map<?, ?> y = ((ConfigurationSection) val.get("y")).getValues(false);
|
||||
Tree tree;
|
||||
try {
|
||||
tree = Objects.requireNonNull(parent.getConfig().getTreeRegistry().get(e.getKey()));
|
||||
} catch(NullPointerException ex2) {
|
||||
throw new NotFoundException("Tree", e.getKey(), parent.getID());
|
||||
}
|
||||
trees.add(tree, (Integer) val.get("weight"));
|
||||
treeHeights.put(tree, new Range((Integer) y.get("min"), (Integer) y.get("max")));
|
||||
} catch(ClassCastException ex) {
|
||||
throw new ConfigException("Unable to parse Tree configuration! Check YAML syntax.", parent.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ProbabilityCollection<Tree> getTrees() {
|
||||
return trees;
|
||||
}
|
||||
|
||||
public Map<Tree, Range> getTreeHeights() {
|
||||
return treeHeights;
|
||||
}
|
||||
|
||||
public int getTreeDensity() {
|
||||
return treeDensity;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.biome;
|
||||
|
||||
import com.dfsek.terra.config.genconfig.noise.NoiseConfig;
|
||||
import com.dfsek.terra.generation.config.WorldGenerator;
|
||||
import com.dfsek.terra.math.BlankFunction;
|
||||
import com.dfsek.terra.util.DataUtil;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import parsii.eval.Parser;
|
||||
import parsii.eval.Scope;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class GeneratorOptions {
|
||||
|
||||
private final Map<Long, WorldGenerator> generators = new HashMap<>();
|
||||
|
||||
private final boolean preventSmooth;
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
|
||||
private final Palette<BlockData>[] palettes = new Palette[256];
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
|
||||
private final Palette<BlockData>[] slantPalettes = new Palette[256];
|
||||
|
||||
|
||||
private final String equation;
|
||||
private final String elevationEquation;
|
||||
private final Scope userVariables;
|
||||
private final Map<String, NoiseConfig> noiseBuilders;
|
||||
|
||||
private final boolean elevationInterpolation;
|
||||
|
||||
public GeneratorOptions(String equation, @Nullable String elevateEquation, Scope userVariables, Map<Integer, Palette<BlockData>> paletteMap, Map<Integer, Palette<BlockData>> slantPaletteMap, Map<String, NoiseConfig> noiseBuilders, boolean preventSmooth, boolean elevationInterpolation)
|
||||
throws ParseException {
|
||||
this.equation = equation;
|
||||
this.elevationEquation = elevateEquation;
|
||||
this.userVariables = userVariables;
|
||||
this.noiseBuilders = noiseBuilders;
|
||||
this.preventSmooth = preventSmooth;
|
||||
|
||||
Scope s = new Scope().withParent(userVariables);
|
||||
Parser p = new Parser();
|
||||
for(Map.Entry<String, NoiseConfig> e : noiseBuilders.entrySet()) {
|
||||
int dimensions = e.getValue().getDimensions();
|
||||
if(dimensions == 2 || dimensions == 3) p.registerFunction(e.getKey(), new BlankFunction(dimensions));
|
||||
}
|
||||
p.parse(equation, s); // Validate equation at config load time to prevent error during world load.
|
||||
if(elevateEquation != null) p.parse(elevateEquation, s);
|
||||
|
||||
|
||||
for(int y = 0; y < 256; y++) {
|
||||
Palette<BlockData> d = DataUtil.BLANK_PALETTE;
|
||||
for(Map.Entry<Integer, Palette<BlockData>> e : paletteMap.entrySet()) {
|
||||
if(e.getKey() >= y) {
|
||||
d = e.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
palettes[y] = d;
|
||||
Palette<BlockData> slantPalette = null;
|
||||
for(Map.Entry<Integer, Palette<BlockData>> e : slantPaletteMap.entrySet()) {
|
||||
if(e.getKey() >= y) {
|
||||
slantPalette = e.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
slantPalettes[y] = slantPalette;
|
||||
}
|
||||
this.elevationInterpolation = elevationInterpolation;
|
||||
}
|
||||
|
||||
public WorldGenerator getGenerator(long seed) {
|
||||
return generators.computeIfAbsent(seed, s -> new WorldGenerator(seed, equation, elevationEquation, userVariables, noiseBuilders, palettes, slantPalettes, preventSmooth)
|
||||
.setElevationInterpolation(elevationInterpolation));
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.noise;
|
||||
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.generation.config.NoiseBuilder;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
|
||||
public class NoiseConfig {
|
||||
private final NoiseBuilder builder;
|
||||
private final int dimensions;
|
||||
|
||||
public NoiseConfig(ConfigurationSection section) throws ConfigException {
|
||||
NoiseBuilder builder = new NoiseBuilder();
|
||||
try {
|
||||
builder.setType(FastNoiseLite.NoiseType.valueOf(section.getString("type", "OpenSimplex2")))
|
||||
.setFrequency(section.getDouble("frequency", 0.02D))
|
||||
.setRotationType3D(FastNoiseLite.RotationType3D.valueOf(section.getString("rotation", "None")))
|
||||
.setSeedOffset(section.getInt("offset", 0));
|
||||
|
||||
dimensions = section.getInt("dimensions", 3);
|
||||
if(dimensions != 2 && dimensions != 3)
|
||||
throw new ConfigException("Invalid number of dimensions: " + dimensions, "Noise");
|
||||
|
||||
|
||||
if(section.contains("fractal")) {
|
||||
builder.setFractalType(FastNoiseLite.FractalType.valueOf(section.getString("fractal.type", "FBm")))
|
||||
.setOctaves(section.getInt("fractal.octaves", 1))
|
||||
.setFractalGain(section.getDouble("fractal.gain", 0.5D))
|
||||
.setFractalLacunarity(section.getDouble("fractal.lacunarity", 2.0D))
|
||||
.setPingPong(section.getDouble("fractal.ping-pong", 2.0D))
|
||||
.setWeightedStrength(section.getDouble("fractal.weighted-strength", 0.0D));
|
||||
}
|
||||
|
||||
if(section.contains("cellular")) {
|
||||
builder.setCellularDistanceFunction(FastNoiseLite.CellularDistanceFunction.valueOf(section.getString("cellular.distance", "EuclideanSq")))
|
||||
.setCellularReturnType(FastNoiseLite.CellularReturnType.valueOf(section.getString("cellular.return", "Distance")));
|
||||
}
|
||||
|
||||
if(section.contains("warp")) {
|
||||
builder.setDomainWarpType(FastNoiseLite.DomainWarpType.valueOf(section.getString("warp.type", "OpenSimplex2")))
|
||||
.setDomainWarpAmp(section.getDouble("warp.amplitude", 1.0D));
|
||||
}
|
||||
this.builder = builder;
|
||||
} catch(IllegalArgumentException | ClassCastException e) {
|
||||
throw new ConfigException(e.getMessage(), "Noise");
|
||||
}
|
||||
}
|
||||
|
||||
public NoiseBuilder getBuilder() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
public int getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.structure;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.structure.features.EntityFeature;
|
||||
import com.dfsek.terra.structure.features.Feature;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.polydev.gaea.math.Range;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class EntityFeatureConfig implements FeatureConfig {
|
||||
private final EntityFeature feature;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public EntityFeatureConfig(Map<String, Object> items) throws InvalidConfigurationException {
|
||||
if(!items.containsKey("entity")) throw new ConfigException("No EntityType specified!", "EntityFeature");
|
||||
if(!items.containsKey("amount")) throw new ConfigException("No amount specified!", "EntityFeature");
|
||||
if(!items.containsKey("attempts")) throw new ConfigException("Attempts not specified!", "EntityFeature");
|
||||
if(!items.containsKey("in-height"))
|
||||
throw new ConfigException("Spawn Checking Height not specified!", "EntityFeature");
|
||||
if(!items.containsKey("spawnable-on"))
|
||||
throw new ConfigException("No Spawnable-on materials specified!", "EntityFeature");
|
||||
if(!items.containsKey("spawnable-in"))
|
||||
throw new ConfigException("No Spawnable-in materials specified!", "EntityFeature");
|
||||
|
||||
EntityType type;
|
||||
try {
|
||||
type = EntityType.valueOf((String) items.get("entity"));
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new InvalidConfigurationException("No such EntityType: " + items.get("entity"));
|
||||
} catch(ClassCastException e) {
|
||||
throw new InvalidConfigurationException("Error in Entity Configuration!");
|
||||
}
|
||||
|
||||
int height = (Integer) items.get("in-height");
|
||||
|
||||
Range amount;
|
||||
try {
|
||||
Map<String, Integer> amountMap = (Map<String, Integer>) items.get("amount");
|
||||
amount = new Range(amountMap.get("min"), amountMap.get("max"));
|
||||
} catch(ClassCastException e) {
|
||||
throw new InvalidConfigurationException("Error in Amount Configuration!");
|
||||
}
|
||||
|
||||
Set<Material> on = ConfigUtil.toBlockData((List<String>) items.get("spawnable-on"), "SpawnableOn", "");
|
||||
Set<Material> in = ConfigUtil.toBlockData((List<String>) items.get("spawnable-in"), "SpawnableIn", "");
|
||||
|
||||
this.feature = new EntityFeature(type, amount, on, in, height);
|
||||
Debug.info("Loaded EntityFeature with type: " + type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Feature getFeature() {
|
||||
return feature;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.structure;
|
||||
|
||||
import com.dfsek.terra.structure.features.Feature;
|
||||
|
||||
public interface FeatureConfig {
|
||||
Feature getFeature();
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
package com.dfsek.terra.config.genconfig.structure;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import com.dfsek.terra.procgen.GridSpawn;
|
||||
import com.dfsek.terra.structure.Structure;
|
||||
import com.dfsek.terra.structure.features.Feature;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
import org.polydev.gaea.math.Range;
|
||||
import org.polydev.gaea.structures.loot.LootTable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
|
||||
public class StructureConfig extends TerraConfig {
|
||||
private final ProbabilityCollection<Structure> structure = new ProbabilityCollection<>();
|
||||
private final GridSpawn spawn;
|
||||
private final String id;
|
||||
private final Range searchStart;
|
||||
private final Range bound;
|
||||
private final Map<Integer, LootTable> loot = new HashMap<>();
|
||||
private final List<Feature> features;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public StructureConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||
super(file, config);
|
||||
if(!contains("id")) throw new ConfigException("No ID specified!", "null");
|
||||
id = getString("id");
|
||||
if(!contains("files")) throw new ConfigException("No files specified!", getID());
|
||||
try {
|
||||
for(Map.Entry<String, Object> e : Objects.requireNonNull(getConfigurationSection("files")).getValues(false).entrySet()) {
|
||||
try {
|
||||
File structureFile = new File(config.getDataFolder() + File.separator + "structures" + File.separator + "data", e.getKey() + ".tstructure");
|
||||
structure.add(Structure.load(structureFile), (Integer) e.getValue());
|
||||
} catch(FileNotFoundException ex) {
|
||||
Debug.stack(ex);
|
||||
throw new NotFoundException("Structure File", e.getKey(), getID());
|
||||
} catch(ClassCastException ex) {
|
||||
Debug.stack(ex);
|
||||
throw new ConfigException("Unable to parse Structure configuration! Check YAML syntax.", getID());
|
||||
}
|
||||
}
|
||||
} catch(IOException | NullPointerException e) {
|
||||
if(ConfigUtil.debug) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new NotFoundException("Structure", getString("file"), getID());
|
||||
}
|
||||
if(contains("loot")) {
|
||||
for(Map.Entry<String, Object> e : Objects.requireNonNull(getConfigurationSection("loot")).getValues(false).entrySet()) {
|
||||
File lootFile = new File(config.getDataFolder() + File.separator + "structures" + File.separator + "loot", e.getValue().toString() + ".json");
|
||||
try {
|
||||
loot.put(Integer.valueOf(e.getKey()), new LootTable(FileUtils.readFileToString(lootFile)));
|
||||
Debug.info("Loaded loot table from " + lootFile.getAbsolutePath() + " with ID " + e.getKey());
|
||||
} catch(FileNotFoundException ex) {
|
||||
Debug.stack(ex);
|
||||
throw new NotFoundException("Loot Table File", e.getKey(), getID());
|
||||
} catch(ClassCastException | NumberFormatException ex) {
|
||||
Debug.stack(ex);
|
||||
throw new ConfigException("Unable to parse Structure Loot configuration! Check YAML syntax.", getID());
|
||||
} catch(ParseException parseException) {
|
||||
Debug.stack(parseException);
|
||||
throw new ConfigException("Invalid loot table data in file: " + lootFile.getAbsolutePath(), getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
features = new ArrayList<>();
|
||||
if(contains("features")) {
|
||||
for(Map<?, ?> map : getMapList("features")) {
|
||||
for(Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
if(entry.getKey().equals("ENTITY_FEATURE"))
|
||||
features.add(new EntityFeatureConfig((Map<String, Object>) entry.getValue()).getFeature());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spawn = new GridSpawn(getInt("spawn.width", 500), getInt("spawn.padding", 100));
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<Feature> getFeatures() {
|
||||
return features;
|
||||
}
|
||||
|
||||
public Structure getStructure(Random r) {
|
||||
return structure.get(r);
|
||||
}
|
||||
|
||||
public GridSpawn getSpawn() {
|
||||
return spawn;
|
||||
}
|
||||
|
||||
public Range getBound() {
|
||||
return bound;
|
||||
}
|
||||
|
||||
public Range getSearchStart() {
|
||||
return searchStart;
|
||||
}
|
||||
|
||||
public LootTable getLoot(int id) {
|
||||
return loot.get(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.dfsek.terra.config.loaders;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.config.files.Loader;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.polydev.gaea.structures.loot.LootTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class LootTableLoader implements TypeLoader<LootTable> {
|
||||
private final Loader loader;
|
||||
|
||||
public LootTableLoader(Loader loader) {
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootTable load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
try(InputStream stream = loader.get("structures/loot/" + o + ".json")) {
|
||||
return new LootTable(IOUtils.toString(stream, StandardCharsets.UTF_8));
|
||||
} catch(IOException | ParseException | NullPointerException e) {
|
||||
throw new LoadException("Unable to load loot", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.dfsek.terra.config.loaders;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.util.MaterialSet;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class MaterialSetLoader implements TypeLoader<MaterialSet> {
|
||||
@Override
|
||||
public MaterialSet load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
List<String> stringData = (List<String>) o;
|
||||
MaterialSet set = new MaterialSet();
|
||||
|
||||
for(String string : stringData) {
|
||||
try {
|
||||
if(string.startsWith("#")) set.addTag(string.substring(1));
|
||||
else set.add((Material) configLoader.loadType(Material.class, string));
|
||||
} catch(NullPointerException e) {
|
||||
throw new LoadException("Invalid data identifier \"" + string + "\"", e);
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.dfsek.terra.config.loaders;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollection<Object>> {
|
||||
@Override
|
||||
public ProbabilityCollection<Object> load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
|
||||
|
||||
ProbabilityCollection<Object> collection = new ProbabilityCollection<>();
|
||||
|
||||
if(type instanceof ParameterizedType) {
|
||||
ParameterizedType pType = (ParameterizedType) type;
|
||||
Type generic = pType.getActualTypeArguments()[0];
|
||||
if(o instanceof Map) {
|
||||
Map<Object, Integer> map = (Map<Object, Integer>) o;
|
||||
for(Map.Entry<Object, Integer> entry : map.entrySet()) {
|
||||
collection.add(configLoader.loadType(generic, entry.getKey()), entry.getValue());
|
||||
}
|
||||
} else if(o instanceof List) {
|
||||
List<Map<Object, Integer>> map = (List<Map<Object, Integer>>) o;
|
||||
for(Map<Object, Integer> l : map) {
|
||||
for(Map.Entry<Object, Integer> entry : l.entrySet()) {
|
||||
collection.add(configLoader.loadType(generic, entry.getKey()), entry.getValue());
|
||||
}
|
||||
}
|
||||
} else throw new LoadException("Malformed Probability Collection: " + o);
|
||||
} else throw new LoadException("Unable to load config! Could not retrieve parameterized type: " + type);
|
||||
|
||||
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.dfsek.terra.config.loaders;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import org.polydev.gaea.math.Range;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class RangeLoader implements TypeLoader<Range> {
|
||||
@Override
|
||||
public Range load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
Map<String, Integer> map = (Map<String, Integer>) o;
|
||||
return new Range(map.get("min"), map.get("max"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.dfsek.terra.config.loaders;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.config.files.Loader;
|
||||
import com.dfsek.terra.structure.Structure;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class StructureLoader implements TypeLoader<Structure> {
|
||||
private final Loader loader;
|
||||
|
||||
public StructureLoader(Loader loader) {
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Structure load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
try(InputStream stream = loader.get("structures/data/" + o + ".tstructure")) {
|
||||
return Structure.fromStream(stream);
|
||||
} catch(IOException | ClassNotFoundException e) {
|
||||
throw new LoadException("Unable to load structure", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
src/main/java/com/dfsek/terra/config/loaders/Types.java
Normal file
49
src/main/java/com/dfsek/terra/config/loaders/Types.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package com.dfsek.terra.config.loaders;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
import org.polydev.gaea.tree.Tree;
|
||||
import org.polydev.gaea.world.Flora;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Class to hold Type instances for types with generics.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public final class Types {
|
||||
public static final Type MATERIAL_SET_TYPE;
|
||||
public static final Type MATERIAL_PROBABILITY_COLLECTION_TYPE;
|
||||
public static final Type BLOCK_DATA_PALETTE_TYPE;
|
||||
public static final Type BLOCK_DATA_PROBABILITY_COLLECTION_TYPE;
|
||||
public static final Type FLORA_PROBABILITY_COLLECTION_TYPE;
|
||||
public static final Type TREE_PROBABILITY_COLLECTION_TYPE;
|
||||
|
||||
static {
|
||||
MATERIAL_SET_TYPE = getType("materialSet");
|
||||
MATERIAL_PROBABILITY_COLLECTION_TYPE = getType("materialProbabilityCollection");
|
||||
BLOCK_DATA_PALETTE_TYPE = getType("blockDataPalette");
|
||||
BLOCK_DATA_PROBABILITY_COLLECTION_TYPE = getType("blockDataProbabilityCollection");
|
||||
FLORA_PROBABILITY_COLLECTION_TYPE = getType("floraProbabilityCollection");
|
||||
TREE_PROBABILITY_COLLECTION_TYPE = getType("treeProbabilityCollection");
|
||||
}
|
||||
|
||||
private Set<Material> materialSet;
|
||||
private Palette<BlockData> blockDataPalette;
|
||||
private ProbabilityCollection<Material> materialProbabilityCollection;
|
||||
private ProbabilityCollection<BlockData> blockDataProbabilityCollection;
|
||||
private ProbabilityCollection<Flora> floraProbabilityCollection;
|
||||
private ProbabilityCollection<Tree> treeProbabilityCollection;
|
||||
|
||||
private static Type getType(String dummyFieldName) {
|
||||
try {
|
||||
return Types.class.getDeclaredField(dummyFieldName).getGenericType();
|
||||
} catch(NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.dfsek.terra.config.loaders.config;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.config.loaders.Types;
|
||||
import com.dfsek.terra.generation.items.flora.FloraLayer;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
import org.polydev.gaea.math.ProbabilityCollection;
|
||||
import org.polydev.gaea.math.Range;
|
||||
import org.polydev.gaea.world.Flora;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class FloraLayerLoader implements TypeLoader<FloraLayer> {
|
||||
@Override
|
||||
public FloraLayer load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
Map<String, Object> map = (Map<String, Object>) o;
|
||||
double density = ((Number) map.get("density")).doubleValue();
|
||||
Range range = (Range) configLoader.loadType(Range.class, map.get("y"));
|
||||
if(range == null) throw new LoadException("Flora range unspecified");
|
||||
ProbabilityCollection<Flora> items = (ProbabilityCollection<Flora>) configLoader.loadType(Types.FLORA_PROBABILITY_COLLECTION_TYPE, map.get("items"));
|
||||
|
||||
if(map.containsKey("simplex-frequency")) {
|
||||
FastNoiseLite noiseLite = new FastNoiseLite();
|
||||
noiseLite.setFrequency((Double) map.get("simplex-frequency"));
|
||||
return new FloraLayer(density, range, items, noiseLite);
|
||||
}
|
||||
|
||||
return new FloraLayer(density, range, items, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.dfsek.terra.config.loaders.config;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.procgen.GridSpawn;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class GridSpawnLoader implements TypeLoader<GridSpawn> {
|
||||
@Override
|
||||
public GridSpawn load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
Map<String, Integer> map = (Map<String, Integer>) o;
|
||||
return new GridSpawn(map.get("width"), map.get("padding"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.dfsek.terra.config.loaders.config;
|
||||
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.generation.config.NoiseBuilder;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class NoiseBuilderLoader implements TypeLoader<NoiseBuilder> {
|
||||
private static final ConfigLoader LOADER = new ConfigLoader();
|
||||
|
||||
static {
|
||||
LOADER.registerLoader(FastNoiseLite.NoiseType.class, (t, object, cf) -> FastNoiseLite.NoiseType.valueOf((String) object));
|
||||
LOADER.registerLoader(FastNoiseLite.FractalType.class, (t, object, cf) -> FastNoiseLite.FractalType.valueOf((String) object));
|
||||
LOADER.registerLoader(FastNoiseLite.DomainWarpType.class, (t, object, cf) -> FastNoiseLite.DomainWarpType.valueOf((String) object));
|
||||
LOADER.registerLoader(FastNoiseLite.RotationType3D.class, (t, object, cf) -> FastNoiseLite.RotationType3D.valueOf((String) object));
|
||||
LOADER.registerLoader(FastNoiseLite.CellularReturnType.class, (t, object, cf) -> FastNoiseLite.CellularReturnType.valueOf((String) object));
|
||||
LOADER.registerLoader(FastNoiseLite.CellularDistanceFunction.class, (t, object, cf) -> FastNoiseLite.CellularDistanceFunction.valueOf((String) object));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoiseBuilder load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
NoiseBuilder builder = new NoiseBuilder();
|
||||
try {
|
||||
LOADER.load(builder, new Configuration((Map<String, Object>) o));
|
||||
} catch(ConfigException e) {
|
||||
throw new LoadException("Could not load noise", e);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.dfsek.terra.config.loaders.config;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.generation.items.ores.OreConfig;
|
||||
import org.polydev.gaea.math.Range;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class OreConfigLoader implements TypeLoader<OreConfig> {
|
||||
@Override
|
||||
public OreConfig load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
Map<String, Integer> map = (Map<String, Integer>) o;
|
||||
Range amount = new Range(map.get("min"), map.get("max"));
|
||||
Range height = new Range(map.get("min-height"), map.get("max-height"));
|
||||
return new OreConfig(amount, height);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.dfsek.terra.config.loaders.config;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.generation.items.ores.Ore;
|
||||
import com.dfsek.terra.generation.items.ores.OreConfig;
|
||||
import com.dfsek.terra.generation.items.ores.OreHolder;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class OreHolderLoader implements TypeLoader<OreHolder> {
|
||||
@Override
|
||||
public OreHolder load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
OreHolder holder = new OreHolder();
|
||||
Map<String, Object> map = (Map<String, Object>) o;
|
||||
|
||||
for(Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
holder.add((Ore) configLoader.loadType(Ore.class, entry.getKey()), (OreConfig) configLoader.loadType(OreConfig.class, entry.getValue()));
|
||||
}
|
||||
|
||||
return holder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.config.loaders.config;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.structure.features.EntityFeature;
|
||||
import com.dfsek.terra.structure.features.Feature;
|
||||
import com.dfsek.terra.util.MaterialSet;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.polydev.gaea.math.Range;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings({"unchecked", "SwitchStatementWithTooFewBranches"}) // We will do more features laterTM
|
||||
public class StructureFeatureLoader implements TypeLoader<Feature> {
|
||||
@Override
|
||||
public Feature load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
Map<String, Object> map = (Map<String, Object>) o;
|
||||
switch((String) map.get("type")) {
|
||||
case "ENTITY_FEATURE":
|
||||
MaterialSet stand = (MaterialSet) configLoader.loadType(MaterialSet.class, map.get("spawnable-on"));
|
||||
MaterialSet in = (MaterialSet) configLoader.loadType(MaterialSet.class, map.get("spawnable-in"));
|
||||
Range amount = (Range) configLoader.loadType(Range.class, map.get("amount"));
|
||||
EntityType entityType = (EntityType) configLoader.loadType(EntityType.class, map.get("entity"));
|
||||
Integer height = (Integer) configLoader.loadType(Integer.class, map.get("in-height"));
|
||||
return new EntityFeature(entityType, amount, stand, in, height);
|
||||
default:
|
||||
throw new LoadException("Invalid feature type: \"" + map.get("type") + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user