mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-18 10:32:30 +00:00
Performance improvements
This commit is contained in:
parent
ca5accafa2
commit
0f29a506d0
2
pom.xml
2
pom.xml
@ -95,7 +95,7 @@
|
||||
<dependency>
|
||||
<groupId>org.polydev</groupId>
|
||||
<artifactId>gaea</artifactId>
|
||||
<version>1.10.48</version>
|
||||
<version>1.10.80</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.lucko</groupId>
|
||||
|
@ -10,14 +10,13 @@ import com.dfsek.terra.generation.TerraChunkGenerator;
|
||||
import com.dfsek.terra.image.WorldImageGenerator;
|
||||
import com.dfsek.terra.structure.GaeaStructure;
|
||||
import com.dfsek.terra.structure.InitializationException;
|
||||
import com.dfsek.terra.structure.StructureSpawn;
|
||||
import com.dfsek.terra.procgen.GridSpawn;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@ -33,7 +32,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class TerraCommand implements CommandExecutor, TabExecutor {
|
||||
@ -189,7 +187,7 @@ public class TerraCommand implements CommandExecutor, TabExecutor {
|
||||
}
|
||||
return true;
|
||||
} else if("getspawn".equals(args[1])) {
|
||||
Vector v = new StructureSpawn(250, 250).getNearestSpawn(pl.getLocation().getBlockX(), pl.getLocation().getBlockZ(), pl.getWorld().getSeed());
|
||||
Vector v = new GridSpawn(250, 250).getNearestSpawn(pl.getLocation().getBlockX(), pl.getLocation().getBlockZ(), pl.getWorld().getSeed());
|
||||
sender.sendMessage(v.getBlockX() + ":" + v.getBlockZ());
|
||||
}
|
||||
}
|
||||
|
@ -45,8 +45,8 @@ public enum TerraTree implements Tree {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void plant(Location location, Random random, boolean b, JavaPlugin javaPlugin) {
|
||||
if(!validSpawns.contains(location.clone().subtract(0, 1, 0).getBlock().getType())) return;
|
||||
public boolean plant(Location location, Random random, boolean b, JavaPlugin javaPlugin) {
|
||||
if(!validSpawns.contains(location.clone().subtract(0, 1, 0).getBlock().getType())) return false;
|
||||
NMSStructure temp = getInstance(location, random);
|
||||
int[] size = temp.getDimensions();
|
||||
switch(random.nextInt(4)) {
|
||||
@ -67,6 +67,6 @@ public enum TerraTree implements Tree {
|
||||
break;
|
||||
}
|
||||
temp.paste();
|
||||
//location.getBlock().setType(Material.GOLD_BLOCK);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
50
src/main/java/com/dfsek/terra/carving/Cavern.java
Normal file
50
src/main/java/com/dfsek/terra/carving/Cavern.java
Normal file
@ -0,0 +1,50 @@
|
||||
package com.dfsek.terra.carving;
|
||||
|
||||
import com.dfsek.terra.procgen.GridSpawn;
|
||||
import com.dfsek.terra.procgen.voxel.DeformedSphere;
|
||||
import com.dfsek.terra.procgen.voxel.Tube;
|
||||
import com.dfsek.terra.procgen.voxel.VoxelGeometry;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.polydev.gaea.math.FastNoise;
|
||||
import org.polydev.gaea.math.MathUtil;
|
||||
import org.polydev.gaea.world.carving.CarvingData;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Cavern {
|
||||
private final Node node;
|
||||
private final long seed;
|
||||
public Cavern(World w) {
|
||||
this.node = new Node(w);
|
||||
this.seed = w.getSeed();
|
||||
}
|
||||
public VoxelGeometry carveChunk(int chunkX, int chunkZ) {
|
||||
long seedC = MathUtil.getCarverChunkSeed(chunkX, chunkZ, seed);
|
||||
Random chunk = new Random(seedC);
|
||||
Vector org = node.getNodeLocation((chunkX << 4)+8, (chunkZ << 4)+8).clone().setY(chunk.nextInt(128));
|
||||
VoxelGeometry carve = VoxelGeometry.getBlank();
|
||||
|
||||
FastNoise smpl = new FastNoise((int) seedC);
|
||||
smpl.setFrequency(0.01f);
|
||||
smpl.setNoiseType(FastNoise.NoiseType.Simplex);
|
||||
Bukkit.getLogger().info("Cavern: " + org.toString());
|
||||
carve.merge(new DeformedSphere(org.clone(), chunk.nextInt(4)+3, 0.75, smpl));
|
||||
|
||||
Vector _00 = new Vector(org.getX()+16, new Random(MathUtil.getCarverChunkSeed(chunkX+1, chunkZ, seed)).nextInt(128), org.getZ());
|
||||
|
||||
carve.merge(new Tube(org, _00, 4));
|
||||
return carve;
|
||||
}
|
||||
public static class Node {
|
||||
private final long seed;
|
||||
private final GridSpawn spawn = new GridSpawn(16, 0);
|
||||
public Node(World w) {
|
||||
this.seed = w.getSeed();
|
||||
}
|
||||
public Vector getNodeLocation(int x, int z) {
|
||||
return spawn.getNearestSpawn(x, z, seed);
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,8 @@ import org.polydev.gaea.generation.GenerationPhase;
|
||||
import org.polydev.gaea.world.carving.Carver;
|
||||
import org.polydev.gaea.world.carving.Worm;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class UserDefinedCarver extends Carver {
|
||||
@ -21,6 +23,7 @@ public class UserDefinedCarver extends Carver {
|
||||
private final int hash;
|
||||
private final int topCut;
|
||||
private final int bottomCut;
|
||||
|
||||
public UserDefinedCarver(Range height, Range radius, Range length, double[] start, double[] mutate, double[] radiusMultiplier, int hash, int topCut, int bottomCut) {
|
||||
super(height.getMin(), height.getMax());
|
||||
this.radius = radius;
|
||||
@ -36,7 +39,7 @@ public class UserDefinedCarver extends Carver {
|
||||
@Override
|
||||
public Worm getWorm(long l, Vector vector) {
|
||||
Random r = new Random(l+hash);
|
||||
return new UserDefinedWorm(length.get(r), r, vector, radius.getMax(), topCut, bottomCut);
|
||||
return new UserDefinedWorm((int) (length.get(r)/2), r, vector, radius.getMax(), topCut, bottomCut);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -54,7 +57,7 @@ public class UserDefinedCarver extends Carver {
|
||||
super.setBottomCut(bottomCut);
|
||||
runningRadius = radius.get(r);
|
||||
this.maxRad = maxRad;
|
||||
direction = new Vector((r.nextDouble()-0.5D)*start[0], (r.nextDouble()-0.5D)*start[1], (r.nextDouble()-0.5D)*start[2]).normalize();
|
||||
direction = new Vector((r.nextDouble()-0.5D)*start[0], (r.nextDouble()-0.5D)*start[1], (r.nextDouble()-0.5D)*start[2]).normalize().multiply(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -62,9 +65,9 @@ public class UserDefinedCarver extends Carver {
|
||||
setRadius(new int[] {(int) (runningRadius*radiusMultiplier[0]), (int) (runningRadius*radiusMultiplier[1]), (int) (runningRadius*radiusMultiplier[2])});
|
||||
runningRadius += (getRandom().nextDouble()-0.5)*mutate[3];
|
||||
runningRadius = Math.max(Math.min(runningRadius, maxRad), 1);
|
||||
direction.rotateAroundX(Math.toRadians(getRandom().nextDouble()*mutate[0]));
|
||||
direction.rotateAroundY(Math.toRadians(getRandom().nextDouble()*mutate[1]));
|
||||
direction.rotateAroundZ(Math.toRadians(getRandom().nextDouble()*mutate[2]));
|
||||
direction.rotateAroundX(Math.toRadians(getRandom().nextDouble()*mutate[0]*2));
|
||||
direction.rotateAroundY(Math.toRadians(getRandom().nextDouble()*mutate[1]*2));
|
||||
direction.rotateAroundZ(Math.toRadians(getRandom().nextDouble()*mutate[2]*2));
|
||||
getRunning().add(direction);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
|
||||
import com.dfsek.terra.config.ConfigLoader;
|
||||
import com.dfsek.terra.config.ConfigUtil;
|
||||
import com.dfsek.terra.config.TerraConfigObject;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -9,7 +8,6 @@ import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.polydev.gaea.math.FastNoise;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -6,9 +6,7 @@ import com.dfsek.terra.config.ConfigUtil;
|
||||
import com.dfsek.terra.config.TerraConfigObject;
|
||||
import com.dfsek.terra.population.StructurePopulator;
|
||||
import com.dfsek.terra.structure.GaeaStructure;
|
||||
import com.dfsek.terra.structure.StructureSpawn;
|
||||
import com.dfsek.terra.structure.StructureSpawnRequirement;
|
||||
import org.bukkit.Bukkit;
|
||||
import com.dfsek.terra.procgen.GridSpawn;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
|
||||
import java.io.File;
|
||||
@ -20,7 +18,7 @@ import java.util.Objects;
|
||||
public class StructureConfig extends TerraConfigObject {
|
||||
private static final Map<String, StructureConfig> configs = new HashMap<>();
|
||||
private GaeaStructure structure;
|
||||
private StructureSpawn spawn;
|
||||
private GridSpawn spawn;
|
||||
private String id;
|
||||
private Range searchStart;
|
||||
private Range bound;
|
||||
@ -42,7 +40,7 @@ public class StructureConfig extends TerraConfigObject {
|
||||
}
|
||||
if(!contains("id")) throw new InvalidConfigurationException("No ID specified!");
|
||||
id = getString("id");
|
||||
spawn = new StructureSpawn(getInt("spawn.width", 500), getInt("spawn.padding", 100));
|
||||
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));
|
||||
try {
|
||||
@ -62,7 +60,7 @@ public class StructureConfig extends TerraConfigObject {
|
||||
return structure;
|
||||
}
|
||||
|
||||
public StructureSpawn getSpawn() {
|
||||
public GridSpawn getSpawn() {
|
||||
return spawn;
|
||||
}
|
||||
|
||||
|
@ -37,59 +37,13 @@ public class SlabGenerator extends GenerationPopulator {
|
||||
if(config.getSlabs() == null) continue;
|
||||
double thresh = config.getSlabThreshold();
|
||||
for(int y = 0; y < world.getMaxHeight(); y++) {
|
||||
if(chunk.getType(x, y, z).isSolid()) continue;
|
||||
prepareBlockPart(interp, chunk, new Vector(x, y, z), config.getSlabs(), config.getStairs(), thresh);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
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());
|
||||
double _11 = interp.getNoise(block.getBlockX(), block.getBlockY() - 0.4, block.getBlockZ());
|
||||
if(_11 > thresh) {
|
||||
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 _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 _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 _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);
|
||||
|
||||
if(stairs != null) {
|
||||
Palette<BlockData> stairPalette = stairs.get(down.getMaterial());
|
||||
if(stairPalette != null) {
|
||||
BlockData stair = stairPalette.get(0, block.getBlockX(), block.getBlockZ());
|
||||
Stairs finalStair = getStair(new double[] {_01, _10, _12, _21}, (Stairs) stair, thresh);
|
||||
if(finalStair != null) {
|
||||
if(orig.matches(WATER)) finalStair.setWaterlogged(true);
|
||||
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), finalStair);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
BlockData slab = slabs.getOrDefault(down.getMaterial(), AIRPALETTE).get(0, block.getBlockX(), block.getBlockZ());
|
||||
if(slab instanceof Waterlogged) {
|
||||
((Waterlogged) slab).setWaterlogged(orig.matches(WATER));
|
||||
} else if(orig.matches(WATER)) return;
|
||||
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), slab);
|
||||
}
|
||||
}
|
||||
|
||||
private static Stairs getStair(double[] vals, Stairs stair, double thresh) {
|
||||
if(vals.length != 4) throw new IllegalArgumentException();
|
||||
Stairs stairNew = (Stairs) stair.clone();
|
||||
if(vals[0] > thresh) {
|
||||
stairNew.setFacing(BlockFace.WEST);
|
||||
} else if(vals[1] > thresh) {
|
||||
stairNew.setFacing(BlockFace.NORTH);
|
||||
} else if(vals[2] > thresh) {
|
||||
stairNew.setFacing(BlockFace.SOUTH);
|
||||
} else if(vals[3] > thresh) {
|
||||
stairNew.setFacing(BlockFace.EAST);
|
||||
} else return null;
|
||||
return stairNew;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.dfsek.terra.generation;
|
||||
|
||||
import com.dfsek.terra.Terra;
|
||||
import com.dfsek.terra.biome.TerraBiomeGrid;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.WorldConfig;
|
||||
import com.dfsek.terra.config.genconfig.BiomeConfig;
|
||||
import com.dfsek.terra.population.CavePopulator;
|
||||
import com.dfsek.terra.population.FloraPopulator;
|
||||
@ -13,11 +13,15 @@ import com.dfsek.terra.structure.StructureSpawnRequirement;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.block.data.type.Stairs;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.polydev.gaea.biome.Biome;
|
||||
import org.polydev.gaea.biome.BiomeGrid;
|
||||
import org.polydev.gaea.generation.GaeaChunkGenerator;
|
||||
import org.polydev.gaea.generation.GenerationPhase;
|
||||
import org.polydev.gaea.generation.GenerationPopulator;
|
||||
@ -25,6 +29,7 @@ import org.polydev.gaea.math.ChunkInterpolator;
|
||||
import org.polydev.gaea.math.FastNoise;
|
||||
import org.polydev.gaea.population.PopulationManager;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import org.polydev.gaea.world.palette.RandomPalette;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
@ -36,10 +41,10 @@ import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class TerraChunkGenerator extends GaeaChunkGenerator {
|
||||
private static final BlockData STONE = Material.STONE.createBlockData();
|
||||
private static final BlockData WATER = Material.WATER.createBlockData();
|
||||
private final PopulationManager popMan = new PopulationManager();
|
||||
private final PopulationManager popMan = new PopulationManager(Terra.getInstance());
|
||||
private boolean needsLoad = true;
|
||||
|
||||
|
||||
private static final Map<World, PopulationManager> popMap = new HashMap<>();
|
||||
|
||||
public TerraChunkGenerator() {
|
||||
@ -58,21 +63,79 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
|
||||
int zOrig = (chunkZ << 4);
|
||||
for(byte x = 0; x < 16; x++) {
|
||||
for(byte z = 0; z < 16; z++) {
|
||||
int paletteLevel = 0;
|
||||
int cx = xOrig + x;
|
||||
int cz = zOrig + z;
|
||||
Biome b = getBiomeGrid(world).getBiome(xOrig+x, zOrig+z, GenerationPhase.PALETTE_APPLY);
|
||||
BiomeConfig c = BiomeConfig.fromBiome((UserDefinedBiome) b);
|
||||
int sea = c.getSeaLevel();
|
||||
Palette<BlockData> seaPalette = c.getOceanPalette();
|
||||
for(int y = 0; y < 256; y++) {
|
||||
if(super.getInterpolatedNoise(x, y, z) > 0) chunk.setBlock(x, y, z, STONE);
|
||||
else if(y <= sea) {
|
||||
chunk.setBlock(x, y, z, seaPalette.get(sea-y, x+xOrig, z+zOrig));
|
||||
for(int y = world.getMaxHeight()-1; y >= 0; y--) {
|
||||
BlockData data;
|
||||
if(super.getInterpolatedNoise(x, y, z) > 0) {
|
||||
data = b.getGenerator().getPalette(y).get(paletteLevel, cx, cz);
|
||||
chunk.setBlock(x, y, z, data);
|
||||
if(paletteLevel == 0 && c.getSlabs() != null) {
|
||||
prepareBlockPart(data, chunk.getBlockData(x, y+1, z), chunk, new Vector(x, y+1, z), c.getSlabs(), c.getStairs(), c.getSlabThreshold());
|
||||
}
|
||||
paletteLevel++;
|
||||
} else if(y <= sea) {
|
||||
chunk.setBlock(x, y, z, seaPalette.get(sea-y, x+xOrig, z+zOrig));
|
||||
paletteLevel = 0;
|
||||
} else paletteLevel = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
private void prepareBlockPart(BlockData down, BlockData orig, ChunkData chunk, Vector block, Map<Material, Palette<BlockData>> slabs, Map<Material, Palette<BlockData>> stairs, double thresh) {
|
||||
double _11 = getInterpolatedNoise(block.getBlockX(), block.getBlockY() - 0.4, block.getBlockZ());
|
||||
if(_11 > thresh) {
|
||||
//double _00 = interp.getNoise(block.getBlockX() - 0.5, block.getBlockY(), block.getBlockZ() - 0.5);
|
||||
double _01 = getInterpolatedNoise(block.getBlockX() - 0.5, block.getBlockY(), block.getBlockZ());
|
||||
//double _02 = interp.getNoise(block.getBlockX() - 0.5, block.getBlockY(), block.getBlockZ() + 0.5);
|
||||
double _10 = getInterpolatedNoise(block.getBlockX(), block.getBlockY(), block.getBlockZ() - 0.5);
|
||||
double _12 = getInterpolatedNoise(block.getBlockX(), block.getBlockY(), block.getBlockZ() + 0.5);
|
||||
//double _20 = interp.getNoise(block.getBlockX() + 0.5, block.getBlockY(), block.getBlockZ() - 0.5);
|
||||
double _21 = getInterpolatedNoise(block.getBlockX() + 0.5, block.getBlockY(), block.getBlockZ());
|
||||
//double _22 = interp.getNoise(block.getBlockX() + 0.5, block.getBlockY(), block.getBlockZ() + 0.5);
|
||||
|
||||
if(stairs != null) {
|
||||
Palette<BlockData> stairPalette = stairs.get(down.getMaterial());
|
||||
if(stairPalette != null) {
|
||||
BlockData stair = stairPalette.get(0, block.getBlockX(), block.getBlockZ());
|
||||
Stairs finalStair = getStair(new double[] {_01, _10, _12, _21}, (Stairs) stair, thresh);
|
||||
if(finalStair != null) {
|
||||
if(orig.matches(Util.WATER)) finalStair.setWaterlogged(true);
|
||||
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), finalStair);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
BlockData slab = slabs.getOrDefault(down.getMaterial(), Util.BLANK_PALETTE).get(0, block.getBlockX(), block.getBlockZ());
|
||||
if(slab instanceof Waterlogged) {
|
||||
((Waterlogged) slab).setWaterlogged(orig.matches(Util.WATER));
|
||||
} else if(orig.matches(Util.WATER)) return;
|
||||
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), slab);
|
||||
}
|
||||
}
|
||||
|
||||
private static Stairs getStair(double[] vals, Stairs stair, double thresh) {
|
||||
if(vals.length != 4) throw new IllegalArgumentException();
|
||||
Stairs stairNew = (Stairs) stair.clone();
|
||||
if(vals[0] > thresh) {
|
||||
stairNew.setFacing(BlockFace.WEST);
|
||||
} else if(vals[1] > thresh) {
|
||||
stairNew.setFacing(BlockFace.NORTH);
|
||||
} else if(vals[2] > thresh) {
|
||||
stairNew.setFacing(BlockFace.SOUTH);
|
||||
} else if(vals[3] > thresh) {
|
||||
stairNew.setFacing(BlockFace.EAST);
|
||||
} else return null;
|
||||
return stairNew;
|
||||
}
|
||||
|
||||
private void load(World w) {
|
||||
try {
|
||||
popMan.loadBlocks(w);
|
||||
|
@ -23,19 +23,29 @@ public class UserDefinedGenerator extends Generator {
|
||||
private final Variable xVar = s.getVariable("x");
|
||||
private final Variable yVar = s.getVariable("y");
|
||||
private final Variable zVar = s.getVariable("z");
|
||||
private final TreeMap<Integer, Palette<BlockData>> paletteMap;
|
||||
@SuppressWarnings("unchecked")
|
||||
private final Palette<BlockData>[] palettes = new Palette[256];
|
||||
private final NoiseFunction2 n2 = new NoiseFunction2();
|
||||
private final NoiseFunction3 n3 = new NoiseFunction3();
|
||||
|
||||
private static final Object noiseLock = new Object();
|
||||
|
||||
|
||||
public UserDefinedGenerator(String e, List<Variable> v, TreeMap<Integer, Palette<BlockData>> pa) throws ParseException {
|
||||
public UserDefinedGenerator(String equation, List<Variable> v, TreeMap<Integer, Palette<BlockData>> pa) throws ParseException {
|
||||
Parser p = new Parser();
|
||||
p.registerFunction("noise2", n2);
|
||||
p.registerFunction("noise3", n3);
|
||||
this.paletteMap = pa;
|
||||
this.noiseExp = p.parse(e, s);
|
||||
for(int y = 0; y < 256; y++) {
|
||||
Palette<BlockData> d = Util.BLANK_PALETTE;
|
||||
for(Map.Entry<Integer, Palette<BlockData>> e : pa.entrySet()) {
|
||||
if(e.getKey() >= y) {
|
||||
d = e.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
palettes[y] = d;
|
||||
}
|
||||
this.noiseExp = p.parse(equation, s);
|
||||
}
|
||||
/**
|
||||
* Gets the 2D noise at a pair of coordinates using the provided FastNoise instance.
|
||||
@ -85,9 +95,6 @@ public class UserDefinedGenerator extends Generator {
|
||||
*/
|
||||
@Override
|
||||
public Palette<BlockData> getPalette(int y) {
|
||||
for(Map.Entry<Integer, Palette<BlockData>> e : paletteMap.entrySet()) {
|
||||
if(e.getKey() >= y ) return e.getValue();
|
||||
}
|
||||
return null;
|
||||
return palettes[y];
|
||||
}
|
||||
}
|
||||
|
15
src/main/java/com/dfsek/terra/generation/Util.java
Normal file
15
src/main/java/com/dfsek/terra/generation/Util.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.dfsek.terra.generation;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import org.polydev.gaea.world.palette.RandomPalette;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Util {
|
||||
public static final BlockData STONE = Material.STONE.createBlockData();
|
||||
public static final BlockData WATER = Material.WATER.createBlockData();
|
||||
public static final BlockData AIR = Material.AIR.createBlockData();
|
||||
public static final Palette<BlockData> BLANK_PALETTE = new RandomPalette<BlockData>(new Random(2403)).add(AIR, 1);
|
||||
}
|
@ -16,6 +16,7 @@ import org.polydev.gaea.world.carving.CarvingData;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
@ -22,8 +22,7 @@ public class OrePopulator extends GaeaBlockPopulator {
|
||||
@Override
|
||||
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
|
||||
try (ProfileFuture ignored = TerraProfiler.fromWorld(world).measure("OreTime")) {
|
||||
Location l = chunk.getBlock(8, 0, 0).getLocation();
|
||||
Biome b = TerraBiomeGrid.fromWorld(world).getBiome(l.getBlockX(), l.getBlockZ(), GenerationPhase.POPULATE);
|
||||
Biome b = TerraBiomeGrid.fromWorld(world).getBiome((chunk.getX() << 4)+8, (chunk.getZ() << 4) + 8, GenerationPhase.POPULATE);
|
||||
for(Map.Entry<OreConfig, Range> e : BiomeConfig.fromBiome((UserDefinedBiome) b).getOres().entrySet()) {
|
||||
int num = e.getValue().get(random);
|
||||
for(int i = 0; i < num; i++) {
|
||||
|
@ -1,13 +1,11 @@
|
||||
package com.dfsek.terra.population;
|
||||
|
||||
import com.dfsek.terra.Terra;
|
||||
import com.dfsek.terra.TerraProfiler;
|
||||
import com.dfsek.terra.biome.TerraBiomeGrid;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.genconfig.BiomeConfig;
|
||||
import com.dfsek.terra.config.genconfig.StructureConfig;
|
||||
import com.dfsek.terra.structure.GaeaStructure;
|
||||
import com.dfsek.terra.structure.StructureSpawn;
|
||||
import com.dfsek.terra.structure.StructureSpawnRequirement;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
@ -16,16 +14,10 @@ import org.bukkit.World;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.polydev.gaea.generation.GenerationPhase;
|
||||
import org.polydev.gaea.population.GaeaBlockPopulator;
|
||||
import org.polydev.gaea.profiler.ProfileFuture;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class StructurePopulator extends BlockPopulator {
|
||||
|
||||
|
@ -25,18 +25,18 @@ public class TreePopulator extends GaeaBlockPopulator {
|
||||
Location origin = chunk.getBlock(x, 0, z).getLocation();
|
||||
Biome b = TerraBiomeGrid.fromWorld(world).getBiome(origin, GenerationPhase.POPULATE);
|
||||
if(((UserDefinedDecorator) b.getDecorator()).getTreeChance() < random.nextInt(100)) return;
|
||||
int numTrees = 0;
|
||||
for(int i = 0; i < 48; i++) {
|
||||
int max = 50;
|
||||
int att = 0;
|
||||
for(int i = 0; i < b.getDecorator().getTreeDensity() && att < max; ) {
|
||||
att++;
|
||||
int y = WorldUtil.getHighestValidSpawnAt(chunk, x, z);
|
||||
if(y <= 0) continue;
|
||||
origin = chunk.getBlock(x, y, z).getLocation().add(0, 1, 0);
|
||||
b = TerraBiomeGrid.fromWorld(world).getBiome(origin, GenerationPhase.POPULATE);
|
||||
numTrees++;
|
||||
try {
|
||||
b.getDecorator().getTrees().get(random).plant(origin, random, false, Terra.getInstance());
|
||||
if(b.getDecorator().getTrees().get(random).plant(origin, random, false, Terra.getInstance())) i++;
|
||||
} catch(NullPointerException ignore) {}
|
||||
if(numTrees >= b.getDecorator().getTreeDensity()) break;
|
||||
x = random.nextInt(16); // Decrease chances of chunk-crossing trees
|
||||
x = random.nextInt(16);
|
||||
z = random.nextInt(16);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package com.dfsek.terra.structure;
|
||||
package com.dfsek.terra.procgen;
|
||||
|
||||
import com.dfsek.terra.config.ConfigUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.polydev.gaea.math.MathUtil;
|
||||
|
||||
@ -9,20 +7,28 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class StructureSpawn {
|
||||
public class GridSpawn {
|
||||
private final int separation;
|
||||
private final int width;
|
||||
public StructureSpawn(int width, int separation) {
|
||||
public GridSpawn(int width, int separation) {
|
||||
this.separation = separation;
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nearest spawnpoint
|
||||
* @param x X coordinate
|
||||
* @param z Z coordinate
|
||||
* @param seed Seed for RNG
|
||||
* @return Vector representing nearest spawnpoint
|
||||
*/
|
||||
public Vector getNearestSpawn(int x, int z, long seed) {
|
||||
int structureChunkX = x / (width + 2*separation);
|
||||
int structureChunkZ = z / (width + 2*separation);
|
||||
List<Vector> zones = new ArrayList<>();
|
||||
for(int xi = structureChunkX-1; xi <= structureChunkX+1; xi++) {
|
||||
for(int zi = structureChunkZ-1; zi <= structureChunkZ+1; zi++) {
|
||||
zones.add(getStructureChunkSpawn(xi, zi, seed));
|
||||
zones.add(getChunkSpawn(xi, zi, seed));
|
||||
}
|
||||
}
|
||||
Vector shortest = zones.get(0);
|
||||
@ -32,7 +38,15 @@ public class StructureSpawn {
|
||||
}
|
||||
return shortest;
|
||||
}
|
||||
private Vector getStructureChunkSpawn(int structureChunkX, int structureChunkZ, long seed) {
|
||||
|
||||
/**
|
||||
* Get the X/Z coordinates of the spawnpoint in the nearest Chunk (not Minecraft chunk)
|
||||
* @param structureChunkX Chunk X coordinate
|
||||
* @param structureChunkZ Chunk Z coordinate
|
||||
* @param seed Seed for RNG
|
||||
* @return Vector representing spawnpoint
|
||||
*/
|
||||
private Vector getChunkSpawn(int structureChunkX, int structureChunkZ, long seed) {
|
||||
Random r = new Random(MathUtil.getCarverChunkSeed(structureChunkX, structureChunkZ, seed));
|
||||
int offsetX = r.nextInt(width);
|
||||
int offsetZ = r.nextInt(width);
|
@ -0,0 +1,20 @@
|
||||
package com.dfsek.terra.procgen.voxel;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.polydev.gaea.math.FastNoise;
|
||||
|
||||
public class DeformedSphere extends VoxelGeometry {
|
||||
public DeformedSphere(Vector start, int rad, double deform, FastNoise noise) {
|
||||
for(int x = -rad; x <= rad; x++) {
|
||||
for(int y = -rad; y <= rad; y++) {
|
||||
for(int z = -rad; z <= rad; z++) {
|
||||
Vector c = new Vector(x, y, z);
|
||||
if(c.length() < (rad + 0.5) * ((noise.getNoise(x, y, z)+1)*deform)) {
|
||||
addVector(c.add(start));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
19
src/main/java/com/dfsek/terra/procgen/voxel/Sphere.java
Normal file
19
src/main/java/com/dfsek/terra/procgen/voxel/Sphere.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.dfsek.terra.procgen.voxel;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
import org.polydev.gaea.math.FastNoise;
|
||||
|
||||
public class Sphere extends VoxelGeometry {
|
||||
public Sphere(Vector start, int rad) {
|
||||
for(int x = -rad; x <= rad; x++) {
|
||||
for(int y = -rad; y <= rad; y++) {
|
||||
for(int z = -rad; z <= rad; z++) {
|
||||
Vector c = new Vector(x, y, z);
|
||||
if(c.length() < rad + 0.5) {
|
||||
addVector(c.add(start));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
src/main/java/com/dfsek/terra/procgen/voxel/Tube.java
Normal file
15
src/main/java/com/dfsek/terra/procgen/voxel/Tube.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.dfsek.terra.procgen.voxel;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class Tube extends VoxelGeometry {
|
||||
public Tube(Vector start, Vector end, int radius) {
|
||||
Vector step = start.clone().subtract(end).normalize();
|
||||
Vector run = start.clone();
|
||||
int steps = (int) start.distance(end);
|
||||
for(int i = 0; i < steps; i++) {
|
||||
merge(new Sphere(run, radius));
|
||||
run.add(step);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.dfsek.terra.procgen.voxel;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class VoxelGeometry {
|
||||
public List<Vector> geometry = new ArrayList<>();
|
||||
|
||||
public List<Vector> getGeometry() {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
protected void addVector(Vector v) {
|
||||
geometry.add(v);
|
||||
}
|
||||
|
||||
public void merge(VoxelGeometry other) {
|
||||
geometry.addAll(other.getGeometry());
|
||||
}
|
||||
public static VoxelGeometry getBlank() {
|
||||
return new Blank();
|
||||
}
|
||||
private static class Blank extends VoxelGeometry {}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user