mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 02:20:57 +00:00
Improve flora placement algorithm
This commit is contained in:
@@ -16,6 +16,6 @@ public class FloraFactory implements TerraFactory<FloraTemplate, Flora> {
|
||||
for(PaletteLayer layer : config.getFloraPalette()) {
|
||||
palette.add(layer.getLayer(), layer.getSize());
|
||||
}
|
||||
return new TerraFlora(palette, config.doPhysics(), config.isCeiling(), config.getIrrigable(), config.getSpawnable(), config.getReplaceable(), config.getMaxPlacements(), config.getSearch(), config.isSpawnBlacklist());
|
||||
return new TerraFlora(palette, config.doPhysics(), config.isCeiling(), config.getIrrigable(), config.getSpawnable(), config.getReplaceable(), config.getMaxPlacements(), config.getSearch(), config.isSpawnBlacklist(), config.getIrrigableOffset());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,15 @@ public class FloraTemplate extends AbstractableTemplate {
|
||||
@Abstractable
|
||||
private int maxPlacements = -1;
|
||||
|
||||
@Value("irrigable-offset")
|
||||
@Abstractable
|
||||
@Default
|
||||
private int irrigableOffset;
|
||||
|
||||
public int getIrrigableOffset() {
|
||||
return irrigableOffset;
|
||||
}
|
||||
|
||||
public TerraFlora.Search getSearch() {
|
||||
return search;
|
||||
}
|
||||
|
||||
@@ -112,13 +112,13 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
|
||||
if(stairs != null) {
|
||||
Palette<BlockData> stairPalette = stairs.get(up.getMaterial());
|
||||
if(stairPalette != null) {
|
||||
BlockData stair = stairPalette.get(0, block.getBlockX(), block.getBlockZ());
|
||||
BlockData stair = stairPalette.get(0, block.getBlockX(), block.getBlockZ()).clone();
|
||||
Stairs stairNew = (Stairs) stair.clone();
|
||||
stairNew.setHalf(Bisected.Half.TOP);
|
||||
if(placePart(orig, chunk, block, thresh, sampler, stairNew)) return;
|
||||
}
|
||||
}
|
||||
BlockData slab = slabs.getOrDefault(up.getMaterial(), DataUtil.BLANK_PALETTE).get(0, block.getBlockX(), block.getBlockZ());
|
||||
BlockData slab = slabs.getOrDefault(up.getMaterial(), DataUtil.BLANK_PALETTE).get(0, block.getBlockX(), block.getBlockZ()).clone();
|
||||
if(slab instanceof Bisected) ((Bisected) slab).setHalf(Bisected.Half.TOP);
|
||||
if(slab instanceof Slab) ((Slab) slab).setType(Slab.Type.TOP);
|
||||
if(slab instanceof Waterlogged) {
|
||||
|
||||
@@ -30,7 +30,9 @@ public class TerraFlora implements Flora {
|
||||
|
||||
private final boolean spawnBlacklist;
|
||||
|
||||
public TerraFlora(Palette<BlockData> floraPalette, boolean physics, boolean ceiling, MaterialSet irrigable, MaterialSet spawnable, MaterialSet replaceable, int maxPlacements, Search search, boolean spawnBlacklist) {
|
||||
private final int irrigableOffset;
|
||||
|
||||
public TerraFlora(Palette<BlockData> floraPalette, boolean physics, boolean ceiling, MaterialSet irrigable, MaterialSet spawnable, MaterialSet replaceable, int maxPlacements, Search search, boolean spawnBlacklist, int irrigableOffset) {
|
||||
this.floraPalette = floraPalette;
|
||||
this.physics = physics;
|
||||
this.spawnBlacklist = spawnBlacklist;
|
||||
@@ -40,6 +42,7 @@ public class TerraFlora implements Flora {
|
||||
this.replaceable = replaceable;
|
||||
this.maxPlacements = maxPlacements;
|
||||
this.search = search;
|
||||
this.irrigableOffset = irrigableOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,7 +53,7 @@ public class TerraFlora implements Flora {
|
||||
for(int y : range) {
|
||||
if(y > 255 || y < 0) continue;
|
||||
current = current.getRelative(search.equals(Search.UP) ? BlockFace.UP : BlockFace.DOWN);
|
||||
if((spawnBlacklist != spawnable.contains(current.getType())) && isIrrigated(current) && valid(size, current)) {
|
||||
if((spawnBlacklist != spawnable.contains(current.getType())) && isIrrigated(current.getRelative(BlockFace.UP, irrigableOffset)) && valid(size, current)) {
|
||||
blocks.add(current);
|
||||
if(maxPlacements > 0 && blocks.size() >= maxPlacements) break;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.dfsek.terra.TerraProfiler;
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.biome.grid.TerraBiomeGrid;
|
||||
import com.dfsek.terra.generation.items.flora.FloraLayer;
|
||||
import com.dfsek.terra.procgen.math.Vector2;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
@@ -12,6 +13,9 @@ import org.polydev.gaea.generation.GenerationPhase;
|
||||
import org.polydev.gaea.population.GaeaBlockPopulator;
|
||||
import org.polydev.gaea.profiler.ProfileFuture;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
@@ -25,15 +29,26 @@ public class FloraPopulator extends GaeaBlockPopulator {
|
||||
TerraWorld tw = TerraWorld.getWorld(world);
|
||||
if(!tw.isSafe()) return;
|
||||
TerraBiomeGrid grid = tw.getGrid();
|
||||
Map<Vector2, List<FloraLayer>> layers = new HashMap<>();
|
||||
for(int x = 0; x < 16; x++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, GenerationPhase.POPULATE);
|
||||
Vector2 l = new Vector2(x, z);
|
||||
biome.getConfig().getFlora().forEach(layer -> {
|
||||
if(layer.getDensity() >= random.nextDouble() * 100D) layer.place(chunk, l, random);
|
||||
});
|
||||
layers.put(l, biome.getConfig().getFlora());
|
||||
}
|
||||
}
|
||||
int iter = 0;
|
||||
boolean finished = false;
|
||||
while(!finished) {
|
||||
finished = true;
|
||||
for(Map.Entry<Vector2, List<FloraLayer>> entry : layers.entrySet()) {
|
||||
if(entry.getValue().size() <= iter) continue;
|
||||
finished = false;
|
||||
FloraLayer layer = entry.getValue().get(iter);
|
||||
if(layer.getDensity() >= random.nextDouble() * 100D) layer.place(chunk, entry.getKey(), random);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user