Better placement

This commit is contained in:
Daniel Mills 2020-01-26 16:42:19 -05:00
parent f645589cda
commit 5d410764e1
17 changed files with 513 additions and 191 deletions

View File

@ -147,7 +147,7 @@
<dependency> <dependency>
<groupId>ninja.bytecode</groupId> <groupId>ninja.bytecode</groupId>
<artifactId>Shuriken</artifactId> <artifactId>Shuriken</artifactId>
<version>1.1</version> <version>1.1.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.volmit</groupId> <groupId>com.volmit</groupId>

View File

@ -11,14 +11,14 @@ public class Settings
public static class PerformanceSettings public static class PerformanceSettings
{ {
public PerformanceMode performanceMode = PerformanceMode.HALF_CPU; public PerformanceMode performanceMode = PerformanceMode.EXPLICIT;
public ObjectMode objectMode = ObjectMode.PARALLAX; public ObjectMode objectMode = ObjectMode.PARALLAX;
public int threadPriority = Thread.MAX_PRIORITY; public int threadPriority = Thread.MAX_PRIORITY;
public int threadCount = 4; public int threadCount = 16;
public boolean debugMode = true; public boolean debugMode = true;
public int decorationAccuracy = 2; public int decorationAccuracy = 1;
public boolean noObjectFail = false; public boolean noObjectFail = false;
public boolean verbose = false; public boolean verbose = true;
public int placeHistoryLimit = 8192; public int placeHistoryLimit = 8192;
} }

View File

@ -36,6 +36,14 @@ public class CommandObjectLoad extends MortarCommand
if(args.length < 1) if(args.length < 1)
{ {
sender.sendMessage("/iris object load <name>"); sender.sendMessage("/iris object load <name>");
sender.sendMessage("Use -c to place at cursor");
sender.sendMessage("Use -g to place with gravity");
sender.sendMessage("Use -w to set hydrophilic");
sender.sendMessage("Use -u to set submerged");
sender.sendMessage("Use -h:<int> to shift vertically");
sender.sendMessage("Use -m:<int> to set max slope");
sender.sendMessage("Use -b:<int> to set base slope");
sender.sendMessage("Use -f:N -t:S to rotate north to south (180 deg)");
return true; return true;
} }
@ -43,6 +51,7 @@ public class CommandObjectLoad extends MortarCommand
GenObject s = new GenObject(1, 1, 1); GenObject s = new GenObject(1, 1, 1);
File f = new File(Iris.instance.getDataFolder(), "schematics/" + args[0] + ".ish"); File f = new File(Iris.instance.getDataFolder(), "schematics/" + args[0] + ".ish");
if(!f.exists()) if(!f.exists())
{ {
sender.sendMessage("Can't find " + args[0]); sender.sendMessage("Can't find " + args[0]);
@ -55,25 +64,74 @@ public class CommandObjectLoad extends MortarCommand
s.read(fin, true); s.read(fin, true);
boolean cursor = false; boolean cursor = false;
boolean gravity = false;
Direction df = null; Direction df = null;
Direction dt = null; Direction dt = null;
int shift = 0;
for(String i : args) for(String i : args)
{ {
if(i.equalsIgnoreCase("cursor")) if(i.equalsIgnoreCase("-c"))
{ {
sender.sendMessage("Placing @ Cursor");
cursor = true; cursor = true;
break; continue;
} }
if(i.startsWith("from:")) if(i.equalsIgnoreCase("-u"))
{
sender.sendMessage("Placing Submerged");
s.setSubmerged(true);
continue;
}
if(i.equalsIgnoreCase("-w"))
{
sender.sendMessage("Placing with Hydrophilia");
s.setHydrophilic(true);
continue;
}
if(i.equalsIgnoreCase("-g"))
{
sender.sendMessage("Placing with Gravity");
gravity = true;
continue;
}
if(i.startsWith("-m:"))
{
shift = Integer.valueOf(i.split("\\Q:\\E")[1]);
sender.sendMessage("Max Slope set to " + shift);
s.setMaxslope(shift);
continue;
}
if(i.startsWith("-b:"))
{
shift = Integer.valueOf(i.split("\\Q:\\E")[1]);
sender.sendMessage("Base Slope set to " + shift);
s.setBaseslope(shift);
continue;
}
if(i.startsWith("-h:"))
{
shift = Integer.valueOf(i.split("\\Q:\\E")[1]);
sender.sendMessage("Shifting Placement by 0," + shift + ",0");
continue;
}
if(i.startsWith("-f:"))
{ {
df = Direction.valueOf(i.split("\\Q:\\E")[1].toUpperCase().substring(0, 1)); df = Direction.valueOf(i.split("\\Q:\\E")[1].toUpperCase().substring(0, 1));
continue;
} }
if(i.startsWith("to:")) if(i.startsWith("-t:"))
{ {
dt = Direction.valueOf(i.split("\\Q:\\E")[1].toUpperCase().substring(0, 1)); dt = Direction.valueOf(i.split("\\Q:\\E")[1].toUpperCase().substring(0, 1));
continue;
} }
} }
@ -90,6 +148,8 @@ public class CommandObjectLoad extends MortarCommand
at = p.getTargetBlock(null, 64).getLocation(); at = p.getTargetBlock(null, 64).getLocation();
} }
s.setShift(0, shift, 0);
s.setGravity(gravity);
WandController.pasteSchematic(s, at); WandController.pasteSchematic(s, at);
p.playSound(p.getLocation(), Sound.BLOCK_ENCHANTMENT_TABLE_USE, 1f, 1.25f); p.playSound(p.getLocation(), Sound.BLOCK_ENCHANTMENT_TABLE_USE, 1f, 1.25f);
sender.sendMessage("Pasted " + args[0] + " (" + Form.f(s.getSchematic().size()) + " Blocks Modified)"); sender.sendMessage("Pasted " + args[0] + " (" + Form.f(s.getSchematic().size()) + " Blocks Modified)");

