Caching Revisited

This commit is contained in:
Dan Macbook 2020-08-14 05:16:58 -04:00
parent 948317c27a
commit 7f98aff531
8 changed files with 202 additions and 130 deletions

View File

@ -171,36 +171,38 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator {
} }
public BiomeResult sampleBiome(int x, int z) { public BiomeResult sampleBiome(int x, int z) {
if (!getDimension().getFocus().equals("")) { return getCache().getRawBiome(x, z, () -> {
IrisBiome biome = loadBiome(getDimension().getFocus()); if (!getDimension().getFocus().equals("")) {
IrisBiome biome = loadBiome(getDimension().getFocus());
for (String i : getDimension().getRegions()) { for (String i : getDimension().getRegions()) {
IrisRegion reg = loadRegion(i); IrisRegion reg = loadRegion(i);
if (reg.getLandBiomes().contains(biome.getLoadKey())) { if (reg.getLandBiomes().contains(biome.getLoadKey())) {
biome.setInferredType(InferredType.LAND); biome.setInferredType(InferredType.LAND);
break; break;
}
if (reg.getSeaBiomes().contains(biome.getLoadKey())) {
biome.setInferredType(InferredType.SEA);
break;
}
if (reg.getShoreBiomes().contains(biome.getLoadKey())) {
biome.setInferredType(InferredType.SHORE);
break;
}
} }
if (reg.getSeaBiomes().contains(biome.getLoadKey())) { return new BiomeResult(biome, 0);
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 = glBiome.getRegion(wx, wz);
BiomeResult res = glBiome.generateRegionData(wx, wz, x, z, region);
double wx = getModifiedX(x, z); return res;
double wz = getModifiedZ(x, z); });
IrisRegion region = glBiome.getRegion(wx, wz);
BiomeResult res = glBiome.generateRegionData(wx, wz, x, z, region);
return res;
} }
} }

View File

@ -24,6 +24,7 @@ import com.volmit.iris.Iris;
import com.volmit.iris.IrisContext; import com.volmit.iris.IrisContext;
import com.volmit.iris.IrisDataManager; import com.volmit.iris.IrisDataManager;
import com.volmit.iris.IrisMetrics; import com.volmit.iris.IrisMetrics;
import com.volmit.iris.gen.atomics.AtomicMulticache;
import com.volmit.iris.noise.CNG; import com.volmit.iris.noise.CNG;
import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisBiome;
import com.volmit.iris.object.IrisDimension; import com.volmit.iris.object.IrisDimension;
@ -46,6 +47,7 @@ import net.md_5.bungee.api.ChatColor;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public abstract class ContextualChunkGenerator extends ChunkGenerator implements Listener { public abstract class ContextualChunkGenerator extends ChunkGenerator implements Listener {
private AtomicMulticache cache;
private IrisDataManager data; private IrisDataManager data;
protected boolean failing; protected boolean failing;
protected int task; protected int task;
@ -70,6 +72,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
perSecond = new ChronoLatch(1000); perSecond = new ChronoLatch(1000);
hlast = M.ms(); hlast = M.ms();
hlock = new IrisLock("HotLock"); hlock = new IrisLock("HotLock");
cache = new AtomicMulticache();
CNG.creates = 0; CNG.creates = 0;
generated = 0; generated = 0;
ticks = 0; ticks = 0;

View File

@ -81,7 +81,8 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
@Override @Override
public int getHighest(int x, int z, boolean ignoreFluid) { public int getHighest(int x, int z, boolean ignoreFluid) {
int h = (int) Math.round(ignoreFluid ? getTerrainHeight(x, z) : getTerrainWaterHeight(x, z)); int h = (int) Math
.round(ignoreFluid ? getTerrainHeight(x, z) : getTerrainWaterHeight(x, z));
if (getDimension().isCarving() && h >= getDimension().getCarvingMin()) { if (getDimension().isCarving() && h >= getDimension().getCarvingMin()) {
while (getGlCarve().isCarved(x, h, z)) { while (getGlCarve().isCarved(x, h, z)) {

View File

@ -20,7 +20,6 @@ import lombok.EqualsAndHashCode;
public abstract class ParallelChunkGenerator extends BiomeChunkGenerator { public abstract class ParallelChunkGenerator extends BiomeChunkGenerator {
private GroupedExecutor accelerant; private GroupedExecutor accelerant;
private int threads; private int threads;
protected boolean safe;
protected int cacheX; protected int cacheX;
protected int cacheZ; protected int cacheZ;
private IrisLock genlock; private IrisLock genlock;
@ -28,7 +27,6 @@ public abstract class ParallelChunkGenerator extends BiomeChunkGenerator {
public ParallelChunkGenerator(String dimensionName, int threads) { public ParallelChunkGenerator(String dimensionName, int threads) {
super(dimensionName); super(dimensionName);
safe = false;
cacheX = 0; cacheX = 0;
cacheZ = 0; cacheZ = 0;
this.threads = threads; this.threads = threads;
@ -68,6 +66,7 @@ public abstract class ParallelChunkGenerator extends BiomeChunkGenerator {
genlock.lock(); genlock.lock();
cacheX = x; cacheX = x;
cacheZ = z; cacheZ = z;
getCache().targetChunk(cacheX, cacheZ);
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
AtomicSliverMap map = new AtomicSliverMap(); AtomicSliverMap map = new AtomicSliverMap();
HeightMap height = new HeightMap(); HeightMap height = new HeightMap();
@ -90,11 +89,7 @@ public abstract class ParallelChunkGenerator extends BiomeChunkGenerator {
} }
} }
setCachingAllowed(true);
setSafe(false);
accelerant.waitFor(key); accelerant.waitFor(key);
setSafe(true);
setCachingAllowed(false);
map.write(data, grid, height); map.write(data, grid, height);
getMetrics().getTerrain().put(p.getMilliseconds()); getMetrics().getTerrain().put(p.getMilliseconds());
p = PrecisionStopwatch.start(); p = PrecisionStopwatch.start();

View File

@ -68,7 +68,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
double wx = getZoomed(ox); double wx = getZoomed(ox);
double wz = getZoomed(oz); double wz = getZoomed(oz);
int depth = 0; int depth = 0;
double noise = getNoiseHeight(rx, rz) + fluidHeight; double noise = getTerrainHeight(rx, rz);
int height = (int) Math.round(noise); int height = (int) Math.round(noise);
boolean carvable = getDimension().isCarving() && height > getDimension().getCarvingMin(); boolean carvable = getDimension().isCarving() && height > getDimension().getCarvingMin();
IrisRegion region = sampleRegion(rx, rz); IrisRegion region = sampleRegion(rx, rz);
@ -409,7 +409,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
} }
protected double getNoiseHeight(int rx, int rz) { private double getNoiseHeight(int rx, int rz) {
double wx = getZoomed(rx); double wx = getZoomed(rx);
double wz = getZoomed(rz); double wz = getZoomed(rz);
double h = getBiomeHeight(wx, wz, rx, rz); double h = getBiomeHeight(wx, wz, rx, rz);
@ -477,9 +477,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
@Override @Override
public IrisRegion sampleRegion(int x, int z) { public IrisRegion sampleRegion(int x, int z) {
IrisRegion r = super.sampleRegion(x, z); return getCache().getRegion(x, z, () -> super.sampleRegion(x, z));
return r;
} }
public BiomeResult sampleTrueBiome(int x, int z, double noise) { public BiomeResult sampleTrueBiome(int x, int z, double noise) {
@ -487,27 +485,26 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
return focus(); return focus();
} }
double wx = getModifiedX(x, z); return getCache().getBiome(x, z, () -> {
double wz = getModifiedZ(x, z); double wx = getModifiedX(x, z);
IrisRegion region = sampleRegion(x, z); double wz = getModifiedZ(x, z);
int height = (int) Math.round(noise); IrisRegion region = sampleRegion(x, z);
double sh = region.getShoreHeight(wx, wz); int height = (int) Math.round(noise);
BiomeResult res = sampleTrueBiomeBase(x, z, height); double sh = region.getShoreHeight(wx, wz);
IrisBiome current = res.getBiome(); BiomeResult res = sampleTrueBiomeBase(x, z, height);
IrisBiome current = res.getBiome();
if (current.isSea() && height > getDimension().getFluidHeight() - sh) { if (current.isSea() && height > getDimension().getFluidHeight() - sh) {
return glBiome.generateData(InferredType.SHORE, wx, wz, x, z, region); return glBiome.generateData(InferredType.SHORE, wx, wz, x, z, region);
} }
return res; return res;
});
} }
@Override @Override
protected int onSampleColumnHeight(int cx, int cz, int rx, int rz, int x, int z) { protected int onSampleColumnHeight(int cx, int cz, int rx, int rz, int x, int z) {
int fluidHeight = getDimension().getFluidHeight(); return (int) Math.round(getTerrainHeight(rx, rz));
double noise = getNoiseHeight(rx, rz);
return (int) Math.round(noise) + fluidHeight;
} }
private boolean touchesSea(int rx, int rz) { private boolean touchesSea(int rx, int rz) {
@ -528,7 +525,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
} }
public double getTerrainHeight(int x, int z) { public double getTerrainHeight(int x, int z) {
return getNoiseHeight(x, z) + getFluidHeight(); return getCache().getHeight(x, z, () -> getNoiseHeight(x, z) + getFluidHeight());
} }
public double getTerrainWaterHeight(int x, int z) { public double getTerrainWaterHeight(int x, int z) {

View File

@ -0,0 +1,105 @@
package com.volmit.iris.gen.atomics;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import com.volmit.iris.Iris;
import com.volmit.iris.object.IrisRegion;
import com.volmit.iris.util.BiomeResult;
import com.volmit.iris.util.Form;
import com.volmit.iris.util.KMap;
public class AtomicMulticache {
private final AtomicInteger x;
private final AtomicInteger z;
private final KMap<Long, Double> height;
private final KMap<Long, BiomeResult> biome;
private final KMap<Long, BiomeResult> rawBiome;
private final KMap<Long, IrisRegion> region;
private int r = 0;
private int w = 0;
private int m = 0;
public AtomicMulticache() {
x = new AtomicInteger(0);
z = new AtomicInteger(0);
height = new KMap<Long, Double>();
biome = new KMap<Long, BiomeResult>();
rawBiome = new KMap<Long, BiomeResult>();
region = new KMap<Long, IrisRegion>();
}
public void targetChunk(int x, int z) {
this.x.set(x);
this.z.set(z);
Iris.info("R: " + Form.f(r) + " W: " + Form.f(w) + " M: " + Form.f(m) + " (" + Form.pc(r / (double) (r + m), 1)
+ "), SIZE: " + Form.f(height.size() + biome.size() + region.size()));
height.clear();
region.size();
biome.size();
r = 0;
w = 0;
m = 0;
}
public double getHeight(int x, int z, Supplier<Double> g) {
return height.compute(pos(x, z), (k, v) -> {
if (v == null) {
m++;
w++;
return g.get();
}
r++;
return v;
});
}
public IrisRegion getRegion(int x, int z, Supplier<IrisRegion> g) {
return region.compute(pos(x, z), (k, v) -> {
if (v == null) {
m++;
w++;
return g.get();
}
r++;
return v;
});
}
public BiomeResult getBiome(int x, int z, Supplier<BiomeResult> g) {
return biome.compute(pos(x, z), (k, v) -> {
if (v == null) {
m++;
w++;
return g.get();
}
r++;
return v;
});
}
public BiomeResult getRawBiome(int x, int z, Supplier<BiomeResult> g) {
return rawBiome.compute(pos(x, z), (k, v) -> {
if (v == null) {
m++;
w++;
return g.get();
}
r++;
return v;
});
}
private long pos(int x, int z) {
return (((long) x) << 32) | (z & 0xffffffffL);
}
}

View File

@ -26,19 +26,21 @@ import lombok.EqualsAndHashCode;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisObject extends IrisRegistrant public class IrisObject extends IrisRegistrant {
{
private static final Material SNOW = Material.SNOW; private static final Material SNOW = Material.SNOW;
private static final BlockData AIR = B.getBlockData("CAVE_AIR"); private static final BlockData AIR = B.getBlockData("CAVE_AIR");
private static final BlockData[] SNOW_LAYERS = new BlockData[] {B.getBlockData("minecraft:snow[layers=1]"), B.getBlockData("minecraft:snow[layers=2]"), B.getBlockData("minecraft:snow[layers=3]"), B.getBlockData("minecraft:snow[layers=4]"), B.getBlockData("minecraft:snow[layers=5]"), B.getBlockData("minecraft:snow[layers=6]"), B.getBlockData("minecraft:snow[layers=7]"), B.getBlockData("minecraft:snow[layers=8]")}; private static final BlockData[] SNOW_LAYERS = new BlockData[] { B.getBlockData("minecraft:snow[layers=1]"),
B.getBlockData("minecraft:snow[layers=2]"), B.getBlockData("minecraft:snow[layers=3]"),
B.getBlockData("minecraft:snow[layers=4]"), B.getBlockData("minecraft:snow[layers=5]"),
B.getBlockData("minecraft:snow[layers=6]"), B.getBlockData("minecraft:snow[layers=7]"),
B.getBlockData("minecraft:snow[layers=8]") };
private KMap<BlockVector, BlockData> blocks; private KMap<BlockVector, BlockData> blocks;
private int w; private int w;
private int d; private int d;
private int h; private int h;
private transient BlockVector center; private transient BlockVector center;
public IrisObject(int w, int h, int d) public IrisObject(int w, int h, int d) {
{
blocks = new KMap<>(); blocks = new KMap<>();
this.w = w; this.w = w;
this.h = h; this.h = h;
@ -46,8 +48,7 @@ public class IrisObject extends IrisRegistrant
center = new BlockVector(w / 2, h / 2, d / 2); center = new BlockVector(w / 2, h / 2, d / 2);
} }
public static BlockVector sampleSize(File file) throws IOException public static BlockVector sampleSize(File file) throws IOException {
{
FileInputStream in = new FileInputStream(file); FileInputStream in = new FileInputStream(file);
DataInputStream din = new DataInputStream(in); DataInputStream din = new DataInputStream(in);
BlockVector bv = new BlockVector(din.readInt(), din.readInt(), din.readInt()); BlockVector bv = new BlockVector(din.readInt(), din.readInt(), din.readInt());
@ -55,8 +56,7 @@ public class IrisObject extends IrisRegistrant
return bv; return bv;
} }
public void read(InputStream in) throws IOException public void read(InputStream in) throws IOException {
{
DataInputStream din = new DataInputStream(in); DataInputStream din = new DataInputStream(in);
this.w = din.readInt(); this.w = din.readInt();
this.h = din.readInt(); this.h = din.readInt();
@ -64,36 +64,32 @@ public class IrisObject extends IrisRegistrant
center = new BlockVector(w / 2, h / 2, d / 2); center = new BlockVector(w / 2, h / 2, d / 2);
int s = din.readInt(); int s = din.readInt();
for(int i = 0; i < s; i++) for (int i = 0; i < s; i++) {
{ blocks.put(new BlockVector(din.readShort(), din.readShort(), din.readShort()),
blocks.put(new BlockVector(din.readShort(), din.readShort(), din.readShort()), B.getBlockData(din.readUTF())); B.getBlockData(din.readUTF()));
} }
} }
public void read(File file) throws IOException public void read(File file) throws IOException {
{
FileInputStream fin = new FileInputStream(file); FileInputStream fin = new FileInputStream(file);
read(fin); read(fin);
fin.close(); fin.close();
} }
public void write(File file) throws IOException public void write(File file) throws IOException {
{
file.getParentFile().mkdirs(); file.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(file); FileOutputStream out = new FileOutputStream(file);
write(out); write(out);
out.close(); out.close();
} }
public void write(OutputStream o) throws IOException public void write(OutputStream o) throws IOException {
{
DataOutputStream dos = new DataOutputStream(o); DataOutputStream dos = new DataOutputStream(o);
dos.writeInt(w); dos.writeInt(w);
dos.writeInt(h); dos.writeInt(h);
dos.writeInt(d); dos.writeInt(d);
dos.writeInt(blocks.size()); dos.writeInt(blocks.size());
for(BlockVector i : blocks.k()) for (BlockVector i : blocks.k()) {
{
dos.writeShort(i.getBlockX()); dos.writeShort(i.getBlockX());
dos.writeShort(i.getBlockY()); dos.writeShort(i.getBlockY());
dos.writeShort(i.getBlockZ()); dos.writeShort(i.getBlockZ());
@ -101,83 +97,67 @@ public class IrisObject extends IrisRegistrant
} }
} }
public void setUnsigned(int x, int y, int z, BlockData block) public void setUnsigned(int x, int y, int z, BlockData block) {
{ if (x >= w || y >= h || z >= d) {
if(x >= w || y >= h || z >= d)
{
throw new RuntimeException(x + " " + y + " " + z + " exceeds limit of " + w + " " + h + " " + d); throw new RuntimeException(x + " " + y + " " + z + " exceeds limit of " + w + " " + h + " " + d);
} }
BlockVector v = new BlockVector(x, y, z).subtract(center).toBlockVector(); BlockVector v = new BlockVector(x, y, z).subtract(center).toBlockVector();
if(block == null) if (block == null) {
{
blocks.remove(v); blocks.remove(v);
} }
else else {
{
blocks.put(v, block); blocks.put(v, block);
} }
} }
public void place(int x, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng) public void place(int x, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng) {
{
place(x, -1, z, placer, config, rng); place(x, -1, z, placer, config, rng);
} }
public void place(int x, int yv, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng) public void place(int x, int yv, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng) {
{
int spinx = rng.imax() / 1000; int spinx = rng.imax() / 1000;
int spiny = rng.imax() / 1000; int spiny = rng.imax() / 1000;
int spinz = rng.imax() / 1000; int spinz = rng.imax() / 1000;
int y = yv < 0 ? placer.getHighest(x, z, config.isUnderwater()) + config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY() : yv; int y = yv < 0 ? placer.getHighest(x, z, config.isUnderwater()) + config.getRotation()
.rotate(new BlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY() : yv;
if(yv >= 0 && config.isBottom()) if (yv >= 0 && config.isBottom()) {
{
y += Math.floorDiv(h, 2); y += Math.floorDiv(h, 2);
} }
KMap<ChunkPosition, Integer> heightmap = config.getSnow() > 0 ? new KMap<>() : null; KMap<ChunkPosition, Integer> heightmap = config.getSnow() > 0 ? new KMap<>() : null;
if(yv < 0) if (yv < 0) {
{ if (!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z)) {
if(!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z))
{
return; return;
} }
} }
if(config.isBore()) if (config.isBore()) {
{ for (int i = x - Math.floorDiv(w, 2); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0); i++) {
for(int i = x - Math.floorDiv(w, 2); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0); i++) for (int j = y - Math.floorDiv(h, 2); j <= y + Math.floorDiv(h, 2) - (h % 2 == 0 ? 1 : 0); j++) {
{ for (int k = z - Math.floorDiv(d, 2); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0); k++) {
for(int j = y - Math.floorDiv(h, 2); j <= y + Math.floorDiv(h, 2) - (h % 2 == 0 ? 1 : 0); j++)
{
for(int k = z - Math.floorDiv(d, 2); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0); k++)
{
placer.set(i, j, k, AIR); placer.set(i, j, k, AIR);
} }
} }
} }
} }
for(BlockVector g : blocks.keySet()) for (BlockVector g : blocks.keySet()) {
{
BlockVector i = g.clone(); BlockVector i = g.clone();
i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone(); i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone();
i = config.getTranslate().translate(i.clone(), config.getRotation(), spinx, spiny, spinz).clone(); i = config.getTranslate().translate(i.clone(), config.getRotation(), spinx, spiny, spinz).clone();
BlockData data = blocks.get(g).clone(); BlockData data = blocks.get(g).clone();
if(placer.isPreventingDecay() && data instanceof Leaves && !((Leaves) data).isPersistent()) if (placer.isPreventingDecay() && data instanceof Leaves && !((Leaves) data).isPersistent()) {
{
((Leaves) data).setPersistent(true); ((Leaves) data).setPersistent(true);
} }
for(IrisObjectReplace j : config.getEdit()) for (IrisObjectReplace j : config.getEdit()) {
{ if (j.isExact() ? j.getFind().matches(data) : j.getFind().getMaterial().equals(data.getMaterial())) {
if(j.isExact() ? j.getFind().matches(data) : j.getFind().getMaterial().equals(data.getMaterial()))
{
data = j.getReplace(); data = j.getReplace();
} }
} }
@ -187,44 +167,36 @@ public class IrisObject extends IrisRegistrant
int yy = y + (int) Math.round(i.getY()); int yy = y + (int) Math.round(i.getY());
int zz = z + (int) Math.round(i.getZ()); int zz = z + (int) Math.round(i.getZ());
if(heightmap != null) if (heightmap != null) {
{
ChunkPosition pos = new ChunkPosition(xx, zz); ChunkPosition pos = new ChunkPosition(xx, zz);
if(!heightmap.containsKey(pos)) if (!heightmap.containsKey(pos)) {
{
heightmap.put(pos, yy); heightmap.put(pos, yy);
} }
if(heightmap.get(pos) < yy) if (heightmap.get(pos) < yy) {
{
heightmap.put(pos, yy); heightmap.put(pos, yy);
} }
} }
if(config.isMeld() && !placer.isSolid(xx, yy, zz)) if (config.isMeld() && !placer.isSolid(xx, yy, zz)) {
{
continue; continue;
} }
placer.set(xx, yy, zz, data); placer.set(xx, yy, zz, data);
} }
if(heightmap != null) if (heightmap != null) {
{
RNG rngx = rng.nextParallelRNG(3468854); RNG rngx = rng.nextParallelRNG(3468854);
for(ChunkPosition i : heightmap.k()) for (ChunkPosition i : heightmap.k()) {
{
int vx = i.getX(); int vx = i.getX();
int vy = heightmap.get(i); int vy = heightmap.get(i);
int vz = i.getZ(); int vz = i.getZ();
if(config.getSnow() > 0) if (config.getSnow() > 0) {
{
BlockData bd = placer.get(vx, vy, vz); BlockData bd = placer.get(vx, vy, vz);
if(bd != null && bd.getMaterial().equals(SNOW)) if (bd != null && bd.getMaterial().equals(SNOW)) {
{
continue; continue;
} }
@ -235,10 +207,8 @@ public class IrisObject extends IrisRegistrant
} }
} }
public void place(Location at) public void place(Location at) {
{ for (BlockVector i : blocks.keySet()) {
for(BlockVector i : blocks.keySet())
{
at.clone().add(0, getCenter().getY(), 0).add(i).getBlock().setBlockData(blocks.get(i), false); at.clone().add(0, getCenter().getY(), 0).add(i).getBlock().setBlockData(blocks.get(i), false);
} }
} }

View File

@ -2,8 +2,7 @@ package com.volmit.iris.util;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
public interface IObjectPlacer public interface IObjectPlacer {
{
public int getHighest(int x, int z); public int getHighest(int x, int z);
public int getHighest(int x, int z, boolean ignoreFluid); public int getHighest(int x, int z, boolean ignoreFluid);