"Perfection"

This commit is contained in:
Daniel Mills 2020-01-21 17:49:20 -05:00
parent 0e12c6906f
commit 0483bc0afe
12 changed files with 284 additions and 307 deletions

View File

@ -1,5 +1,8 @@
package ninja.bytecode.iris; package ninja.bytecode.iris;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
@ -10,13 +13,20 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import mortar.api.nms.NMP; import mortar.api.nms.NMP;
import mortar.api.sched.J;
import mortar.util.text.C; import mortar.util.text.C;
import ninja.bytecode.iris.controller.TimingsController; import ninja.bytecode.iris.controller.PackController;
import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.WorldReactor;
import ninja.bytecode.iris.generator.genobject.PlacedObject; import ninja.bytecode.iris.generator.genobject.PlacedObject;
import ninja.bytecode.iris.pack.CompiledDimension;
import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.util.BiomeLayer; import ninja.bytecode.iris.util.BiomeLayer;
import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.collections.GMap;
import ninja.bytecode.shuriken.execution.ChronoLatch;
import ninja.bytecode.shuriken.format.F; import ninja.bytecode.shuriken.format.F;
import ninja.bytecode.shuriken.logging.L;
public class CommandIris implements CommandExecutor public class CommandIris implements CommandExecutor
{ {
@ -34,6 +44,7 @@ public class CommandIris implements CommandExecutor
msg(sender, "/iris rtp [biome] - RTP to a biome"); msg(sender, "/iris rtp [biome] - RTP to a biome");
msg(sender, "/iris otp [schematic] - RTP to a specific schematic"); msg(sender, "/iris otp [schematic] - RTP to a specific schematic");
msg(sender, "/iris info - Chunk info"); msg(sender, "/iris info - Chunk info");
msg(sender, "/iris hotload - Recompile pack & inject into worlds");
msg(sender, "/iris reload - Reload & Recompile"); msg(sender, "/iris reload - Reload & Recompile");
msg(sender, "/iris clean - Clean Pack Install in Iris Folder"); msg(sender, "/iris clean - Clean Pack Install in Iris Folder");
msg(sender, "/ish - Iris Schematic Commands"); msg(sender, "/ish - Iris Schematic Commands");
@ -216,6 +227,130 @@ public class CommandIris implements CommandExecutor
} }
} }
if(args[0].equalsIgnoreCase("hotload"))
{
msg(sender, "=== Hotloading Pack ===");
PackController c = Iris.getController(PackController.class);
GMap<String, String> f = new GMap<>();
for(World i : Bukkit.getWorlds())
{
if(i.getGenerator() instanceof IrisGenerator)
{
String n = ((IrisGenerator) i.getGenerator()).getDimension().getName();
msg(sender, "Preparing " + n);
f.put(i.getName(), n);
}
}
if(f.isEmpty())
{
msg(sender, "No Worlds to inject!");
return true;
}
J.a(() ->
{
try
{
Consumer<String> m = (msg) ->
{
J.s(() ->
{
String mm = msg;
if(msg.contains("|"))
{
GList<String> fx = new GList<>();
fx.add(msg.split("\\Q|\\E"));
fx.remove(0);
fx.remove(0);
mm = fx.toString("");
}
msg(sender, mm.replaceAll("\\Q \\E", ""));
});
};
L.addLogConsumer(m);
c.compile();
L.logConsumers.remove(m);
for(String fi : f.k())
{
J.s(() ->
{
World i = Bukkit.getWorld(fi);
CompiledDimension dim = c.getDimension(f.get(fi));
for(String k : c.getDimensions().k())
{
if(c.getDimension(k).getName().equals(f.get(fi)))
{
dim = c.getDimension(k);
break;
}
}
if(dim == null)
{
J.s(() -> msg(sender, "Cannot find dimnension: " + f.get(fi)));
return;
}
msg(sender, "Injecting " + i.getName());
IrisGenerator g = ((IrisGenerator) i.getGenerator());
g.inject(dim);
});
}
J.s(() ->
{
if(sender instanceof Player)
{
ChronoLatch cl = new ChronoLatch(3000);
Player p = (Player) sender;
World ww = ((Player) sender).getWorld();
msg(p, "Regenerating View Distance");
WorldReactor r = new WorldReactor(ww);
r.generateRegionNormal(p, true, 45, (pct) ->
{
if(cl.flip())
{
msg(p, "Regenerating " + F.pc(pct));
}
}, () ->
{
msg(p, "Done!");
for(Chunk i : p.getWorld().getLoadedChunks())
{
if(i.getWorld().isChunkInUse(i.getX(), i.getZ()))
{
NMP.CHUNK.refresh(p, i);
}
}
});
}
}, 5);
}
catch(Throwable e)
{
e.printStackTrace();
Consumer<String> m = (msg) ->
{
J.s(() -> msg(sender, msg.replaceAll("\\Q \\E", "")));
};
L.addLogConsumer(m);
L.ex(e);
L.logConsumers.remove(m);
}
});
}
if(args[0].equalsIgnoreCase("reload")) if(args[0].equalsIgnoreCase("reload"))
{ {
msg(sender, "Reloading Iris..."); msg(sender, "Reloading Iris...");

View File

@ -1,12 +1,9 @@
package ninja.bytecode.iris; package ninja.bytecode.iris;
import java.lang.reflect.Executable;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import com.amazonaws.http.ExecutionContext;
import mortar.compute.math.M; import mortar.compute.math.M;
import mortar.util.text.C; import mortar.util.text.C;
import ninja.bytecode.iris.controller.ExecutionController; import ninja.bytecode.iris.controller.ExecutionController;

View File

@ -12,14 +12,14 @@ public class Settings
public static class PerformanceSettings public static class PerformanceSettings
{ {
public PerformanceMode performanceMode = PerformanceMode.HALF_CPU; public PerformanceMode performanceMode = PerformanceMode.HALF_CPU;
public ObjectMode objectMode = ObjectMode.FAST_LIGHTING; public ObjectMode objectMode = ObjectMode.NONE;
public boolean fastMode = false; public boolean fastMode = false;
public int threadPriority = Thread.MAX_PRIORITY; public int threadPriority = Thread.MAX_PRIORITY;
public int threadCount = 4; public int threadCount = 4;
public boolean debugMode = true; public boolean debugMode = true;
public int decorationAccuracy = 2; public int decorationAccuracy = 2;
public boolean noObjectFail = false; public boolean noObjectFail = false;
public boolean verbose = true; public boolean verbose = false;
public int placeHistoryLimit = 8192; public int placeHistoryLimit = 8192;
} }
@ -43,10 +43,10 @@ public class Settings
public double caveDensity = 5; public double caveDensity = 5;
public double caveScale = 1.2; public double caveScale = 1.2;
public double biomeScale = 0.65; public double biomeScale = 0.65;
public boolean flatBedrock = true; public boolean flatBedrock = false;
public boolean genCarving = true; public boolean genCarving = false;
public boolean genCaverns = true; public boolean genCaverns = false;
public boolean genCaves = true; public boolean genCaves = false;
public double carvingChance = 0.352; public double carvingChance = 0.352;
public double cavernChance = 0.321; public double cavernChance = 0.321;
public int minCarvingHeight = 75; public int minCarvingHeight = 75;

View File

@ -5,6 +5,8 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.bukkit.command.CommandSender;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.genobject.GenObject; import ninja.bytecode.iris.generator.genobject.GenObject;
@ -158,6 +160,26 @@ public class PackController implements IrisController
ready = true; ready = true;
} }
public GMap<String, CompiledDimension> getCompiledDimensions()
{
return compiledDimensions;
}
public GMap<String, IrisDimension> getDimensions()
{
return dimensions;
}
public GMap<String, IrisBiome> getBiomes()
{
return biomes;
}
public GMap<String, GenObjectGroup> getGenObjectGroups()
{
return genObjectGroups;
}
public CompiledDimension getDimension(String name) public CompiledDimension getDimension(String name)
{ {
return compiledDimensions.get(name); return compiledDimensions.get(name);

View File

@ -64,7 +64,6 @@ public class IrisGenerator extends ParallaxWorldGenerator
//@done //@done
private boolean disposed; private boolean disposed;
private double[][][] scatterCache;
private CNG scatter; private CNG scatter;
private MB ICE = new MB(Material.ICE); private MB ICE = new MB(Material.ICE);
private MB PACKED_ICE = new MB(Material.PACKED_ICE); private MB PACKED_ICE = new MB(Material.PACKED_ICE);
@ -110,7 +109,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
public double scatter(int x, int y, int z) public double scatter(int x, int y, int z)
{ {
return scatterCache[Math.abs(x) % 16][Math.abs(y) % 16][Math.abs(z) % 16]; return scatter.noise(x, y, z);
} }
public boolean scatterChance(int x, int y, int z, double chance) public boolean scatterChance(int x, int y, int z, double chance)
@ -125,8 +124,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
{ {
return; return;
} }
random = new Random(world.getSeed());
//@builder
rTerrain = new RNG(world.getSeed()); rTerrain = new RNG(world.getSeed());
glLNoise = new GenLayerLayeredNoise(this, world, random, rTerrain.nextParallelRNG(2)); glLNoise = new GenLayerLayeredNoise(this, world, random, rTerrain.nextParallelRNG(2));
glBiome = new GenLayerBiome(this, world, random, rTerrain.nextParallelRNG(4), dim.getBiomes()); glBiome = new GenLayerBiome(this, world, random, rTerrain.nextParallelRNG(4), dim.getBiomes());
@ -135,28 +133,12 @@ public class IrisGenerator extends ParallaxWorldGenerator
glCaverns = new GenLayerCaverns(this, world, random, rTerrain.nextParallelRNG(-3)); glCaverns = new GenLayerCaverns(this, world, random, rTerrain.nextParallelRNG(-3));
glSnow = new GenLayerSnow(this, world, random, rTerrain.nextParallelRNG(5)); glSnow = new GenLayerSnow(this, world, random, rTerrain.nextParallelRNG(5));
glCliffs = new GenLayerCliffs(this, world, random, rTerrain.nextParallelRNG(9)); glCliffs = new GenLayerCliffs(this, world, random, rTerrain.nextParallelRNG(9));
scatterCache = new double[16][][];
scatter = new CNG(rTerrain.nextParallelRNG(52), 1, 1).scale(10); scatter = new CNG(rTerrain.nextParallelRNG(52), 1, 1).scale(10);
if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX)) if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX))
{ {
god = new GenObjectDecorator(this); god = new GenObjectDecorator(this);
} }
//@done
for(int i = 0; i < 16; i++)
{
scatterCache[i] = new double[16][];
for(int j = 0; j < 16; j++)
{
scatterCache[i][j] = new double[16];
for(int k = 0; k < 16; k++)
{
scatterCache[i][j][k] = scatter.noise(i, j, k);
}
}
}
} }
@Override @Override
@ -185,6 +167,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome)
{ {
random = new Random(world.getSeed());
PrecisionStopwatch s = getMetrics().start(); PrecisionStopwatch s = getMetrics().start();
ChunkData d = super.generateChunkData(world, random, x, z, biome); ChunkData d = super.generateChunkData(world, random, x, z, biome);
getMetrics().stop("chunk:ms", s); getMetrics().stop("chunk:ms", s);
@ -312,7 +295,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
{ {
GList<BlockPopulator> p = new GList<>(); GList<BlockPopulator> p = new GList<>();
if(Iris.settings.performance.objectMode.equals(ObjectMode.FAST_LIGHTING) || Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING)) if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY) || Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING))
{ {
p.add(god = new GenObjectDecorator(this)); p.add(god = new GenObjectDecorator(this));
} }
@ -406,7 +389,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
else else
{ {
MB mbx = biome.getScatterChanceSingle(); MB mbx = biome.getScatterChanceSingle(scatter(wxx, i, wzx));
if(!mbx.material.equals(Material.AIR)) if(!mbx.material.equals(Material.AIR))
{ {
@ -549,4 +532,10 @@ public class IrisGenerator extends ParallaxWorldGenerator
{ {
dispose(); dispose();
} }
public void inject(CompiledDimension dimension)
{
this.dim = dimension;
onInit(getWorld(), rTerrain);
}
} }

View File

@ -1,6 +1,5 @@
package ninja.bytecode.iris.generator; package ninja.bytecode.iris.generator;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.bukkit.Chunk; import org.bukkit.Chunk;
@ -11,204 +10,45 @@ import mortar.api.nms.NMP;
import mortar.api.sched.J; import mortar.api.sched.J;
import mortar.compute.math.M; import mortar.compute.math.M;
import mortar.lang.collection.FinalDouble; import mortar.lang.collection.FinalDouble;
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
import ninja.bytecode.iris.util.ChronoQueue; import ninja.bytecode.iris.util.ChronoQueue;
import ninja.bytecode.iris.util.ChunkPlan;
import ninja.bytecode.iris.util.SMCAVector;
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.collections.GMap;
import ninja.bytecode.shuriken.execution.ChronoLatch;
import ninja.bytecode.shuriken.execution.NastyRunnable;
import ninja.bytecode.shuriken.execution.TaskExecutor;
import ninja.bytecode.shuriken.math.RNG;
public class WorldReactor public class WorldReactor
{ {
private final World world; private final World world;
private IrisGenerator gen;
public WorldReactor(World world) public WorldReactor(World world)
{ {
this.world = world; this.world = world;
if(!(world.getGenerator() instanceof IrisGenerator))
{
throw new IllegalArgumentException(world.getName() + " is not an iris world.");
}
this.gen = ((IrisGenerator) world.getGenerator());
} }
public void generateMultipleRegions(GMap<SMCAVector, TaskExecutor> g, boolean force, double mst, Consumer<Double> progress, Runnable done) public void generateRegionNormal(Player p, boolean force, double mst, Consumer<Double> progress, Runnable done)
{ {
ChronoLatch cl = new ChronoLatch(50); ChronoQueue q = new ChronoQueue(mst, 10240);
GMap<SMCAVector, Double> p = new GMap<>(); FinalDouble of = new FinalDouble(0D);
ReentrantLock r = new ReentrantLock(); FinalDouble max = new FinalDouble(0D);
for(SMCAVector i : g.k())
for(int xx = p.getLocation().getChunk().getX() - 32; xx < p.getLocation().getChunk().getX() + 32; xx++)
{ {
generateRegion(i.getX(), i.getZ(), g.get(i), force, mst / (double) g.size(), (xp) -> int x = xx;
for(int zz = p.getLocation().getChunk().getZ() - 32; zz < p.getLocation().getChunk().getZ() + 32; zz++)
{ {
r.lock(); int z = zz;
p.put(i, xp);
double m = 0;
for(double j : p.v()) if(world.isChunkLoaded(x, z) || world.loadChunk(x, z, false))
{ {
m += j;
}
r.unlock();
double h = m / (double) p.size();
if(h == 1D || cl.flip())
{
progress.accept(h);
}
}, () ->
{
p.remove(i);
if(p.isEmpty())
{
done.run();
}
});
}
}
public void generateRegion(int mx, int mz, TaskExecutor executor, boolean force, double mst, Consumer<Double> progress, Runnable done)
{
J.a(() ->
{
FinalDouble of = new FinalDouble(0D);
FinalDouble max = new FinalDouble(0D);
PrecisionStopwatch t = PrecisionStopwatch.start();
GMap<SMCAVector, AtomicChunkData> data = new GMap<>();
GMap<SMCAVector, ChunkPlan> plan = new GMap<>();
GList<NastyRunnable> parallax = new GList<>();
GList<NastyRunnable> noise = new GList<>();
GList<Runnable> chunk = new GList<>();
ReentrantLock lock = new ReentrantLock();
for(int xx = mx << 5; xx < (mx << 5) + 32; xx++)
{
int x = xx;
for(int zz = mz << 5; zz < (mz << 5) + 32; zz++)
{
int z = zz;
SMCAVector w = new SMCAVector(x, z);
if(!force && world.loadChunk(x, z, false))
{
// continue;
}
max.add(1); max.add(1);
parallax.add(() -> q.queue(() ->
{ {
gen.doGenParallax(x, z); world.regenerateChunk(x, z);
of.add(1);
progress.accept(of.get() / max.get());
});
max.add(0.1);
noise.add(() ->
{
AtomicChunkData tydata = new AtomicChunkData(world);
ChunkPlan typlan = new ChunkPlan();
for(int i = 0; i < 16; i++)
{
for(int j = 0; j < 16; j++)
{
gen.onGenColumn((x << 4) + i, (z << 4) + j, i, j, typlan, tydata, true);
}
}
gen.getWorldData().getChunk(x, z).inject(tydata);
gen.onPostChunk(world, x, z, new RNG(world.getSeed()), tydata, typlan);
lock.lock();
data.put(w, tydata);
plan.put(w, typlan);
lock.unlock();
of.add(1);
progress.accept(of.get() / max.get());
});
max.add(4);
chunk.add(() ->
{
if(world.loadChunk(x, z, false))
{
world.regenerateChunk(x, z);
}
else
{
world.loadChunk(x, z, true);
}
Chunk cc = world.getChunkAt(x, z); Chunk cc = world.getChunkAt(x, z);
NMP.host.relight(cc); NMP.host.relight(cc);
cc.unload(true); of.add(1);
});
}
}
executor.startWork().queue(parallax).execute(); if(of.get() == max.get())
executor.startWork().queue(noise).execute();
gen.setSplicer((world, random, x, z, biome) ->
{
SMCAVector w = new SMCAVector(x, z);
for(int i = 0; i < 16; i++)
{
for(int j = 0; j < 16; j++)
{
try
{
biome.setBiome((x << 4) + i, (z << 4) + j, plan.get(w).getBiome(i, j).getRealBiome());
}
catch(Throwable e)
{
}
}
}
AtomicChunkData f = data.get(w);
if(f != null)
{
}
return f;
});
t.end();
J.s(() ->
{
PrecisionStopwatch s = PrecisionStopwatch.start();
ChronoQueue q = new ChronoQueue(mst, 1096);
int m = 0;
for(Runnable i : chunk)
{
int gg = m;
q.queue(() ->
{
i.run();
of.add(4);
if(gg == chunk.size() - 1)
{ {
progress.accept(1D); progress.accept(1D);
s.end();
q.dieSlowly(); q.dieSlowly();
done.run(); done.run();
} }
@ -217,61 +57,16 @@ public class WorldReactor
{ {
progress.accept(M.clip(of.get() / max.get(), 0D, 1D)); progress.accept(M.clip(of.get() / max.get(), 0D, 1D));
} }
}); });
m++;
} }
});
});
}
public void generateRegionNormal(Player p, boolean force, double mst, Consumer<Double> progress, Runnable done)
{
ChronoQueue q = new ChronoQueue(mst, 1024);
FinalDouble of = new FinalDouble(0D);
FinalDouble max = new FinalDouble(0D);
for(int xx = p.getLocation().getChunk().getX() - 32; xx < p.getLocation().getChunk().getX() + 32; xx++)
{
int x = xx;
for(int zz = p.getLocation().getChunk().getX() - 32; zz < p.getLocation().getChunk().getX() + 32; zz++)
{
int z = zz;
max.add(1);
q.queue(() ->
{
if(world.loadChunk(x, z, false))
{
world.regenerateChunk(x, z);
}
else
{
world.loadChunk(x, z, true);
}
Chunk cc = world.getChunkAt(x, z);
NMP.host.relight(cc);
of.add(1);
if(of.get() == max.get())
{
progress.accept(1D);
q.dieSlowly();
done.run();
}
else
{
progress.accept(M.clip(of.get() / max.get(), 0D, 1D));
}
});
} }
} }
q.dieSlowly(); J.s(() ->
{
q.dieSlowly();
}, 20);
} }
} }

View File

@ -9,6 +9,7 @@ import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.BlockPopulator;
import mortar.api.sched.S;
import mortar.logic.format.F; import mortar.logic.format.F;
import mortar.util.text.C; import mortar.util.text.C;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
@ -27,6 +28,7 @@ import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.collections.GMap;
import ninja.bytecode.shuriken.collections.GSet; import ninja.bytecode.shuriken.collections.GSet;
import ninja.bytecode.shuriken.execution.ChronoLatch; import ninja.bytecode.shuriken.execution.ChronoLatch;
import ninja.bytecode.shuriken.execution.J;
import ninja.bytecode.shuriken.logging.L; import ninja.bytecode.shuriken.logging.L;
import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG; import ninja.bytecode.shuriken.math.RNG;
@ -102,44 +104,57 @@ public class GenObjectDecorator extends BlockPopulator
@Override @Override
public void populate(World world, Random random, Chunk source) public void populate(World world, Random random, Chunk source)
{ {
try Runnable m = () ->
{ {
if(g.isDisposed()) try
{ {
placeHistory.clear(); if(g.isDisposed())
return;
}
GSet<IrisBiome> hits = new GSet<>();
int cx = source.getX();
int cz = source.getZ();
for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++)
{
int x = (cx << 4) + random.nextInt(16);
int z = (cz << 4) + random.nextInt(16);
IrisBiome biome = g.getBiome((int) g.getOffsetX(x), (int) g.getOffsetZ(z));
if(hits.contains(biome))
{ {
continue; placeHistory.clear();
return;
} }
GMap<GenObjectGroup, Double> objects = populationCache.get(biome); GSet<IrisBiome> hits = new GSet<>();
int cx = source.getX();
int cz = source.getZ();
if(objects == null) for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++)
{ {
continue; int x = (cx << 4) + random.nextInt(16);
} int z = (cz << 4) + random.nextInt(16);
IrisBiome biome = g.getBiome((int) g.getOffsetX(x), (int) g.getOffsetZ(z));
hits.add(biome); if(hits.contains(biome))
populate(world, cx, cz, random, biome); {
continue;
}
GMap<GenObjectGroup, Double> objects = populationCache.get(biome);
if(objects == null)
{
continue;
}
hits.add(biome);
populate(world, cx, cz, random, biome);
}
} }
catch(Throwable e)
{
e.printStackTrace();
}
};
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
{
J.a(m);
} }
catch(Throwable e) else
{ {
e.printStackTrace(); m.run();
} }
} }
@ -195,7 +210,7 @@ public class GenObjectDecorator extends BlockPopulator
} }
} }
if(Iris.settings.performance.objectMode.equals(ObjectMode.FAST_LIGHTING)) if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
{ {
placer = new NMSPlacer(world); placer = new NMSPlacer(world);
} }
@ -210,28 +225,48 @@ public class GenObjectDecorator extends BlockPopulator
placer = new BukkitPlacer(world, false); placer = new BukkitPlacer(world, false);
} }
Location start = go.place(x, by, z, placer); Runnable rx = () ->
if(start != null)
{ {
g.hitObject(); Location start = go.place(x, by, z, placer);
if(Iris.settings.performance.verbose)
{
L.v(C.GRAY + "Placed " + C.DARK_GREEN + i.getName() + C.WHITE + "/" + C.DARK_GREEN + go.getName() + C.GRAY + " at " + C.DARK_GREEN + F.f(start.getBlockX()) + " " + F.f(start.getBlockY()) + " " + F.f(start.getBlockZ()));
}
if(Iris.settings.performance.debugMode) if(start != null)
{ {
placeHistory.add(new PlacedObject(start.getBlockX(), start.getBlockY(), start.getBlockZ(), i.getName() + ":" + go.getName())); g.hitObject();
if(Iris.settings.performance.verbose)
if(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
{ {
while(placeHistory.size() > Iris.settings.performance.placeHistoryLimit) L.v(C.GRAY + "Placed " + C.DARK_GREEN + i.getName() + C.WHITE + "/" + C.DARK_GREEN + go.getName() + C.GRAY + " at " + C.DARK_GREEN + F.f(start.getBlockX()) + " " + F.f(start.getBlockY()) + " " + F.f(start.getBlockZ()));
}
if(Iris.settings.performance.debugMode)
{
placeHistory.add(new PlacedObject(start.getBlockX(), start.getBlockY(), start.getBlockZ(), i.getName() + ":" + go.getName()));
if(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
{ {
placeHistory.remove(0); while(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
{
placeHistory.remove(0);
}
} }
} }
} }
};
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
{
new S(20)
{
@Override
public void run()
{
rx.run();
}
};
}
else
{
rx.run();
} }
} }
} }

