Implement new Palette types

This commit is contained in:
dfsek 2020-09-20 22:59:50 -07:00
parent 2424b907be
commit 44f302b564
13 changed files with 74 additions and 54 deletions

View File

@ -83,7 +83,7 @@
<dependency> <dependency>
<groupId>org.polydev</groupId> <groupId>org.polydev</groupId>
<artifactId>gaea</artifactId> <artifactId>gaea</artifactId>
<version>1.8.1</version> <version>1.9.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.vecmath</groupId> <groupId>javax.vecmath</groupId>
@ -91,6 +91,12 @@
<version>1.5.2</version> <version>1.5.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>javax.vecmath</groupId>
<artifactId>vecmath</artifactId>
<version>1.5.2</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -12,8 +12,8 @@ import org.bukkit.generator.BlockPopulator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.generation.GaeaChunkGenerator; import org.polydev.gaea.generation.GaeaChunkGenerator;
import org.polydev.gaea.generation.GenerationPopulator; import org.polydev.gaea.generation.GenerationPopulator;
import org.polydev.gaea.math.ChunkInterpolator;
import org.polydev.gaea.math.FastNoise; import org.polydev.gaea.math.FastNoise;
import org.polydev.gaea.math.InterpolationType;
import org.polydev.gaea.population.PopulationManager; import org.polydev.gaea.population.PopulationManager;
import java.util.Arrays; import java.util.Arrays;
@ -24,7 +24,7 @@ import java.util.Random;
public class TerraChunkGenerator extends GaeaChunkGenerator { public class TerraChunkGenerator extends GaeaChunkGenerator {
private final PopulationManager popMan = new PopulationManager(); private final PopulationManager popMan = new PopulationManager();
public TerraChunkGenerator() { public TerraChunkGenerator() {
super(InterpolationType.TRILINEAR); super(ChunkInterpolator.InterpolationType.TRILINEAR);
popMan.attach(new TreePopulator()); popMan.attach(new TreePopulator());
popMan.attach(new FaunaPopulator()); popMan.attach(new FaunaPopulator());
popMan.attach(new OrePopulator()); popMan.attach(new OrePopulator());

View File

@ -14,17 +14,12 @@ public class BiomeZone {
private final World w; private final World w;
private final FastNoise noise; private final FastNoise noise;
private static final Map<World, BiomeZone> zones = new HashMap<>(); private static final Map<World, BiomeZone> zones = new HashMap<>();
private static final double[] normalMap = new double[] {-0.572874128818512D, -0.5007192492485046D, -0.4495924413204193D, -0.41612040996551514D, -0.3814384937286377D, -0.3477869927883148D, -0.31369876861572266D, -0.28042978048324585D, -0.24612723290920258D, -0.21002958714962006D, -0.17449893057346344D, -0.1394101232290268D, -0.10480091720819473D, -0.0714595764875412D, -0.03575916960835457D, -0.0017036114586517215D, 0.03202686831355095D, 0.06717526167631149D, 0.10201185941696167D, 0.13758908212184906D, 0.17380206286907196D, 0.20863550901412964D, 0.24430148303508759D, 0.2795235514640808D, 0.31312644481658936D, 0.3475150465965271D, 0.38061848282814026D, 0.415109783411026D, 0.44838231801986694D, 0.4965132176876068D, 0.5715073347091675D, 0.7126374840736389D};
private BiomeZone(World w, float freq) { private BiomeZone(World w, float freq) {
this.w = w; this.w = w;
this.noise = new FastNoise((int) w.getSeed()+2); this.noise = new FastNoise((int) w.getSeed()+2);
FastNoise base = new FastNoise((int) (w.getSeed()+2)); this.noise.setNoiseType(FastNoise.NoiseType.SimplexFractal);
base.setNoiseType(FastNoise.NoiseType.Simplex); this.noise.setFractalOctaves(4);
base.setFrequency(freq); this.noise.setFrequency(WorldConfig.fromWorld(w).zoneFreq);
this.noise.setCellularDistanceFunction(FastNoise.CellularDistanceFunction.Natural);
this.noise.setCellularNoiseLookup(base);
this.noise.setFrequency(freq);
setZones(WorldConfig.fromWorld(w).definedGrids); setZones(WorldConfig.fromWorld(w).definedGrids);
zones.put(w, this); zones.put(w, this);
} }

View File

@ -10,7 +10,7 @@ import org.polydev.gaea.math.parsii.eval.Parser;
import org.polydev.gaea.math.parsii.eval.Scope; import org.polydev.gaea.math.parsii.eval.Scope;
import org.polydev.gaea.math.parsii.eval.Variable; import org.polydev.gaea.math.parsii.eval.Variable;
import org.polydev.gaea.math.parsii.tokenizer.ParseException; import org.polydev.gaea.math.parsii.tokenizer.ParseException;
import org.polydev.gaea.world.BlockPalette; import org.polydev.gaea.world.palette.BlockPalette;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;

View File

@ -7,12 +7,12 @@ import org.polydev.gaea.biome.BiomeGrid;
public class UserDefinedGrid extends BiomeGrid { public class UserDefinedGrid extends BiomeGrid {
public UserDefinedGrid(World w, float freq1, float freq2, BiomeGridConfig config) { public UserDefinedGrid(World w, float freq1, float freq2, BiomeGridConfig config) {
super(w, freq1, freq2, config.getBiomeGrid().length, config.getBiomeGrid()[0].length); super(w, freq1, freq2, config.getBiomeGrid().length, config.getBiomeGrid()[0].length);
super.setNormalType(NormalType.CELLULAR); super.setNormalType(NormalType.LOOKUP4096);
super.setGrid(config.getBiomeGrid()); super.setGrid(config.getBiomeGrid());
} }
public UserDefinedGrid(World w, float freq1, float freq2, UserDefinedBiome[][] b) { public UserDefinedGrid(World w, float freq1, float freq2, UserDefinedBiome[][] b) {
super(w, freq1, freq2, b.length, b[0].length); super(w, freq1, freq2, b.length, b[0].length);
super.setNormalType(NormalType.CELLULAR); super.setNormalType(NormalType.LOOKUP4096);
super.setGrid(b); super.setGrid(b);
} }
} }

View File

@ -6,32 +6,31 @@ import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.genconfig.BiomeConfig; import com.dfsek.terra.config.genconfig.BiomeConfig;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.polydev.gaea.world.BlockPalette;
import org.polydev.gaea.world.carving.Carver; import org.polydev.gaea.world.carving.Carver;
import org.polydev.gaea.world.carving.Worm; import org.polydev.gaea.world.carving.Worm;
import java.util.Random; import java.util.Random;
public class UserDefinedCarver extends Carver { public class UserDefinedCarver extends Carver {
private BlockPalette inner;
private BlockPalette walls;
private final double[] start; // 0, 1, 2 = x, y, z. private final double[] start; // 0, 1, 2 = x, y, z.
private final double[] mutate; // 0, 1, 2 = x, y, z. 3 = radius. private final double[] mutate; // 0, 1, 2 = x, y, z. 3 = radius.
private final double[] radiusMultiplier; private final double[] radiusMultiplier;
private final MaxMin length; private final MaxMin length;
private final MaxMin radius; private final MaxMin radius;
public UserDefinedCarver(MaxMin height, MaxMin radius, MaxMin length, double[] start, double[] mutate, double[] radiusMultiplier) { private final int hash;
public UserDefinedCarver(MaxMin height, MaxMin radius, MaxMin length, double[] start, double[] mutate, double[] radiusMultiplier, int hash) {
super(height.getMin(), height.getMax()); super(height.getMin(), height.getMax());
this.radius = radius; this.radius = radius;
this.length = length; this.length = length;
this.start = start; this.start = start;
this.mutate = mutate; this.mutate = mutate;
this.radiusMultiplier = radiusMultiplier; this.radiusMultiplier = radiusMultiplier;
this.hash = hash;
} }
@Override @Override
public Worm getWorm(long l, Vector vector) { public Worm getWorm(long l, Vector vector) {
Random r = new Random(l); 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());
} }

View File

@ -17,9 +17,10 @@ import org.polydev.gaea.math.ProbabilityCollection;
import org.polydev.gaea.math.parsii.tokenizer.ParseException; import org.polydev.gaea.math.parsii.tokenizer.ParseException;
import org.polydev.gaea.tree.Tree; import org.polydev.gaea.tree.Tree;
import org.polydev.gaea.tree.TreeType; import org.polydev.gaea.tree.TreeType;
import org.polydev.gaea.world.BlockPalette;
import org.polydev.gaea.world.Fauna; import org.polydev.gaea.world.Fauna;
import org.polydev.gaea.world.FaunaType; import org.polydev.gaea.world.FaunaType;
import org.polydev.gaea.world.palette.BlockPalette;
import org.polydev.gaea.world.palette.RandomPalette;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -27,6 +28,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Random;
import java.util.TreeMap; import java.util.TreeMap;
public class BiomeConfig extends TerraConfigObject { public class BiomeConfig extends TerraConfigObject {
@ -64,7 +66,7 @@ public class BiomeConfig extends TerraConfigObject {
try { try {
if(((String) entry.getKey()).startsWith("BLOCK:")) { if(((String) entry.getKey()).startsWith("BLOCK:")) {
try { try {
paletteMap.put((Integer) entry.getValue(), new BlockPalette().addBlockData(new ProbabilityCollection<BlockData>().add(Bukkit.createBlockData(((String) entry.getKey()).substring(6)), 1), 1)); paletteMap.put((Integer) entry.getValue(), new RandomPalette(new Random(0)).addBlockData(new ProbabilityCollection<BlockData>().add(Bukkit.createBlockData(((String) entry.getKey()).substring(6)), 1), 1));
} catch(IllegalArgumentException ex) { } catch(IllegalArgumentException ex) {
throw new InvalidConfigurationException("SEVERE configuration error for BlockPalettes in biome " + getFriendlyName() + ", ID: " + biomeID + ". BlockData " + entry.getKey() + " is invalid!"); throw new InvalidConfigurationException("SEVERE configuration error for BlockPalettes in biome " + getFriendlyName() + ", ID: " + biomeID + ". BlockData " + entry.getKey() + " is invalid!");
} }

View File

@ -92,7 +92,8 @@ public class CarverConfig extends TerraConfigObject {
MaxMin radius = new MaxMin(getInt("start.radius.min"), getInt("start.radius.max")); MaxMin radius = new MaxMin(getInt("start.radius.min"), getInt("start.radius.max"));
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");
carver = new UserDefinedCarver(height, radius, length, start, mutate, radiusMultiplier); if(id == null) throw new InvalidConfigurationException("No ID specified for Carver!");
carver = new UserDefinedCarver(height, radius, length, start, mutate, radiusMultiplier, id.hashCode());
caveConfig.put(id, this); caveConfig.put(id, this);
} }

View File

@ -9,9 +9,9 @@ import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.plugin.java.JavaPlugin;
import org.polydev.gaea.world.BlockPalette;
import org.polydev.gaea.world.Fauna; import org.polydev.gaea.world.Fauna;
import org.polydev.gaea.world.palette.BlockPalette;
import org.polydev.gaea.world.palette.RandomPalette;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -45,7 +45,9 @@ public class FaunaConfig extends TerraConfigObject implements Fauna {
throw new InvalidConfigurationException("Invalid material ID in spawnable list: " + e.getMessage()); throw new InvalidConfigurationException("Invalid material ID in spawnable list: " + e.getMessage());
} }
faunaPalette = PaletteConfig.getPalette(getMapList("blocks")); BlockPalette p = new RandomPalette(new Random(getInt("seed", 4)));
faunaPalette = PaletteConfig.getPalette(getMapList("blocks"), p);
if(!contains("id")) throw new InvalidConfigurationException("Fauna ID unspecified!"); if(!contains("id")) throw new InvalidConfigurationException("Fauna ID unspecified!");
this.id = getString("id"); this.id = getString("id");
if(!contains("name")) throw new InvalidConfigurationException("Fauna Name unspecified!"); if(!contains("name")) throw new InvalidConfigurationException("Fauna Name unspecified!");
@ -76,7 +78,7 @@ public class FaunaConfig extends TerraConfigObject implements Fauna {
if(!location.clone().add(0, i+1, 0).getBlock().isEmpty()) return false; if(!location.clone().add(0, i+1, 0).getBlock().isEmpty()) return false;
} }
for(int i = 0; i < size; i++) { for(int i = 0; i < size; i++) {
location.clone().add(0, i+1, 0).getBlock().setBlockData(faunaPalette.getBlockData(size-(i+1), new Random()), false); location.clone().add(0, i+1, 0).getBlock().setBlockData(faunaPalette.getBlockData(size-(i+1), location.getBlockX(), location.getBlockZ()), false);
} }
return true; return true;
} }

View File

@ -6,14 +6,18 @@ import org.bukkit.Bukkit;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.polydev.gaea.math.FastNoise;
import org.polydev.gaea.math.ProbabilityCollection; import org.polydev.gaea.math.ProbabilityCollection;
import org.polydev.gaea.world.BlockPalette; import org.polydev.gaea.world.palette.BlockPalette;
import org.polydev.gaea.world.palette.RandomPalette;
import org.polydev.gaea.world.palette.SimplexPalette;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random;
public class PaletteConfig extends TerraConfigObject { public class PaletteConfig extends TerraConfigObject {
private static final Map<String, PaletteConfig> palettes = new HashMap<>(); private static final Map<String, PaletteConfig> palettes = new HashMap<>();
@ -21,13 +25,24 @@ public class PaletteConfig extends TerraConfigObject {
private String paletteID; private String paletteID;
private boolean isEnabled = false; private boolean isEnabled = false;
private String friendlyName; private String friendlyName;
private boolean useNoise = false;
private float nFreq;
public PaletteConfig(File file) throws IOException, InvalidConfigurationException { public PaletteConfig(File file) throws IOException, InvalidConfigurationException {
super(file); super(file);
} }
@Override @Override
public void init() throws InvalidConfigurationException { public void init() throws InvalidConfigurationException {
palette = getPalette(getMapList("blocks")); BlockPalette pal;
if(getBoolean("simplex", false)) {
useNoise = true;
FastNoise pNoise = new FastNoise(getInt("seed", 3));
pNoise.setNoiseType(FastNoise.NoiseType.SimplexFractal);
pNoise.setFractalOctaves(4);
pNoise.setFrequency((float) getDouble("frequency", 0.02));
pal = new SimplexPalette(pNoise);
} else pal = new RandomPalette(new Random(getInt("seed", 3)));
palette = getPalette(getMapList("blocks"), pal);
if(!contains("id")) throw new InvalidConfigurationException("Grid ID unspecified!"); if(!contains("id")) throw new InvalidConfigurationException("Grid ID unspecified!");
this.paletteID = getString("id"); this.paletteID = getString("id");
if(!contains("name")) throw new InvalidConfigurationException("Grid Name unspecified!"); if(!contains("name")) throw new InvalidConfigurationException("Grid Name unspecified!");
@ -52,8 +67,7 @@ public class PaletteConfig extends TerraConfigObject {
return paletteID; return paletteID;
} }
protected static BlockPalette getPalette(List<Map<?, ?>> maps) throws InvalidConfigurationException { protected static BlockPalette getPalette(List<Map<?, ?>> maps, BlockPalette p) throws InvalidConfigurationException {
BlockPalette p = new BlockPalette();
for(Map<?, ?> m : maps) { for(Map<?, ?> m : maps) {
try { try {
ProbabilityCollection<BlockData> layer = new ProbabilityCollection<>(); ProbabilityCollection<BlockData> layer = new ProbabilityCollection<>();
@ -70,7 +84,7 @@ public class PaletteConfig extends TerraConfigObject {
@Override @Override
public String toString() { public String toString() {
return "BlockPalette with name: " + getFriendlyName() + ", ID " + getID() + " with " + getPalette().getSize() + " layers"; return "BlockPalette with name: " + getFriendlyName() + ", ID " + getID() + " with " + getPalette().getSize() + " layers, using Simplex: " + useNoise;
} }
public static PaletteConfig fromID(String id) { public static PaletteConfig fromID(String id) {

View File

@ -7,6 +7,7 @@ import org.bukkit.Location;
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.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.BlockPopulator;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -14,8 +15,10 @@ import org.polydev.gaea.profiler.ProfileFuture;
import org.polydev.gaea.world.carving.CarvingData; import org.polydev.gaea.world.carving.CarvingData;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set;
public class CavePopulator extends BlockPopulator { public class CavePopulator extends BlockPopulator {
@Override @Override
@ -23,20 +26,22 @@ public class CavePopulator extends BlockPopulator {
ProfileFuture cave = TerraProfiler.fromWorld(world).measure("CaveTime"); ProfileFuture cave = TerraProfiler.fromWorld(world).measure("CaveTime");
for(CarverConfig c : CarverConfig.getCarvers()) { for(CarverConfig c : CarverConfig.getCarvers()) {
Map<Location, Material> shiftCandidate = new HashMap<>(); Map<Location, Material> shiftCandidate = new HashMap<>();
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.getCarver().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();
boolean liquid = m.equals(Material.WATER) || m.equals(Material.LAVA); boolean liquid = b.getType().equals(Material.WATER) || b.getType().equals(Material.LAVA);
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), liquid); b.setBlockData(c.getPaletteInner(v.getBlockY()).get(random), false);
} else if(c.isReplaceableOuter(m)){ } else if(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), liquid); b.setBlockData(c.getPaletteOuter(v.getBlockY()).get(random), false);
} else if(liquid) { }
b.setBlockData(b.getBlockData(), true); if(liquid) {
updateNeeded.add(b);
} }
} }
int i = 0; int i = 0;
@ -54,7 +59,12 @@ public class CavePopulator extends BlockPopulator {
} catch(NullPointerException ignored) {} } catch(NullPointerException ignored) {}
i++; i++;
} }
if(i > 0) System.out.println("Shifted " + i + " blocks. " + j + " successful shifts."); for(Block b : updateNeeded) {
BlockData orig = b.getBlockData();
b.setBlockData(Material.AIR.createBlockData(), true);
b.setBlockData(orig, true);
}
if(i > 0) System.out.println("Shifted " + i + " blocks. " + j + " successful shifts. " + updateNeeded.size() + " blocks updated.");
} }
if(cave != null) cave.complete(); if(cave != null) cave.complete();

File diff suppressed because one or more lines are too long

View File

@ -15,14 +15,9 @@ public class LookupGenerator {
List<Double> vals = new ArrayList<>(); List<Double> vals = new ArrayList<>();
FastNoise noise = new FastNoise(); FastNoise noise = new FastNoise();
FastNoise noiseLookup = new FastNoise(); noise.setNoiseType(FastNoise.NoiseType.SimplexFractal);
noiseLookup.setNoiseType(FastNoise.NoiseType.Simplex);
noiseLookup.setFrequency(0.02f);
noise.setFrequency(0.02f); noise.setFrequency(0.02f);
noise.setNoiseType(FastNoise.NoiseType.Cellular); noise.setFractalOctaves(4);
noise.setCellularDistanceFunction(FastNoise.CellularDistanceFunction.Natural);
noise.setCellularReturnType(FastNoise.CellularReturnType.NoiseLookup);
noise.setCellularNoiseLookup(noiseLookup);
int[] numbers = new int[dist]; int[] numbers = new int[dist];
double min = Integer.MAX_VALUE; double min = Integer.MAX_VALUE;
double max = Integer.MIN_VALUE; double max = Integer.MIN_VALUE;