From 064a30190c4d55b9a580542cf92c36021e53d735 Mon Sep 17 00:00:00 2001 From: dfsek Date: Tue, 13 Oct 2020 18:25:22 -0700 Subject: [PATCH] Merge tree and flora population, increase performance of both. --- .../java/com/dfsek/terra/TerraProfiler.java | 1 - .../biome/failsafe/FailoverDecorator.java | 2 +- .../config/genconfig/biome/BiomeConfig.java | 2 +- .../genconfig/biome/BiomeTreeConfig.java | 6 -- .../terra/generation/TerraChunkGenerator.java | 3 - .../generation/UserDefinedDecorator.java | 8 +-- .../terra/population/FloraPopulator.java | 39 +++++++++++ .../dfsek/terra/population/TreePopulator.java | 69 ------------------- 8 files changed, 42 insertions(+), 88 deletions(-) delete mode 100644 src/main/java/com/dfsek/terra/population/TreePopulator.java diff --git a/src/main/java/com/dfsek/terra/TerraProfiler.java b/src/main/java/com/dfsek/terra/TerraProfiler.java index 78ada7391..2b90e31dc 100644 --- a/src/main/java/com/dfsek/terra/TerraProfiler.java +++ b/src/main/java/com/dfsek/terra/TerraProfiler.java @@ -14,7 +14,6 @@ public class TerraProfiler extends WorldProfiler { public TerraProfiler(World w) { super(w); this - .addMeasurement(new Measurement(25000000, DataType.PERIOD_MILLISECONDS), "TreeGenTime") .addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "FloraTime") .addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "OreTime") .addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "CaveTime") diff --git a/src/main/java/com/dfsek/terra/biome/failsafe/FailoverDecorator.java b/src/main/java/com/dfsek/terra/biome/failsafe/FailoverDecorator.java index 0b5f1be2e..6e280d4fc 100644 --- a/src/main/java/com/dfsek/terra/biome/failsafe/FailoverDecorator.java +++ b/src/main/java/com/dfsek/terra/biome/failsafe/FailoverDecorator.java @@ -7,6 +7,6 @@ import org.polydev.gaea.world.Flora; public final class FailoverDecorator extends UserDefinedDecorator { public FailoverDecorator() { - super(new ProbabilityCollection<>(), new ProbabilityCollection<>(), 0, 0, 0); + super(new ProbabilityCollection<>(), new ProbabilityCollection<>(), 0, 0); } } diff --git a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfig.java index e3009d5dc..73c49e1aa 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfig.java @@ -124,7 +124,7 @@ public class BiomeConfig extends TerraConfig { if(eq == null || eq.equals("")) 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.getTreeChance(), tree.getTreeDensity()); + 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; diff --git a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeTreeConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeTreeConfig.java index ca6c0b581..6fc17b1e3 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeTreeConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeTreeConfig.java @@ -18,7 +18,6 @@ import java.util.Objects; public class BiomeTreeConfig extends TerraConfigSection { private final ProbabilityCollection trees = new ProbabilityCollection<>(); private final Map treeHeights = new HashMap<>(); - private int treeChance; private int treeDensity; public BiomeTreeConfig(TerraConfig parent) throws InvalidConfigurationException { super(parent); @@ -26,7 +25,6 @@ public class BiomeTreeConfig extends TerraConfigSection { if(c == null) return; Map cfg = c.getValues(false); if(cfg.size() == 0) return; - treeChance = parent.getInt("trees.chance", 0); treeDensity = parent.getInt("trees.density", 0); for(Map.Entry e : cfg.entrySet()) { try { @@ -61,8 +59,4 @@ public class BiomeTreeConfig extends TerraConfigSection { public int getTreeDensity() { return treeDensity; } - - public int getTreeChance() { - return treeChance; - } } diff --git a/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java b/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java index 3fb50a6eb..0dbfdafbb 100644 --- a/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java +++ b/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java @@ -13,10 +13,8 @@ import com.dfsek.terra.population.FloraPopulator; import com.dfsek.terra.population.OrePopulator; import com.dfsek.terra.population.SnowPopulator; import com.dfsek.terra.population.StructurePopulator; -import com.dfsek.terra.population.TreePopulator; import com.dfsek.terra.structure.StructureSpawnRequirement; import com.dfsek.terra.util.DataUtil; -import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Material; import org.bukkit.World; @@ -55,7 +53,6 @@ public class TerraChunkGenerator extends GaeaChunkGenerator { public TerraChunkGenerator() { super(ChunkInterpolator.InterpolationType.TRILINEAR); - popMan.attach(new TreePopulator()); popMan.attach(new FloraPopulator()); popMan.attach(new OrePopulator()); popMan.attach(new SnowPopulator()); diff --git a/src/main/java/com/dfsek/terra/generation/UserDefinedDecorator.java b/src/main/java/com/dfsek/terra/generation/UserDefinedDecorator.java index 5465b03e7..347aed9ab 100644 --- a/src/main/java/com/dfsek/terra/generation/UserDefinedDecorator.java +++ b/src/main/java/com/dfsek/terra/generation/UserDefinedDecorator.java @@ -11,15 +11,13 @@ public class UserDefinedDecorator extends Decorator { private final ProbabilityCollection flora; private final ProbabilityCollection trees; private final int floraChance; - private final int treeChance; private final int treeDensity; - public UserDefinedDecorator(ProbabilityCollection flora, ProbabilityCollection trees, int floraChance, int treeChance, int treeDensity) { + public UserDefinedDecorator(ProbabilityCollection flora, ProbabilityCollection trees, int floraChance, int treeDensity) { this.flora = flora; this.trees = trees; this.floraChance = floraChance; - this.treeChance = treeChance; this.treeDensity = treeDensity; } @@ -28,10 +26,6 @@ public class UserDefinedDecorator extends Decorator { return trees; } - public int getTreeChance() { - return treeChance; - } - @Override public int getTreeDensity() { return treeDensity; diff --git a/src/main/java/com/dfsek/terra/population/FloraPopulator.java b/src/main/java/com/dfsek/terra/population/FloraPopulator.java index e8a7492a4..afa235f5a 100644 --- a/src/main/java/com/dfsek/terra/population/FloraPopulator.java +++ b/src/main/java/com/dfsek/terra/population/FloraPopulator.java @@ -1,5 +1,6 @@ package com.dfsek.terra.population; +import com.dfsek.terra.Terra; import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.TerraWorld; import com.dfsek.terra.biome.TerraBiomeGrid; @@ -7,17 +8,26 @@ import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.genconfig.biome.BiomeConfig; import com.dfsek.terra.config.genconfig.biome.BiomeFloraConfig; +import com.dfsek.terra.generation.UserDefinedDecorator; import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.block.Block; import org.jetbrains.annotations.NotNull; +import org.polydev.gaea.biome.Biome; import org.polydev.gaea.generation.GenerationPhase; +import org.polydev.gaea.math.Range; import org.polydev.gaea.population.GaeaBlockPopulator; import org.polydev.gaea.profiler.ProfileFuture; +import org.polydev.gaea.tree.Tree; import org.polydev.gaea.world.Flora; +import java.util.ArrayList; +import java.util.List; import java.util.Random; +/** + * Populates Flora and Trees + */ public class FloraPopulator extends GaeaBlockPopulator { @Override public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) { @@ -29,6 +39,12 @@ public class FloraPopulator extends GaeaBlockPopulator { 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); + if((x & 1) == 0 && (z & 1) == 0) { + int treeChance = biome.getDecorator().getTreeDensity(); + if(random.nextInt(1000) < treeChance) { + if(doTrees(biome, tw, random, chunk, offset(random, x), offset(random, z))) continue; + } + } if(biome.getDecorator().getFloraChance() <= 0) continue; try { BiomeConfig c = config.getBiome(biome); @@ -47,4 +63,27 @@ public class FloraPopulator extends GaeaBlockPopulator { } } } + private static boolean 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))) { + Tree tree = biome.getDecorator().getTrees().get(random); + Range range = world.getConfig().getBiome(biome).getTreeRange(tree); + if(!range.isInRange(block.getY())) continue; + try { + return tree.plant(block.getLocation(), random, false, Terra.getInstance()); + } catch(NullPointerException ignore) {} + } + return false; + } + private static int offset(Random r, int i) { + return Math.min(Math.max(i + r.nextInt(3)-1, 0), 15); + } + public static List getValidTreeSpawnsAt(Chunk chunk, int x, int z, Range check) { + List blocks = new ArrayList<>(); + for(int y : check) { + if(chunk.getBlock(x, y, z).getType().isSolid() && chunk.getBlock(x, y + 1, z).getType().isAir()) { + blocks.add(chunk.getBlock(x, y, z)); + } + } + return blocks; + } } diff --git a/src/main/java/com/dfsek/terra/population/TreePopulator.java b/src/main/java/com/dfsek/terra/population/TreePopulator.java deleted file mode 100644 index 19556267b..000000000 --- a/src/main/java/com/dfsek/terra/population/TreePopulator.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.dfsek.terra.population; - -import com.dfsek.terra.Terra; -import com.dfsek.terra.TerraProfiler; -import com.dfsek.terra.TerraWorld; -import com.dfsek.terra.biome.TerraBiomeGrid; -import com.dfsek.terra.biome.UserDefinedBiome; -import com.dfsek.terra.config.base.ConfigPack; -import com.dfsek.terra.config.base.WorldConfig; -import com.dfsek.terra.generation.UserDefinedDecorator; -import org.bukkit.Chunk; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.jetbrains.annotations.NotNull; -import org.polydev.gaea.biome.Biome; -import org.polydev.gaea.generation.GenerationPhase; -import org.polydev.gaea.math.Range; -import org.polydev.gaea.population.GaeaBlockPopulator; -import org.polydev.gaea.profiler.ProfileFuture; -import org.polydev.gaea.tree.Tree; -import org.polydev.gaea.util.WorldUtil; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -public class TreePopulator extends GaeaBlockPopulator { - @Override - public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) { - try(ProfileFuture ignored = TerraProfiler.fromWorld(world).measure("TreeGenTime")) { - TerraWorld tw = TerraWorld.getWorld(world); - if(!tw.isSafe()) return; - TerraBiomeGrid grid = tw.getGrid();; - int x = random.nextInt(16); - int z = random.nextInt(16); - int origX = chunk.getX() << 4; - int origZ = chunk.getZ() << 4; - Biome b = grid.getBiome(x+origX, z+origZ, GenerationPhase.POPULATE); - if(((UserDefinedDecorator) b.getDecorator()).getTreeChance() < random.nextInt(100)) return; - int max = 32; - int att = 0; - for(int i = 0; i < b.getDecorator().getTreeDensity() && att < max; ) { - att++; - for(Block block : getValidSpawnsAt(chunk, x, z, new Range(0, 254))) { - b = grid.getBiome(x+origX, z+origZ, GenerationPhase.POPULATE); - Tree tree = b.getDecorator().getTrees().get(random); - Range range = tw.getConfig().getBiome((UserDefinedBiome) b).getTreeRange(tree); - if(!range.isInRange(block.getY())) continue; - try { - if(tree.plant(block.getLocation(), random, false, Terra.getInstance())) i++; - } catch(NullPointerException ignore) {} - } - - x = random.nextInt(16); - z = random.nextInt(16); - } - } - } - public List getValidSpawnsAt(Chunk chunk, int x, int z, Range check) { - List blocks = new ArrayList<>(); - for(int y : check) { - if(chunk.getBlock(x, y, z).getType().isSolid() && chunk.getBlock(x, y + 1, z).getType().isAir()) { - blocks.add(chunk.getBlock(x, y, z)); - } - } - return blocks; - } -}