This commit is contained in:
Daniel Mills 2020-01-24 17:54:46 -05:00
parent 31bf39d2e5
commit eb359f79cb
12 changed files with 450 additions and 31 deletions

View File

@ -5,6 +5,7 @@ import java.util.UUID;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Difficulty; import org.bukkit.Difficulty;
import org.bukkit.GameMode;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
@ -93,6 +94,7 @@ public class Iris extends MortarPlugin
r.setPhysicsThrottle(5); r.setPhysicsThrottle(5);
r.setMonsterActivationRange(5); r.setMonsterActivationRange(5);
r.setArrowDespawnRate(1); r.setArrowDespawnRate(1);
r.setForcedGameMode(GameMode.CREATIVE);
r.load(); r.load();
for(Player i : Bukkit.getOnlinePlayers()) for(Player i : Bukkit.getOnlinePlayers())

View File

@ -25,6 +25,7 @@ public class Settings
public static class GeneratorSettings public static class GeneratorSettings
{ {
public InterpolationMode interpolationMode = InterpolationMode.BILINEAR; public InterpolationMode interpolationMode = InterpolationMode.BILINEAR;
public int blockSmoothing = 1;
public int interpolationRadius = 6; public int interpolationRadius = 6;
public double objectDensity = 1D; public double objectDensity = 1D;
public double horizontalZoom = 2; public double horizontalZoom = 2;

View File

@ -28,6 +28,11 @@ public class CommandFindBiome extends MortarCommand
else else
{ {
if(sender.isPlayer())
{
sender.sendMessage(sender.player().getWorld().getGenerator().getClass().getCanonicalName());
}
sender.sendMessage("Console / Non-Iris World."); sender.sendMessage("Console / Non-Iris World.");
return true; return true;
} }

View File

@ -130,11 +130,28 @@ public class PackController extends Controller
{ {
d.registerObject(genObjectGroups.get(k)); d.registerObject(genObjectGroups.get(k));
if(j.isLush())
{
try
{
GenObjectGroup ggx = genObjectGroups.get(k).copy("-lush-" + j.getLush());
ggx.applyLushFilter(j.getLush());
d.registerObject(ggx);
j.getSchematicGroups().put(ggx.getName(), j.getSchematicGroups().get(k));
j.getSchematicGroups().remove(k);
}
catch(Throwable e)
{
e.printStackTrace();
}
}
if(j.isSnowy()) if(j.isSnowy())
{ {
try try
{ {
GenObjectGroup ggx = genObjectGroups.get(k).copy("-snowy-" + j.getSnow()); GenObjectGroup ggx = genObjectGroups.get(k).copy("-snow-" + j.getSnow());
ggx.applySnowFilter((int) (j.getSnow() * 4)); ggx.applySnowFilter((int) (j.getSnow() * 4));
d.registerObject(ggx); d.registerObject(ggx);
j.getSchematicGroups().put(ggx.getName(), j.getSchematicGroups().get(k)); j.getSchematicGroups().put(ggx.getName(), j.getSchematicGroups().get(k));

View File

@ -5,9 +5,11 @@ import java.util.Random;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.TreeSpecies;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.BlockPopulator;
import org.bukkit.material.Leaves;
import org.bukkit.util.NumberConversions; import org.bukkit.util.NumberConversions;
import mortar.util.text.C; import mortar.util.text.C;
@ -358,32 +360,6 @@ public class IrisGenerator extends ParallaxWorldGenerator
if(i == height - 1) if(i == height - 1)
{ {
mb = biome.getSurface(wx, wz, rTerrain); mb = biome.getSurface(wx, wz, rTerrain);
if(biome.getSnow() > 0)
{
double level = glSnow.getHeight(wx, wz) * biome.getSnow();
int blocks = (int) level;
level -= blocks;
int layers = (int) (level * 7D);
int snowHeight = blocks + (layers > 0 ? 1 : 0);
for(int j = 0; j < snowHeight; j++)
{
highest = j == snowHeight - 1 ? highest < j ? j : highest : highest < j + 1 ? j + 1 : highest;
data.setBlock(x, i + j + 1, z, j == snowHeight - 1 ? Material.SNOW : Material.SNOW_BLOCK, j == snowHeight - 1 ? (byte) layers : (byte) 0);
}
}
else
{
MB mbx = biome.getScatterChanceSingle(scatter(wxx, i, wzx));
if(!mbx.material.equals(Material.AIR))
{
highest = i > highest ? i : highest;
data.setBlock(x, i + 1, z, mbx.material, mbx.data);
}
}
} }
highest = i > highest ? i : highest; highest = i > highest ? i : highest;
@ -414,7 +390,181 @@ public class IrisGenerator extends ParallaxWorldGenerator
} }
@Override @Override
public void onPostChunk(World world, int x, int z, Random random, AtomicChunkData data, ChunkPlan plan) protected void onDecorateChunk(World world, int cx, int cz, AtomicChunkData data, ChunkPlan plan)
{
int x = 0;
int z = 0;
int h = 0;
int v = 0;
int border = 0;
int above = 0;
int below = 0;
for(int f = 0; f < Iris.settings.gen.blockSmoothing; f++)
{
for(x = 0; x < 16; x++)
{
for(z = 0; z < 16; z++)
{
h = plan.getRealHeight(x, z);
border = 0;
if(x == 0 || x == 15)
{
border++;
}
if(z == 0 || z == 15)
{
border++;
}
if(h > Iris.settings.gen.seaLevel)
{
above = 0;
below = 0;
if(x + 1 <= 15)
{
v = plan.getRealHeight(x + 1, z);
if(v > h)
{
above++;
}
else if(v < h)
{
below++;
}
}
if(x - 1 >= 0)
{
v = plan.getRealHeight(x - 1, z);
if(v > h)
{
above++;
}
else if(v < h)
{
below++;
}
}
if(z + 1 <= 15)
{
v = plan.getRealHeight(x, z + 1);
if(v > h)
{
above++;
}
else if(v < h)
{
below++;
}
}
if(z - 1 >= 0)
{
v = plan.getRealHeight(x, z - 1);
if(v > h)
{
above++;
}
else if(v < h)
{
below++;
}
}
// Patch Hole
if(above >= 4 - border)
{
data.setBlock(x, h + 1, z, data.getMB(x, h, z));
plan.setRealHeight(x, z, h + 1);
}
// Remove Nipple
else if(below >= 4 - border)
{
data.setBlock(x, h - 1, z, data.getMB(x, h, z));
data.setBlock(x, h, z, Material.AIR);
plan.setRealHeight(x, z, h - 1);
}
}
}
}
}
}
@SuppressWarnings("deprecation")
@Override
protected void onDecorateColumn(World world, int x, int z, int wx, int wz, AtomicChunkData data, ChunkPlan plan)
{
int h = plan.getRealHeight(x, z);
if(h < 63)
{
return;
}
IrisBiome biome = plan.getBiome(x, z);
if(biome == null)
{
return;
}
if(biome.getSnow() > 0)
{
double level = glSnow.getHeight(wx, wz) * biome.getSnow();
int blocks = (int) level;
level -= blocks;
int layers = (int) (level * 7D);
int snowHeight = blocks + (layers > 0 ? 1 : 0);
for(int j = 0; j < snowHeight; j++)
{
data.setBlock(x, h + j + 1, z, j == snowHeight - 1 ? Material.SNOW : Material.SNOW_BLOCK, j == snowHeight - 1 ? (byte) layers : (byte) 0);
}
}
if(biome.getLush() > 0.33)
{
double cnd = (1D - biome.getLush() > 1 ? 1 : biome.getLush()) / 3.5D;
double g = glSnow.getHeight(wz, wx);
if(g > cnd)
{
double gx = glSnow.getHeight(wx * 2.25, wz * 2.25);
Leaves l = new Leaves(TreeSpecies.values()[(int) (gx * (TreeSpecies.values().length - 1))]);
l.setDecaying(false);
l.setDecayable(false);
data.setBlock(x, h - 1, z, data.getMB(x, h, z));
data.setBlock(x, h, z, l.getItemType(), l.getData());
}
}
else
{
MB mbx = biome.getScatterChanceSingle(scatter(wx, h, wz));
if(!mbx.material.equals(Material.AIR))
{
data.setBlock(x, h + 1, z, mbx.material, mbx.data);
}
}
}
@Override
public void onPostChunk(World world, int cx, int cz, Random random, AtomicChunkData data, ChunkPlan plan)
{ {
} }

View File

@ -448,4 +448,9 @@ public final class AtomicChunkData implements ChunkGenerator.ChunkData
} }
} }
} }
public void setBlock(int x, int y, int z, MB mb)
{
setBlock(x, y, z, mb.material, mb.data);
}
} }