View File

@ -382,7 +382,11 @@ public class IrisGenerator extends ParallaxWorldGenerator
hl = hl == 0 && !t.equals(Material.AIR) ? i : hl; hl = hl == 0 && !t.equals(Material.AIR) ? i : hl;
} }
glCaves.genCaves(wxxf, wzxf, x, z, data, plan); if(!surfaceOnly)
{
glCaves.genCaves(wxxf, wzxf, x, z, data, plan);
}
plan.setRealHeight(x, z, hl); plan.setRealHeight(x, z, hl);
plan.setRealWaterHeight(x, z, hw == 0 ? seaLevel : hw); plan.setRealWaterHeight(x, z, hw == 0 ? seaLevel : hw);
plan.setBiome(x, z, biome); plan.setBiome(x, z, biome);
@ -397,6 +401,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
@Override @Override
protected void onDecorateChunk(World world, int cx, int cz, AtomicChunkData data, ChunkPlan plan) protected void onDecorateChunk(World world, int cx, int cz, AtomicChunkData data, ChunkPlan plan)
{ {
PrecisionStopwatch p = PrecisionStopwatch.start();
int x = 0; int x = 0;
int z = 0; int z = 0;
int hhx = 0; int hhx = 0;
@ -503,50 +508,19 @@ public class IrisGenerator extends ParallaxWorldGenerator
data.setBlock(x, hhx, z, Material.AIR); data.setBlock(x, hhx, z, Material.AIR);
plan.setRealHeight(x, z, hhx - 1); plan.setRealHeight(x, z, hhx - 1);
} }
// Slab Smoothing
else if(below == 0 && above > 0 && f == Iris.settings.gen.blockSmoothing - 1)
{
MB d = data.getMB(x, hhx, z);
if(d.material.equals(Material.STAINED_CLAY) && d.data == 1)
{
data.setBlock(x, hhx + 1, z, Material.STONE_SLAB2);
}
else if(d.material.equals(Material.SAND))
{
if(d.data == 0)
{
data.setBlock(x, hhx + 1, z, Material.STEP, (byte) 1);
}
if(d.data == 1)
{
data.setBlock(x, hhx + 1, z, Material.STONE_SLAB2);
}
}
else if(d.material.equals(Material.SNOW_BLOCK))
{
data.setBlock(x, hhx + 1, z, Material.SNOW, (byte) 4);
}
else if(d.material.equals(Material.STONE) || d.material.equals(Material.COBBLESTONE) || d.material.equals(Material.GRAVEL))
{
data.setBlock(x, hhx + 1, z, Material.STEP, (byte) 3);
}
}
} }
} }
} }
} }
getMetrics().stop("decoration:ms:/chunk:..", p);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
protected void onDecorateColumn(World world, int x, int z, int wx, int wz, AtomicChunkData data, ChunkPlan plan) protected void onDecorateColumn(World world, int x, int z, int wx, int wz, AtomicChunkData data, ChunkPlan plan)
{ {
PrecisionStopwatch p = PrecisionStopwatch.start();
int h = plan.getRealHeight(x, z); int h = plan.getRealHeight(x, z);
if(h < 63) if(h < 63)
@ -613,6 +587,8 @@ public class IrisGenerator extends ParallaxWorldGenerator
} }
} }
} }
getMetrics().stop("pardecoration:ms:x256:/chunk:..", p);
} }
@Override @Override

