9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-26 02:29:14 +00:00
This commit is contained in:
Daniel Mills
2020-07-19 04:09:42 -04:00
parent 5b8d812fc8
commit f995f6568c
9 changed files with 352 additions and 81 deletions

View File

@@ -101,7 +101,7 @@ public class Iris extends JavaPlugin implements BoardProvider
lines.add(ChatColor.GREEN + "Noise" + ChatColor.GRAY + ": " + Form.f((int) hits.getAverage()));
lines.add(ChatColor.GREEN + "Parallax Regions" + ChatColor.GRAY + ": " + Form.f((int) g.getParallaxMap().getLoadedRegions().size()));
lines.add(ChatColor.GREEN + "Parallax Chunks" + ChatColor.GRAY + ": " + Form.f((int) g.getParallaxMap().getLoadedChunks().size()));
lines.add(ChatColor.GREEN + "Sliver Buffer" + ChatColor.GRAY + ": " + Form.f((int) g.getSliverBuffer()));
lines.add(ChatColor.GREEN + "BUD Requests" + ChatColor.GRAY + ": " + Form.f((int) g.getUpdateBlocks().size()));
if(er != null && b != null)
{

View File

@@ -8,6 +8,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.layer.GenLayerBiome;
import ninja.bytecode.iris.object.InferredType;
import ninja.bytecode.iris.object.IrisBiome;
import ninja.bytecode.iris.object.IrisBiomeGeneratorLink;
import ninja.bytecode.iris.object.IrisGenerator;
@@ -155,6 +156,36 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
public BiomeResult sampleBiome(int x, int z)
{
if(!getDimension().getFocus().equals(""))
{
IrisBiome biome = Iris.data.getBiomeLoader().load(getDimension().getFocus());
for(String i : getDimension().getRegions())
{
IrisRegion reg = Iris.data.getRegionLoader().load(i);
if(reg.getLandBiomes().contains(biome.getLoadKey()))
{
biome.setInferredType(InferredType.LAND);
break;
}
if(reg.getSeaBiomes().contains(biome.getLoadKey()))
{
biome.setInferredType(InferredType.SEA);
break;
}
if(reg.getShoreBiomes().contains(biome.getLoadKey()))
{
biome.setInferredType(InferredType.SHORE);
break;
}
}
return new BiomeResult(biome, 0);
}
ChunkPosition pos = new ChunkPosition(x, z);
if(biomeHitCache.containsKey(pos))

View File

@@ -1,5 +1,7 @@
package ninja.bytecode.iris.generator;
import java.lang.reflect.Method;
import org.bukkit.Chunk;
import org.bukkit.entity.Player;
@@ -14,6 +16,8 @@ import ninja.bytecode.iris.util.BiomeResult;
@EqualsAndHashCode(callSuper = false)
public class IrisChunkGenerator extends ParallaxChunkGenerator implements IrisContext
{
private Method initLighting;
public IrisChunkGenerator(String dimensionName, int threads)
{
super(dimensionName, threads);
@@ -40,7 +44,7 @@ public class IrisChunkGenerator extends ParallaxChunkGenerator implements IrisCo
@Override
protected void onTick(int ticks)
{
}
@Override
@@ -59,7 +63,7 @@ public class IrisChunkGenerator extends ParallaxChunkGenerator implements IrisCo
@Override
protected void onChunkLoaded(Chunk c)
{
updateLights();
}
@Override

View File

@@ -1,21 +1,31 @@
package ninja.bytecode.iris.generator;
import java.util.concurrent.locks.ReentrantLock;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.Bisected.Half;
import org.bukkit.block.data.BlockData;
import lombok.Data;
import lombok.EqualsAndHashCode;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.object.InferredType;
import ninja.bytecode.iris.object.IrisBiome;
import ninja.bytecode.iris.object.IrisBiomeDecorator;
import ninja.bytecode.iris.object.IrisRegion;
import ninja.bytecode.iris.object.atomics.AtomicSliver;
import ninja.bytecode.iris.util.BiomeMap;
import ninja.bytecode.iris.util.BiomeResult;
import ninja.bytecode.iris.util.BlockPosition;
import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KList;
import ninja.bytecode.shuriken.collections.KSet;
import ninja.bytecode.shuriken.logging.L;
import ninja.bytecode.shuriken.math.M;
@Data
@EqualsAndHashCode(callSuper = false)
@@ -24,6 +34,10 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
protected static final BlockData AIR = Material.AIR.createBlockData();
protected static final BlockData STONE = Material.STONE.createBlockData();
protected static final BlockData WATER = Material.WATER.createBlockData();
private KList<BlockPosition> updateBlocks = new KList<>();
private ReentrantLock relightLock = new ReentrantLock();
private long lastUpdateRequest = M.ms();
private long lastChunkLoad = M.ms();
public TerrainChunkGenerator(String dimensionName, int threads)
{
@@ -35,75 +49,182 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
super.onInit(world, rng);
}
public void queueUpdate(int x, int y, int z)
{
if(M.ms() - lastUpdateRequest > 3000 && M.ms() - lastChunkLoad > 3000)
{
updateBlocks.clear();
}
updateBlocks.add(new BlockPosition(x, y, z));
lastUpdateRequest = M.ms();
}
public void updateLights()
{
if(M.ms() - lastUpdateRequest > 3000 && M.ms() - lastChunkLoad > 3000)
{
updateBlocks.clear();
}
for(BlockPosition i : updateBlocks.copy())
{
if(getWorld().isChunkLoaded(i.getChunkX(), i.getChunkZ()))
{
updateBlocks.remove(i);
Block b = getWorld().getBlockAt(i.getX(), i.getY(), i.getZ());
BlockData bd = b.getBlockData();
b.setBlockData(AIR, false);
b.setBlockData(bd, true);
}
}
while(updateBlocks.size() > 5000)
{
updateBlocks.remove(0);
}
lastChunkLoad = M.ms();
}
public void checkUnderwater(int x, int y, int z, BlockData d)
{
if(d.getMaterial().equals(Material.SEA_PICKLE) || d.getMaterial().equals(Material.SOUL_SAND) || d.getMaterial().equals(Material.MAGMA_BLOCK))
{
queueUpdate(x, y, z);
}
}
public void checkSurface(int x, int y, int z, BlockData d)
{
if(d.getMaterial().equals(Material.SEA_PICKLE) || d.getMaterial().equals(Material.TORCH) || d.getMaterial().equals(Material.REDSTONE_TORCH) || d.getMaterial().equals(Material.TORCH))
{
queueUpdate(x, y, z);
}
}
@Override
protected void onGenerateColumn(int cx, int cz, int rx, int rz, int x, int z, AtomicSliver sliver, BiomeMap biomeMap)
{
BlockData block;
int fluidHeight = getDimension().getFluidHeight();
double ox = getModifiedX(rx, rz);
double oz = getModifiedZ(rx, rz);
double wx = getZoomed(ox);
double wz = getZoomed(oz);
int depth = 0;
double noise = getNoiseHeight(rx, rz);
int height = (int) Math.round(noise) + fluidHeight;
IrisBiome biome = sampleTrueBiome(rx, rz).getBiome();
KList<BlockData> layers = biome.generateLayers(wx, wz, masterRandom, height);
for(int k = Math.max(height, fluidHeight); k >= 0; k--)
try
{
boolean underwater = k > height && k <= fluidHeight;
BlockData block;
int fluidHeight = getDimension().getFluidHeight();
double ox = getModifiedX(rx, rz);
double oz = getModifiedZ(rx, rz);
double wx = getZoomed(ox);
double wz = getZoomed(oz);
int depth = 0;
double noise = getNoiseHeight(rx, rz);
int height = (int) Math.round(noise) + fluidHeight;
IrisBiome biome = sampleTrueBiome(rx, rz).getBiome();
if(biomeMap != null)
KList<BlockData> layers = biome.generateLayers(wx, wz, masterRandom, height);
for(int k = Math.max(height, fluidHeight); k >= 0; k--)
{
sliver.set(k, biome.getDerivative());
biomeMap.setBiome(x, z, biome);
}
boolean underwater = k > height && k <= fluidHeight;
if(underwater)
{
block = WATER;
}
else
{
block = layers.hasIndex(depth) ? layers.get(depth) : STONE;
depth++;
}
sliver.set(k, block);
if(k == Math.max(height, fluidHeight) && block.getMaterial().isSolid() && k < 255)
{
int j = 0;
for(IrisBiomeDecorator i : biome.getDecorators())
if(biomeMap != null)
{
BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG(biome.hashCode() + j++), wx, wz);
sliver.set(k, biome.getDerivative());
biomeMap.setBiome(x, z, biome);
}
if(d != null)
if(underwater)
{
block = WATER;
}
else
{
block = layers.hasIndex(depth) ? layers.get(depth) : STONE;
depth++;
}
sliver.set(k, block);
if(k == height && block.getMaterial().isSolid() && k < fluidHeight && biome.isSea())
{
int j = 0;
for(IrisBiomeDecorator i : biome.getDecorators())
{
if(d instanceof Bisected && k < 254)
{
Bisected t = ((Bisected) d.clone());
t.setHalf(Half.TOP);
Bisected b = ((Bisected) d.clone());
b.setHalf(Half.BOTTOM);
sliver.set(k + 1, b);
sliver.set(k + 2, t);
}
BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG(biome.hashCode() + j++), wx, wz);
else
if(d != null)
{
sliver.set(k + 1, d);
}
int stack = i.getHeight(getMasterRandom().nextParallelRNG(39456 + i.hashCode()), wx, wz);
break;
if(stack == 1)
{
sliver.set(k + 1, d);
checkUnderwater(rx, k + 1, rz, d);
}
else if(k < fluidHeight - stack)
{
for(int l = 0; l < stack; l++)
{
sliver.set(k + l + 1, d);
checkUnderwater(rx, k + l + 1, rz, d);
}
}
break;
}
}
}
if(k == Math.max(height, fluidHeight) && block.getMaterial().isSolid() && k < 255 && !biome.isSea())
{
int j = 0;
for(IrisBiomeDecorator i : biome.getDecorators())
{
BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG(biome.hashCode() + j++), wx, wz);
if(d != null)
{
if(d instanceof Bisected && k < 254)
{
Bisected t = ((Bisected) d.clone());
t.setHalf(Half.TOP);
Bisected b = ((Bisected) d.clone());
b.setHalf(Half.BOTTOM);
sliver.set(k + 1, b);
sliver.set(k + 2, t);
}
else
{
int stack = i.getHeight(getMasterRandom().nextParallelRNG(39456 + i.hashCode()), wx, wz);
if(stack == 1)
{
sliver.set(k + 1, d);
}
else if(k < 255 - stack)
{
for(int l = 0; l < stack; l++)
{
sliver.set(k + l + 1, d);
}
}
}
break;
}
}
}
}
}
catch(Throwable e)
{
fail(e);
}
}
protected double getNoiseHeight(int rx, int rz)
@@ -116,6 +237,36 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
public BiomeResult sampleTrueBiome(int x, int z)
{
if(!getDimension().getFocus().equals(""))
{
IrisBiome biome = Iris.data.getBiomeLoader().load(getDimension().getFocus());
for(String i : getDimension().getRegions())
{
IrisRegion reg = Iris.data.getRegionLoader().load(i);
if(reg.getLandBiomes().contains(biome.getLoadKey()))
{
biome.setInferredType(InferredType.LAND);
break;
}
if(reg.getSeaBiomes().contains(biome.getLoadKey()))
{
biome.setInferredType(InferredType.SEA);
break;
}
if(reg.getShoreBiomes().contains(biome.getLoadKey()))
{
biome.setInferredType(InferredType.SHORE);
break;
}
}
return new BiomeResult(biome, 0);
}
double wx = getModifiedX(x, z);
double wz = getModifiedZ(x, z);
IrisRegion region = sampleRegion(x, z);

View File

@@ -1,9 +1,9 @@
package ninja.bytecode.iris.object;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import lombok.Data;
import ninja.bytecode.iris.util.BlockDataTools;
import ninja.bytecode.iris.util.CNG;
import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KList;
@@ -14,14 +14,39 @@ public class IrisBiomeDecorator
{
private Dispersion variance = Dispersion.SCATTER;
private Dispersion dispersion = Dispersion.SCATTER;
private Dispersion verticalVariance = Dispersion.SCATTER;
private int iterations = 5;
private int stackMin = 1;
private int stackMax = 1;
private double zoom = 1;
private double verticalZoom = 1;
private double chance = 0.1;
private KList<String> palette = new KList<String>().qadd("GRASS");
private transient KMap<Long, CNG> layerGenerators;
private transient CNG heightGenerator;
private transient KList<BlockData> blockData;
public int getHeight(RNG rng, double x, double z)
{
if(stackMin == stackMax)
{
return stackMin;
}
return getGenerator(rng).fit(stackMin, stackMax, x * (verticalVariance.equals(Dispersion.SCATTER) ? 1000D : 1D), z * (verticalVariance.equals(Dispersion.SCATTER) ? 1000D : 1D));
}
public CNG getHeightGenerator(RNG rng)
{
if(heightGenerator == null)
{
heightGenerator = CNG.signature(rng.nextParallelRNG(iterations + getBlockData().size() + stackMax + stackMin)).scale(1D / verticalZoom);
}
return heightGenerator;
}
public CNG getGenerator(RNG rng)
{
long key = rng.nextParallelRNG(1).nextLong();
@@ -33,9 +58,9 @@ public class IrisBiomeDecorator
if(!layerGenerators.containsKey(key))
{
layerGenerators.put(key, CNG.signature(rng.nextParallelRNG(iterations + getBlockData().size())));
layerGenerators.put(key, CNG.signature(rng.nextParallelRNG(iterations + getBlockData().size())).scale(1D / zoom));
}
return layerGenerators.get(key);
}
@@ -47,9 +72,32 @@ public class IrisBiomeDecorator
public BlockData getBlockData(RNG rng, double x, double z)
{
if(getGenerator(rng) == null)
{
return null;
}
if(getBlockData() == null)
{
return null;
}
if(getBlockData().isEmpty())
{
return null;
}
if(getGenerator(rng).fitDoubleD(0D, 1D, x * (dispersion.equals(Dispersion.SCATTER) ? 1000D : 1D), z * (dispersion.equals(Dispersion.SCATTER) ? 1000D : 1D)) <= chance)
{
return getBlockData().get(getGenerator(rng.nextParallelRNG(53)).fit(0, getBlockData().size() - 1, x * (dispersion.equals(Dispersion.SCATTER) ? 1000D : 1D), z * (dispersion.equals(Dispersion.SCATTER) ? 1000D : 1D)));
try
{
return getBlockData().get(getGenerator(rng.nextParallelRNG(53)).fit(0, getBlockData().size() - 1, x * (dispersion.equals(Dispersion.SCATTER) ? 1000D : 1D), z * (dispersion.equals(Dispersion.SCATTER) ? 1000D : 1D)));
}
catch(Throwable e)
{
}
}
return null;
@@ -62,18 +110,10 @@ public class IrisBiomeDecorator
blockData = new KList<>();
for(String i : palette)
{
try
BlockData bx = BlockDataTools.getBlockData(i);
if(bx != null)
{
Material m = Material.valueOf(i);
if(m != null)
{
blockData.add(m.createBlockData());
}
}
catch(Throwable e)
{
blockData.add(bx);
}
}
}

View File

@@ -20,6 +20,7 @@ public class IrisDimension extends IrisRegistrant
private Environment environment = Environment.NORMAL;
private KList<String> regions = new KList<>();
private int fluidHeight = 63;
private String focus = "";
private double biomeZoom = 5D;
private double terrainZoom = 2D;
private double dimensionAngleDeg = 0;

View File

@@ -20,18 +20,28 @@ public class BlockDataTools
return bdc.get(bd).clone();
}
BlockData bdx = parseBlockData(bd);
if(bdx == null)
try
{
Iris.warn("Unknown Block Data '" + bd + "'");
nulls.add(bd);
BlockData bdx = parseBlockData(bd);
if(bdx == null)
{
Iris.warn("Unknown Block Data '" + bd + "'");
nulls.add(bd);
return bdx;
}
bdc.put(bd, bdx);
return bdx;
}
bdc.put(bd, bdx);
return bdx;
catch(Throwable e)
{
Iris.warn("Unknown Block Data '" + bd + "'");
}
return null;
}
public static BlockData parseBlockData(String ix)

View File

@@ -0,0 +1,28 @@
package ninja.bytecode.iris.util;
import lombok.Data;
@Data
public class BlockPosition
{
private int x;
private int y;
private int z;
public BlockPosition(int x, int y, int z)
{
this.x = x;
this.y = y;
this.z = z;
}
public int getChunkX()
{
return x >> 4;
}
public int getChunkZ()
{
return z >> 4;
}
}