summaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
authorEvilSeph <evilseph@unaligned.org>2011-06-17 09:23:19 -0400
committerEvilSeph <evilseph@unaligned.org>2011-06-17 09:23:19 -0400
commit10fb5dc843b9edb0d8086615c2db749623664044 (patch)
tree86a7d78f11976f1ab0477706d9a84a79eac3aabb /src/main
parent105cc5393cabb6db1db7270af01313327cfc4f99 (diff)
downloadcraftbukkit-10fb5dc843b9edb0d8086615c2db749623664044.tar
craftbukkit-10fb5dc843b9edb0d8086615c2db749623664044.tar.gz
craftbukkit-10fb5dc843b9edb0d8086615c2db749623664044.tar.lz
craftbukkit-10fb5dc843b9edb0d8086615c2db749623664044.tar.xz
craftbukkit-10fb5dc843b9edb0d8086615c2db749623664044.zip
Added ChunkSnapShot improvements. Thanks mikeprimm!
Added support for biome data to chunk snapshot Added method for returning empty chunk snapshot (for ungenerated chunks)
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/bukkit/craftbukkit/CraftChunk.java95
-rw-r--r--src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java77
-rw-r--r--src/main/java/org/bukkit/craftbukkit/CraftWorld.java5
3 files changed, 170 insertions, 7 deletions
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
index 7e92056c..2d870eec 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
@@ -13,6 +13,8 @@ import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.entity.Entity;
import org.bukkit.craftbukkit.util.ConcurrentSoftMap;
import org.bukkit.ChunkSnapshot;
+import net.minecraft.server.BiomeBase;
+import net.minecraft.server.WorldChunkManager;
public class CraftChunk implements Chunk {
private WeakReference<net.minecraft.server.Chunk> weakChunk;
@@ -111,13 +113,100 @@ public class CraftChunk implements Chunk {
* @return ChunkSnapshot
*/
public ChunkSnapshot getChunkSnapshot() {
+ return getChunkSnapshot(true, false, false);
+ }
+
+ /**
+ * Capture thread-safe read-only snapshot of chunk data
+ * @param includeMaxblocky - if true, snapshot includes per-coordinate maximum Y values
+ * @param includeBiome - if true, snapshot includes per-coordinate biome type
+ * @param includeBiomeTempRain - if true, snapshot includes per-coordinate raw biome temperature and rainfall
+ * @return ChunkSnapshot
+ */
+ public ChunkSnapshot getChunkSnapshot(boolean includeMaxblocky, boolean includeBiome, boolean includeBiomeTempRain) {
net.minecraft.server.Chunk chunk = getHandle();
byte[] buf = new byte[32768 + 16384 + 16384 + 16384]; // Get big enough buffer for whole chunk
chunk.a(buf, 0, 0, 0, 16, 128, 16, 0); // Get whole chunk
- byte[] hmap = new byte[256]; // Get copy of height map
- System.arraycopy(chunk.h, 0, hmap, 0, 256);
+ byte[] hmap = null;
+
+ if (includeMaxblocky) {
+ hmap = new byte[256]; // Get copy of height map
+ System.arraycopy(chunk.h, 0, hmap, 0, 256);
+ }
+
+ BiomeBase[] biome = null;
+ double[] biomeTemp = null;
+ double[] biomeRain = null;
+
+ if (includeBiome || includeBiomeTempRain) {
+ WorldChunkManager wcm = chunk.world.getWorldChunkManager();
+ BiomeBase[] bb = wcm.a(getX()<<4, getZ()<<4, 16, 16);
+
+ if (includeBiome) {
+ biome = new BiomeBase[256];
+ System.arraycopy(bb, 0, biome, 0, biome.length);
+ }
+
+ if (includeBiomeTempRain) {
+ biomeTemp = new double[256];
+ biomeRain = new double[256];
+ System.arraycopy(wcm.a, 0, biomeTemp, 0, biomeTemp.length);
+ System.arraycopy(wcm.b, 0, biomeRain, 0, biomeRain.length);
+ }
+ }
World w = getWorld();
- return new CraftChunkSnapshot(getX(), getZ(), w.getName(), w.getFullTime(), buf, hmap);
+ return new CraftChunkSnapshot(getX(), getZ(), w.getName(), w.getFullTime(), buf, hmap, biome, biomeTemp, biomeRain);
+ }
+ /**
+ * Empty chunk snapshot - nothing but air blocks, but can include valid biome data
+ */
+ private static class EmptyChunkSnapshot extends CraftChunkSnapshot {
+ EmptyChunkSnapshot(int x, int z, String w, long wtime, BiomeBase[] biome, double[] biomeTemp, double[] biomeRain) {
+ super(x, z, w, wtime, null, null, biome, biomeTemp, biomeRain);
+ }
+
+ public final int getBlockTypeId(int x, int y, int z) {
+ return 0;
+ }
+
+ public final int getBlockData(int x, int y, int z) {
+ return 0;
+ }
+
+ public final int getBlockSkyLight(int x, int y, int z) {
+ return 15;
+ }
+
+ public final int getBlockEmittedLight(int x, int y, int z) {
+ return 0;
+ }
+
+ public final int getHighestBlockYAt(int x, int z) {
+ return 0;
+ }
}
+ public static ChunkSnapshot getEmptyChunkSnapshot(int x, int z, CraftWorld w, boolean includeBiome, boolean includeBiomeTempRain) {
+ BiomeBase[] biome = null;
+ double[] biomeTemp = null;
+ double[] biomeRain = null;
+
+ if (includeBiome || includeBiomeTempRain) {
+ WorldChunkManager wcm = w.getHandle().getWorldChunkManager();
+ BiomeBase[] bb = wcm.a(x<<4, z<<4, 16, 16);
+
+ if (includeBiome) {
+ biome = new BiomeBase[256];
+ System.arraycopy(bb, 0, biome, 0, biome.length);
+ }
+
+ if (includeBiomeTempRain) {
+ biomeTemp = new double[256];
+ biomeRain = new double[256];
+ System.arraycopy(wcm.a, 0, biomeTemp, 0, biomeTemp.length);
+ System.arraycopy(wcm.b, 0, biomeRain, 0, biomeRain.length);
+ }
+ }
+ return new EmptyChunkSnapshot(x, z, w.getName(), w.getFullTime(), biome, biomeTemp, biomeRain);
+ }
} \ No newline at end of file
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
index 5004575e..3337093a 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
@@ -1,6 +1,9 @@
package org.bukkit.craftbukkit;
import org.bukkit.ChunkSnapshot;
+import org.bukkit.block.Biome;
+
+import net.minecraft.server.BiomeBase;
/**
* Represents a static, thread-safe snapshot of chunk of blocks
* Purpose is to allow clean, efficient copy of a chunk data to be made, and then handed off for processing in another thread (e.g. map rendering)
@@ -10,7 +13,10 @@ public class CraftChunkSnapshot implements ChunkSnapshot {
private final String worldname;
private final byte[] buf; // Flat buffer in uncompressed chunk file format
private final byte[] hmap; // Height map
- private final long capture_fulltime;
+ private final long captureFulltime;
+ private final BiomeBase[] biome;
+ private final double[] biomeTemp;
+ private final double[] biomeRain;
private static final int BLOCKDATA_OFF = 32768;
private static final int BLOCKLIGHT_OFF = BLOCKDATA_OFF + 16384;
@@ -19,13 +25,16 @@ public class CraftChunkSnapshot implements ChunkSnapshot {
/**
* Constructor
*/
- CraftChunkSnapshot(int x, int z, String wname, long wtime, byte[] buf, byte[] hmap) {
+ CraftChunkSnapshot(int x, int z, String wname, long wtime, byte[] buf, byte[] hmap, BiomeBase[] biome, double[] biomeTemp, double[] biomeRain) {
this.x = x;
this.z = z;
this.worldname = wname;
- this.capture_fulltime = wtime;
+ this.captureFulltime = wtime;
this.buf = buf;
this.hmap = hmap;
+ this.biome = biome;
+ this.biomeTemp = biomeTemp;
+ this.biomeRain = biomeRain;
}
/**
@@ -121,10 +130,70 @@ public class CraftChunkSnapshot implements ChunkSnapshot {
}
/**
+ * Get biome at given coordinates
+ *
+ * @param x X-coordinate
+ * @param z Z-coordinate
+ * @return Biome at given coordinate
+ */
+ public Biome getBiome(int x, int z) {
+ BiomeBase base = biome[x << 4 | z];
+
+ if (base == BiomeBase.RAINFOREST) {
+ return Biome.RAINFOREST;
+ } else if (base == BiomeBase.SWAMPLAND) {
+ return Biome.SWAMPLAND;
+ } else if (base == BiomeBase.SEASONAL_FOREST) {
+ return Biome.SEASONAL_FOREST;
+ } else if (base == BiomeBase.FOREST) {
+ return Biome.FOREST;
+ } else if (base == BiomeBase.SAVANNA) {
+ return Biome.SAVANNA;
+ } else if (base == BiomeBase.SHRUBLAND) {
+ return Biome.SHRUBLAND;
+ } else if (base == BiomeBase.TAIGA) {
+ return Biome.TAIGA;
+ } else if (base == BiomeBase.DESERT) {
+ return Biome.DESERT;
+ } else if (base == BiomeBase.PLAINS) {
+ return Biome.PLAINS;
+ } else if (base == BiomeBase.ICE_DESERT) {
+ return Biome.ICE_DESERT;
+ } else if (base == BiomeBase.TUNDRA) {
+ return Biome.TUNDRA;
+ } else if (base == BiomeBase.HELL) {
+ return Biome.HELL;
+ }
+ return null;
+ }
+
+ /**
+ * Get raw biome temperature (0.0-1.0) at given coordinate
+ *
+ * @param x X-coordinate
+ * @param z Z-coordinate
+ * @return temperature at given coordinate
+ */
+ public double getRawBiomeTemperature(int x, int z) {
+ return biomeTemp[x << 4 | z];
+ }
+
+ /**
+ * Get raw biome rainfall (0.0-1.0) at given coordinate
+ *
+ * @param x X-coordinate
+ * @param z Z-coordinate
+ * @return rainfall at given coordinate
+ */
+ public double getRawBiomeRainfall(int x, int z) {
+ return biomeRain[x << 4 | z];
+ }
+
+ /**
* Get world full time when chunk snapshot was captured
* @return time in ticks
*/
public long getCaptureFullTime() {
- return capture_fulltime;
+ return captureFulltime;
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 3053937d..b31cf5f1 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -23,6 +23,7 @@ import org.bukkit.util.Vector;
import org.bukkit.BlockChangeDelegate;
import org.bukkit.Bukkit;
import org.bukkit.generator.ChunkGenerator;
+import org.bukkit.ChunkSnapshot;
import org.bukkit.Location;
import org.bukkit.TreeType;
import org.bukkit.World;
@@ -760,4 +761,8 @@ public class CraftWorld implements World {
throw new IllegalArgumentException("Cannot spawn an entity for " + clazz.getName());
}
+
+ public ChunkSnapshot getEmptyChunkSnapshot(int x, int z, boolean includeBiome, boolean includeBiomeTempRain) {
+ return CraftChunk.getEmptyChunkSnapshot(x, z, this, includeBiome, includeBiomeTempRain);
+ }
}