View File

@ -4,7 +4,6 @@ import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -32,11 +31,11 @@ import ninja.bytecode.iris.util.Direction;
import ninja.bytecode.iris.util.IPlacer; import ninja.bytecode.iris.util.IPlacer;
import ninja.bytecode.iris.util.MB; import ninja.bytecode.iris.util.MB;
import ninja.bytecode.iris.util.SBlockVector; import ninja.bytecode.iris.util.SBlockVector;
import ninja.bytecode.iris.util.SChunkVectorShort;
import ninja.bytecode.iris.util.VectorMath; import ninja.bytecode.iris.util.VectorMath;
import ninja.bytecode.shuriken.collections.KList; import ninja.bytecode.shuriken.collections.KList;
import ninja.bytecode.shuriken.collections.KMap; import ninja.bytecode.shuriken.collections.KMap;
import ninja.bytecode.shuriken.io.CustomOutputStream; import ninja.bytecode.shuriken.io.CustomOutputStream;
import ninja.bytecode.shuriken.io.IO;
import ninja.bytecode.shuriken.logging.L; import ninja.bytecode.shuriken.logging.L;
import ninja.bytecode.shuriken.math.RNG; import ninja.bytecode.shuriken.math.RNG;
@ -48,68 +47,19 @@ public class GenObject
private int d; private int d;
private int failures; private int failures;
private int successes; private int successes;
private boolean gravity;
private String name = "?"; private String name = "?";
private KMap<SBlockVector, MB> s; private KMap<SBlockVector, MB> s;
private KMap<SChunkVectorShort, SBlockVector> slopeCache;
private KMap<SChunkVectorShort, SBlockVector> gravityCache;
private BlockVector mount; private BlockVector mount;
private int maxslope;
private int baseslope;
private boolean hydrophilic;
private boolean submerged;
private int mountHeight; private int mountHeight;
private BlockVector shift; private BlockVector shift;
@SuppressWarnings("deprecation")
public void perfectRead(File folder, String name) throws IOException
{
File file = new File(folder, IO.hash(name) + ".ioc");
FileInputStream fin = new FileInputStream(file);
DataInputStream din = new DataInputStream(fin);
centeredHeight = din.readBoolean();
w = din.readShort();
h = din.readShort();
d = din.readShort();
name = din.readUTF();
int size = din.readInt();
s.clear();
for(int i = 0; i < size; i++)
{
s.put(new SBlockVector(din.readShort(), din.readShort(), din.readShort()), MB.of(Material.getMaterial(din.readInt()), din.readByte()));
}
mount = new BlockVector(din.readShort(), din.readShort(), din.readShort());
mountHeight = din.readShort();
shift = new BlockVector(din.readShort(), din.readShort(), din.readShort());
din.close();
}
@SuppressWarnings("deprecation")
public void perfectWrite(File folder) throws IOException
{
File file = new File(folder, IO.hash(name) + ".ioc");
FileOutputStream fos = new FileOutputStream(file);
DataOutputStream dos = new DataOutputStream(fos);
dos.writeBoolean(centeredHeight);
dos.writeShort(w);
dos.writeShort(h);
dos.writeShort(d);
dos.writeUTF(name);
dos.writeInt(s.size());
for(SBlockVector i : s.keySet())
{
dos.writeShort((short) i.getX());
dos.writeShort((short) i.getY());
dos.writeShort((short) i.getZ());
dos.writeInt(s.get(i).material.getId());
dos.writeByte(s.get(i).data);
}
dos.writeShort(mount.getBlockX());
dos.writeShort(mount.getBlockY());
dos.writeShort(mount.getBlockZ());
dos.writeShort(mountHeight);
dos.writeShort(shift.getBlockX());
dos.writeShort(shift.getBlockY());
dos.writeShort(shift.getBlockZ());
dos.close();
}
public GenObject(int w, int h, int d) public GenObject(int w, int h, int d)
{ {
this.w = w; this.w = w;
@ -118,6 +68,11 @@ public class GenObject
shift = new BlockVector(); shift = new BlockVector();
s = new KMap<>(); s = new KMap<>();
centeredHeight = false; centeredHeight = false;
gravity = false;
maxslope = -1;
baseslope = 0;
hydrophilic = false;
submerged = false;
} }
public void recalculateMountShift() public void recalculateMountShift()
@ -159,6 +114,77 @@ public class GenObject
mount = new BlockVector(0, 0, 0); mount = new BlockVector(0, 0, 0);
} }
private KMap<SChunkVectorShort, SBlockVector> getSlopeCache()
{
if(slopeCache == null)
{
computeSlopeCache();
}
return slopeCache;
}
private KMap<SChunkVectorShort, SBlockVector> getGravityCache()
{
if(gravityCache == null)
{
computeGravityCache();
}
return gravityCache;
}
private void computeGravityCache()
{
gravityCache = new KMap<>();
for(SBlockVector i : s.keySet())
{
SChunkVectorShort v = new SChunkVectorShort(i.getX(), i.getZ());
if(!gravityCache.containsKey(v) || gravityCache.get(v).getY() > i.getY())
{
gravityCache.put(v, i);
}
}
}
private void computeSlopeCache()
{
slopeCache = new KMap<>();
int low = Integer.MAX_VALUE;
for(SBlockVector i : s.keySet())
{
SChunkVectorShort v = new SChunkVectorShort(i.getX(), i.getZ());
if(!slopeCache.containsKey(v) || slopeCache.get(v).getY() > i.getY())
{
slopeCache.put(v, i);
}
}
for(SChunkVectorShort i : slopeCache.keySet())
{
int f = (int) slopeCache.get(i).getY();
if(f < low)
{
low = f;
}
}
for(SChunkVectorShort i : slopeCache.k())
{
int f = (int) slopeCache.get(i).getY();
if(f > low - baseslope)
{
slopeCache.remove(i);
}
}
}
private int avg(double[] v) private int avg(double[] v)
{ {
double g = 0; double g = 0;
@ -322,7 +348,7 @@ public class GenObject
start.subtract(mount); start.subtract(mount);
int highestY = placer.getHighestY(start); int highestY = submerged ? placer.getHighestYUnderwater(start) : placer.getHighestY(start);
if(start.getBlockY() + mountHeight > highestY) if(start.getBlockY() + mountHeight > highestY)
{ {
@ -337,7 +363,44 @@ public class GenObject
MB b = getSchematic().get(i); MB b = getSchematic().get(i);
Location f = start.clone().add(i.toBlockVector()); Location f = start.clone().add(i.toBlockVector());
if(!Iris.settings.performance.noObjectFail) if(gravity)
{
SChunkVectorShort v = new SChunkVectorShort(i.getX(), i.getZ());
int offset = (int) i.getY() - (int) getGravityCache().get(v).getY();
f.setY(f.getBlockY() - ((f.getBlockY() - offset) - (submerged ? placer.getHighestYUnderwater(f) : placer.getHighestY(f))));
}
else if(maxslope >= 0)
{
SChunkVectorShort v = new SChunkVectorShort(i.getX(), i.getZ());
SBlockVector m = getSlopeCache().get(v);
if(m == null)
{
continue;
}
int offset = (int) i.getY() - (int) m.getY();
int shift = ((f.getBlockY() - offset) - (submerged ? placer.getHighestYUnderwater(f) : placer.getHighestY(f)));
if(Math.abs(shift) > maxslope)
{
for(Location j : undo.k())
{
placer.set(j, undo.get(j));
}
if(Iris.settings.performance.verbose)
{
L.w(C.WHITE + "Object " + C.YELLOW + getName() + C.WHITE + " failed to place on slope " + C.YELLOW + Math.abs(shift) + C.WHITE + " at " + C.YELLOW + F.f(f.getBlockX()) + " " + F.f(f.getBlockY()) + " " + F.f(f.getBlockZ()));
}
failures++;
return null;
}
}
if(!hydrophilic && !Iris.settings.performance.noObjectFail)
{ {
if(f.getBlockY() == 63 && i.getY() == mountHeight) if(f.getBlockY() == 63 && i.getY() == mountHeight)
{ {
@ -352,7 +415,7 @@ public class GenObject
if(Iris.settings.performance.verbose) if(Iris.settings.performance.verbose)
{ {
L.w(C.WHITE + "Object " + C.YELLOW + getName() + C.WHITE + " failed to place in " + C.YELLOW + m.toString().toLowerCase() + C.WHITE + " at " + C.YELLOW + F.f(f.getBlockX()) + " " + F.f(f.getBlockY()) + " " + F.f(f.getBlockZ())); L.w(C.WHITE + "Object " + C.YELLOW + getName() + C.WHITE + " (hydrophobic) failed to place in " + C.YELLOW + m.toString().toLowerCase() + C.WHITE + " at " + C.YELLOW + F.f(f.getBlockX()) + " " + F.f(f.getBlockY()) + " " + F.f(f.getBlockZ()));
} }
failures++; failures++;
@ -535,6 +598,32 @@ public class GenObject
{ {
try try
{ {
if(j.equals("gravity"))
{
gravity = true;
}
if(j.equals("hydrophilic"))
{
hydrophilic = true;
}
if(j.equals("submerged"))
{
submerged = true;
hydrophilic = true;
}
if(j.startsWith("maxslope "))
{
maxslope = Integer.valueOf(j.split("\\Q \\E")[1]);
}
if(j.startsWith("baseslope "))
{
baseslope = Integer.valueOf(j.split("\\Q \\E")[1]);
}
if(j.startsWith("replace ")) if(j.startsWith("replace "))
{ {
String[] g = j.split("\\Q \\E"); String[] g = j.split("\\Q \\E");
@ -854,4 +943,144 @@ public class GenObject
{ {
s.clear(); s.clear();
} }
public void setGravity(boolean gravity)
{
this.gravity = gravity;
}
public void setShift(int x, int y, int z)
{
shift = new BlockVector(x, y, z);
}
public boolean isCenteredHeight()
{
return centeredHeight;
}
public boolean isGravity()
{
return gravity;
}
public KMap<SBlockVector, MB> getS()
{
return s;
}
public BlockVector getMount()
{
return mount;
}
public int getMaxslope()
{
return maxslope;
}
public int getBaseslope()
{
return baseslope;
}
public boolean isHydrophilic()
{
return hydrophilic;
}
public boolean isSubmerged()
{
return submerged;
}
public int getMountHeight()
{
return mountHeight;
}
public BlockVector getShift()
{
return shift;
}
public void setCenteredHeight(boolean centeredHeight)
{
this.centeredHeight = centeredHeight;
}
public void setW(int w)
{
this.w = w;
}
public void setH(int h)
{
this.h = h;
}
public void setD(int d)
{
this.d = d;
}
public void setFailures(int failures)
{
this.failures = failures;
}
public void setSuccesses(int successes)
{
this.successes = successes;
}
public void setS(KMap<SBlockVector, MB> s)
{
this.s = s;
}
public void setSlopeCache(KMap<SChunkVectorShort, SBlockVector> slopeCache)
{
this.slopeCache = slopeCache;
}
public void setGravityCache(KMap<SChunkVectorShort, SBlockVector> gravityCache)
{
this.gravityCache = gravityCache;
}
public void setMount(BlockVector mount)
{
this.mount = mount;
}
public void setMaxslope(int maxslope)
{
this.maxslope = maxslope;
}
public void setBaseslope(int baseslope)
{
this.baseslope = baseslope;
}
public void setHydrophilic(boolean hydrophilic)
{
this.hydrophilic = hydrophilic;
}
public void setSubmerged(boolean submerged)
{
this.submerged = submerged;
}
public void setMountHeight(int mountHeight)
{
this.mountHeight = mountHeight;
}
public void setShift(BlockVector shift)
{
this.shift = shift;
}
} }

View File

@ -22,7 +22,7 @@ public class GenObjectGroup
private int priority; private int priority;
private double worldChance; private double worldChance;
private int worldRad; private int worldRad;
public GenObjectGroup(String name) public GenObjectGroup(String name)
{ {
this.schematics = new KList<>(); this.schematics = new KList<>();

View File

@ -1,70 +0,0 @@
package ninja.bytecode.iris.generator.genobject;
import java.io.IOException;
import mortar.compute.math.M;
import mortar.util.text.C;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.shuriken.logging.L;
public class PhantomGenObject
{
private GenObject object;
private String name;
private boolean loaded;
private long lastUse;
private long evictionNotice;
private int size;
public PhantomGenObject(GenObject object) throws IOException
{
this.object = object;
this.name = object.getName();
object.perfectWrite(Iris.instance.getObjectCacheFolder());
lastUse = M.ms();
loaded = true;
size = object.getSchematic().size();
evictionNotice = 5000 + (size * 7);
}
public int getSize()
{
return size;
}
public boolean isLoaded()
{
return loaded;
}
public void attemptEviction()
{
if(loaded && M.ms() - lastUse > evictionNotice)
{
loaded = false;
object.dispose();
}
}
public GenObject get()
{
if(!loaded)
{
try
{
object.perfectRead(Iris.instance.getObjectCacheFolder(), name);
loaded = true;
}
catch(IOException e)
{
L.f(C.RED + "Cannot Read Cached Object: " + name);
L.ex(e);
}
}
lastUse = M.ms();
return object;
}
}

View File

@ -157,7 +157,7 @@ public class GenLayerBiome extends GenLayer
return biome; return biome;
} }
if(!Borders.isBorderWithin(x, z, 24, 45, (x / 10D) + (z / 10D), (a, b) -> ocean.getIndex(a, b))) if(!Borders.isBorderWithin(x, z, 7, 45, (x / 10D) + (z / 10D), (a, b) -> ocean.getIndex(a, b)))
{ {
if(region.getDeepOcean() == null) if(region.getDeepOcean() == null)
{ {

View File

@ -11,6 +11,7 @@ import ninja.bytecode.iris.util.Borders;
import ninja.bytecode.iris.util.ChunkPlan; import ninja.bytecode.iris.util.ChunkPlan;
import ninja.bytecode.iris.util.GenLayer; import ninja.bytecode.iris.util.GenLayer;
import ninja.bytecode.iris.util.PolygonGenerator; import ninja.bytecode.iris.util.PolygonGenerator;
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
import ninja.bytecode.shuriken.math.CNG; import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.RNG; import ninja.bytecode.shuriken.math.RNG;
@ -38,6 +39,7 @@ public class GenLayerCaves extends GenLayer
public void genCaves(double xxf, double zzf, int x, int z, AtomicChunkData data, ChunkPlan plan) public void genCaves(double xxf, double zzf, int x, int z, AtomicChunkData data, ChunkPlan plan)
{ {
PrecisionStopwatch s = PrecisionStopwatch.start();
int wxxf = (int) (xxf + gfract.noise(xxf, zzf)); int wxxf = (int) (xxf + gfract.noise(xxf, zzf));
int wzxf = (int) (zzf - gfract.noise(zzf, xxf)); int wzxf = (int) (zzf - gfract.noise(zzf, xxf));
double itr = 2; double itr = 2;
@ -60,7 +62,7 @@ public class GenLayerCaves extends GenLayer
double n = incline * gincline.noise((wxxf + (m * 10000)), (wzxf - (m * 10000))); double n = incline * gincline.noise((wxxf + (m * 10000)), (wzxf - (m * 10000)));
for(double i = 1; i <= w / 3D; i++) for(double i = 1; i <= w / 3D; i++)
{ {
if(Borders.isBorderWithin((wxxf + (m * 10000)), (wzxf - (m * 10000)), 17, w / 2D / i, (wxxf / 3D) + (wzxf / 3D), (xx, zz) -> g.getIndex(xx, zz))) if(Borders.isBorderWithin((wxxf + (m * 10000)), (wzxf - (m * 10000)), 5, w / 2D / i, (wxxf / 3D) + (wzxf / 3D), (xx, zz) -> g.getIndex(xx, zz)))
{ {
int h = (int) ((level + n) - drop); int h = (int) ((level + n) - drop);
if(dig(x, (int) (h + i), z, data) && h + i < lowest) if(dig(x, (int) (h + i), z, data) && h + i < lowest)
@ -83,6 +85,8 @@ public class GenLayerCaves extends GenLayer
} }
} }
} }
iris.getMetrics().stop("caves:ms:x256:/chunk:..", s);
} }
public boolean dig(int x, int y, int z, AtomicChunkData data) public boolean dig(int x, int y, int z, AtomicChunkData data)

View File

@ -19,7 +19,7 @@ public class GenLayerLayeredNoise extends GenLayer
//@builder //@builder
super(iris, world, random, rng); super(iris, world, random, rng);
fract = new CNG(rng.nextParallelRNG(16), 1D, 9).scale(0.0181); fract = new CNG(rng.nextParallelRNG(16), 1D, 9).scale(0.0181);
gen = new CNG(rng.nextParallelRNG(17), 0.19D, 12) gen = new CNG(rng.nextParallelRNG(17), 0.19D, 8)
.scale(0.012) .scale(0.012)
.amp(0.5) .amp(0.5)
.freq(1.1) .freq(1.1)

View File

@ -17,7 +17,7 @@ public class GenLayerSnow extends GenLayer
{ {
//@builder //@builder
super(iris, world, random, rng); super(iris, world, random, rng);
gen = new CNG(rng.nextParallelRNG(117), 1D, 16) gen = new CNG(rng.nextParallelRNG(117), 1D, 1)
.scale(0.059) .scale(0.059)
.amp(0.5) .amp(0.5)
.freq(1.1) .freq(1.1)

View File

@ -1,7 +1,6 @@
package ninja.bytecode.iris.generator.parallax; package ninja.bytecode.iris.generator.parallax;
import java.util.Random; import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
@ -26,7 +25,6 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
private int j; private int j;
private int wx; private int wx;
private int wz; private int wz;
private ReentrantLock biomeLock;
private TaskExecutor backupService; private TaskExecutor backupService;
private TaskGroup tg; private TaskGroup tg;
private boolean ready = false; private boolean ready = false;
@ -105,7 +103,6 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
if(!ready) if(!ready)
{ {
biomeLock = new ReentrantLock();
init(world, random); init(world, random);
ready = true; ready = true;
} }
@ -126,9 +123,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
tg.queue(() -> tg.queue(() ->
{ {
Biome f = generateFullColumn(a, b, c, d, plan.get(), data); Biome f = generateFullColumn(a, b, c, d, plan.get(), data);
biomeLock.lock();
biome.setBiome(c, d, f); biome.setBiome(c, d, f);
biomeLock.unlock();
}); });
} }
} }

View File

@ -1,6 +1,7 @@
package ninja.bytecode.iris.generator.placer; package ninja.bytecode.iris.generator.placer;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.Block;
import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.parallax.ParallaxCache; import ninja.bytecode.iris.generator.parallax.ParallaxCache;
@ -38,4 +39,10 @@ public class AtomicParallaxPlacer extends Placer
{ {
return cache.getHeight(l.getBlockX(), l.getBlockZ()); return cache.getHeight(l.getBlockX(), l.getBlockZ());
} }
@Override
public int getHighestYUnderwater(Location l)
{
return cache.getWaterHeight(l.getBlockX(), l.getBlockZ());
}
} }

View File

@ -10,7 +10,7 @@ import ninja.bytecode.iris.util.Placer;
public class BukkitPlacer extends Placer public class BukkitPlacer extends Placer
{ {
private final boolean applyPhysics; private final boolean applyPhysics;
public BukkitPlacer(World world, boolean applyPhysics) public BukkitPlacer(World world, boolean applyPhysics)
{ {
super(world); super(world);
@ -32,6 +32,29 @@ public class BukkitPlacer extends Placer
l.getBlock().setTypeIdAndData(mb.material.getId(), mb.data, applyPhysics); l.getBlock().setTypeIdAndData(mb.material.getId(), mb.data, applyPhysics);
} }
@Override
public int getHighestYUnderwater(Location l)
{
int y = getHighestY(l);
while(y > 0)
{
y--;
Block b = l.getWorld().getBlockAt(l.getBlockX(), y, l.getBlockZ());
if(!b.isEmpty())
{
if(b.isLiquid())
{
continue;
}
return y + 1;
}
}
return y;
}
@Override @Override
public int getHighestY(Location l) public int getHighestY(Location l)
{ {

View File

@ -46,9 +46,33 @@ public class NMSPlacer extends Placer
return world.getHighestBlockYAt(l); return world.getHighestBlockYAt(l);
} }
@Override
public int getHighestYUnderwater(Location l)
{
int y = getHighestY(l);
while(y > 0)
{
y--;
Block b = l.getWorld().getBlockAt(l.getBlockX(), y, l.getBlockZ());
if(!b.isEmpty())
{
if(b.isLiquid())
{
continue;
}
return y + 1;
}
}
return y;
}
public void flush() public void flush()
{ {
J.attempt(() -> { J.attempt(() ->
{
for(Chunk i : c) for(Chunk i : c)
{ {
NMP.host.relight(i); NMP.host.relight(i);

View File

@ -6,12 +6,14 @@ import org.bukkit.World;
public interface IPlacer public interface IPlacer
{ {
public World getWorld(); public World getWorld();
public MB get(Location l); public MB get(Location l);
public void set(Location l, MB mb); public void set(Location l, MB mb);
public int getHighestY(Location l); public int getHighestY(Location l);
public int getHighestYUnderwater(Location l);
public void flush(); public void flush();
} }

View File

@ -0,0 +1,72 @@
package ninja.bytecode.iris.util;
import java.util.Objects;
public class SChunkVectorShort
{
private short x;
private short z;
public SChunkVectorShort(int x, int z)
{
this.x = (short) (x);
this.z = (short) (z);
}
public SChunkVectorShort(short x, short z)
{
this.x = x;
this.z = z;
}
public SChunkVectorShort(double x, double z)
{
this((int) Math.round(x), (int) Math.round(z));
}
public SChunkVectorShort()
{
this((short) 0, (short) 0);
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = (short) x;
}
public int getZ()
{
return z;
}
public void setZ(int z)
{
this.z = (short) z;
}
@Override
public int hashCode()
{
return Objects.hash(x, z);
}
@Override
public boolean equals(Object obj)
{
if(this == obj)
{
return true;
}
if(!(obj instanceof SChunkVectorShort))
{
return false;
}
SChunkVectorShort other = (SChunkVectorShort) obj;
return x == other.x && z == other.z;
}
}