Implement additional cave config

This commit is contained in:
dfsek 2020-09-25 02:04:55 -07:00
parent f983bf06fa
commit f727e9d297
9 changed files with 106 additions and 24 deletions

View File

@ -46,5 +46,10 @@
<option name="name" value="gaea" /> <option name="name" value="gaea" />
<option name="url" value="file:$PROJECT_DIR$/../Gaea/repo" /> <option name="url" value="file:$PROJECT_DIR$/../Gaea/repo" />
</remote-repository> </remote-repository>
<remote-repository>
<option name="id" value="gaea.local" />
<option name="name" value="gaea-local" />
<option name="url" value="file:$PROJECT_DIR$/../Gaea/repo" />
</remote-repository>
</component> </component>
</project> </project>

View File

@ -65,7 +65,7 @@
</repository> </repository>
<repository> <repository>
<id>gaea.local</id> <id>gaea.local</id>
<name>gaea</name> <name>gaea-local</name>
<url>file:/home/dfsek/Documents/Gaea/repo</url> <url>file:/home/dfsek/Documents/Gaea/repo</url>
</repository> </repository>
<repository> <repository>
@ -95,7 +95,7 @@
<dependency> <dependency>
<groupId>org.polydev</groupId> <groupId>org.polydev</groupId>
<artifactId>gaea</artifactId> <artifactId>gaea</artifactId>
<version>1.10.5</version> <version>1.10.17</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.vecmath</groupId> <groupId>javax.vecmath</groupId>

View File

@ -16,7 +16,7 @@ public class TerraProfiler extends WorldProfiler {
this.addMeasurement(new Measurement(2500000, DataType.PERIOD_MILLISECONDS), "TotalChunkGenTime") this.addMeasurement(new Measurement(2500000, DataType.PERIOD_MILLISECONDS), "TotalChunkGenTime")
.addMeasurement(new Measurement(2500000, DataType.PERIOD_MILLISECONDS), "ChunkBaseGenTime") .addMeasurement(new Measurement(2500000, DataType.PERIOD_MILLISECONDS), "ChunkBaseGenTime")
.addMeasurement(new Measurement(2000000, DataType.PERIOD_MILLISECONDS), "BiomeSetTime") .addMeasurement(new Measurement(2000000, DataType.PERIOD_MILLISECONDS), "BiomeSetTime")
.addMeasurement(new Measurement(25000000, DataType.PERIOD_NANOSECONDS), "TreeGenTime") .addMeasurement(new Measurement(25000000, DataType.PERIOD_MILLISECONDS), "TreeGenTime")
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "FloraTime") .addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "FloraTime")
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "CaveTime") .addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "CaveTime")
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "CaveBlockUpdate"); .addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "CaveBlockUpdate");

View File

