Implement erosion

This commit is contained in:
dfsek 2020-10-05 20:56:26 -07:00
parent 0e760ec87e
commit 2659577322
13 changed files with 193 additions and 15 deletions

View File

@ -7,12 +7,14 @@ import com.dfsek.terra.biome.UserDefinedGrid;
import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.base.ConfigUtil; import com.dfsek.terra.config.base.ConfigUtil;
import com.dfsek.terra.config.base.WorldConfig; import com.dfsek.terra.config.base.WorldConfig;
import com.dfsek.terra.config.exception.ConfigException;
import com.dfsek.terra.config.genconfig.BiomeGridConfig; import com.dfsek.terra.config.genconfig.BiomeGridConfig;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
public class TerraWorld { public class TerraWorld {
private static final Map<World, TerraWorld> map = new HashMap<>(); private static final Map<World, TerraWorld> map = new HashMap<>();
@ -20,6 +22,7 @@ public class TerraWorld {
private final BiomeZone zone; private final BiomeZone zone;
private final ConfigPack config; private final ConfigPack config;
private final WorldConfig worldConfig; private final WorldConfig worldConfig;
private TerraWorld(World w) { private TerraWorld(World w) {
worldConfig = new WorldConfig(w, Terra.getInstance()); worldConfig = new WorldConfig(w, Terra.getInstance());
config = worldConfig.getConfig(); config = worldConfig.getConfig();
@ -39,15 +42,37 @@ public class TerraWorld {
definedGrids[i] = g.getGrid(w, worldConfig); definedGrids[i] = g.getGrid(w, worldConfig);
} }
} catch(NullPointerException e) { } catch(NullPointerException e) {
if(ConfigUtil.debug) e.printStackTrace(); Debug.stack(e);
Bukkit.getLogger().severe("No such BiomeGrid " + partName); Bukkit.getLogger().severe("No such BiomeGrid " + partName);
Bukkit.getLogger().severe("Please check configuration files for errors. Configuration errors will have been reported during initialization."); Bukkit.getLogger().severe("Please check configuration files for errors. Configuration errors will have been reported during initialization.");
Bukkit.getLogger().severe("ONLY report this to Terra if you are SURE your config is error-free."); Bukkit.getLogger().severe("ONLY report this to Terra if you are SURE your config is error-free.");
Bukkit.getLogger().severe("Terrain will NOT generate properly at this point. Correct your config before using your server!"); Bukkit.getLogger().severe("Terrain will NOT generate properly at this point. Correct your config before using your server!");
} }
} }
UserDefinedGrid erosion = null;
if(config.erosionEnable) {
try {
if(config.erosionName.startsWith("BIOME:")) {
UserDefinedBiome[][] temp = new UserDefinedBiome[1][1];
UserDefinedBiome b = Objects.requireNonNull(config.getBiome(config.erosionName.substring(6)).getBiome());
temp[0][0] = b;
erosion = new UserDefinedGrid(w, config.freq1, config.freq2, temp, worldConfig);
Debug.info("Loaded single-biome erosion grid " + config.erosionName);
} else {
BiomeGridConfig g = Objects.requireNonNull(config.getBiomeGrid(config.erosionName));
Debug.info("Loaded BiomeGrid " + g.getID());
erosion = g.getGrid(w, worldConfig);
}
} catch(NullPointerException e) {
Debug.stack(e);
Bukkit.getLogger().severe("No such BiomeGrid (erosion): " + config.erosionName);
Bukkit.getLogger().severe("Please check configuration files for errors. Configuration errors will have been reported during initialization.");
Bukkit.getLogger().severe("ONLY report this to Terra if you are SURE your config is error-free.");
Bukkit.getLogger().severe("Terrain will NOT generate properly at this point. Correct your config before using your server!");
}
}
zone = new BiomeZone(w, worldConfig, definedGrids); zone = new BiomeZone(w, worldConfig, definedGrids);
grid = new TerraBiomeGrid(w, config.freq1, config.freq2, zone, config); grid = new TerraBiomeGrid(w, config.freq1, config.freq2, zone, config, erosion);
} }
public static synchronized TerraWorld getWorld(World w) { public static synchronized TerraWorld getWorld(World w) {

View File

@ -10,6 +10,9 @@ import org.polydev.gaea.math.FastNoise;
import java.util.Objects; import java.util.Objects;
/**
* Holds 1D array of BiomeGrids.
*/
public class BiomeZone { public class BiomeZone {
private final BiomeGrid[] grids; private final BiomeGrid[] grids;
private final FastNoise noise; private final FastNoise noise;
@ -29,18 +32,40 @@ public class BiomeZone {
channel = wc.zoneChannel; channel = wc.zoneChannel;
} }
/**
* Get BiomeGrid at location
* @param x X coordinate
* @param z Z coordinate
* @return BiomeGrid at coordinates.
*/
protected BiomeGrid getGrid(int x, int z) { protected BiomeGrid getGrid(int x, int z) {
return grids[NormalizationUtil.normalize(useImage ? Objects.requireNonNull(imageLoader).getNoiseVal(x, z, channel) : noise.getNoise(x, z), grids.length)]; return grids[NormalizationUtil.normalize(useImage ? Objects.requireNonNull(imageLoader).getNoiseVal(x, z, channel) : noise.getNoise(x, z), grids.length)];
} }
/**
* Get the number of BiomeGrids this BiomeZone holds.
* @return Number of grids
*/
public int getSize() { public int getSize() {
return grids.length; return grids.length;
} }
/**
* Get the normalized grid noise at location
* @param x X coordinate
* @param z Z coordinate
* @return Normalized noise at coordinates
*/
public int getNoise(int x, int z) { public int getNoise(int x, int z) {
return NormalizationUtil.normalize(useImage ? Objects.requireNonNull(imageLoader).getNoiseVal(x, z, channel) : noise.getNoise(x, z), grids.length); return NormalizationUtil.normalize(useImage ? Objects.requireNonNull(imageLoader).getNoiseVal(x, z, channel) : noise.getNoise(x, z), grids.length);
} }
/**
* Get raw grid noise at location
* @param x X coordinate
* @param z Z coordinate
* @return Raw noise at coordinates
*/
public double getRawNoise(int x, int z) { public double getRawNoise(int x, int z) {
return useImage ? Objects.requireNonNull(imageLoader).getNoiseVal(x, z, channel) : noise.getNoise(x, z); return useImage ? Objects.requireNonNull(imageLoader).getNoiseVal(x, z, channel) : noise.getNoise(x, z);
} }

View File

@ -0,0 +1,30 @@
package com.dfsek.terra.biome;
import org.polydev.gaea.math.FastNoise;
/**
* Class to hold noise function to determine erosion.
*/
public class ErosionNoise {
private final double thresh;
private final FastNoise noise;
public ErosionNoise(float freq1, double thresh, long seed) {
FastNoise main = new FastNoise((int) (seed+1));
main.setNoiseType(FastNoise.NoiseType.SimplexFractal);
main.setFractalOctaves(2);
main.setFrequency(freq1);
this.thresh = thresh;
this.noise = main;
}
/**
* Get whether a location is eroded
* @param x X coordinate
* @param z Z coordinate
* @return Whether location is eroded
*/
boolean isEroded(int x, int z) {
double abs = Math.pow(noise.getNoise(x, z), 2);
return abs < thresh;
}
}

View File

@ -9,20 +9,29 @@ import org.polydev.gaea.biome.Biome;
import org.polydev.gaea.biome.BiomeGrid; import org.polydev.gaea.biome.BiomeGrid;
import org.polydev.gaea.generation.GenerationPhase; import org.polydev.gaea.generation.GenerationPhase;
import java.util.HashMap;
import java.util.Map;
public class TerraBiomeGrid extends BiomeGrid { public class TerraBiomeGrid extends BiomeGrid {
private static int failNum = 0; private static int failNum = 0;
private CoordinatePerturb perturb; private CoordinatePerturb perturb;
private ErosionNoise erode;
private UserDefinedGrid erosionGrid;
private final BiomeZone zone; private final BiomeZone zone;
private final boolean perturbPaletteOnly; private final boolean perturbPaletteOnly;
public TerraBiomeGrid(World w, float freq1, float freq2, BiomeZone zone, ConfigPack c) { public TerraBiomeGrid(World w, float freq1, float freq2, BiomeZone zone, ConfigPack c, UserDefinedGrid erosion) {
super(w, freq1, freq2); super(w, freq1, freq2);
if(c.biomeBlend) { if(c.biomeBlend) {
perturb = new CoordinatePerturb(c.blendFreq, c.blendAmp, w.getSeed()); perturb = new CoordinatePerturb(c.blendFreq, c.blendAmp, w.getSeed());
} }
perturbPaletteOnly = c.perturbPaletteOnly; perturbPaletteOnly = c.perturbPaletteOnly;
this.zone = zone; this.zone = zone;
if(c.erosionEnable) {
erode = new ErosionNoise(c.erosionFreq, c.erosionThresh, w.getSeed());
this.erosionGrid = erosion;
}
} }
@Override @Override
@ -35,14 +44,19 @@ public class TerraBiomeGrid extends BiomeGrid {
zp = perturbCoords[1]; zp = perturbCoords[1];
} }
UserDefinedBiome b;
try { try {
return zone.getGrid(xp, zp).getBiome(xp, zp, phase); b = (UserDefinedBiome) zone.getGrid(xp, zp).getBiome(xp, zp, phase);
} catch(NullPointerException e) { } catch(NullPointerException e) {
if(ConfigUtil.debug) e.printStackTrace(); if(ConfigUtil.debug) e.printStackTrace();
if(failNum % 256 == 0) Bukkit.getLogger().severe("[Terra] A severe configuration error has prevented Terra from properly generating terrain at coordinates: " + x + ", " + z + ". Please check your configuration for errors. Any config errors will have been reported above."); if(failNum % 256 == 0) Bukkit.getLogger().severe("[Terra] A severe configuration error has prevented Terra from properly generating terrain at coordinates: " + x + ", " + z + ". Please check your configuration for errors. Any config errors will have been reported above.");
failNum++; failNum++;
return null; return null;
} }
if(erode != null && b.isErodible() && erode.isEroded(xp, zp)) {
return erosionGrid.getBiome(xp, zp, phase);
}
return b;
} }
@Override @Override

View File

@ -14,13 +14,15 @@ public class UserDefinedBiome implements Biome {
private final UserDefinedDecorator decorator; private final UserDefinedDecorator decorator;
private final org.bukkit.block.Biome vanilla; private final org.bukkit.block.Biome vanilla;
private final String id; private final String id;
private final boolean erode;
public UserDefinedBiome(org.bukkit.block.Biome vanilla, UserDefinedDecorator dec, UserDefinedGenerator gen, String id) { public UserDefinedBiome(org.bukkit.block.Biome vanilla, UserDefinedDecorator dec, UserDefinedGenerator gen, boolean erode, String id) {
this.vanilla = vanilla; this.vanilla = vanilla;
this.decorator = dec; this.decorator = dec;
this.gen = gen; this.gen = gen;
this.id = id; this.id = id;
this.erode = erode;
} }
/** /**
@ -66,4 +68,8 @@ public class UserDefinedBiome implements Biome {
public String getID() { public String getID() {
return id; return id;
} }
public boolean isErodible() {
return erode;
}
} }

View File

@ -1,6 +1,8 @@
package com.dfsek.terra.config.base; package com.dfsek.terra.config.base;
import com.dfsek.terra.Debug;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.UserDefinedGrid;
import com.dfsek.terra.carving.UserDefinedCarver; import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.ConfigLoader; import com.dfsek.terra.config.ConfigLoader;
import com.dfsek.terra.config.exception.ConfigException; import com.dfsek.terra.config.exception.ConfigException;
@ -50,6 +52,11 @@ public class ConfigPack extends YamlConfiguration {
public float freq1; public float freq1;
public float freq2; public float freq2;
public float erosionFreq;
public double erosionThresh;
public boolean erosionEnable;
public String erosionName;
public int blendAmp; public int blendAmp;
public boolean biomeBlend; public boolean biomeBlend;
public float blendFreq; public float blendFreq;
@ -89,6 +96,12 @@ public class ConfigPack extends YamlConfiguration {
blendFreq = (float) getDouble("blend.frequency", 0.01); blendFreq = (float) getDouble("blend.frequency", 0.01);
perturbPaletteOnly = getBoolean("blend.ignore-terrain", true); perturbPaletteOnly = getBoolean("blend.ignore-terrain", true);
erosionEnable = getBoolean("erode.enable", false);
erosionFreq = (float) getDouble("erode.frequency", 0.01);
erosionThresh = getDouble("erode.threshold", 0.04);
erosionName = getString("erode.grid");
// Load BiomeGrids from BiomeZone // Load BiomeGrids from BiomeZone
biomeList = getStringList("grids"); biomeList = getStringList("grids");

View File

@ -36,8 +36,8 @@ public class OreConfig extends TerraConfig {
if(!contains("replace")) throw new ConfigException("Ore replaceable materials not found!", getID()); if(!contains("replace")) throw new ConfigException("Ore replaceable materials not found!", getID());
min = getInt("radius.min", 1); min = getInt("radius.min", 1);
max = getInt("radius.max", 1); max = getInt("radius.max", 1);
deform = getDouble("deform"); deform = getDouble("deform", 0.75);
deformFrequency = getDouble("deform-frequency"); deformFrequency = getDouble("deform-frequency", 0.1);
update = getBoolean("update", false); update = getBoolean("update", false);
replaceable = ConfigUtil.toBlockData(getStringList("replace"), "replaceable", getID()); replaceable = ConfigUtil.toBlockData(getStringList("replace"), "replaceable", getID());

View File

@ -17,6 +17,7 @@ public class AbstractBiomeConfig extends TerraConfig {
private final int treeDensity; private final int treeDensity;
private final String equation; private final String equation;
private final int floraAttempts; private final int floraAttempts;
private final int snowChance;
private double slabThreshold; private double slabThreshold;
private BiomeSlabConfig slabs; private BiomeSlabConfig slabs;
private boolean useStairs; private boolean useStairs;
@ -51,6 +52,7 @@ public class AbstractBiomeConfig extends TerraConfig {
floraFreq = (float) getDouble("flora-simplex.frequency", 0.1); floraFreq = (float) getDouble("flora-simplex.frequency", 0.1);
floraSeed = getInt("flora-simplex.seed", 0); floraSeed = getInt("flora-simplex.seed", 0);
seaLevel = getInt("ocean.level", 62); seaLevel = getInt("ocean.level", 62);
snowChance = getInt("snow-chance", 0);
oceanPalette = getString("ocean.palette"); oceanPalette = getString("ocean.palette");
useStairs = getBoolean("slabs.use-stairs-if-available", false); useStairs = getBoolean("slabs.use-stairs-if-available", false);
@ -145,4 +147,8 @@ public class AbstractBiomeConfig extends TerraConfig {
public List<String> getStructureConfigs() { public List<String> getStructureConfigs() {
return structureConfigs; return structureConfigs;
} }
public int getSnowChance() {
return snowChance;
}
} }

View File

@ -49,6 +49,7 @@ public class BiomeConfig extends TerraConfig {
private FastNoise floraNoise; private FastNoise floraNoise;
private final Palette<BlockData> ocean; private final Palette<BlockData> ocean;
private int seaLevel; private int seaLevel;
private int snowChance;
private final List<StructureConfig> structures; private final List<StructureConfig> structures;
private final ConfigPack config; private final ConfigPack config;
@ -87,6 +88,7 @@ public class BiomeConfig extends TerraConfig {
floraSimplex = getBoolean("flora-simplex.enable", Objects.requireNonNull(abstractBiome).isFloraSimplex()); floraSimplex = getBoolean("flora-simplex.enable", Objects.requireNonNull(abstractBiome).isFloraSimplex());
floraFreq = (float) getDouble("flora-simplex.frequency", Objects.requireNonNull(abstractBiome).getFloraFreq()); floraFreq = (float) getDouble("flora-simplex.frequency", Objects.requireNonNull(abstractBiome).getFloraFreq());
seaLevel = getInt("ocean.level", Objects.requireNonNull(abstractBiome).getSeaLevel()); seaLevel = getInt("ocean.level", Objects.requireNonNull(abstractBiome).getSeaLevel());
snowChance = getInt("snow-chance", Objects.requireNonNull(abstractBiome).getSnowChance());
eq = getString("noise-equation", Objects.requireNonNull(abstractBiome).getEquation()); eq = getString("noise-equation", Objects.requireNonNull(abstractBiome).getEquation());
} catch(NullPointerException e) { } catch(NullPointerException e) {
slabThreshold = getDouble("slabs.threshold", 0.1D); slabThreshold = getDouble("slabs.threshold", 0.1D);
@ -98,6 +100,7 @@ public class BiomeConfig extends TerraConfig {
floraSimplex = getBoolean("flora-simplex.enable", false); floraSimplex = getBoolean("flora-simplex.enable", false);
floraFreq = (float) getDouble("flora-simplex.frequency", 0.1); floraFreq = (float) getDouble("flora-simplex.frequency", 0.1);
seaLevel = getInt("ocean.level", 62); seaLevel = getInt("ocean.level", 62);
snowChance = getInt("snow-chance", 0);
eq = getString("noise-equation", null); eq = getString("noise-equation", null);
} }
@ -203,7 +206,7 @@ public class BiomeConfig extends TerraConfig {
try { try {
// Get UserDefinedBiome instance representing this config. // Get UserDefinedBiome instance representing this config.
this.biome = new UserDefinedBiome(vanillaBiome, dec, new UserDefinedGenerator(eq, Collections.emptyList(), palette.getPaletteMap()), biomeID); this.biome = new UserDefinedBiome(vanillaBiome, dec, new UserDefinedGenerator(eq, Collections.emptyList(), palette.getPaletteMap()), getBoolean("erodible", false), biomeID);
} catch(ParseException e) { } catch(ParseException e) {
e.printStackTrace(); e.printStackTrace();
throw new ConfigException("Unable to parse noise equation!", getID()); throw new ConfigException("Unable to parse noise equation!", getID());
@ -278,4 +281,8 @@ public class BiomeConfig extends TerraConfig {
public Range getTreeRange(Tree t) { public Range getTreeRange(Tree t) {
return tree.getTreeHeights().getOrDefault(t, new Range(-1, -1)); return tree.getTreeHeights().getOrDefault(t, new Range(-1, -1));
} }
public int getSnowChance() {
return snowChance;
}
} }

View File

@ -7,8 +7,9 @@ import org.polydev.gaea.world.palette.RandomPalette;
import java.util.Random; import java.util.Random;
public class Util { public class DataUtil {
public static final BlockData STONE = Material.STONE.createBlockData(); public static final BlockData STONE = Material.STONE.createBlockData();
public static final BlockData SNOW = Material.SNOW.createBlockData();
public static final BlockData WATER = Material.WATER.createBlockData(); public static final BlockData WATER = Material.WATER.createBlockData();
public static final BlockData AIR = Material.AIR.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); public static final Palette<BlockData> BLANK_PALETTE = new RandomPalette<BlockData>(new Random(2403)).add(AIR, 1);

View File

@ -9,6 +9,7 @@ import com.dfsek.terra.config.genconfig.biome.BiomeConfig;
import com.dfsek.terra.population.CavePopulator; import com.dfsek.terra.population.CavePopulator;
import com.dfsek.terra.population.FloraPopulator; import com.dfsek.terra.population.FloraPopulator;
import com.dfsek.terra.population.OrePopulator; import com.dfsek.terra.population.OrePopulator;
import com.dfsek.terra.population.SnowPopulator;
import com.dfsek.terra.population.StructurePopulator; import com.dfsek.terra.population.StructurePopulator;
import com.dfsek.terra.population.TreePopulator; import com.dfsek.terra.population.TreePopulator;
import com.dfsek.terra.structure.StructureSpawnRequirement; import com.dfsek.terra.structure.StructureSpawnRequirement;
@ -52,6 +53,7 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
popMan.attach(new TreePopulator()); popMan.attach(new TreePopulator());
popMan.attach(new FloraPopulator()); popMan.attach(new FloraPopulator());
popMan.attach(new OrePopulator()); popMan.attach(new OrePopulator());
popMan.attach(new SnowPopulator());
} }
@Override @Override
@ -102,16 +104,16 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
BlockData stair = stairPalette.get(0, block.getBlockX(), block.getBlockZ()); BlockData stair = stairPalette.get(0, block.getBlockX(), block.getBlockZ());
Stairs finalStair = getStair(new double[] {_01, _10, _12, _21}, (Stairs) stair, thresh); Stairs finalStair = getStair(new double[] {_01, _10, _12, _21}, (Stairs) stair, thresh);
if(finalStair != null) { if(finalStair != null) {
if(orig.matches(Util.WATER)) finalStair.setWaterlogged(true); if(orig.matches(DataUtil.WATER)) finalStair.setWaterlogged(true);
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), finalStair); chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), finalStair);
return; return;
} }
} }
} }
BlockData slab = slabs.getOrDefault(down.getMaterial(), Util.BLANK_PALETTE).get(0, block.getBlockX(), block.getBlockZ()); BlockData slab = slabs.getOrDefault(down.getMaterial(), DataUtil.BLANK_PALETTE).get(0, block.getBlockX(), block.getBlockZ());
if(slab instanceof Waterlogged) { if(slab instanceof Waterlogged) {
((Waterlogged) slab).setWaterlogged(orig.matches(Util.WATER)); ((Waterlogged) slab).setWaterlogged(orig.matches(DataUtil.WATER));
} else if(orig.matches(Util.WATER)) return; } else if(orig.matches(DataUtil.WATER)) return;
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), slab); chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), slab);
} }
} }

View File

@ -36,7 +36,7 @@ public class UserDefinedGenerator extends Generator {
p.registerFunction("noise2", n2); p.registerFunction("noise2", n2);
p.registerFunction("noise3", n3); p.registerFunction("noise3", n3);
for(int y = 0; y < 256; y++) { for(int y = 0; y < 256; y++) {
Palette<BlockData> d = Util.BLANK_PALETTE; Palette<BlockData> d = DataUtil.BLANK_PALETTE;
for(Map.Entry<Integer, Palette<BlockData>> e : pa.entrySet()) { for(Map.Entry<Integer, Palette<BlockData>> e : pa.entrySet()) {
if(e.getKey() >= y) { if(e.getKey() >= y) {
d = e.getValue(); d = e.getValue();

View File

@ -1,15 +1,64 @@
package com.dfsek.terra.population; package com.dfsek.terra.population;
import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.TerraBiomeGrid;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.base.ConfigUtil;
import com.dfsek.terra.generation.DataUtil;
import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.population.GaeaBlockPopulator; import org.polydev.gaea.population.GaeaBlockPopulator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Random; import java.util.Random;
import java.util.Set;
public class SnowPopulator extends GaeaBlockPopulator { public class SnowPopulator extends GaeaBlockPopulator {
private static final Set<Material> blacklistSpawn = new HashSet<>();
private static final BlockData snow = Material.SNOW.createBlockData();
static {
for(Material m : Material.values()) {
String name = m.toString().toLowerCase();
if(name.contains("slab")
|| name.contains("stair")
|| name.contains("wall")
|| name.contains("fence")
|| name.contains("lantern")
|| name.contains("chest")
|| name.contains("door")
|| name.contains("repeater")
|| name.equals("lily_pad")
|| name.equals("snow")) blacklistSpawn.add(m);
}
blacklistSpawn.add(Material.END_STONE);
if(ConfigUtil.debug)
Bukkit.getLogger().info("Added " + blacklistSpawn.size() + " materials to snow blacklist");
}
@Override @Override
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) { public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
int origX = chunk.getX() << 4;
int origZ = chunk.getZ() << 4;
TerraWorld w = TerraWorld.getWorld(world);
TerraBiomeGrid g = w.getGrid();
for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) {
if(random.nextInt(100) >= w.getConfig().getBiome((UserDefinedBiome) g.getBiome(origX+x, origZ+z, GenerationPhase.PALETTE_APPLY)).getSnowChance()) continue;
int y;
Block b = null;
for(y = 254; y > 0; y--) {
b = chunk.getBlock(x, y, z);
if(!b.getType().isAir()) break;
}
if(blacklistSpawn.contains(b.getType()) || b.isPassable()) continue;
chunk.getBlock(x, ++y, z).setBlockData(DataUtil.SNOW);
}
}
} }
} }