That's quite the commit you got there

This commit is contained in:
dfsek
2020-11-26 19:07:43 -07:00
parent dbbe7dbd0d
commit 59141f99bd
92 changed files with 1772 additions and 2495 deletions
+10
View File
@@ -6,6 +6,16 @@
<language minSize="54" name="Java" /> <language minSize="54" name="Java" />
</Languages> </Languages>
</inspection_tool> </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="NonSerializableObjectPassedToObjectStream" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SerialVersionUIDNotStaticFinal" 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"> <inspection_tool class="SerializableHasSerialVersionUIDField" enabled="true" level="WARNING" enabled_by_default="true">
+3 -2
View File
@@ -4,8 +4,9 @@
<entry_points version="2.0"> <entry_points version="2.0">
<entry_point TYPE="field" FQNAME="com.dfsek.terra.util.StructureTypeEnum NETHER_FORTRESS" /> <entry_point TYPE="field" FQNAME="com.dfsek.terra.util.StructureTypeEnum NETHER_FORTRESS" />
</entry_points> </entry_points>
<list size="1"> <list size="2">
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" /> <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> </list>
</component> </component>
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
+1 -1
View File
@@ -30,7 +30,7 @@ java {
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8
} }
val versionObj = Version("1", "5", "0", true) val versionObj = Version("2", "0", "0", true)
version = versionObj version = versionObj
@@ -1,17 +1,5 @@
package com.dfsek.terra; 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.registry.TreeRegistry;
import com.dfsek.terra.util.StructureTypeEnum;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.EnderSignal;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Villager; import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@@ -21,9 +9,6 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent;
import org.bukkit.event.entity.VillagerCareerChangeEvent; import org.bukkit.event.entity.VillagerCareerChangeEvent;
import org.bukkit.event.world.StructureGrowEvent; import org.bukkit.event.world.StructureGrowEvent;
import org.polydev.gaea.GaeaPlugin; import org.polydev.gaea.GaeaPlugin;
import org.polydev.gaea.tree.Tree;
import org.polydev.gaea.tree.TreeType;
import org.polydev.gaea.util.FastRandom;
public class EventListener implements Listener { public class EventListener implements Listener {
private final GaeaPlugin main; private final GaeaPlugin main;
@@ -34,12 +19,13 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL) @EventHandler(priority = EventPriority.NORMAL)
public void onEnderEye(EntitySpawnEvent e) { public void onEnderEye(EntitySpawnEvent e) {
/*
Entity entity = e.getEntity(); Entity entity = e.getEntity();
if(e.getEntityType().equals(EntityType.ENDER_SIGNAL)) { if(e.getEntityType().equals(EntityType.ENDER_SIGNAL)) {
Debug.info("Detected Ender Signal..."); Debug.info("Detected Ender Signal...");
TerraWorld tw = TerraWorld.getWorld(e.getEntity().getWorld()); TerraWorld tw = TerraWorld.getWorld(e.getEntity().getWorld());
EnderSignal signal = (EnderSignal) entity; EnderSignal signal = (EnderSignal) entity;
StructureConfig config = tw.getConfig().getLocatable().get(StructureTypeEnum.STRONGHOLD); StructureTemplate config = tw.getConfig().getTemplate().getStructureLocatables().get(StructureTypeEnum.STRONGHOLD);
if(config != null) { if(config != null) {
Debug.info("Overriding Ender Signal..."); Debug.info("Overriding Ender Signal...");
AsyncStructureFinder finder = new AsyncStructureFinder(tw.getGrid(), config, e.getLocation(), 0, 500, location -> { AsyncStructureFinder finder = new AsyncStructureFinder(tw.getGrid(), config, e.getLocation(), 0, 500, location -> {
@@ -50,6 +36,8 @@ public class EventListener implements Listener {
} else } else
main.getLogger().warning("No overrides are defined for Strongholds. Ender Signals will not work correctly."); main.getLogger().warning("No overrides are defined for Strongholds. Ender Signals will not work correctly.");
} }
*/
// TODO: implementation
} }
@EventHandler @EventHandler
@@ -69,6 +57,7 @@ public class EventListener implements Listener {
@EventHandler @EventHandler
public void onSaplingGrow(StructureGrowEvent e) { public void onSaplingGrow(StructureGrowEvent e) {
/*
if(!TerraWorld.isTerraWorld(e.getWorld())) return; if(!TerraWorld.isTerraWorld(e.getWorld())) return;
TerraWorld tw = TerraWorld.getWorld(e.getWorld()); TerraWorld tw = TerraWorld.getWorld(e.getWorld());
ConfigPack c = tw.getConfig(); ConfigPack c = tw.getConfig();
@@ -80,10 +69,12 @@ public class EventListener implements Listener {
TreeRegistry registry = c.getTreeRegistry(); TreeRegistry registry = c.getTreeRegistry();
Tree tree = registry.get(TreeType.fromBukkit(e.getSpecies()).toString()); Tree tree = registry.get(TreeType.fromBukkit(e.getSpecies()).toString());
Debug.info("Overriding tree type: " + e.getSpecies()); Debug.info("Overriding tree type: " + e.getSpecies());
if(tree instanceof TreeConfig) { if(tree instanceof TerraTree) {
if(!((TreeConfig) tree).plantBlockCheck(e.getLocation(), new FastRandom())) { if(!tree.plant(e.getLocation(), new FastRandom(), Terra.getInstance())) {
block.setBlockData(data); block.setBlockData(data);
} }
} else if(!tree.plant(e.getLocation(), new FastRandom(), Terra.getInstance())) block.setBlockData(data); } else if(!tree.plant(e.getLocation(), new FastRandom(), Terra.getInstance())) block.setBlockData(data);
*/
// TODO: implementation
} }
} }
-2
View File
@@ -2,7 +2,6 @@ package com.dfsek.terra;
import com.dfsek.terra.command.TerraCommand; import com.dfsek.terra.command.TerraCommand;
import com.dfsek.terra.command.structure.LocateCommand; import com.dfsek.terra.command.structure.LocateCommand;
import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.base.PluginConfig; import com.dfsek.terra.config.base.PluginConfig;
import com.dfsek.terra.config.base.WorldConfig; import com.dfsek.terra.config.base.WorldConfig;
import com.dfsek.terra.config.lang.LangUtil; import com.dfsek.terra.config.lang.LangUtil;
@@ -49,7 +48,6 @@ public class Terra extends GaeaPlugin {
Debug.setMain(this); Debug.setMain(this);
PluginConfig.load(this); PluginConfig.load(this);
LangUtil.load(PluginConfig.getLanguage(), this); // Load language. LangUtil.load(PluginConfig.getLanguage(), this); // Load language.
ConfigPack.loadAll(this);
TerraWorld.invalidate(); TerraWorld.invalidate();
PluginCommand c = Objects.requireNonNull(getCommand("terra")); PluginCommand c = Objects.requireNonNull(getCommand("terra"));
+27 -25
View File
@@ -2,14 +2,16 @@ package com.dfsek.terra;
import com.dfsek.terra.biome.BiomeZone; import com.dfsek.terra.biome.BiomeZone;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.grid.SingleBiomeGrid;
import com.dfsek.terra.biome.grid.TerraBiomeGrid; 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.ConfigPack;
import com.dfsek.terra.config.base.ConfigPackTemplate;
import com.dfsek.terra.config.base.WorldConfig; import com.dfsek.terra.config.base.WorldConfig;
import com.dfsek.terra.config.genconfig.BiomeGridConfig; import com.dfsek.terra.config.builder.BiomeGridBuilder;
import com.dfsek.terra.generation.TerraChunkGenerator; import com.dfsek.terra.generation.TerraChunkGenerator;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.polydev.gaea.biome.BiomeGrid;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -28,20 +30,22 @@ public class TerraWorld {
safe = true; safe = true;
worldConfig = loaded.get(w.getName()); worldConfig = loaded.get(w.getName());
config = worldConfig.getConfig(); config = worldConfig.getConfig();
UserDefinedGrid[] definedGrids = new UserDefinedGrid[config.biomeList.size()];
for(int i = 0; i < config.biomeList.size(); i++) { ConfigPackTemplate template = config.getTemplate();
String partName = config.biomeList.get(i);
int zoneSize = template.getGrids().size();
BiomeGrid[] definedGrids = new BiomeGrid[zoneSize];
for(int i = 0; i < zoneSize; i++) {
String partName = template.getGrids().get(i);
try { try {
if(partName.startsWith("BIOME:")) { if(partName.startsWith("BIOME:")) {
UserDefinedBiome[][] temp = new UserDefinedBiome[1][1]; UserDefinedBiome b = config.getBiome(partName.substring(6));
UserDefinedBiome b = config.getBiomes().get(partName.substring(6)).getBiome(); definedGrids[i] = new SingleBiomeGrid(w, b);
temp[0][0] = b;
definedGrids[i] = new UserDefinedGrid(w, config.freq1, config.freq2, temp, worldConfig);
Debug.info("Loaded single-biome grid " + partName); Debug.info("Loaded single-biome grid " + partName);
} else { } else {
BiomeGridConfig g = config.getBiomeGrid(partName); BiomeGridBuilder g = config.getBiomeGrid(partName);
Debug.info("Loaded BiomeGrid " + g.getID()); definedGrids[i] = g.build(w);
definedGrids[i] = g.getGrid(w, worldConfig);
} }
} catch(NullPointerException e) { } catch(NullPointerException e) {
safe = false; safe = false;
@@ -52,31 +56,29 @@ public class TerraWorld {
Bukkit.getLogger().severe("Terrain will NOT generate properly at this point. Correct your config before using your server!"); Bukkit.getLogger().severe("Terrain will NOT generate properly at this point. Correct your config before using your server!");
} }
} }
UserDefinedGrid erosion = null; BiomeGrid erosion = null;
if(config.erosionEnable) { String erosionName = template.getErodeGrid();
if(template.isErode()) {
try { try {
if(config.erosionName.startsWith("BIOME:")) { if(erosionName.startsWith("BIOME:")) {
UserDefinedBiome[][] temp = new UserDefinedBiome[1][1]; UserDefinedBiome b = Objects.requireNonNull(config.getBiome(erosionName.substring(6)));
UserDefinedBiome b = Objects.requireNonNull(config.getBiome(config.erosionName.substring(6)).getBiome()); erosion = new SingleBiomeGrid(w, b);
temp[0][0] = b; Debug.info("Loaded single-biome erosion grid " + erosionName);
erosion = new UserDefinedGrid(w, config.freq1, config.freq2, temp, worldConfig);
Debug.info("Loaded single-biome erosion grid " + config.erosionName);
} else { } else {
BiomeGridConfig g = Objects.requireNonNull(config.getBiomeGrid(config.erosionName)); BiomeGridBuilder g = Objects.requireNonNull(config.getBiomeGrid(erosionName));
Debug.info("Loaded BiomeGrid " + g.getID()); erosion = g.build(w);
erosion = g.getGrid(w, worldConfig);
} }
} catch(NullPointerException e) { } catch(NullPointerException e) {
safe = false; safe = false;
Debug.stack(e); Debug.stack(e);
Bukkit.getLogger().severe("No such BiomeGrid (erosion): " + config.erosionName); Bukkit.getLogger().severe("No such BiomeGrid (erosion): " + erosionName);
Bukkit.getLogger().severe("Please check configuration files for errors. Configuration errors will have been reported during initialization."); 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("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!"); Bukkit.getLogger().severe("Terrain will NOT generate properly at this point. Correct your config before using your server!");
} }
} }
zone = new BiomeZone(w, worldConfig, definedGrids); 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, erosion);
} }
public static void loadWorld(WorldConfig w) { public static void loadWorld(WorldConfig w) {
@@ -0,0 +1,4 @@
package com.dfsek.terra;
public interface WorldObject {
}
@@ -2,7 +2,7 @@ package com.dfsek.terra.async;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.grid.TerraBiomeGrid; import com.dfsek.terra.biome.grid.TerraBiomeGrid;
import com.dfsek.terra.config.genconfig.structure.StructureConfig; import com.dfsek.terra.config.templates.StructureTemplate;
import com.dfsek.terra.structure.Rotation; import com.dfsek.terra.structure.Rotation;
import com.dfsek.terra.structure.Structure; import com.dfsek.terra.structure.Structure;
import org.bukkit.Location; import org.bukkit.Location;
@@ -17,8 +17,8 @@ import java.util.function.Consumer;
/** /**
* Runnable to locate structures asynchronously * Runnable to locate structures asynchronously
*/ */
public class AsyncStructureFinder extends AsyncFeatureFinder<StructureConfig> { public class AsyncStructureFinder extends AsyncFeatureFinder<StructureTemplate> {
public AsyncStructureFinder(TerraBiomeGrid grid, StructureConfig target, @NotNull Location origin, int startRadius, int maxRadius, Consumer<Vector> callback) { public AsyncStructureFinder(TerraBiomeGrid grid, StructureTemplate target, @NotNull Location origin, int startRadius, int maxRadius, Consumer<Vector> callback) {
super(grid, target, origin, startRadius, maxRadius, callback); super(grid, target, origin, startRadius, maxRadius, callback);
setSearchSize(target.getSpawn().getWidth() + 2 * target.getSpawn().getSeparation()); setSearchSize(target.getSpawn().getWidth() + 2 * target.getSpawn().getSeparation());
} }
@@ -30,15 +30,15 @@ public class AsyncStructureFinder extends AsyncFeatureFinder<StructureConfig> {
* @param z Z coordinate * @param z Z coordinate
* @return Whether location is a valid spawn for StructureConfig * @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, StructureTemplate target) {
World world = getWorld(); World world = getWorld();
Location spawn = target.getSpawn().getChunkSpawn(x, z, world.getSeed()).toLocation(world); Location spawn = target.getSpawn().getChunkSpawn(x, z, world.getSeed()).toLocation(world);
if(!((UserDefinedBiome) getGrid().getBiome(spawn)).getConfig().getStructures().contains(target)) if(!((UserDefinedBiome) getGrid().getBiome(spawn)).getConfig().getStructures().contains(target))
return false; return false;
Random r2 = new FastRandom(spawn.hashCode()); 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); Rotation rotation = Rotation.fromDegrees(r2.nextInt(4) * 90);
for(int y = target.getSearchStart().get(r2); y > 0; y--) { for(int y = target.getY().get(r2); y > 0; y--) {
if(!target.getBound().isInRange(y)) return false; if(!target.getBound().isInRange(y)) return false;
spawn.setY(y); spawn.setY(y);
if(!struc.checkSpawns(spawn, rotation)) continue; if(!struc.checkSpawns(spawn, rotation)) continue;
@@ -26,7 +26,7 @@ public class BiomeZone {
this.noise.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2); this.noise.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
this.noise.setFractalType(FastNoiseLite.FractalType.FBm); this.noise.setFractalType(FastNoiseLite.FractalType.FBm);
this.noise.setFractalOctaves(4); this.noise.setFractalOctaves(4);
this.noise.setFrequency(wc.getConfig().zoneFreq); this.noise.setFrequency(wc.getConfig().getTemplate().getZoneFreq());
this.grids = grids; this.grids = grids;
imageLoader = wc.imageLoader; imageLoader = wc.imageLoader;
useImage = wc.fromImage; useImage = wc.fromImage;
@@ -0,0 +1,4 @@
package com.dfsek.terra.biome;
public class OreEntry {
}
@@ -0,0 +1,10 @@
package com.dfsek.terra.biome;
import org.bukkit.block.data.BlockData;
import org.polydev.gaea.world.palette.Palette;
public class PaletteHolder {
public Palette<BlockData> getPalette(int y) {
return null; // TODO: implementation
}
}
@@ -1,7 +1,8 @@
package com.dfsek.terra.biome; package com.dfsek.terra.biome;
import com.dfsek.terra.config.genconfig.biome.BiomeConfig; import com.dfsek.terra.WorldObject;
import com.dfsek.terra.config.genconfig.biome.GeneratorOptions; import com.dfsek.terra.config.builder.GeneratorBuilder;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.generation.UserDefinedDecorator; import com.dfsek.terra.generation.UserDefinedDecorator;
import org.bukkit.World; import org.bukkit.World;
import org.polydev.gaea.biome.Biome; import org.polydev.gaea.biome.Biome;
@@ -14,16 +15,16 @@ import java.util.List;
/** /**
* Class representing a config-defined biome * Class representing a config-defined biome
*/ */
public class UserDefinedBiome implements Biome { public class UserDefinedBiome implements Biome, WorldObject {
private final GeneratorOptions gen; private final GeneratorBuilder gen;
private final UserDefinedDecorator decorator; private final UserDefinedDecorator decorator;
private final org.bukkit.block.Biome vanilla; private final org.bukkit.block.Biome vanilla;
private final String id; private final String id;
private final BiomeConfig config; private final BiomeTemplate config;
private final boolean erode; private final boolean 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, boolean erode, BiomeTemplate config) {
this.vanilla = vanilla; this.vanilla = vanilla;
this.decorator = dec; this.decorator = dec;
this.gen = gen; this.gen = gen;
@@ -49,7 +50,7 @@ public class UserDefinedBiome implements Biome {
*/ */
@Override @Override
public Generator getGenerator() { public Generator getGenerator() {
return gen.getGenerator(0); return gen.build(0);
} }
/** /**
@@ -80,12 +81,12 @@ public class UserDefinedBiome implements Biome {
return erode; return erode;
} }
public BiomeConfig getConfig() { public BiomeTemplate getConfig() {
return config; return config;
} }
@Override @Override
public Generator getGenerator(World w) { 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,6 +5,7 @@ import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.postprocessing.CoordinatePerturb; import com.dfsek.terra.biome.postprocessing.CoordinatePerturb;
import com.dfsek.terra.biome.postprocessing.ErosionNoise; import com.dfsek.terra.biome.postprocessing.ErosionNoise;
import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.base.ConfigPackTemplate;
import com.dfsek.terra.config.base.PluginConfig; import com.dfsek.terra.config.base.PluginConfig;
import com.dfsek.terra.config.lang.LangUtil; import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.procgen.math.Vector2; import com.dfsek.terra.procgen.math.Vector2;
@@ -21,16 +22,17 @@ public class TerraBiomeGrid extends BiomeGrid {
private final BiomeZone zone; private final BiomeZone zone;
private CoordinatePerturb perturb; private CoordinatePerturb perturb;
private ErosionNoise erode; private ErosionNoise erode;
private UserDefinedGrid erosionGrid; private BiomeGrid 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, BiomeGrid erosion) {
super(w, freq1, freq2, 0, 0); super(w, freq1, freq2, 0, 0);
if(c.biomeBlend) { ConfigPackTemplate t = c.getTemplate();
perturb = new CoordinatePerturb(c.blendFreq, c.blendAmp, w.getSeed()); if(c.getTemplate().isBlend()) {
perturb = new CoordinatePerturb(t.getBlendFreq(), t.getBlendAmp(), w.getSeed());
} }
this.zone = zone; this.zone = zone;
if(c.erosionEnable) { if(c.getTemplate().isErode()) {
erode = new ErosionNoise(c.erosionFreq, c.erosionThresh, c.erosionOctaves, w.getSeed()); erode = new ErosionNoise(t.getErodeFreq(), t.getErodeThresh(), t.getErodeOctaves(), w.getSeed());
this.erosionGrid = erosion; this.erosionGrid = erosion;
} }
} }
@@ -1,6 +1,5 @@
package com.dfsek.terra.biome.grid; package com.dfsek.terra.biome.grid;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.base.WorldConfig; import com.dfsek.terra.config.base.WorldConfig;
import com.dfsek.terra.image.ImageLoader; import com.dfsek.terra.image.ImageLoader;
import org.bukkit.Location; import org.bukkit.Location;
@@ -16,7 +15,7 @@ public class UserDefinedGrid extends BiomeGrid {
private final ImageLoader.Channel channelX; private final ImageLoader.Channel channelX;
private final ImageLoader.Channel channelZ; 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(w, freq1, freq2, b.length, b[0].length);
super.setGrid(b); super.setGrid(b);
imageLoader = c.imageLoader; imageLoader = c.imageLoader;
@@ -9,7 +9,7 @@ import org.polydev.gaea.math.FastNoiseLite;
public class CoordinatePerturb { public class CoordinatePerturb {
private final FastNoiseLite perturbX; private final FastNoiseLite perturbX;
private final FastNoiseLite perturbZ; private final FastNoiseLite perturbZ;
private final int amplitude; private final double amplitude;
/** /**
* Create a CoordinatePerturb object with a given frequency, amplitude, and seed. * Create a CoordinatePerturb object with a given frequency, amplitude, and seed.
@@ -18,7 +18,7 @@ public class CoordinatePerturb {
* @param amplitude Offset amplitude * @param amplitude Offset amplitude
* @param seed Noise seed * @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 = new FastNoiseLite((int) seed);
perturbX.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2); perturbX.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
perturbX.setFrequency(frequency); perturbX.setFrequency(frequency);
@@ -0,0 +1,53 @@
package com.dfsek.terra.carving;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.polydev.gaea.math.ProbabilityCollection;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
@SuppressWarnings("unchecked")
public class CarverPalette {
private final boolean blacklist;
private final Set<Material> replace;
private final TreeMap<Integer, ProbabilityCollection<BlockData>> map = new TreeMap<>();
private ProbabilityCollection<BlockData>[] layers;
public CarverPalette(Set<Material> 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;
}
}
}
@@ -3,6 +3,7 @@ package com.dfsek.terra.carving;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.templates.CarverTemplate;
import net.jafama.FastMath; import net.jafama.FastMath;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
@@ -26,8 +27,9 @@ public class UserDefinedCarver extends Carver {
private double step = 2; private double step = 2;
private Range recalc = new Range(8, 10); private Range recalc = new Range(8, 10);
private double recalcMagnitude = 3; private double recalcMagnitude = 3;
private final CarverTemplate config;
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 radius, Range length, double[] start, double[] mutate, double[] radiusMultiplier, int hash, int topCut, int bottomCut, CarverTemplate config) {
super(height.getMin(), height.getMax()); super(height.getMin(), height.getMax());
this.radius = radius; this.radius = radius;
this.length = length; this.length = length;
@@ -37,6 +39,7 @@ public class UserDefinedCarver extends Carver {
this.hash = hash; this.hash = hash;
this.topCut = topCut; this.topCut = topCut;
this.bottomCut = bottomCut; this.bottomCut = bottomCut;
this.config = config;
} }
@Override @Override
@@ -60,7 +63,11 @@ public class UserDefinedCarver extends Carver {
@Override @Override
public boolean isChunkCarved(World w, int chunkX, int chunkZ, Random random) { public boolean isChunkCarved(World w, int chunkX, int chunkZ, Random random) {
ConfigPack c = TerraWorld.getWorld(w).getConfig(); 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); return new FastRandom(random.nextLong() + hash).nextInt(100) < ((UserDefinedBiome) TerraWorld.getWorld(w).getGrid().getBiome(chunkX << 4, chunkZ << 4, GenerationPhase.POPULATE)).getConfig().getCarvers().get(this);
}
public CarverTemplate getConfig() {
return config;
} }
private class UserDefinedWorm extends Worm { private class UserDefinedWorm extends Worm {
@@ -1,18 +1,11 @@
package com.dfsek.terra.command; 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.World;
import org.bukkit.block.Block;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.command.WorldCommand; import org.polydev.gaea.command.WorldCommand;
import org.polydev.gaea.util.FastRandom;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -24,6 +17,7 @@ public class OreCommand extends WorldCommand {
@Override @Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World w) { public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World w) {
/*
Block bl = sender.getTargetBlockExact(25); Block bl = sender.getTargetBlockExact(25);
if(args.length > 0) { if(args.length > 0) {
OreConfig ore = TerraWorld.getWorld(w).getConfig().getOre(args[0]); OreConfig ore = TerraWorld.getWorld(w).getConfig().getOre(args[0]);
@@ -40,7 +34,11 @@ public class OreCommand extends WorldCommand {
} else { } else {
LangUtil.send("command.ore.main-menu", sender); LangUtil.send("command.ore.main-menu", sender);
} }
*/
return true; return true;
// TODO: implementation
} }
@Override @Override
@@ -1,7 +1,6 @@
package com.dfsek.terra.command; package com.dfsek.terra.command;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.base.PluginConfig; import com.dfsek.terra.config.base.PluginConfig;
import com.dfsek.terra.config.lang.LangUtil; import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@@ -31,7 +30,6 @@ public class ReloadCommand extends Command implements DebugCommand {
public boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) { public boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
PluginConfig.load(getMain()); PluginConfig.load(getMain());
LangUtil.load(PluginConfig.getLanguage(), getMain()); // Load language. LangUtil.load(PluginConfig.getLanguage(), getMain()); // Load language.
ConfigPack.loadAll(getMain());
TerraWorld.invalidate(); TerraWorld.invalidate();
LangUtil.send("command.reload", sender); LangUtil.send("command.reload", sender);
return true; return true;
@@ -3,11 +3,10 @@ package com.dfsek.terra.command.biome;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.base.ConfigPack; 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.lang.LangUtil;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.generation.TerraChunkGenerator; import com.dfsek.terra.generation.TerraChunkGenerator;
import com.dfsek.terra.structure.TerraStructure;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@@ -30,7 +29,7 @@ public class BiomeInfoCommand extends WorldCommand {
ConfigPack cfg = TerraWorld.getWorld(world).getConfig(); ConfigPack cfg = TerraWorld.getWorld(world).getConfig();
UserDefinedBiome b; UserDefinedBiome b;
try { try {
b = cfg.getBiome(id).getBiome(); b = cfg.getBiome(id);
} catch(IllegalArgumentException | NullPointerException e) { } catch(IllegalArgumentException | NullPointerException e) {
LangUtil.send("command.biome.invalid", sender, id); LangUtil.send("command.biome.invalid", sender, id);
return true; return true;
@@ -40,18 +39,19 @@ public class BiomeInfoCommand extends WorldCommand {
sender.sendMessage("Erodible: " + b.isErodible()); sender.sendMessage("Erodible: " + b.isErodible());
BiomeConfig bio = b.getConfig(); BiomeTemplate bio = b.getConfig();
List<StructureConfig> structureConfigs = bio.getStructures(); List<TerraStructure> structureConfigs = bio.getStructures();
if(structureConfigs.size() == 0) sender.sendMessage("No Structures"); if(structureConfigs.size() == 0) sender.sendMessage("No Structures");
else { else {
sender.sendMessage("-------Structures-------"); sender.sendMessage("-------Structures-------");
for(StructureConfig c : structureConfigs) { for(TerraStructure c : structureConfigs) {
sender.sendMessage(" - " + c.getID()); sender.sendMessage(" - " + c.getID());
} }
} }
// Get snow info // Get snow info
/*
BiomeSnowConfig snowConfig = bio.getSnow(); BiomeSnowConfig snowConfig = bio.getSnow();
StringBuilder snowMessage = new StringBuilder("----------Snow----------\n"); StringBuilder snowMessage = new StringBuilder("----------Snow----------\n");
int comp = snowConfig.getSnowChance(0); int comp = snowConfig.getSnowChance(0);
@@ -84,6 +84,8 @@ public class BiomeInfoCommand extends WorldCommand {
sender.sendMessage("Do snow: " + snowConfig.doSnow()); sender.sendMessage("Do snow: " + snowConfig.doSnow());
*/
// TODO: implementation
return true; return true;
} }
@@ -39,7 +39,7 @@ public class BiomeLocateCommand extends WorldCommand {
} }
UserDefinedBiome b; UserDefinedBiome b;
try { try {
b = TerraWorld.getWorld(world).getConfig().getBiome(id).getBiome(); b = TerraWorld.getWorld(world).getConfig().getBiome(id);
} catch(IllegalArgumentException | NullPointerException e) { } catch(IllegalArgumentException | NullPointerException e) {
LangUtil.send("command.biome.invalid", sender, id); LangUtil.send("command.biome.invalid", sender, id);
return true; return true;
@@ -3,8 +3,8 @@ package com.dfsek.terra.command.structure;
import com.dfsek.terra.Terra; import com.dfsek.terra.Terra;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.async.AsyncStructureFinder; 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.config.lang.LangUtil;
import com.dfsek.terra.config.templates.StructureTemplate;
import com.dfsek.terra.generation.TerraChunkGenerator; import com.dfsek.terra.generation.TerraChunkGenerator;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@@ -38,7 +38,7 @@ public class LocateCommand extends WorldCommand {
LangUtil.send("command.structure.invalid-radius", sender, args[1]); LangUtil.send("command.structure.invalid-radius", sender, args[1]);
return true; return true;
} }
StructureConfig s; StructureTemplate s;
try { try {
s = Objects.requireNonNull(TerraWorld.getWorld(world).getConfig().getStructure(id)); s = Objects.requireNonNull(TerraWorld.getWorld(world).getConfig().getStructure(id));
} catch(IllegalArgumentException | NullPointerException e) { } 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.PluginConfig;
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(PluginConfig.isDebug()) 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,127 @@
package com.dfsek.terra.config.base; package com.dfsek.terra.config.base;
import com.dfsek.terra.Debug; import com.dfsek.tectonic.abstraction.AbstractConfigLoader;
import com.dfsek.terra.Terra; import com.dfsek.tectonic.exception.ConfigException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.carving.UserDefinedCarver; import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.ConfigLoader; import com.dfsek.terra.config.builder.BiomeGridBuilder;
import com.dfsek.terra.config.exception.ConfigException; import com.dfsek.terra.config.exception.FileMissingException;
import com.dfsek.terra.config.exception.NotFoundException; import com.dfsek.terra.config.factories.BiomeFactory;
import com.dfsek.terra.config.genconfig.BiomeGridConfig; import com.dfsek.terra.config.factories.BiomeGridFactory;
import com.dfsek.terra.config.genconfig.CarverConfig; import com.dfsek.terra.config.factories.CarverFactory;
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.lang.LangUtil; import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.registry.FloraRegistry; import com.dfsek.terra.config.loaders.NoiseBuilderLoader;
import com.dfsek.terra.registry.TreeRegistry; import com.dfsek.terra.config.templates.BiomeGridTemplate;
import com.dfsek.terra.util.StructureTypeEnum; import com.dfsek.terra.config.templates.BiomeTemplate;
import org.bukkit.configuration.ConfigurationSection; import com.dfsek.terra.config.templates.CarverTemplate;
import org.bukkit.configuration.InvalidConfigurationException; import com.dfsek.terra.config.templates.StructureTemplate;
import org.bukkit.configuration.file.YamlConfiguration; import com.dfsek.terra.generation.config.NoiseBuilder;
import org.bukkit.plugin.java.JavaPlugin; import com.dfsek.terra.util.ConfigUtil;
import parsii.eval.Scope;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.FileInputStream;
import java.nio.file.Files; import java.io.FileNotFoundException;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors;
/** /**
* Represents a Terra configuration pack. * Represents a Terra configuration pack.
*/ */
public class ConfigPack extends YamlConfiguration { public class ConfigPack {
private static final Map<String, ConfigPack> configs = new HashMap<>(); private static final Map<String, ConfigPack> configs = new HashMap<>();
public final List<String> biomeList; private final ConfigPackTemplate template = new ConfigPackTemplate();
public final double zoneFreq; private final Map<String, UserDefinedBiome> biomes = new HashMap<>();
public final double freq1; private final Map<String, BiomeGridBuilder> biomeGrids = new HashMap<>();
public final double freq2; private final Map<String, StructureTemplate> structures = new HashMap<>();
public final double erosionFreq; private final Map<String, UserDefinedCarver> carvers = new HashMap<>();
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();
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;
public ConfigPack(File file) throws IOException, InvalidConfigurationException { public ConfigPack(File folder) throws ConfigException {
long l = System.nanoTime(); long l = System.nanoTime();
load(new File(file, "pack.yml"));
dataFolder = file;
if(!contains("id")) throw new ConfigException("No ID specified!", "null"); File pack = new File(folder, "pack.yml");
this.id = getString("id");
Map<String, Object> noise = Objects.requireNonNull(getConfigurationSection("noise")).getValues(false); ConfigLoader loader = new ConfigLoader();
for(Map.Entry<String, Object> entry : noise.entrySet()) { loader.registerLoader(NoiseBuilder.class, new NoiseBuilderLoader());
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 { try {
subfolder = Files.walk(file.toPath(), 1) loader.load(template, new FileInputStream(pack));
.filter(Files::isDirectory) } catch(FileNotFoundException e) {
.collect(Collectors.toList()); throw new FileMissingException("No pack.yml file found in " + folder.getAbsolutePath(), e);
} catch(IOException e) {
e.printStackTrace();
return;
}
subfolder.remove(0);
for(Path folder : subfolder) {
ConfigPack config;
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();
}
} }
AbstractConfigLoader abstractConfigLoader = new AbstractConfigLoader();
List<StructureTemplate> structureTemplates = abstractConfigLoader.load(ConfigUtil.loadFromPath(new File(folder, "structures/single").toPath()), StructureTemplate::new);
structureTemplates.forEach(structure -> structures.put(structure.getId(), structure));
List<CarverTemplate> carverTemplates = abstractConfigLoader.load(ConfigUtil.loadFromPath(new File(folder, "carving").toPath()), CarverTemplate::new);
CarverFactory carverFactory = new CarverFactory();
carverTemplates.forEach(carver -> carvers.put(carver.getId(), carverFactory.build(carver)));
List<BiomeTemplate> biomeTemplates = abstractConfigLoader.load(ConfigUtil.loadFromPath(new File(folder, "biomes").toPath()), () -> new BiomeTemplate(this));
BiomeFactory biomeFactory = new BiomeFactory();
biomeTemplates.forEach(biome -> biomes.put(biome.getID(), biomeFactory.build(biome)));
List<BiomeGridTemplate> biomeGridTemplates = abstractConfigLoader.load(ConfigUtil.loadFromPath(new File(folder, "grids").toPath()), BiomeGridTemplate::new);
BiomeGridFactory biomeGridFactory = new BiomeGridFactory();
biomeGridTemplates.forEach(grid -> biomeGrids.put(grid.getID(), biomeGridFactory.build(grid)));
configs.put(template.getID(), this);
LangUtil.log("config-pack.loaded", Level.INFO, template.getID(), String.valueOf((System.nanoTime() - l) / 1000000D));
} }
public static synchronized ConfigPack fromID(String id) { public static ConfigPack fromID(String id) {
return configs.get(id); return configs.get(id);
} }
public String getID() { public UserDefinedBiome getBiome(String id) {
return 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); return biomes.get(id);
} }
public CarverConfig getCarver(String id) { public BiomeGridBuilder getBiomeGrid(String id) {
return carvers.get(id); return biomeGrids.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 List<String> getBiomeIDs() { public List<String> getBiomeIDs() {
List<String> fill = new ArrayList<>(); List<String> biomeIDs = new ArrayList<>();
for(BiomeConfig b : biomes.values()) { biomes.forEach((id, biome) -> biomeIDs.add(id));
fill.add(b.getID()); return biomeIDs;
} }
return fill;
public StructureTemplate getStructure(String id) {
return structures.get(id);
}
public Set<StructureTemplate> getStructures() {
return new HashSet<>(structures.values());
}
public Collection<UserDefinedCarver> getCarvers() {
return carvers.values();
}
public UserDefinedCarver getCarver(String id) {
return carvers.get(id);
} }
public List<String> getStructureIDs() { public List<String> getStructureIDs() {
List<String> fill = new ArrayList<>(); List<String> ids = new ArrayList<>();
for(StructureConfig s : structures.values()) { structures.forEach((id, structure) -> ids.add(id));
fill.add(s.getID()); return ids;
}
return fill;
} }
public FloraRegistry getFloraRegistry() { public ConfigPackTemplate getTemplate() {
return floraRegistry; return template;
}
public TreeRegistry getTreeRegistry() {
return treeRegistry;
} }
} }
@@ -0,0 +1,171 @@
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("erode.grid")
@Default
private String erodeGrid = null;
@Value("vanilla.mobs")
@Default
private boolean vanillaMobs = false;
@Value("vanilla.caves")
@Default
private boolean vanillaCaves = false;
@Value("vanilla.decorations")
@Default
private boolean vanillaDecorations = false;
@Value("vanilla.structures")
@Default
private boolean vanillaStructures = false;
public String getID() {
return id;
}
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;
}
public String getErodeGrid() {
return erodeGrid;
}
}
@@ -1,39 +0,0 @@
package com.dfsek.terra.config.base;
import com.dfsek.terra.Debug;
import com.dfsek.terra.config.exception.ConfigException;
import com.dfsek.terra.util.TagUtil;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.InvalidConfigurationException;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
public final class ConfigUtil {
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;
}
}
@@ -1,7 +1,7 @@
package com.dfsek.terra.config.base; package com.dfsek.terra.config.base;
import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.terra.Debug; import com.dfsek.terra.Debug;
import com.dfsek.terra.config.exception.ConfigException;
import com.dfsek.terra.config.lang.LangUtil; import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.image.ImageLoader; import com.dfsek.terra.image.ImageLoader;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
@@ -16,7 +16,7 @@ import java.io.IOException;
import java.util.Objects; import java.util.Objects;
import java.util.logging.Level; import java.util.logging.Level;
public class WorldConfig { public class WorldConfig implements ConfigTemplate {
private final String worldID; private final String worldID;
private final String configID; private final String configID;
private final GaeaPlugin main; private final GaeaPlugin main;
@@ -42,8 +42,6 @@ public class WorldConfig {
FileConfiguration config = new YamlConfiguration(); FileConfiguration config = new YamlConfiguration();
Debug.info("Loading config " + configID + " for world " + worldID); Debug.info("Loading config " + configID + " for world " + worldID);
try { // Load/create world config file 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"); File configFile = new File(main.getDataFolder() + File.separator + "worlds", worldID + ".yml");
if(!configFile.exists()) { if(!configFile.exists()) {
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored
@@ -58,9 +56,6 @@ public class WorldConfig {
tConfig = ConfigPack.fromID(configID); 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);
// Load image stuff // Load image stuff
try { try {
biomeXChannel = ImageLoader.Channel.valueOf(Objects.requireNonNull(config.getString("image.channels.biome-x", "red")).toUpperCase()); biomeXChannel = ImageLoader.Channel.valueOf(Objects.requireNonNull(config.getString("image.channels.biome-x", "red")).toUpperCase());
@@ -84,7 +79,7 @@ public class WorldConfig {
} catch(IllegalArgumentException | NullPointerException e) { } catch(IllegalArgumentException | NullPointerException e) {
throw new InvalidConfigurationException(e.getCause()); 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) { } catch(IOException | InvalidConfigurationException e) {
e.printStackTrace(); e.printStackTrace();
LangUtil.log("world-config.error", Level.SEVERE, worldID); LangUtil.log("world-config.error", Level.SEVERE, worldID);
@@ -0,0 +1,41 @@
package com.dfsek.terra.config.builder;
import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.grid.UserDefinedGrid;
import org.bukkit.World;
import org.polydev.gaea.biome.Biome;
public class BiomeGridBuilder {
private double xFreq;
private double zFreq;
private Biome[][] biomes;
public UserDefinedGrid build(World world) {
return new UserDefinedGrid(world, xFreq, zFreq, biomes, TerraWorld.getWorld(world).getWorldConfig());
}
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;
}
}
@@ -0,0 +1,84 @@
package com.dfsek.terra.config.builder;
import com.dfsek.terra.biome.PaletteHolder;
import com.dfsek.terra.generation.config.NoiseBuilder;
import com.dfsek.terra.generation.config.WorldGenerator;
import parsii.eval.Scope;
import java.util.Map;
public class GeneratorBuilder {
private String noiseEquation;
private String elevationEquation;
private Scope varScope;
private Map<String, NoiseBuilder> noiseBuilderMap;
private PaletteHolder palettes;
private PaletteHolder slantPalettes;
private boolean preventInterpolation;
public WorldGenerator build(long seed) {
return new WorldGenerator(seed, noiseEquation, elevationEquation, varScope, noiseBuilderMap, palettes, slantPalettes, preventInterpolation);
}
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;
}
}
@@ -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,23 @@
package com.dfsek.terra.config.factories;
import com.dfsek.terra.biome.UserDefinedBiome;
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> {
@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());
return new UserDefinedBiome(template.getVanilla(), decorator, generatorBuilder, template.isErodible(), template);
}
}
@@ -0,0 +1,35 @@
package com.dfsek.terra.config.factories;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.builder.BiomeGridBuilder;
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 BiomeGridBuilder build(BiomeGridTemplate config) {
BiomeGridBuilder holder = new BiomeGridBuilder();
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,15 @@
package com.dfsek.terra.config.factories;
import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.templates.CarverTemplate;
public class CarverFactory implements TerraFactory<CarverTemplate, UserDefinedCarver> {
@Override
public UserDefinedCarver build(CarverTemplate config) {
double[] start = new double[] {config.getStartX(), config.getStartY(), config.getStartZ()};
double[] mutate = new double[] {config.getMutateX(), config.getMutateY(), config.getMutateZ(), config.getMutateRadius()};
double[] radius = new double[] {config.getRadMX(), config.getRadMY(), config.getRadMZ()};
int hash = config.getId().hashCode();
return new UserDefinedCarver(config.getHeight(), config.getRadius(), config.getLength(), start, mutate, radius, hash, config.getCutTop(), config.getCutBottom(), config);
}
}
@@ -0,0 +1,7 @@
package com.dfsek.terra.config.factories;
import com.dfsek.tectonic.config.ConfigTemplate;
public interface TerraFactory<C extends ConfigTemplate, O> {
O build(C config);
}
@@ -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,105 +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.base.PluginConfig;
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(PluginConfig.isDebug()) {
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.PluginConfig;
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(PluginConfig.isDebug()) 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.PluginConfig;
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(PluginConfig.isDebug()) 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.PluginConfig;
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(PluginConfig.isDebug()) {
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,15 @@
package com.dfsek.terra.config.loaders;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import org.bukkit.Bukkit;
import org.bukkit.block.data.BlockData;
import java.lang.reflect.Type;
public class BlockDataLoader implements TypeLoader<BlockData> {
@Override
public BlockData load(Type type, Object o, ConfigLoader configLoader) {
return Bukkit.createBlockData((String) o);
}
}
@@ -0,0 +1,15 @@
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.bukkit.Material;
import java.lang.reflect.Type;
public class MaterialLoader implements TypeLoader<Material> {
@Override
public Material load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
return Material.getMaterial((String) o);
}
}
@@ -0,0 +1,37 @@
package com.dfsek.terra.config.loaders;
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,30 @@
package com.dfsek.terra.config.loaders.base;
import com.dfsek.tectonic.config.Configuration;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.carving.CarverPalette;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.polydev.gaea.math.ProbabilityCollection;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Set;
@SuppressWarnings("unchecked")
public class CarverPaletteLoader implements TypeLoader<CarverPalette> {
@Override
public CarverPalette load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
Configuration configuration = new Configuration((Map<String, Object>) o);
CarverPalette palette = new CarverPalette((Set<Material>) configLoader.loadType(Set.class, configuration.get("replace")), (Boolean) configuration.get("replace-blacklist"));
for(Map<String, Object> map : (List<Map<String, Object>>) configuration.get("layers")) {
ProbabilityCollection<BlockData> layer = (ProbabilityCollection<BlockData>) configLoader.loadType(ProbabilityCollection.class, map.get("materials"));
palette.add(layer, (Integer) map.get("y"));
}
return palette;
}
}
@@ -0,0 +1,43 @@
package com.dfsek.terra.config.templates;
import com.dfsek.tectonic.annotations.Abstractable;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import org.polydev.gaea.biome.Biome;
import java.util.List;
@SuppressWarnings("unused")
public class BiomeGridTemplate implements ConfigTemplate {
@Value("grid")
@Abstractable
private List<List<Biome>> grid;
@Value("id")
private String id;
@Value("frequency.x")
@Abstractable
private double xFreq;
@Value("frequency.z")
@Abstractable
private double zFreq;
public String getID() {
return id;
}
public List<List<Biome>> getGrid() {
return grid;
}
public double getXFreq() {
return xFreq;
}
public double getZFreq() {
return zFreq;
}
}
@@ -0,0 +1,135 @@
package com.dfsek.terra.config.templates;
import com.dfsek.tectonic.annotations.Abstractable;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.terra.biome.PaletteHolder;
import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.generation.items.ores.Ore;
import com.dfsek.terra.structure.TerraStructure;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.polydev.gaea.util.GlueList;
import org.polydev.gaea.world.palette.Palette;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SuppressWarnings({"FieldMayBeFinal", "unused"})
public class BiomeTemplate implements ConfigTemplate {
private final ConfigPack pack;
@Value("id")
private String id;
@Value("palette")
@Abstractable
private PaletteHolder palette;
@Value("slant.palette")
@Abstractable
private PaletteHolder slantPalette;
@Value("vanilla")
@Abstractable
private Biome vanilla;
@Value("erodible")
@Abstractable
@Default
private boolean erodible = false;
@Value("structures")
@Abstractable
@Default
private List<TerraStructure> structures = new GlueList<>();
@Value("carving")
@Abstractable
@Default
private Map<UserDefinedCarver, Integer> carvers = new HashMap<>();
@Value("noise-equation")
@Abstractable
private String noiseEquation;
@Value("ores")
@Abstractable
@Default
private List<Ore> ores = new GlueList<>();
@Value("ocean.level")
@Default
private int seaLevel = 62;
@Value("ocean.palette")
@Default
private Palette<BlockData> oceanPalette; // TODO: default palette
@Value("slant.y-offset.top")
@Default
private double slantOffsetTop = 0.5D;
@Value("slant.y-offset-bottom")
@Default
private double slantOffsetBottom = 0.25;
@Value("elevation.equation")
@Default
@Abstractable
private String elevationEquation = null;
public BiomeTemplate(ConfigPack pack) {
this.pack = pack;
}
public String getElevationEquation() {
return elevationEquation;
}
public ConfigPack getPack() {
return pack;
}
public int getSeaLevel() {
return seaLevel;
}
public Palette<BlockData> getOceanPalette() {
return oceanPalette;
}
public String getID() {
return id;
}
public PaletteHolder getPalette() {
return palette;
}
public PaletteHolder getSlantPalette() {
return slantPalette;
}
public Biome getVanilla() {
return vanilla;
}
public boolean isErodible() {
return erodible;
}
public List<TerraStructure> getStructures() {
return structures;
}
public Map<UserDefinedCarver, Integer> getCarvers() {
return carvers;
}
public String getNoiseEquation() {
return noiseEquation;
}
public List<Ore> getOres() {
return ores;
}
public double getSlantOffsetTop() {
return slantOffsetTop;
}
public double getSlantOffsetBottom() {
return slantOffsetBottom;
}
}
@@ -0,0 +1,205 @@
package com.dfsek.terra.config.templates;
import com.dfsek.tectonic.annotations.Abstractable;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.terra.carving.CarverPalette;
import org.bukkit.Material;
import org.polydev.gaea.math.Range;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@SuppressWarnings({"unused", "FieldMayBeFinal"})
public class CarverTemplate implements ConfigTemplate {
@Value("id")
private String id;
@Value("step")
@Abstractable
@Default
private int step = 2;
@Value("length")
@Abstractable
private Range length;
@Value("start.x")
@Abstractable
private double startX;
@Value("start.y")
@Abstractable
private double startY;
@Value("start.z")
@Abstractable
private double startZ;
@Value("start.radius.x")
@Abstractable
private double radMX;
@Value("start.radius.y")
@Abstractable
private double radMY;
@Value("start.radius.z")
@Abstractable
private double radMZ;
@Value("start.radius")
@Abstractable
private Range radius;
@Value("start.height")
@Abstractable
private Range height;
@Value("cut.bottom")
@Abstractable
@Default
private int cutBottom = 0;
@Value("cut.top")
@Abstractable
@Default
private int cutTop = 0;
@Value("mutate.x")
@Abstractable
private double mutateX;
@Value("mutate.y")
@Abstractable
private double mutateY;
@Value("mutate.z")
@Abstractable
private double mutateZ;
@Value("mutate.radius")
@Abstractable
private double mutateRadius;
@Value("palette.top")
@Abstractable
private CarverPalette top;
@Value("palette.bottom")
@Abstractable
private CarverPalette bottom;
@Value("palette.outer")
@Abstractable
private CarverPalette outer;
@Value("palette.inner")
@Abstractable
private CarverPalette inner;
@Value("shift")
@Abstractable
@Default
private Map<Material, Set<Material>> shift = new HashMap<>();
@Value("update")
@Abstractable
@Default
private Set<Material> update = new HashSet<>();
public String getId() {
return id;
}
public int getStep() {
return step;
}
public Range getLength() {
return length;
}
public double getStartX() {
return startX;
}
public double getStartY() {
return startY;
}
public double getStartZ() {
return startZ;
}
public double getRadMX() {
return radMX;
}
public double getRadMY() {
return radMY;
}
public double getRadMZ() {
return radMZ;
}
public Range getRadius() {
return radius;
}
public Range getHeight() {
return height;
}
public int getCutBottom() {
return cutBottom;
}
public int getCutTop() {
return cutTop;
}
public double getMutateX() {
return mutateX;
}
public double getMutateY() {
return mutateY;
}
public double getMutateZ() {
return mutateZ;
}
public double getMutateRadius() {
return mutateRadius;
}
public CarverPalette getTop() {
return top;
}
public CarverPalette getBottom() {
return bottom;
}
public CarverPalette getOuter() {
return outer;
}
public CarverPalette getInner() {
return inner;
}
public Map<Material, Set<Material>> getShift() {
return shift;
}
public Set<Material> getUpdate() {
return update;
}
}
@@ -0,0 +1,65 @@
package com.dfsek.terra.config.templates;
import com.dfsek.tectonic.annotations.Abstractable;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import com.google.common.collect.Sets;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.polydev.gaea.world.palette.Palette;
import java.util.Set;
@SuppressWarnings({"FieldMayBeFinal", "unused"})
public class FloraTemplate implements ConfigTemplate {
@Value("id")
private String id;
@Value("spawnable")
@Abstractable
private Set<BlockData> spawnable;
@Value("replaceable")
@Abstractable
@Default
private Set<BlockData> replaceable = Sets.newHashSet(Material.AIR.createBlockData());
@Value("layers")
@Abstractable
private Palette<BlockData> floraPalette;
@Value("physics")
@Abstractable
@Default
private boolean doPhysics = false;
@Value("ceiling")
@Abstractable
@Default
private boolean ceiling = false;
public Set<BlockData> getReplaceable() {
return replaceable;
}
public Set<BlockData> getSpawnable() {
return spawnable;
}
public String getID() {
return id;
}
public Palette<BlockData> getFloraPalette() {
return floraPalette;
}
public boolean doPhysics() {
return doPhysics;
}
public boolean isCeiling() {
return ceiling;
}
}
@@ -0,0 +1,78 @@
package com.dfsek.terra.config.templates;
import com.dfsek.tectonic.annotations.Abstractable;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import org.bukkit.block.data.BlockData;
import java.util.List;
@SuppressWarnings({"unused", "FieldMayBeFinal"})
public class OreTemplate implements ConfigTemplate {
@Value("id")
private String id;
@Value("material")
@Abstractable
private BlockData material;
@Value("radius.min")
@Abstractable
private double minRadius;
@Value("radius.max")
@Abstractable
private double maxRadius;
@Value("deform")
@Abstractable
@Default
private double deform = 0.75D;
@Value("deform-frequency")
@Abstractable
@Default
private double deformFrequency = 0.1D;
@Value("replace")
@Abstractable
private List<BlockData> replaceable;
@Value("physics")
@Abstractable
@Default
private boolean physics = false;
public BlockData getMaterial() {
return material;
}
public double getDeform() {
return deform;
}
public double getDeformFrequency() {
return deformFrequency;
}
public double getMaxRadius() {
return maxRadius;
}
public double getMinRadius() {
return minRadius;
}
public List<BlockData> getReplaceable() {
return replaceable;
}
public boolean doPhysics() {
return physics;
}
public String getId() {
return id;
}
}
@@ -0,0 +1,49 @@
package com.dfsek.terra.config.templates;
import com.dfsek.tectonic.annotations.Abstractable;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import org.bukkit.block.data.BlockData;
import org.polydev.gaea.world.palette.Palette;
@SuppressWarnings({"FieldMayBeFinal", "unused"})
public class PaletteTemplate implements ConfigTemplate {
@Value("id")
private String id;
@Value("palette")
@Abstractable
private Palette<BlockData> palette;
@Value("simplex")
@Abstractable
@Default
private boolean simplex = false;
@Value("frequency")
@Abstractable
@Default
private double frequency = 0.02D;
@Value("seed")
@Abstractable
@Default
private long seed = 0;
public String getId() {
return id;
}
public double getFrequency() {
return frequency;
}
public long getSeed() {
return seed;
}
public Palette<BlockData> getPalette() {
return palette;
}
}
@@ -0,0 +1,78 @@
package com.dfsek.terra.config.templates;
import com.dfsek.tectonic.annotations.Abstractable;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.terra.procgen.GridSpawn;
import com.dfsek.terra.structure.Structure;
import org.polydev.gaea.math.ProbabilityCollection;
import org.polydev.gaea.math.Range;
import org.polydev.gaea.structures.loot.LootTable;
import java.util.Map;
@SuppressWarnings("unused")
public class StructureTemplate implements ConfigTemplate {
@Value("id")
private String id;
@Value("files")
@Abstractable
private ProbabilityCollection<Structure> structures;
@Value("spawn.start")
@Abstractable
private Range y;
@Value("spawn.bound")
@Abstractable
private Range bound;
@Value("spawn.width")
@Abstractable
private int width;
@Value("spawn.padding")
@Abstractable
private int padding;
@Value("spawn")
@Abstractable
private GridSpawn spawn;
@Value("loot")
@Abstractable
private Map<Integer, LootTable> loot;
public Map<Integer, LootTable> getLoot() {
return loot;
}
public String getId() {
return id;
}
public ProbabilityCollection<Structure> getStructures() {
return structures;
}
public Range getY() {
return y;
}
public Range getBound() {
return bound;
}
public int getWidth() {
return width;
}
public int getPadding() {
return padding;
}
public GridSpawn getSpawn() {
return spawn;
}
}
@@ -0,0 +1,46 @@
package com.dfsek.terra.config.templates;
import com.dfsek.tectonic.annotations.Abstractable;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.terra.structure.Structure;
import org.bukkit.Material;
import org.polydev.gaea.math.ProbabilityCollection;
import java.util.Set;
@SuppressWarnings({"unused", "FieldMayBeFinal"})
public class TreeTemplate implements ConfigTemplate {
@Value("files")
@Abstractable
private ProbabilityCollection<Structure> structures;
@Value("id")
private String id;
@Value("y-offset")
@Abstractable
@Default
private int yOffset = 0;
@Value("spawnable")
@Abstractable
private Set<Material> spawnable;
public ProbabilityCollection<Structure> getStructures() {
return structures;
}
public String getId() {
return id;
}
public int getyOffset() {
return yOffset;
}
public Set<Material> getSpawnable() {
return spawnable;
}
}
@@ -1,25 +1,25 @@
package com.dfsek.terra.event; package com.dfsek.terra.event;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.config.genconfig.OreConfig; import com.dfsek.terra.generation.items.ores.Ore;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
public class OreVeinGenerateEvent extends TerraWorldEvent implements Cancellable { public class OreVeinGenerateEvent extends TerraWorldEvent implements Cancellable {
private boolean cancelled; private boolean cancelled;
private OreConfig config; private Ore ore;
public OreVeinGenerateEvent(TerraWorld tw, Location l, OreConfig config) { public OreVeinGenerateEvent(TerraWorld tw, Location l, Ore ore) {
super(tw, l); super(tw, l);
this.config = config; this.ore = ore;
} }
public OreConfig getConfig() { public Ore getConfig() {
return config; return ore;
} }
public void setConfig(OreConfig config) { public void setOre(Ore ore) {
this.config = config; this.ore = ore;
} }
@Override @Override
@@ -6,10 +6,8 @@ import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.genconfig.biome.BiomeConfig;
import com.dfsek.terra.config.genconfig.biome.BiomeSlabConfig;
import com.dfsek.terra.config.lang.LangUtil; import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.generation.config.WorldGenerator; import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.population.CavePopulator; import com.dfsek.terra.population.CavePopulator;
import com.dfsek.terra.population.FloraPopulator; import com.dfsek.terra.population.FloraPopulator;
import com.dfsek.terra.population.OrePopulator; import com.dfsek.terra.population.OrePopulator;
@@ -79,11 +77,11 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
popMap.get(c.getWorld()).checkNeighbors(c.getX(), c.getZ(), c.getWorld()); popMap.get(c.getWorld()).checkNeighbors(c.getX(), c.getZ(), c.getWorld());
} }
private static Palette<BlockData> getPalette(int x, int y, int z, BiomeConfig c, ChunkInterpolator interpolator, ElevationInterpolator elevationInterpolator) { private static Palette<BlockData> getPalette(int x, int y, int z, BiomeTemplate c, ChunkInterpolator interpolator, ElevationInterpolator elevationInterpolator) {
Palette<BlockData> slant = ((WorldGenerator) c.getBiome().getGenerator()).getSlantPalette(y); Palette<BlockData> slant = c.getSlantPalette().getPalette(y);
if(slant != null) { if(slant != null) {
double ySlantOffsetTop = c.getYSlantOffsetTop(); double ySlantOffsetTop = c.getSlantOffsetTop();
double ySlantOffsetBottom = c.getYSlantOffsetBottom(); double ySlantOffsetBottom = c.getSlantOffsetBottom();
boolean top = interpolator.getNoise(x, y + ySlantOffsetTop - elevationInterpolator.getElevation(x, z), z) > 0; boolean top = interpolator.getNoise(x, y + ySlantOffsetTop - elevationInterpolator.getElevation(x, z), z) > 0;
boolean bottom = interpolator.getNoise(x, y - ySlantOffsetBottom - elevationInterpolator.getElevation(x, z), z) > 0; boolean bottom = interpolator.getNoise(x, y - ySlantOffsetBottom - elevationInterpolator.getElevation(x, z), z) > 0;
@@ -96,7 +94,7 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
if((north || south || east || west) && (!(north && south && east && west))) return slant; if((north || south || east || west) && (!(north && south && east && west))) return slant;
} }
} }
return c.getBiome().getGenerator().getPalette(y); return c.getPalette().getPalette(y);
} }
private static void prepareBlockPart(BlockData down, BlockData orig, ChunkData chunk, Vector block, Map<Material, Palette<BlockData>> slabs, private static void prepareBlockPart(BlockData down, BlockData orig, ChunkData chunk, Vector block, Map<Material, Palette<BlockData>> slabs,
@@ -166,21 +164,20 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
int cz = zOrig + z; int cz = zOrig + z;
Biome b = grid.getBiome(xOrig + x, zOrig + z, GenerationPhase.PALETTE_APPLY); Biome b = grid.getBiome(xOrig + x, zOrig + z, GenerationPhase.PALETTE_APPLY);
BiomeConfig c = ((UserDefinedBiome) b).getConfig(); BiomeTemplate c = ((UserDefinedBiome) b).getConfig();
double elevate = elevationInterpolator.getElevation(x, z); double elevate = elevationInterpolator.getElevation(x, z);
BiomeSlabConfig slab = c.getSlabs(); int sea = c.getSeaLevel();
int sea = c.getOcean().getSeaLevel(); Palette<BlockData> seaPalette = c.getOceanPalette();
Palette<BlockData> seaPalette = c.getOcean().getOcean();
for(int y = world.getMaxHeight() - 1; y >= 0; y--) { for(int y = world.getMaxHeight() - 1; y >= 0; y--) {
if(interpolator.getNoise(x, y - elevate, z) > 0) { if(interpolator.getNoise(x, y - elevate, z) > 0) {
BlockData data = getPalette(x, y, z, c, interpolator, elevationInterpolator).get(paletteLevel, cx, cz); BlockData data = getPalette(x, y, z, c, interpolator, elevationInterpolator).get(paletteLevel, cx, cz);
chunk.setBlock(x, y, z, data); chunk.setBlock(x, y, z, data);
if(paletteLevel == 0 && slab != null && y < 255) { /*if(paletteLevel == 0 && slab != null && y < 255) {
prepareBlockPart(data, chunk.getBlockData(x, y + 1, z), chunk, new Vector(x, y + 1, z), slab.getSlabs(), prepareBlockPart(data, chunk.getBlockData(x, y + 1, z), chunk, new Vector(x, y + 1, z), slab.getSlabs(),
slab.getStairs(), slab.getSlabThreshold(), interpolator, elevationInterpolator); slab.getStairs(), slab.getSlabThreshold(), interpolator, elevationInterpolator);
} }*/
paletteLevel++; paletteLevel++;
} else if(y <= sea) { } else if(y <= sea) {
chunk.setBlock(x, y, z, seaPalette.get(sea - y, x + xOrig, z + zOrig)); chunk.setBlock(x, y, z, seaPalette.get(sea - y, x + xOrig, z + zOrig));
@@ -238,22 +235,22 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
@Override @Override
public boolean shouldGenerateCaves() { public boolean shouldGenerateCaves() {
return configPack.vanillaCaves; return configPack.getTemplate().vanillaCaves();
} }
@Override @Override
public boolean shouldGenerateDecorations() { public boolean shouldGenerateDecorations() {
return configPack.vanillaDecoration; return configPack.getTemplate().vanillaDecorations();
} }
@Override @Override
public boolean shouldGenerateMobs() { public boolean shouldGenerateMobs() {
return configPack.vanillaMobs; return configPack.getTemplate().vanillaMobs();
} }
@Override @Override
public boolean shouldGenerateStructures() { public boolean shouldGenerateStructures() {
return configPack.vanillaStructures; return configPack.getTemplate().vanillaStructures();
} }
} }
@@ -1,27 +1,75 @@
package com.dfsek.terra.generation.config; package com.dfsek.terra.generation.config;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import org.polydev.gaea.math.FastNoiseLite; import org.polydev.gaea.math.FastNoiseLite;
public class NoiseBuilder { public class NoiseBuilder implements ConfigTemplate {
@Value("type")
@Default
private FastNoiseLite.NoiseType type = FastNoiseLite.NoiseType.OpenSimplex2; private FastNoiseLite.NoiseType type = FastNoiseLite.NoiseType.OpenSimplex2;
@Value("octaves")
@Default
private int octaves = 1; private int octaves = 1;
@Value("fractal.type")
@Default
private FastNoiseLite.FractalType fractalType = FastNoiseLite.FractalType.None; private FastNoiseLite.FractalType fractalType = FastNoiseLite.FractalType.None;
@Value("frequency")
@Default
private double frequency = 0.02D; private double frequency = 0.02D;
@Value("fractal.gain")
@Default
private double fractalGain = 0.5D; private double fractalGain = 0.5D;
@Value("fractal.lacunarity")
@Default
private double fractalLacunarity = 2.0D; private double fractalLacunarity = 2.0D;
@Value("fractal.ping-pong")
@Default
private double pingPong = 2.0D; private double pingPong = 2.0D;
@Value("fractal.weighted-strength")
@Default
private double weightedStrength = 0.0D; private double weightedStrength = 0.0D;
@Value("offset")
@Default
private int seedOffset = 0; private int seedOffset = 0;
@Value("cellular.distance")
@Default
private FastNoiseLite.CellularDistanceFunction cellularDistanceFunction = FastNoiseLite.CellularDistanceFunction.EuclideanSq; private FastNoiseLite.CellularDistanceFunction cellularDistanceFunction = FastNoiseLite.CellularDistanceFunction.EuclideanSq;
@Value("cellular.return")
@Default
private FastNoiseLite.CellularReturnType cellularReturnType = FastNoiseLite.CellularReturnType.Distance; private FastNoiseLite.CellularReturnType cellularReturnType = FastNoiseLite.CellularReturnType.Distance;
@Value("cellular.jitter")
@Default
private double cellularJitter = 1.0D; private double cellularJitter = 1.0D;
@Value("domain-warp.type")
@Default
private FastNoiseLite.DomainWarpType domainWarpType = FastNoiseLite.DomainWarpType.OpenSimplex2; private FastNoiseLite.DomainWarpType domainWarpType = FastNoiseLite.DomainWarpType.OpenSimplex2;
@Value("domain-warp.amplitude")
@Default
private double domainWarpAmp = 1.0D; private double domainWarpAmp = 1.0D;
@Value("rotation-type")
@Default
private FastNoiseLite.RotationType3D rotationType3D = FastNoiseLite.RotationType3D.None; private FastNoiseLite.RotationType3D rotationType3D = FastNoiseLite.RotationType3D.None;
@Value("dimensions")
@Default
private int dimensions = 2;
public FastNoiseLite build(int seed) { public FastNoiseLite build(int seed) {
FastNoiseLite noise = new FastNoiseLite(seed + seedOffset); FastNoiseLite noise = new FastNoiseLite(seed + seedOffset);
if(!fractalType.equals(FastNoiseLite.FractalType.None)) { if(!fractalType.equals(FastNoiseLite.FractalType.None)) {
@@ -182,5 +230,13 @@ public class NoiseBuilder {
this.rotationType3D = rotationType3D; this.rotationType3D = rotationType3D;
return this; return this;
} }
public int getDimensions() {
return dimensions;
}
public void setDimensions(int dimensions) {
this.dimensions = dimensions;
}
} }
@@ -1,6 +1,6 @@
package com.dfsek.terra.generation.config; package com.dfsek.terra.generation.config;
import com.dfsek.terra.config.genconfig.noise.NoiseConfig; import com.dfsek.terra.biome.PaletteHolder;
import com.dfsek.terra.math.NoiseFunction2; import com.dfsek.terra.math.NoiseFunction2;
import com.dfsek.terra.math.NoiseFunction3; import com.dfsek.terra.math.NoiseFunction3;
import com.dfsek.terra.math.RandomFunction; import com.dfsek.terra.math.RandomFunction;
@@ -20,9 +20,9 @@ import java.util.Map;
public class WorldGenerator extends Generator { public class WorldGenerator extends Generator {
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"}) @SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
private final Palette<BlockData>[] palettes; private final PaletteHolder palettes;
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"}) @SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
private final Palette<BlockData>[] slantPalettes; private final PaletteHolder slantPalettes;
private final boolean preventSmooth; private final boolean preventSmooth;
private final Expression noiseExp; private final Expression noiseExp;
@@ -35,7 +35,7 @@ public class WorldGenerator extends Generator {
private boolean elevationInterpolation = true; private boolean elevationInterpolation = true;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public WorldGenerator(long seed, String equation, String elevateEquation, Scope vScope, Map<String, NoiseConfig> noiseBuilders, Palette[] palettes, Palette[] slantPalettes, boolean preventSmooth) { public WorldGenerator(long seed, String equation, String elevateEquation, Scope vScope, Map<String, NoiseBuilder> noiseBuilders, PaletteHolder palettes, PaletteHolder slantPalettes, boolean preventSmooth) {
Parser p = new Parser(); Parser p = new Parser();
p.registerFunction("rand", new RandomFunction()); p.registerFunction("rand", new RandomFunction());
Parser ep = new Parser(); Parser ep = new Parser();
@@ -52,14 +52,14 @@ public class WorldGenerator extends Generator {
this.palettes = palettes; this.palettes = palettes;
this.slantPalettes = slantPalettes; this.slantPalettes = slantPalettes;
for(Map.Entry<String, NoiseConfig> e : noiseBuilders.entrySet()) { for(Map.Entry<String, NoiseBuilder> e : noiseBuilders.entrySet()) {
switch(e.getValue().getDimensions()) { switch(e.getValue().getDimensions()) {
case 2: case 2:
p.registerFunction(e.getKey(), new NoiseFunction2(seed, e.getValue().getBuilder())); p.registerFunction(e.getKey(), new NoiseFunction2(seed, e.getValue()));
ep.registerFunction(e.getKey(), new NoiseFunction2(seed, e.getValue().getBuilder())); ep.registerFunction(e.getKey(), new NoiseFunction2(seed, e.getValue()));
break; break;
case 3: case 3:
p.registerFunction(e.getKey(), new NoiseFunction3(seed, e.getValue().getBuilder())); p.registerFunction(e.getKey(), new NoiseFunction3(seed, e.getValue()));
break; break;
} }
} }
@@ -111,11 +111,11 @@ public class WorldGenerator extends Generator {
*/ */
@Override @Override
public Palette<BlockData> getPalette(int y) { public Palette<BlockData> getPalette(int y) {
return palettes[y]; return palettes.getPalette(y);
} }
public Palette<BlockData> getSlantPalette(int y) { public Palette<BlockData> getSlantPalette(int y) {
return slantPalettes[y]; return slantPalettes.getPalette(y);
} }
@@ -0,0 +1,21 @@
package com.dfsek.terra.generation.items;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.polydev.gaea.math.Range;
import org.polydev.gaea.world.Flora;
import java.util.List;
public class TerraFlora implements Flora {
@Override
public List<Block> getValidSpawnsAt(Chunk chunk, int i, int i1, Range range) {
return null;
}
@Override
public boolean plant(Location location) {
return false;
}
}
@@ -0,0 +1,14 @@
package com.dfsek.terra.generation.items;
import org.bukkit.Location;
import org.bukkit.plugin.java.JavaPlugin;
import org.polydev.gaea.tree.Tree;
import java.util.Random;
public class TerraTree implements Tree {
@Override
public boolean plant(Location location, Random random, JavaPlugin javaPlugin) {
return false;
}
}
@@ -0,0 +1,19 @@
package com.dfsek.terra.generation.items.ores;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.block.data.BlockData;
import org.polydev.gaea.math.Range;
import java.util.Random;
public class DeformedSphereOre extends Ore {
public DeformedSphereOre(Range height, Range amount, BlockData material) {
super(height, amount, material);
}
public void generate(Location origin, Chunk c, Random r) {
// TODO: implementation
}
}
@@ -0,0 +1,34 @@
package com.dfsek.terra.generation.items.ores;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.block.data.BlockData;
import org.polydev.gaea.math.Range;
import java.util.Random;
public abstract class Ore {
private final Range height;
private final Range amount;
private final BlockData material;
public Ore(Range height, Range amount, BlockData material) {
this.height = height;
this.amount = amount;
this.material = material;
}
public BlockData getMaterial() {
return material;
}
public Range getAmount() {
return amount;
}
public Range getHeight() {
return height;
}
public abstract void generate(Location origin, Chunk c, Random r);
}
@@ -2,8 +2,9 @@ package com.dfsek.terra.population;
import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.genconfig.CarverConfig; import com.dfsek.terra.config.templates.CarverTemplate;
import com.dfsek.terra.util.PopulationUtil; import com.dfsek.terra.util.PopulationUtil;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
@@ -38,32 +39,34 @@ public class CavePopulator extends BlockPopulator {
if(!tw.isSafe()) return; if(!tw.isSafe()) return;
ConfigPack config = tw.getConfig(); ConfigPack config = tw.getConfig();
for(CarverConfig c : config.getCarvers().values()) { for(UserDefinedCarver c : config.getCarvers()) {
CarverTemplate template = c.getConfig();
Map<Location, Material> shiftCandidate = new HashMap<>(); Map<Location, Material> shiftCandidate = new HashMap<>();
Set<Block> updateNeeded = new HashSet<>(); Set<Block> updateNeeded = new HashSet<>();
Map<Vector, CarvingData.CarvingType> blocks = c.getCarver().carve(chunk.getX(), chunk.getZ(), world).getCarvedBlocks(); Map<Vector, CarvingData.CarvingType> blocks = c.carve(chunk.getX(), chunk.getZ(), world).getCarvedBlocks();
for(Map.Entry<Vector, CarvingData.CarvingType> e : blocks.entrySet()) { for(Map.Entry<Vector, CarvingData.CarvingType> e : blocks.entrySet()) {
Vector v = e.getKey(); Vector v = e.getKey();
Block b = chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ()); Block b = chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ());
Material m = b.getType(); Material m = b.getType();
if(e.getValue().equals(CarvingData.CarvingType.CENTER) && c.isReplaceableInner(m)) { if(e.getValue().equals(CarvingData.CarvingType.CENTER) && template.getInner().canReplace(m)) {
if(c.getShiftedBlocks().containsKey(b.getType())) if(template.getShift().containsKey(b.getType()))
shiftCandidate.put(b.getLocation(), b.getType()); shiftCandidate.put(b.getLocation(), b.getType());
b.setBlockData(c.getPaletteInner(v.getBlockY()).get(random), c.shouldUpdateOcean() && borderingOcean(b)); b.setBlockData(template.getInner().get(v.getBlockY()).get(random), false);
} else if(e.getValue().equals(CarvingData.CarvingType.WALL) && c.isReplaceableOuter(m)) { } else if(e.getValue().equals(CarvingData.CarvingType.WALL) && template.getOuter().canReplace(m)) {
if(c.getShiftedBlocks().containsKey(b.getType())) if(template.getShift().containsKey(b.getType()))
shiftCandidate.put(b.getLocation(), b.getType()); shiftCandidate.put(b.getLocation(), b.getType());
b.setBlockData(c.getPaletteOuter(v.getBlockY()).get(random), c.shouldUpdateOcean() && borderingOcean(b)); b.setBlockData(template.getOuter().get(v.getBlockY()).get(random), false);
} else if(e.getValue().equals(CarvingData.CarvingType.TOP) && c.isReplaceableTop(m)) { } else if(e.getValue().equals(CarvingData.CarvingType.TOP) && template.getTop().canReplace(m)) {
if(c.getShiftedBlocks().containsKey(b.getType())) if(template.getShift().containsKey(b.getType()))
shiftCandidate.put(b.getLocation(), b.getType()); shiftCandidate.put(b.getLocation(), b.getType());
b.setBlockData(c.getPaletteTop(v.getBlockY()).get(random), c.shouldUpdateOcean() && borderingOcean(b)); b.setBlockData(template.getTop().get(v.getBlockY()).get(random), false);
} else if(e.getValue().equals(CarvingData.CarvingType.BOTTOM) && c.isReplaceableBottom(m)) { } else if(e.getValue().equals(CarvingData.CarvingType.BOTTOM) && template.getBottom().canReplace(m)) {
if(c.getShiftedBlocks().containsKey(b.getType())) if(template.getShift().containsKey(b.getType()))
shiftCandidate.put(b.getLocation(), b.getType()); shiftCandidate.put(b.getLocation(), b.getType());
b.setBlockData(c.getPaletteBottom(v.getBlockY()).get(random), c.shouldUpdateOcean() && borderingOcean(b)); b.setBlockData(template.getBottom().get(v.getBlockY()).get(random), false);
} }
if(c.getUpdateBlocks().contains(m)) { if(template.getUpdate().contains(m)) {
updateNeeded.add(b); updateNeeded.add(b);
} }
} }
@@ -74,7 +77,7 @@ public class CavePopulator extends BlockPopulator {
do mut.subtract(0, 1, 0); do mut.subtract(0, 1, 0);
while(mut.getBlock().getType().equals(orig)); while(mut.getBlock().getType().equals(orig));
try { try {
if(c.getShiftedBlocks().get(entry.getValue()).contains(mut.getBlock().getType())) { if(template.getShift().get(entry.getValue()).contains(mut.getBlock().getType())) {
mut.getBlock().setBlockData(shiftStorage.computeIfAbsent(entry.getValue(), Material::createBlockData), false); mut.getBlock().setBlockData(shiftStorage.computeIfAbsent(entry.getValue(), Material::createBlockData), false);
} }
} catch(NullPointerException ignore) { } catch(NullPointerException ignore) {
@@ -85,18 +88,6 @@ public class CavePopulator extends BlockPopulator {
b.setBlockData(AIR, false); b.setBlockData(AIR, false);
b.setBlockData(orig, true); b.setBlockData(orig, true);
} }
/*for(Map.Entry<Vector, CarvingData.CarvingType> e : new SimplexCarver(chunk.getX(), chunk.getZ()).carve(chunk.getX(), chunk.getZ(), world).getCarvedBlocks().entrySet()) {
Vector v = e.getKey();
switch(e.getValue()) {
case TOP:
case CENTER:
chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ()).setBlockData(AIR, false);
break;
case BOTTOM:
chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ()).setBlockData(Material.MYCELIUM.createBlockData(), false);
}
}*/
} }
} }
@@ -4,16 +4,13 @@ import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.grid.TerraBiomeGrid; import com.dfsek.terra.biome.grid.TerraBiomeGrid;
import com.dfsek.terra.config.genconfig.biome.BiomeConfig; import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.config.genconfig.biome.BiomeFloraConfig;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.generation.GenerationPhase; import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.population.GaeaBlockPopulator; import org.polydev.gaea.population.GaeaBlockPopulator;
import org.polydev.gaea.profiler.ProfileFuture; import org.polydev.gaea.profiler.ProfileFuture;
import org.polydev.gaea.world.Flora;
import java.util.Random; import java.util.Random;
@@ -35,9 +32,9 @@ public class FloraPopulator extends GaeaBlockPopulator {
UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, GenerationPhase.POPULATE); UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, GenerationPhase.POPULATE);
if(biome.getDecorator().getFloraChance() <= 0) continue; if(biome.getDecorator().getFloraChance() <= 0) continue;
try { try {
BiomeConfig c = biome.getConfig(); BiomeTemplate c = biome.getConfig();
BiomeFloraConfig f = c.getFlora(); /*
for(int i = 0; i < f.getFloraAttempts(); i++) { for(int i = 0; i < 0; i++) {
Flora item; Flora item;
if(f.isFloraSimplex()) if(f.isFloraSimplex())
item = biome.getDecorator().getFlora().get(f.getFloraNoise(), originX + x, originZ + z); item = biome.getDecorator().getFlora().get(f.getFloraNoise(), originX + x, originZ + z);
@@ -47,6 +44,7 @@ public class FloraPopulator extends GaeaBlockPopulator {
item.plant(highest.getLocation()); item.plant(highest.getLocation());
} }
} }
*/
} catch(NullPointerException ignore) { } catch(NullPointerException ignore) {
} }
} }
@@ -3,21 +3,20 @@ package com.dfsek.terra.population;
import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.genconfig.OreConfig; import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.config.genconfig.biome.BiomeOreConfig;
import com.dfsek.terra.event.OreVeinGenerateEvent; import com.dfsek.terra.event.OreVeinGenerateEvent;
import com.dfsek.terra.generation.items.ores.Ore;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.biome.Biome; import org.polydev.gaea.biome.Biome;
import org.polydev.gaea.generation.GenerationPhase; import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.math.Range;
import org.polydev.gaea.population.GaeaBlockPopulator; import org.polydev.gaea.population.GaeaBlockPopulator;
import org.polydev.gaea.profiler.ProfileFuture; import org.polydev.gaea.profiler.ProfileFuture;
import java.util.Map;
import java.util.Random; import java.util.Random;
public class OrePopulator extends GaeaBlockPopulator { public class OrePopulator extends GaeaBlockPopulator {
@@ -30,20 +29,19 @@ public class OrePopulator extends GaeaBlockPopulator {
for(int cx = -1; cx <= 1; cx++) { for(int cx = -1; cx <= 1; cx++) {
for(int cz = -1; cz <= 1; cz++) { for(int cz = -1; cz <= 1; cz++) {
Biome b = TerraWorld.getWorld(world).getGrid().getBiome(((chunk.getX() + cx) << 4) + 8, ((chunk.getZ() + cz) << 4) + 8, GenerationPhase.POPULATE); Biome b = TerraWorld.getWorld(world).getGrid().getBiome(((chunk.getX() + cx) << 4) + 8, ((chunk.getZ() + cz) << 4) + 8, GenerationPhase.POPULATE);
BiomeOreConfig ores = ((UserDefinedBiome) b).getConfig().getOres(); BiomeTemplate config = ((UserDefinedBiome) b).getConfig();
for(Map.Entry<OreConfig, Range> e : ores.getOres().entrySet()) { for(Ore ore : config.getOres()) {
int num = e.getValue().get(r); int num = ore.getAmount().get(r);
OreConfig ore = e.getKey();
for(int i = 0; i < num; i++) { for(int i = 0; i < num; i++) {
int x = r.nextInt(16) + cx * 16; int x = r.nextInt(16) + cx * 16;
int z = r.nextInt(16) + cz * 16; int z = r.nextInt(16) + cz * 16;
int y = ores.getOreHeights().get(ore).get(r); int y = ore.getHeight().get(r);
Vector v = new Vector(x, y, z); Vector v = new Vector(x, y, z);
OreVeinGenerateEvent event = new OreVeinGenerateEvent(tw, v.toLocation(world), ore); OreVeinGenerateEvent event = new OreVeinGenerateEvent(tw, v.toLocation(world), ore);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if(!event.isCancelled()) { if(!event.isCancelled()) {
ore.doVeinSingle(new Vector(x, y, z), chunk, r); ore.generate(new Location(world, x, y, z), chunk, r);
} }
} }
} }
@@ -2,21 +2,13 @@ package com.dfsek.terra.population;
import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.grid.TerraBiomeGrid; import com.dfsek.terra.biome.grid.TerraBiomeGrid;
import com.dfsek.terra.config.base.PluginConfig; import com.dfsek.terra.config.base.PluginConfig;
import com.dfsek.terra.config.genconfig.biome.BiomeConfig;
import com.dfsek.terra.util.DataUtil;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Snowable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.population.GaeaBlockPopulator; import org.polydev.gaea.population.GaeaBlockPopulator;
import org.polydev.gaea.profiler.ProfileFuture; import org.polydev.gaea.profiler.ProfileFuture;
@@ -58,8 +50,9 @@ public class SnowPopulator extends GaeaBlockPopulator {
TerraBiomeGrid g = w.getGrid(); TerraBiomeGrid g = w.getGrid();
for(int x = 0; x < 16; x++) { for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) { for(int z = 0; z < 16; z++) {
BiomeConfig biome = ((UserDefinedBiome) g.getBiome(origX + x, origZ + z, GenerationPhase.PALETTE_APPLY)).getConfig(); /*
if(!biome.getSnow().doSnow()) continue; BiomeTemplate biome = ((UserDefinedBiome) g.getBiome(origX + x, origZ + z, GenerationPhase.PALETTE_APPLY)).getConfig();
if(!biome) continue;
int y; int y;
Block b = null; Block b = null;
for(y = 254; y > 0; y--) { for(y = 254; y > 0; y--) {
@@ -76,6 +69,9 @@ public class SnowPopulator extends GaeaBlockPopulator {
} }
b.getRelative(BlockFace.UP).setBlockData(DataUtil.SNOW, phys); b.getRelative(BlockFace.UP).setBlockData(DataUtil.SNOW, phys);
*/
// TODO: implementation
} }
} }
} }
@@ -6,12 +6,11 @@ import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.grid.TerraBiomeGrid; import com.dfsek.terra.biome.grid.TerraBiomeGrid;
import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.genconfig.structure.StructureConfig; import com.dfsek.terra.config.templates.StructureTemplate;
import com.dfsek.terra.procgen.math.Vector2; import com.dfsek.terra.procgen.math.Vector2;
import com.dfsek.terra.structure.Rotation; import com.dfsek.terra.structure.Rotation;
import com.dfsek.terra.structure.Structure; import com.dfsek.terra.structure.Structure;
import com.dfsek.terra.structure.StructureContainedInventory; import com.dfsek.terra.structure.StructureContainedInventory;
import com.dfsek.terra.structure.features.Feature;
import com.dfsek.terra.util.PopulationUtil; import com.dfsek.terra.util.PopulationUtil;
import com.dfsek.terra.util.structure.RotationUtil; import com.dfsek.terra.util.structure.RotationUtil;
import net.jafama.FastMath; import net.jafama.FastMath;
@@ -41,13 +40,13 @@ public class StructurePopulator extends BlockPopulator {
TerraBiomeGrid grid = tw.getGrid(); TerraBiomeGrid grid = tw.getGrid();
ConfigPack config = tw.getConfig(); ConfigPack config = tw.getConfig();
structure: structure:
for(StructureConfig conf : config.getAllStructures()) { for(StructureTemplate conf : config.getStructures()) {
Location spawn = conf.getSpawn().getNearestSpawn(cx + 8, cz + 8, world.getSeed()).toLocation(world); Location spawn = conf.getSpawn().getNearestSpawn(cx + 8, cz + 8, world.getSeed()).toLocation(world);
if(!((UserDefinedBiome) grid.getBiome(spawn)).getConfig().getStructures().contains(conf)) continue; if(!((UserDefinedBiome) grid.getBiome(spawn)).getConfig().getStructures().contains(conf)) continue;
Random r2 = new FastRandom(spawn.hashCode()); Random r2 = new FastRandom(spawn.hashCode());
Structure struc = conf.getStructure(r2); Structure struc = conf.getStructures().get(r2);
Rotation rotation = Rotation.fromDegrees(r2.nextInt(4) * 90); Rotation rotation = Rotation.fromDegrees(r2.nextInt(4) * 90);
for(int y = conf.getSearchStart().get(r2); y > 0; y--) { for(int y = conf.getY().get(r2); y > 0; y--) {
if(!conf.getBound().isInRange(y)) continue structure; if(!conf.getBound().isInRange(y)) continue structure;
spawn.setY(y); spawn.setY(y);
if(!struc.checkSpawns(spawn, rotation)) continue; if(!struc.checkSpawns(spawn, rotation)) continue;
@@ -64,7 +63,7 @@ public class StructurePopulator extends BlockPopulator {
continue; continue;
Debug.info("Target is in chunk."); Debug.info("Target is in chunk.");
Debug.info(spawn.toString() + " became: " + inv.toString() + " (" + rotation + ", " + inv.getBlock().getType() + ")"); Debug.info(spawn.toString() + " became: " + inv.toString() + " (" + rotation + ", " + inv.getBlock().getType() + ")");
LootTable table = conf.getLoot(i.getUid()); LootTable table = conf.getLoot().get(i.getUid());
if(table == null) continue; if(table == null) continue;
Debug.info("Target has table assigned."); Debug.info("Target has table assigned.");
table.fillInventory(((BlockInventoryHolder) inv.getBlock().getState()).getInventory(), random); table.fillInventory(((BlockInventoryHolder) inv.getBlock().getState()).getInventory(), random);
@@ -73,7 +72,8 @@ public class StructurePopulator extends BlockPopulator {
Debug.stack(e); Debug.stack(e);
} }
} }
for(Feature f : conf.getFeatures()) f.apply(struc, rotation, spawn, chunk); // Apply features. //for(Feature f : conf.getFeatures()) f.apply(struc, rotation, spawn, chunk); // Apply features.
// TODO: features
break; break;
} }
} }
@@ -1,15 +1,11 @@
package com.dfsek.terra.population; package com.dfsek.terra.population;
import com.dfsek.terra.Terra;
import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.grid.TerraBiomeGrid; import com.dfsek.terra.biome.grid.TerraBiomeGrid;
import com.dfsek.terra.event.TreeGenerateEvent;
import net.jafama.FastMath; import net.jafama.FastMath;
import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -17,7 +13,6 @@ import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.math.Range; import org.polydev.gaea.math.Range;
import org.polydev.gaea.population.GaeaBlockPopulator; import org.polydev.gaea.population.GaeaBlockPopulator;
import org.polydev.gaea.profiler.ProfileFuture; import org.polydev.gaea.profiler.ProfileFuture;
import org.polydev.gaea.tree.Tree;
import org.polydev.gaea.util.GlueList; import org.polydev.gaea.util.GlueList;
import java.util.List; import java.util.List;
@@ -25,6 +20,7 @@ import java.util.Random;
public class TreePopulator extends GaeaBlockPopulator { public class TreePopulator extends GaeaBlockPopulator {
/*
private static void doTrees(@NotNull UserDefinedBiome biome, TerraWorld world, @NotNull Random random, @NotNull Chunk chunk, int x, int z) { private static void doTrees(@NotNull UserDefinedBiome biome, TerraWorld world, @NotNull Random random, @NotNull Chunk chunk, int x, int z) {
for(Block block : getValidTreeSpawnsAt(chunk, x, z, new Range(0, 254))) { for(Block block : getValidTreeSpawnsAt(chunk, x, z, new Range(0, 254))) {
Tree tree = biome.getDecorator().getTrees().get(random); Tree tree = biome.getDecorator().getTrees().get(random);
@@ -40,6 +36,8 @@ public class TreePopulator extends GaeaBlockPopulator {
} }
} }
*/
// TODO: implementation
public static List<Block> getValidTreeSpawnsAt(Chunk chunk, int x, int z, Range check) { public static List<Block> getValidTreeSpawnsAt(Chunk chunk, int x, int z, Range check) {
List<Block> blocks = new GlueList<>(); List<Block> blocks = new GlueList<>();
for(int y : check) { for(int y : check) {
@@ -68,7 +66,7 @@ public class TreePopulator extends GaeaBlockPopulator {
if(random.nextInt(1000) < treeChance) { if(random.nextInt(1000) < treeChance) {
int xt = offset(random, x); int xt = offset(random, x);
int zt = offset(random, z); int zt = offset(random, z);
doTrees(biome, tw, random, chunk, xt, zt); //doTrees(biome, tw, random, chunk, xt, zt); TODO: implementation
} }
} }
} }
@@ -0,0 +1,16 @@
package com.dfsek.terra.registry;
import com.dfsek.tectonic.exception.ConfigException;
import com.dfsek.terra.config.base.ConfigPack;
import java.io.File;
/**
* Class to hold config packs
*/
public class ConfigRegistry extends TerraRegistry<ConfigPack> {
public void load(File folder) throws ConfigException {
ConfigPack pack = new ConfigPack(folder);
add(pack.getTemplate().getID(), pack);
}
}
@@ -0,0 +1,6 @@
package com.dfsek.terra.registry;
import com.dfsek.terra.generation.items.ores.DeformedSphereOre;
public class OreRegistry extends TerraRegistry<DeformedSphereOre> {
}
@@ -0,0 +1,8 @@
package com.dfsek.terra.structure;
// TODO: implementation
public class TerraStructure {
public String getID() {
return null;
}
}
@@ -2,7 +2,7 @@ package com.dfsek.terra.structure.spawn;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.genconfig.biome.BiomeConfig; import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.generation.config.WorldGenerator; import com.dfsek.terra.generation.config.WorldGenerator;
import org.bukkit.World; import org.bukkit.World;
import org.polydev.gaea.generation.GenerationPhase; import org.polydev.gaea.generation.GenerationPhase;
@@ -16,8 +16,8 @@ public class AirSpawn extends Requirement {
public boolean matches(int x, int y, int z) { public boolean matches(int x, int y, int z) {
TerraWorld tw = TerraWorld.getWorld(getWorld()); TerraWorld tw = TerraWorld.getWorld(getWorld());
UserDefinedBiome b = (UserDefinedBiome) tw.getGrid().getBiome(x, z, GenerationPhase.POPULATE); UserDefinedBiome b = (UserDefinedBiome) tw.getGrid().getBiome(x, z, GenerationPhase.POPULATE);
BiomeConfig c = b.getConfig(); BiomeTemplate c = b.getConfig();
if(y <= c.getOcean().getSeaLevel()) return false; if(y <= c.getSeaLevel()) return false;
int yf = (int) (y - ((WorldGenerator) b.getGenerator()).getElevation(x, z)); int yf = (int) (y - ((WorldGenerator) b.getGenerator()).getElevation(x, z));
return b.getGenerator().getNoise(getNoise(), getWorld(), x, yf, z) <= 0; return b.getGenerator().getNoise(getNoise(), getWorld(), x, yf, z) <= 0;
} }
@@ -2,7 +2,7 @@ package com.dfsek.terra.structure.spawn;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.genconfig.biome.BiomeConfig; import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.generation.config.WorldGenerator; import com.dfsek.terra.generation.config.WorldGenerator;
import org.bukkit.World; import org.bukkit.World;
import org.polydev.gaea.generation.GenerationPhase; import org.polydev.gaea.generation.GenerationPhase;
@@ -16,8 +16,8 @@ public class OceanSpawn extends Requirement {
public boolean matches(int x, int y, int z) { public boolean matches(int x, int y, int z) {
TerraWorld tw = TerraWorld.getWorld(getWorld()); TerraWorld tw = TerraWorld.getWorld(getWorld());
UserDefinedBiome b = (UserDefinedBiome) tw.getGrid().getBiome(x, z, GenerationPhase.POPULATE); UserDefinedBiome b = (UserDefinedBiome) tw.getGrid().getBiome(x, z, GenerationPhase.POPULATE);
BiomeConfig c = b.getConfig(); BiomeTemplate c = b.getConfig();
if(y > c.getOcean().getSeaLevel()) return false; if(y > c.getSeaLevel()) return false;
int yf = (int) (y - ((WorldGenerator) b.getGenerator()).getElevation(x, z)); int yf = (int) (y - ((WorldGenerator) b.getGenerator()).getElevation(x, z));
return b.getGenerator().getNoise(getNoise(), getWorld(), x, yf, z) <= 0; return b.getGenerator().getNoise(getNoise(), getWorld(), x, yf, z) <= 0;
} }
@@ -0,0 +1,30 @@
package com.dfsek.terra.util;
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.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public final class ConfigUtil {
public static List<InputStream> loadFromPath(Path folder) {
List<InputStream> streams = new ArrayList<>();
try(Stream<Path> paths = Files.walk(folder)) {
paths.filter(Files::isRegularFile).filter(file -> file.endsWith(".yml")).forEach(file -> {
try {
streams.add(new FileInputStream(file.toFile()));
} catch(FileNotFoundException e) {
e.printStackTrace();
}
});
} catch(IOException e) {
e.printStackTrace();
}
return streams;
}
}