View File

@ -654,6 +654,182 @@ public class GenObject
} }
} }
@SuppressWarnings("deprecation")
public void applyLushFilter(double factor)
{
int minX = 0;
int maxX = 0;
int minY = 0;
int maxY = 0;
int minZ = 0;
int maxZ = 0;
boolean added = false;
for(SBlockVector i : getSchematic().keySet())
{
if(i.getX() > maxX)
{
maxX = (int) i.getX();
}
if(i.getY() > maxY)
{
maxY = (int) i.getY();
}
if(i.getZ() > maxZ)
{
maxZ = (int) i.getZ();
}
if(i.getX() < minX)
{
minX = (int) i.getX();
}
if(i.getY() < minY)
{
minY = (int) i.getY();
}
if(i.getZ() < minZ)
{
minZ = (int) i.getZ();
}
}
for(int i = minX; i <= maxX; i++)
{
for(int j = minY; j <= maxY; j++)
{
for(int k = minZ; k <= maxZ; k++)
{
SBlockVector at = new SBlockVector(i, j, k);
if(M.r(factor / 20D) && getSchematic().containsKey(at) && !getSchematic().get(at).material.equals(Material.VINE))
{
SBlockVector a = new SBlockVector(i + 1, j, k);
SBlockVector b = new SBlockVector(i - 1, j, k);
SBlockVector c = new SBlockVector(i, j, k + 1);
SBlockVector d = new SBlockVector(i, j, k - 1);
Vine v = null;
KMap<SBlockVector, MB> e = new KMap<>();
if(!getSchematic().containsKey(a))
{
v = new Vine(BlockFace.WEST);
SBlockVector ma = new SBlockVector(a.getX(), a.getY(), a.getZ() + 1);
SBlockVector mb = new SBlockVector(a.getX(), a.getY(), a.getZ() - 1);
if(getSchematic().containsKey(ma) && !getSchematic().get(ma).material.equals(Material.VINE))
{
v = new Vine(BlockFace.SOUTH, BlockFace.WEST);
}
else if(getSchematic().containsKey(mb) && !getSchematic().get(mb).material.equals(Material.VINE))
{
v = new Vine(BlockFace.NORTH, BlockFace.WEST);
}
e.put(a, MB.of(Material.VINE, v.getData()));
}
if(!getSchematic().containsKey(b))
{
v = new Vine(BlockFace.EAST);
SBlockVector ma = new SBlockVector(b.getX(), b.getY(), b.getZ() + 1);
SBlockVector mb = new SBlockVector(b.getX(), b.getY(), b.getZ() - 1);
if(getSchematic().containsKey(ma) && !getSchematic().get(ma).material.equals(Material.VINE))
{
v = new Vine(BlockFace.SOUTH, BlockFace.EAST);
}
else if(getSchematic().containsKey(mb) && !getSchematic().get(mb).material.equals(Material.VINE))
{
v = new Vine(BlockFace.NORTH, BlockFace.EAST);
}
e.put(b, MB.of(Material.VINE, v.getData()));
}
if(!getSchematic().containsKey(c))
{
v = new Vine(BlockFace.NORTH);
SBlockVector ma = new SBlockVector(c.getX() + 1, c.getY(), c.getZ());
SBlockVector mb = new SBlockVector(c.getX() - 1, c.getY(), c.getZ());
if(getSchematic().containsKey(ma) && !getSchematic().get(ma).material.equals(Material.VINE))
{
v = new Vine(BlockFace.NORTH, BlockFace.EAST);
}
else if(getSchematic().containsKey(mb) && !getSchematic().get(mb).material.equals(Material.VINE))
{
v = new Vine(BlockFace.NORTH, BlockFace.WEST);
}
e.put(c, MB.of(Material.VINE, v.getData()));
}
if(!getSchematic().containsKey(d))
{
v = new Vine(BlockFace.SOUTH);
SBlockVector ma = new SBlockVector(d.getX() + 1, d.getY(), d.getZ());
SBlockVector mb = new SBlockVector(d.getX() - 1, d.getY(), d.getZ());
if(getSchematic().containsKey(ma) && !getSchematic().get(ma).material.equals(Material.VINE))
{
v = new Vine(BlockFace.SOUTH, BlockFace.EAST);
}
else if(getSchematic().containsKey(mb) && !getSchematic().get(mb).material.equals(Material.VINE))
{
v = new Vine(BlockFace.SOUTH, BlockFace.WEST);
}
e.put(d, MB.of(Material.VINE, v.getData()));
}
if(!e.isEmpty())
{
added = true;
}
for(SBlockVector n : e.k())
{
for(int g = 0; g < (factor * 1.25) * RNG.r.nextDouble(); g++)
{
if(n.getY() - (g + 1) < minY)
{
break;
}
SBlockVector p = new SBlockVector(n.getX(), n.getY() - g, n.getZ());
if(e.containsKey(p) || getSchematic().containsKey(p))
{
break;
}
e.put(p, e.get(n));
}
}
getSchematic().putAll(e);
}
}
}
}
if(added)
{
w++;
d++;
recalculateMountShift();
}
}
public double getSuccess() public double getSuccess()
{ {
return (double) successes / ((double) successes + (double) failures); return (double) successes / ((double) successes + (double) failures);

View File

@ -84,6 +84,22 @@ public class GenObjectGroup
} }
} }
public void applyLushFilter(double factor)
{
if(flags.contains("no lush"))
{
L.i(ChatColor.DARK_GREEN + "Skipping Lush Filter for " + ChatColor.GRAY + getName());
return;
}
L.i(ChatColor.GREEN + "Applying Lush Filter to " + ChatColor.WHITE + getName());
for(GenObject i : schematics)
{
i.applyLushFilter(factor);
}
}
public void applySnowFilter(int factor) public void applySnowFilter(int factor)
{ {
if(flags.contains("no snow")) if(flags.contains("no snow"))

View File

@ -148,8 +148,8 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl
@Override @Override
public final void postChunk(World world, int x, int z, Random random, AtomicChunkData data, ChunkPlan plan) public final void postChunk(World world, int x, int z, Random random, AtomicChunkData data, ChunkPlan plan)
{ {
getWorldData().inject(x, z, data);
onPostChunk(world, x, z, random, data, plan); onPostChunk(world, x, z, random, data, plan);
getWorldData().inject(x, z, data);
} }
@Override @Override

View File

@ -135,6 +135,25 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
plan.set(initChunk(world, x, z, random)); plan.set(initChunk(world, x, z, random));
TaskResult r = tg.execute(); TaskResult r = tg.execute();
onDecorateChunk(world, x, z, data, plan.get());
TaskGroup gd = startWork();
for(i = 0; i < 16; i++)
{
wx = (x << 4) + i;
for(j = 0; j < 16; j++)
{
wz = (z << 4) + j;
int a = wx;
int b = wz;
int c = i;
int d = j;
gd.queue(() -> onDecorateColumn(world, c, d, a, b, data, plan.get()));
}
}
gd.execute();
postChunk(world, x, z, random, data, plan.get()); postChunk(world, x, z, random, data, plan.get());
rs.put(r.timeElapsed); rs.put(r.timeElapsed);
cg++; cg++;
@ -163,6 +182,10 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
return data.toChunkData(); return data.toChunkData();
} }
protected abstract void onDecorateColumn(World world2, int i2, int j2, int wx2, int wz2, AtomicChunkData data, ChunkPlan chunkPlan);
protected abstract void onDecorateChunk(World world2, int x, int z, AtomicChunkData data, ChunkPlan chunkPlan);
public abstract void init(World world, Random random); public abstract void init(World world, Random random);
public abstract ChunkPlan initChunk(World world, int x, int z, Random random); public abstract ChunkPlan initChunk(World world, int x, int z, Random random);