@ -18,7 +18,9 @@ public class UserDefinedCarver extends Carver {
private final MaxMin length; private final MaxMin length;
private final MaxMin radius; private final MaxMin radius;
private final int hash; private final int hash;
public UserDefinedCarver(MaxMin height, MaxMin radius, MaxMin length, double[] start, double[] mutate, double[] radiusMultiplier, int hash) { private final int topCut;
private final int bottomCut;
public UserDefinedCarver(MaxMin height, MaxMin radius, MaxMin length, double[] start, double[] mutate, double[] radiusMultiplier, int hash, int topCut, int bottomCut) {
super(height.getMin(), height.getMax()); super(height.getMin(), height.getMax());
this.radius = radius; this.radius = radius;
this.length = length; this.length = length;
@ -26,12 +28,14 @@ public class UserDefinedCarver extends Carver {
this.mutate = mutate; this.mutate = mutate;
this.radiusMultiplier = radiusMultiplier; this.radiusMultiplier = radiusMultiplier;
this.hash = hash; this.hash = hash;
this.topCut = topCut;
this.bottomCut = bottomCut;
} }
@Override @Override
public Worm getWorm(long l, Vector vector) { public Worm getWorm(long l, Vector vector) {
Random r = new Random(l+hash); Random r = new Random(l+hash);
return new UserDefinedWorm(length.get(r), r, vector, radius.getMax()); return new UserDefinedWorm(length.get(r), r, vector, radius.getMax(), topCut, bottomCut);
} }
@Override @Override
@ -43,8 +47,10 @@ public class UserDefinedCarver extends Carver {
private final Vector direction; private final Vector direction;
private final int maxRad; private final int maxRad;
private double runningRadius; private double runningRadius;
public UserDefinedWorm(int length, Random r, Vector origin, int maxRad) { public UserDefinedWorm(int length, Random r, Vector origin, int maxRad, int topCut, int bottomCut) {
super(length, r, origin); super(length, r, origin);
super.setTopCut(topCut);
super.setBottomCut(bottomCut);
runningRadius = radius.get(r); runningRadius = radius.get(r);
this.maxRad = maxRad; this.maxRad = maxRad;
direction = new Vector((r.nextDouble()-0.5D)*start[0], (r.nextDouble()-0.5D)*start[1], (r.nextDouble()-0.5D)*start[2]).normalize(); direction = new Vector((r.nextDouble()-0.5D)*start[0], (r.nextDouble()-0.5D)*start[1], (r.nextDouble()-0.5D)*start[2]).normalize();

View File

@ -71,8 +71,8 @@ public class WorldConfig {
// Get values from config. // Get values from config.
seaLevel = config.getInt("sea-level", 63); seaLevel = config.getInt("sea-level", 63);
zoneFreq = 1f/config.getInt("frequencies.zone", 1536); zoneFreq = 1f/config.getInt("frequencies.zone", 1536);
freq1 = 1f/config.getInt("frequencies.grid-1", 256); freq1 = 1f/config.getInt("frequencies.grid-x", 256);
freq2 = 1f/config.getInt("frequencies.grid-2", 512); freq2 = 1f/config.getInt("frequencies.grid-z", 512);
fromImage = config.getBoolean("image.use-image", false); fromImage = config.getBoolean("image.use-image", false);
// Load image stuff // Load image stuff

View File

@ -28,12 +28,18 @@ public class CarverConfig extends TerraConfigObject {
private String id; private String id;
private Set<Material> replaceableInner; private Set<Material> replaceableInner;
private Set<Material> replaceableOuter; private Set<Material> replaceableOuter;
private Set<Material> replaceableTop;
private Set<Material> replaceableBottom;
private Set<Material> update; private Set<Material> update;
private Map<Material, Set<Material>> shift; private Map<Material, Set<Material>> shift;
private Map<Integer, ProbabilityCollection<BlockData>> inner; private Map<Integer, ProbabilityCollection<BlockData>> inner;
private Map<Integer, ProbabilityCollection<BlockData>> outer; private Map<Integer, ProbabilityCollection<BlockData>> outer;
private Map<Integer, ProbabilityCollection<BlockData>> top;
private Map<Integer, ProbabilityCollection<BlockData>> bottom;
private boolean replaceIsBlacklistInner; private boolean replaceIsBlacklistInner;
private boolean replaceIsBlacklistOuter; private boolean replaceIsBlacklistOuter;
private boolean replaceIsBlacklistTop;
private boolean replaceIsBlacklistBottom;
public CarverConfig(File file) throws IOException, InvalidConfigurationException { public CarverConfig(File file) throws IOException, InvalidConfigurationException {
super(file); super(file);
@ -53,8 +59,14 @@ public class CarverConfig extends TerraConfigObject {
outer = getBlocks("palette.outer.blocks"); outer = getBlocks("palette.outer.blocks");
top = getBlocks("palette.top.blocks");
bottom = getBlocks("palette.bottom.blocks");
replaceableInner = new HashSet<>(); replaceableInner = new HashSet<>();
replaceableOuter = new HashSet<>(); replaceableOuter = new HashSet<>();
replaceableTop = new HashSet<>();
replaceableBottom = new HashSet<>();
for(String s : getStringList("palette.inner.replace")) { for(String s : getStringList("palette.inner.replace")) {
try { try {
@ -72,6 +84,22 @@ public class CarverConfig extends TerraConfigObject {
throw new InvalidConfigurationException("Could not load data for " + s); throw new InvalidConfigurationException("Could not load data for " + s);
} }
} }
for(String s : getStringList("palette.top.replace")) {
try {
if(replaceableTop.contains(Bukkit.createBlockData(s).getMaterial())) Bukkit.getLogger().warning("Duplicate material in replaceable list: " + s);
replaceableTop.add(Bukkit.createBlockData(s).getMaterial());
} catch(NullPointerException | IllegalArgumentException e) {
throw new InvalidConfigurationException("Could not load data for " + s);
}
}
for(String s : getStringList("palette.bottom.replace")) {
try {
if(replaceableBottom.contains(Bukkit.createBlockData(s).getMaterial())) Bukkit.getLogger().warning("Duplicate material in replaceable list: " + s);
replaceableBottom.add(Bukkit.createBlockData(s).getMaterial());
} catch(NullPointerException | IllegalArgumentException e) {
throw new InvalidConfigurationException("Could not load data for " + s);
}
}
update = new HashSet<>(); update = new HashSet<>();
for(String s : getStringList("update")) { for(String s : getStringList("update")) {
@ -104,7 +132,7 @@ public class CarverConfig extends TerraConfigObject {
MaxMin height = new MaxMin(getInt("start.height.min"), getInt("start.height.max")); MaxMin height = new MaxMin(getInt("start.height.min"), getInt("start.height.max"));
id = getString("id"); id = getString("id");
if(id == null) throw new InvalidConfigurationException("No ID specified for Carver!"); if(id == null) throw new InvalidConfigurationException("No ID specified for Carver!");
carver = new UserDefinedCarver(height, radius, length, start, mutate, radiusMultiplier, id.hashCode()); carver = new UserDefinedCarver(height, radius, length, start, mutate, radiusMultiplier, id.hashCode(), getInt("cut.top", 0), getInt("cut.bottom", 0));
caveConfig.put(id, this); caveConfig.put(id, this);
} }
@ -149,6 +177,20 @@ public class CarverConfig extends TerraConfigObject {
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) { public ProbabilityCollection<BlockData> getPaletteInner(int y) {
for(Map.Entry<Integer, ProbabilityCollection<BlockData>> e : inner.entrySet()) { for(Map.Entry<Integer, ProbabilityCollection<BlockData>> e : inner.entrySet()) {
if(e.getKey() >= y ) return e.getValue(); if(e.getKey() >= y ) return e.getValue();
@ -163,6 +205,20 @@ public class CarverConfig extends TerraConfigObject {
return null; 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;
}
@Override @Override
public String toString() { public String toString() {
return "Carver with ID " + getID(); return "Carver with ID " + getID();

View File

@ -8,6 +8,8 @@ import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Slab;
import org.bukkit.block.data.type.Stairs; import org.bukkit.block.data.type.Stairs;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
@ -21,6 +23,7 @@ import java.util.Random;
public class SlabGenerator extends GenerationPopulator { public class SlabGenerator extends GenerationPopulator {
private static final BlockData AIR = Material.AIR.createBlockData(); private static final BlockData AIR = Material.AIR.createBlockData();
private static final BlockData WATER = Material.WATER.createBlockData();
private static final Palette<BlockData> AIRPALETTE = new RandomPalette<BlockData>(new Random(2403)).add(AIR, 1); private static final Palette<BlockData> AIRPALETTE = new RandomPalette<BlockData>(new Random(2403)).add(AIR, 1);
@Override @Override
public ChunkGenerator.ChunkData populate(World world, ChunkGenerator.ChunkData chunk, Random random, int chunkX, int chunkZ, ChunkInterpolator interp) { public ChunkGenerator.ChunkData populate(World world, ChunkGenerator.ChunkData chunk, Random random, int chunkX, int chunkZ, ChunkInterpolator interp) {
@ -42,42 +45,48 @@ public class SlabGenerator extends GenerationPopulator {
} }
private static void prepareBlockPart(ChunkInterpolator interp, ChunkGenerator.ChunkData chunk, Vector block, Map<Material, Palette<BlockData>> slabs, Map<Material, Palette<BlockData>> stairs, double thresh) { private static void prepareBlockPart(ChunkInterpolator interp, ChunkGenerator.ChunkData chunk, Vector block, Map<Material, Palette<BlockData>> slabs, Map<Material, Palette<BlockData>> stairs, double thresh) {
BlockData down = chunk.getBlockData(block.getBlockX(), block.getBlockY()-1, block.getBlockZ()); BlockData down = chunk.getBlockData(block.getBlockX(), block.getBlockY()-1, block.getBlockZ());
double _11 = interp.getNoise(block.getBlockX(), block.getBlockY() - 0.5, block.getBlockZ()); double _11 = interp.getNoise(block.getBlockX(), block.getBlockY() - 0.4, block.getBlockZ());
if(_11 > thresh) { if(_11 > thresh) {
double _00 = interp.getNoise(block.getBlockX() - 0.5, block.getBlockY(), block.getBlockZ() - 0.5); BlockData orig = chunk.getBlockData(block.getBlockX(), block.getBlockY(), block.getBlockZ());
//double _00 = interp.getNoise(block.getBlockX() - 0.5, block.getBlockY(), block.getBlockZ() - 0.5);
double _01 = interp.getNoise(block.getBlockX() - 0.5, block.getBlockY(), block.getBlockZ()); double _01 = interp.getNoise(block.getBlockX() - 0.5, block.getBlockY(), block.getBlockZ());
double _02 = interp.getNoise(block.getBlockX() - 0.5, block.getBlockY(), block.getBlockZ() + 0.5); //double _02 = interp.getNoise(block.getBlockX() - 0.5, block.getBlockY(), block.getBlockZ() + 0.5);
double _10 = interp.getNoise(block.getBlockX(), block.getBlockY(), block.getBlockZ() - 0.5); double _10 = interp.getNoise(block.getBlockX(), block.getBlockY(), block.getBlockZ() - 0.5);
double _12 = interp.getNoise(block.getBlockX(), block.getBlockY(), block.getBlockZ() + 0.5); double _12 = interp.getNoise(block.getBlockX(), block.getBlockY(), block.getBlockZ() + 0.5);
double _20 = interp.getNoise(block.getBlockX() + 0.5, block.getBlockY(), block.getBlockZ() - 0.5); //double _20 = interp.getNoise(block.getBlockX() + 0.5, block.getBlockY(), block.getBlockZ() - 0.5);
double _21 = interp.getNoise(block.getBlockX() + 0.5, block.getBlockY(), block.getBlockZ()); double _21 = interp.getNoise(block.getBlockX() + 0.5, block.getBlockY(), block.getBlockZ());
double _22 = interp.getNoise(block.getBlockX() + 0.5, block.getBlockY(), block.getBlockZ() + 0.5); //double _22 = interp.getNoise(block.getBlockX() + 0.5, block.getBlockY(), block.getBlockZ() + 0.5);
if(stairs != null) { if(stairs != null) {
Palette<BlockData> stairPalette = stairs.get(down.getMaterial()); Palette<BlockData> stairPalette = stairs.get(down.getMaterial());
if(stairPalette != null) { if(stairPalette != null) {
BlockData stair = stairPalette.get(0, block.getBlockX(), block.getBlockZ()); BlockData stair = stairPalette.get(0, block.getBlockX(), block.getBlockZ());
Stairs finalStair = getStair(new double[] {_00, _01, _02, _10, _12, _20, _21, _22}, (Stairs) stair, thresh); Stairs finalStair = getStair(new double[] {_01, _10, _12, _21}, (Stairs) stair, thresh);
if(finalStair != null) { if(finalStair != null) {
if(orig.matches(WATER)) finalStair.setWaterlogged(true);
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), finalStair); chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), finalStair);
return; return;
} }
} }
} }
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), slabs.getOrDefault(down.getMaterial(), AIRPALETTE).get(0, block.getBlockX(), block.getBlockZ())); BlockData slab = slabs.getOrDefault(down.getMaterial(), AIRPALETTE).get(0, block.getBlockX(), block.getBlockZ());
if(slab instanceof Waterlogged) {
((Waterlogged) slab).setWaterlogged(orig.matches(WATER));
}
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), slab);
} }
} }
private static Stairs getStair(double[] vals, Stairs stair, double thresh) { private static Stairs getStair(double[] vals, Stairs stair, double thresh) {
if(vals.length != 8) throw new IllegalArgumentException(); if(vals.length != 4) throw new IllegalArgumentException();
Stairs stairNew = (Stairs) stair.clone(); Stairs stairNew = (Stairs) stair.clone();
if(vals[1] > thresh) { if(vals[0] > thresh) {
stairNew.setFacing(BlockFace.WEST); stairNew.setFacing(BlockFace.WEST);
} else if(vals[3] > thresh) { } else if(vals[1] > thresh) {
stairNew.setFacing(BlockFace.NORTH); stairNew.setFacing(BlockFace.NORTH);
} else if(vals[4] > thresh) { } else if(vals[2] > thresh) {
stairNew.setFacing(BlockFace.SOUTH); stairNew.setFacing(BlockFace.SOUTH);
} else if(vals[6] > thresh) { } else if(vals[3] > thresh) {
stairNew.setFacing(BlockFace.EAST); stairNew.setFacing(BlockFace.EAST);
} else return null; } else return null;
return stairNew; return stairNew;

View File

@ -35,9 +35,15 @@ public class CavePopulator extends BlockPopulator {
if(e.getValue().equals(CarvingData.CarvingType.CENTER) && c.isReplaceableInner(m)) { if(e.getValue().equals(CarvingData.CarvingType.CENTER) && c.isReplaceableInner(m)) {
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType()); if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
b.setBlockData(c.getPaletteInner(v.getBlockY()).get(random), false); b.setBlockData(c.getPaletteInner(v.getBlockY()).get(random), false);
} else if(c.isReplaceableOuter(m)){ } else if(e.getValue().equals(CarvingData.CarvingType.WALL) && c.isReplaceableOuter(m)){
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType()); if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
b.setBlockData(c.getPaletteOuter(v.getBlockY()).get(random), false); b.setBlockData(c.getPaletteOuter(v.getBlockY()).get(random), false);
} else if(e.getValue().equals(CarvingData.CarvingType.TOP) && c.isReplaceableTop(m)){
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
b.setBlockData(c.getPaletteTop(v.getBlockY()).get(random), false);
} else if(e.getValue().equals(CarvingData.CarvingType.BOTTOM) && c.isReplaceableBottom(m)){
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
b.setBlockData(c.getPaletteBottom(v.getBlockY()).get(random), false);
} }
if(c.getUpdateBlocks().contains(m)) { if(c.getUpdateBlocks().contains(m)) {
updateNeeded.add(b); updateNeeded.add(b);

View File

@ -25,7 +25,7 @@ public class TreePopulator extends GaeaBlockPopulator {
Biome b = TerraBiomeGrid.fromWorld(world).getBiome(origin); Biome b = TerraBiomeGrid.fromWorld(world).getBiome(origin);
if(((UserDefinedDecorator) b.getDecorator()).getTreeChance() < random.nextInt(100)) return; if(((UserDefinedDecorator) b.getDecorator()).getTreeChance() < random.nextInt(100)) return;
int numTrees = 0; int numTrees = 0;
for(int i = 0; i < 10; i++) { for(int i = 0; i < 48; i++) {
int y = WorldUtil.getHighestValidSpawnAt(chunk, x, z); int y = WorldUtil.getHighestValidSpawnAt(chunk, x, z);
if(y <= 0) continue; if(y <= 0) continue;
origin = chunk.getBlock(x, y, z).getLocation().add(0, 1, 0); origin = chunk.getBlock(x, y, z).getLocation().add(0, 1, 0);
@ -34,7 +34,7 @@ public class TreePopulator extends GaeaBlockPopulator {
try { try {
b.getDecorator().getTrees().get(random).plant(origin, random, false, Terra.getInstance()); b.getDecorator().getTrees().get(random).plant(origin, random, false, Terra.getInstance());
} catch(NullPointerException ignored) {} } catch(NullPointerException ignored) {}
if(numTrees >= b.getDecorator().getTreeDensity()) return; if(numTrees >= b.getDecorator().getTreeDensity()) break;
x = random.nextInt(16); // Decrease chances of chunk-crossing trees x = random.nextInt(16); // Decrease chances of chunk-crossing trees
z = random.nextInt(16); z = random.nextInt(16);
} }