View File

@ -73,6 +73,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome)
{ {
random = new Random(world.getSeed());
if(splicer != null) if(splicer != null)
{ {
AtomicChunkData d = splicer.onSpliceAvailable(world, random, x, z, biome); AtomicChunkData d = splicer.onSpliceAvailable(world, random, x, z, biome);

View File

@ -589,11 +589,11 @@ public class IrisBiome
return scatterChance; return scatterChance;
} }
public MB getScatterChanceSingle() public MB getScatterChanceSingle(double d)
{ {
for(MB i : getScatterChance().keySet()) for(MB i : getScatterChance().keySet())
{ {
if(M.r(getScatterChance().get(i))) if(d < getScatterChance().get(i))
{ {
return i; return i;
} }

View File

@ -20,7 +20,7 @@ import ninja.bytecode.shuriken.math.RNG;
public class BiomeLayer public class BiomeLayer
{ {
private static final IrisBiome VOID = new IrisBiome("Master", Biome.VOID).height(-1).dirt(MB.of(Material.END_BRICKS)).seal(RNG.r); public static final IrisBiome VOID = new IrisBiome("Master", Biome.VOID).height(-1).dirt(MB.of(Material.END_BRICKS)).seal(RNG.r);
private GList<BiomeLayer> children; private GList<BiomeLayer> children;
private EnumPolygonGenerator<BiomeLayer> gen; private EnumPolygonGenerator<BiomeLayer> gen;
private IrisBiome biome; private IrisBiome biome;
@ -46,18 +46,21 @@ public class BiomeLayer
return; return;
} }
GList<BiomeLayer> b = new GList<>();
GMap<BiomeLayer, Double> rarities = new GMap<>(); GMap<BiomeLayer, Double> rarities = new GMap<>();
for(BiomeLayer i : getChildren()) for(BiomeLayer i : getChildren())
{ {
b.add(i);
rarities.put(i, i.getBiome().getRarity()); rarities.put(i, i.getBiome().getRarity());
} }
if(!getBiome().equals(VOID)) if(!getBiome().equals(VOID))
{ {
b.add(this);
rarities.put(this, getBiome().getRarity()); rarities.put(this, getBiome().getRarity());
} }
gen = new EnumPolygonGenerator<>(iris.getRTerrain().nextParallelRNG(1022 + getBiome().getRealBiome().ordinal() + getBiome().hashCode()), scale, octaves, rarities, factory).useRarity(); gen = new EnumPolygonGenerator<>(iris.getRTerrain().nextParallelRNG(1022 + getBiome().getRealBiome().ordinal()), scale, octaves, b, rarities, factory).useRarity();
for(BiomeLayer i : getChildren()) for(BiomeLayer i : getChildren())
{ {

View File

@ -12,7 +12,7 @@ public enum ObjectMode
* *
* Lighting is applied later with packets * Lighting is applied later with packets
*/ */
FAST_LIGHTING, QUICK_N_DIRTY,
/** /**
* Somewhat slow but produces near-perfect results. Updates lighting. * Somewhat slow but produces near-perfect results. Updates lighting.

View File

@ -1,5 +1,6 @@
package ninja.bytecode.iris.util; package ninja.bytecode.iris.util;
import java.util.Collections;
import java.util.function.Function; import java.util.function.Function;
import mortar.lang.collection.GList; import mortar.lang.collection.GList;
@ -155,10 +156,9 @@ public class PolygonGenerator
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public EnumPolygonGenerator(RNG rng, double scale, int octaves, GMap<T, Double> choiceRarities, Function<CNG, CNG> factory) public EnumPolygonGenerator(RNG rng, double scale, int octaves, GList<T> c, GMap<T, Double> choiceRarities, Function<CNG, CNG> factory)
{ {
super(rng, choiceRarities.size(), scale / (double) choiceRarities.size(), octaves, factory); super(rng, choiceRarities.size(), scale / (double) choiceRarities.size(), octaves, factory);
GList<T> c = choiceRarities.k();
this.choices = (T[]) c.toArray(); this.choices = (T[]) c.toArray();
int m = 0; int m = 0;
@ -182,7 +182,7 @@ public class PolygonGenerator
public T getChoice(double... dim) public T getChoice(double... dim)
{ {
return choices[super.getIndex(dim)]; return choices[getIndex(dim)];
} }
} }
} }