mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Caching Revisited
This commit is contained in:
parent
948317c27a
commit
7f98aff531
@ -164,43 +164,45 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IrisRegion sampleRegion(int x, int z) {
|
public IrisRegion sampleRegion(int x, int z) {
|
||||||
|
|
||||||
double wx = getModifiedX(x, z);
|
double wx = getModifiedX(x, z);
|
||||||
double wz = getModifiedZ(x, z);
|
double wz = getModifiedZ(x, z);
|
||||||
return glBiome.getRegion(wx, wz);
|
return glBiome.getRegion(wx, wz);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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)) {
|
||||||
|
@ -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();
|
||||||
|
@ -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) {
|
||||||
|
105
src/main/java/com/volmit/iris/gen/atomics/AtomicMulticache.java
Normal file
105
src/main/java/com/volmit/iris/gen/atomics/AtomicMulticache.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user