package net.glowstone; import net.glowstone.GlowChunk.ChunkSection; import net.glowstone.constants.GlowBiome; import org.bukkit.ChunkSnapshot; import org.bukkit.World; import org.bukkit.block.Biome; /** * Class representing a snapshot of a chunk. */ public class GlowChunkSnapshot implements ChunkSnapshot { private final int x, z; private final String world; private final long time; private final ChunkSection[] sections; private final byte[] height; private final double[] temp, humid; private final byte[] biomes; public GlowChunkSnapshot(int x, int z, World world, ChunkSection[] sections, byte[] height, byte[] biomes, boolean svTemp) { this.x = x; this.z = z; this.world = world.getName(); this.time = world.getFullTime(); int numSections = sections != null ? sections.length : 0; this.sections = new ChunkSection[numSections]; for (int i = 0; i < numSections; ++i) { if (sections[i] != null) { this.sections[i] = sections[i].snapshot(); } } this.height = height; this.biomes = biomes; if (svTemp) { final int baseX = x << 4, baseZ = z << 4; temp = new double[16 * 16]; humid = new double[16 * 16]; for (int xx = 0; xx < 16; ++xx) { for (int zz = 0; zz < 16; ++zz) { temp[coordToIndex(xx, zz)] = world.getTemperature(baseX + xx, baseZ + zz); humid[coordToIndex(xx, zz)] = world.getHumidity(baseX + xx, baseZ + zz); } } } else { temp = humid = null; } } private ChunkSection getSection(int y) { int idx = y >> 4; if (idx < 0 || idx >= sections.length) { return null; } return sections[idx]; } /** * Get the ChunkSection array backing this snapshot. In general, it should not be modified. * @return The array of ChunkSections. */ public ChunkSection[] getRawSections() { return sections; } public int[] getRawHeightmap() { int[] result = new int[height.length]; for (int i = 0; i < result.length; ++i) { result[i] = height[i]; } return result; } public byte[] getRawBiomes() { return biomes; } @Override public int getX() { return x; } @Override public int getZ() { return z; } @Override public String getWorldName() { return world; } @Override public long getCaptureFullTime() { return time; } @Override public boolean isSectionEmpty(int sy) { return sy < 0 || sy >= sections.length || (sections[sy] == null); } @Override public int getBlockTypeId(int x, int y, int z) { ChunkSection section = getSection(y); return section == null ? 0 : section.types[section.index(x, y, z)] >> 4; } @Override public int getBlockData(int x, int y, int z) { ChunkSection section = getSection(y); return section == null ? 0 : section.types[section.index(x, y, z)] & 0xF; } @Override public int getBlockSkyLight(int x, int y, int z) { ChunkSection section = getSection(y); return section == null ? 15 : section.skyLight.get(section.index(x, y, z)); } @Override public int getBlockEmittedLight(int x, int y, int z) { ChunkSection section = getSection(y); return section == null ? 0 : section.blockLight.get(section.index(x, y, z)); } @Override public int getHighestBlockYAt(int x, int z) { return height[coordToIndex(x, z)]; } @Override public Biome getBiome(int x, int z) { return GlowBiome.getBiome(biomes[coordToIndex(x, z)]); } @Override public double getRawBiomeTemperature(int x, int z) { return temp[coordToIndex(x, z)]; } @Override public double getRawBiomeRainfall(int x, int z) { return humid[coordToIndex(x, z)]; } private int coordToIndex(int x, int z) { if (x < 0 || z < 0 || x >= GlowChunk.WIDTH || z >= GlowChunk.HEIGHT) throw new IndexOutOfBoundsException(); return z * GlowChunk.WIDTH + x; } public static class EmptySnapshot extends GlowChunkSnapshot { public EmptySnapshot(int x, int z, World world, boolean svBiome, boolean svTemp) { super(x, z, world, null, null, svBiome ? new byte[256] : null, svTemp); } @Override public int getBlockTypeId(int x, int y, int z) { return 0; } @Override public int getBlockData(int x, int y, int z) { return 0; } @Override public int getBlockSkyLight(int x, int y, int z) { return 15; } @Override public int getBlockEmittedLight(int x, int y, int z) { return 0; } @Override public int getHighestBlockYAt(int x, int z) { return 0; } } }