View File

@ -50,6 +50,7 @@ public class IrisBiome
private boolean simplexScatterRock; private boolean simplexScatterRock;
private boolean simplexScatterSub; private boolean simplexScatterSub;
private double snow; private double snow;
private double lush;
private double cliffChance; private double cliffChance;
private double cliffScale; private double cliffScale;
private double genScale; private double genScale;
@ -117,6 +118,7 @@ public class IrisBiome
this.region = "default"; this.region = "default";
this.core = false; this.core = false;
this.name = name; this.name = name;
lush = 0;
type = BiomeType.LAND; type = BiomeType.LAND;
cliffs = false; cliffs = false;
fluid = MB.of(Material.STATIONARY_WATER); fluid = MB.of(Material.STATIONARY_WATER);
@ -245,6 +247,7 @@ public class IrisBiome
J.attempt(() -> genSwirlScale = o.getDouble("genSwirlScale")); J.attempt(() -> genSwirlScale = o.getDouble("genSwirlScale"));
J.attempt(() -> genScale = o.getDouble("genScale")); J.attempt(() -> genScale = o.getDouble("genScale"));
J.attempt(() -> snow = o.getDouble("snow")); J.attempt(() -> snow = o.getDouble("snow"));
J.attempt(() -> lush = o.getDouble("lush"));
J.attempt(() -> rarity = o.getDouble("rarity")); J.attempt(() -> rarity = o.getDouble("rarity"));
J.attempt(() -> fluid = MB.of(o.getString("fluid"))); J.attempt(() -> fluid = MB.of(o.getString("fluid")));
J.attempt(() -> dirtDepth = o.getInt("subSurfaceDepth")); J.attempt(() -> dirtDepth = o.getInt("subSurfaceDepth"));
@ -308,6 +311,7 @@ public class IrisBiome
J.attempt(() -> j.put("genSwirlScale", genSwirlScale)); J.attempt(() -> j.put("genSwirlScale", genSwirlScale));
J.attempt(() -> j.put("genAmplifier", genAmplifier)); J.attempt(() -> j.put("genAmplifier", genAmplifier));
J.attempt(() -> j.put("snow", snow)); J.attempt(() -> j.put("snow", snow));
J.attempt(() -> j.put("lush", lush));
J.attempt(() -> j.put("cliffs", cliffs)); J.attempt(() -> j.put("cliffs", cliffs));
J.attempt(() -> j.put("cliffScale", cliffScale)); J.attempt(() -> j.put("cliffScale", cliffScale));
J.attempt(() -> j.put("rockScale", rockScale)); J.attempt(() -> j.put("rockScale", rockScale));
@ -1057,10 +1061,20 @@ public class IrisBiome
this.rarity = rarity; this.rarity = rarity;
} }
public double getLush()
{
return lush;
}
public String getRegion()
{
return region;
}
@Override @Override
public int hashCode() public int hashCode()
{ {
return Objects.hash(cliffChance, cliffScale, cliffs, core, dirt, dirtDepth, fluid, genAmplifier, genScale, genSwirl, genSwirlScale, height, name, parent, rarity, realBiome, region, rock, rockDepth, rockScale, scatterChance, scatterSurface, scatterSurfaceRock, scatterSurfaceSub, schematicGroups, simplexScatter, simplexScatterRock, simplexScatterSub, snow, subSurfaceScale, surface, surfaceScale, type); return Objects.hash(bng, cliffChance, cliffScale, cliffs, core, dirt, dirtDepth, fluid, genAmplifier, genScale, genSwirl, genSwirlScale, height, lush, name, parent, poly, polyRock, polySub, rarity, realBiome, region, rock, rockDepth, rockScale, scatterChance, scatterSurface, scatterSurfaceRock, scatterSurfaceSub, schematicGroups, simplexScatter, simplexScatterRock, simplexScatterSub, snow, subSurfaceScale, surface, surfaceScale, type);
} }
@Override @Override
@ -1075,6 +1089,11 @@ public class IrisBiome
return false; return false;
} }
IrisBiome other = (IrisBiome) obj; IrisBiome other = (IrisBiome) obj;
return Double.doubleToLongBits(cliffChance) == Double.doubleToLongBits(other.cliffChance) && Double.doubleToLongBits(cliffScale) == Double.doubleToLongBits(other.cliffScale) && cliffs == other.cliffs && core == other.core && Objects.equals(dirt, other.dirt) && dirtDepth == other.dirtDepth && Objects.equals(fluid, other.fluid) && Double.doubleToLongBits(genAmplifier) == Double.doubleToLongBits(other.genAmplifier) && Double.doubleToLongBits(genScale) == Double.doubleToLongBits(other.genScale) && Double.doubleToLongBits(genSwirl) == Double.doubleToLongBits(other.genSwirl) && Double.doubleToLongBits(genSwirlScale) == Double.doubleToLongBits(other.genSwirlScale) && Double.doubleToLongBits(height) == Double.doubleToLongBits(other.height) && Objects.equals(name, other.name) && Objects.equals(parent, other.parent) && Double.doubleToLongBits(rarity) == Double.doubleToLongBits(other.rarity) && realBiome == other.realBiome && Objects.equals(region, other.region) && Objects.equals(rock, other.rock) && rockDepth == other.rockDepth && Double.doubleToLongBits(rockScale) == Double.doubleToLongBits(other.rockScale) && Objects.equals(scatterChance, other.scatterChance) && scatterSurface == other.scatterSurface && scatterSurfaceRock == other.scatterSurfaceRock && scatterSurfaceSub == other.scatterSurfaceSub && Objects.equals(schematicGroups, other.schematicGroups) && simplexScatter == other.simplexScatter && simplexScatterRock == other.simplexScatterRock && simplexScatterSub == other.simplexScatterSub && Double.doubleToLongBits(snow) == Double.doubleToLongBits(other.snow) && Double.doubleToLongBits(subSurfaceScale) == Double.doubleToLongBits(other.subSurfaceScale) && Objects.equals(surface, other.surface) && Double.doubleToLongBits(surfaceScale) == Double.doubleToLongBits(other.surfaceScale) && type == other.type; return Objects.equals(bng, other.bng) && Double.doubleToLongBits(cliffChance) == Double.doubleToLongBits(other.cliffChance) && Double.doubleToLongBits(cliffScale) == Double.doubleToLongBits(other.cliffScale) && cliffs == other.cliffs && core == other.core && Objects.equals(dirt, other.dirt) && dirtDepth == other.dirtDepth && Objects.equals(fluid, other.fluid) && Double.doubleToLongBits(genAmplifier) == Double.doubleToLongBits(other.genAmplifier) && Double.doubleToLongBits(genScale) == Double.doubleToLongBits(other.genScale) && Double.doubleToLongBits(genSwirl) == Double.doubleToLongBits(other.genSwirl) && Double.doubleToLongBits(genSwirlScale) == Double.doubleToLongBits(other.genSwirlScale) && Double.doubleToLongBits(height) == Double.doubleToLongBits(other.height) && Double.doubleToLongBits(lush) == Double.doubleToLongBits(other.lush) && Objects.equals(name, other.name) && Objects.equals(parent, other.parent) && Objects.equals(poly, other.poly) && Objects.equals(polyRock, other.polyRock) && Objects.equals(polySub, other.polySub) && Double.doubleToLongBits(rarity) == Double.doubleToLongBits(other.rarity) && realBiome == other.realBiome && Objects.equals(region, other.region) && Objects.equals(rock, other.rock) && rockDepth == other.rockDepth && Double.doubleToLongBits(rockScale) == Double.doubleToLongBits(other.rockScale) && Objects.equals(scatterChance, other.scatterChance) && scatterSurface == other.scatterSurface && scatterSurfaceRock == other.scatterSurfaceRock && scatterSurfaceSub == other.scatterSurfaceSub && Objects.equals(schematicGroups, other.schematicGroups) && simplexScatter == other.simplexScatter && simplexScatterRock == other.simplexScatterRock && simplexScatterSub == other.simplexScatterSub && Double.doubleToLongBits(snow) == Double.doubleToLongBits(other.snow) && Double.doubleToLongBits(subSurfaceScale) == Double.doubleToLongBits(other.subSurfaceScale) && Objects.equals(surface, other.surface) && Double.doubleToLongBits(surfaceScale) == Double.doubleToLongBits(other.surfaceScale) && type == other.type;
}
public boolean isLush()
{
return lush > 0;
} }
} }

View File

@ -101,4 +101,9 @@ public class ChunkPlan
{ {
setHeight(new SChunkVector(x, z), h); setHeight(new SChunkVector(x, z), h);
} }
public int biomeCacheSize()
{
return biomeCache.size();
}
} }