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>
<groupId>ninja.bytecode</groupId>
<artifactId>Shuriken</artifactId>
<version>1.1</version>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.volmit</groupId>

View File

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

View File

@ -36,6 +36,14 @@ public class CommandObjectLoad extends MortarCommand
if(args.length < 1)
{
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;
}
@ -43,6 +51,7 @@ public class CommandObjectLoad extends MortarCommand
GenObject s = new GenObject(1, 1, 1);
File f = new File(Iris.instance.getDataFolder(), "schematics/" + args[0] + ".ish");
if(!f.exists())
{
sender.sendMessage("Can't find " + args[0]);
@ -55,25 +64,74 @@ public class CommandObjectLoad extends MortarCommand
s.read(fin, true);
boolean cursor = false;
boolean gravity = false;
Direction df = null;
Direction dt = null;
int shift = 0;
for(String i : args)
{
if(i.equalsIgnoreCase("cursor"))
if(i.equalsIgnoreCase("-c"))
{
sender.sendMessage("Placing @ Cursor");
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));
continue;
}
if(i.startsWith("to:"))
if(i.startsWith("-t:"))
{
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();
}
s.setShift(0, shift, 0);
s.setGravity(gravity);
WandController.pasteSchematic(s, at);
p.playSound(p.getLocation(), Sound.BLOCK_ENCHANTMENT_TABLE_USE, 1f, 1.25f);
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;
}
if(!surfaceOnly)
{
glCaves.genCaves(wxxf, wzxf, x, z, data, plan);
}
plan.setRealHeight(x, z, hl);
plan.setRealWaterHeight(x, z, hw == 0 ? seaLevel : hw);
plan.setBiome(x, z, biome);
@ -397,6 +401,7 @@ public class IrisGenerator extends ParallaxWorldGenerator
@Override
protected void onDecorateChunk(World world, int cx, int cz, AtomicChunkData data, ChunkPlan plan)
{
PrecisionStopwatch p = PrecisionStopwatch.start();
int x = 0;
int z = 0;
int hhx = 0;
@ -503,50 +508,19 @@ public class IrisGenerator extends ParallaxWorldGenerator
data.setBlock(x, hhx, z, Material.AIR);
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")
@Override
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);
if(h < 63)
@ -613,6 +587,8 @@ public class IrisGenerator extends ParallaxWorldGenerator
}
}
}
getMetrics().stop("pardecoration:ms:x256:/chunk:..", p);
}
@Override

View File

@ -4,7 +4,6 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
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.MB;
import ninja.bytecode.iris.util.SBlockVector;
import ninja.bytecode.iris.util.SChunkVectorShort;
import ninja.bytecode.iris.util.VectorMath;
import ninja.bytecode.shuriken.collections.KList;
import ninja.bytecode.shuriken.collections.KMap;
import ninja.bytecode.shuriken.io.CustomOutputStream;
import ninja.bytecode.shuriken.io.IO;
import ninja.bytecode.shuriken.logging.L;
import ninja.bytecode.shuriken.math.RNG;
@ -48,68 +47,19 @@ public class GenObject
private int d;
private int failures;
private int successes;
private boolean gravity;
private String name = "?";
private KMap<SBlockVector, MB> s;
private KMap<SChunkVectorShort, SBlockVector> slopeCache;
private KMap<SChunkVectorShort, SBlockVector> gravityCache;
private BlockVector mount;
private int maxslope;
private int baseslope;
private boolean hydrophilic;
private boolean submerged;
private int mountHeight;
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)
{
this.w = w;
@ -118,6 +68,11 @@ public class GenObject
shift = new BlockVector();
s = new KMap<>();
centeredHeight = false;
gravity = false;
maxslope = -1;
baseslope = 0;
hydrophilic = false;
submerged = false;
}
public void recalculateMountShift()
@ -159,6 +114,77 @@ public class GenObject
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)
{
double g = 0;
@ -322,7 +348,7 @@ public class GenObject
start.subtract(mount);
int highestY = placer.getHighestY(start);
int highestY = submerged ? placer.getHighestYUnderwater(start) : placer.getHighestY(start);
if(start.getBlockY() + mountHeight > highestY)
{
@ -337,7 +363,44 @@ public class GenObject
MB b = getSchematic().get(i);
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)
{
@ -352,7 +415,7 @@ public class GenObject
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++;
@ -535,6 +598,32 @@ public class GenObject
{
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 "))
{
String[] g = j.split("\\Q \\E");
@ -854,4 +943,144 @@ public class GenObject
{
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

@ -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;
}
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)
{

View File

@ -11,6 +11,7 @@ import ninja.bytecode.iris.util.Borders;
import ninja.bytecode.iris.util.ChunkPlan;
import ninja.bytecode.iris.util.GenLayer;
import ninja.bytecode.iris.util.PolygonGenerator;
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
import ninja.bytecode.shuriken.math.CNG;
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)
{
PrecisionStopwatch s = PrecisionStopwatch.start();
int wxxf = (int) (xxf + gfract.noise(xxf, zzf));
int wzxf = (int) (zzf - gfract.noise(zzf, xxf));
double itr = 2;
@ -60,7 +62,7 @@ public class GenLayerCaves extends GenLayer
double n = incline * gincline.noise((wxxf + (m * 10000)), (wzxf - (m * 10000)));
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);
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)

View File

@ -19,7 +19,7 @@ public class GenLayerLayeredNoise extends GenLayer
//@builder
super(iris, world, random, rng);
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)
.amp(0.5)
.freq(1.1)

View File

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

View File

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

View File

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

View File

@ -32,6 +32,29 @@ public class BukkitPlacer extends Placer
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
public int getHighestY(Location l)
{

View File

@ -46,9 +46,33 @@ public class NMSPlacer extends Placer
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()
{
J.attempt(() -> {
J.attempt(() ->
{
for(Chunk i : c)
{
NMP.host.relight(i);

View File

@ -13,5 +13,7 @@ public interface IPlacer
public int getHighestY(Location l);
public int getHighestYUnderwater(Location l);
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;
}
}