From edf7d4f5c85aa8eb2b3837a05b9f30d013bfd6a7 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Mon, 20 Jun 2011 00:09:22 -0500 Subject: [PATCH] Add biome-based coloring option for surface map --- colorschemes/default.txt | 13 +++ colorschemes/flames.txt | 12 +++ colorschemes/ovocean.txt | 12 +++ colorschemes/sk89q.txt | 14 ++- configuration.txt | 9 +- src/main/java/org/dynmap/ColorScheme.java | 44 +++++++-- src/main/java/org/dynmap/MapManager.java | 13 ++- src/main/java/org/dynmap/MapType.java | 6 ++ src/main/java/org/dynmap/flat/FlatMap.java | 5 + .../dynmap/kzedmap/DefaultTileRenderer.java | 15 ++- src/main/java/org/dynmap/kzedmap/KzedMap.java | 8 ++ .../org/dynmap/kzedmap/MapTileRenderer.java | 2 + .../org/dynmap/utils/LegacyMapChunkCache.java | 29 ++++++ .../java/org/dynmap/utils/MapChunkCache.java | 23 +++++ .../java/org/dynmap/utils/MapIterator.java | 14 +++ .../org/dynmap/utils/NewMapChunkCache.java | 91 +++++++++++++++++-- 16 files changed, 290 insertions(+), 20 deletions(-) diff --git a/colorschemes/default.txt b/colorschemes/default.txt index 21c93019..99af51cd 100644 --- a/colorschemes/default.txt +++ b/colorschemes/default.txt @@ -227,3 +227,16 @@ Locked Chest 95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255 Trap Door 96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255 +[RAINFOREST] 0 153 0 255 0 138 0 255 0 153 0 255 0 107 0 255 +[SWAMPLAND] 0 166 186 255 0 149 167 255 0 166 186 255 0 116 130 255 +[SEASONAL_FOREST] 0 189 84 255 0 170 76 255 0 189 84 255 0 132 59 255 +[FOREST] 151 207 176 255 136 186 158 255 151 207 176 255 106 145 123 255 +[SAVANNA] 192 220 192 255 173 198 173 255 192 220 192 255 134 154 134 255 +[SHRUBLAND] 255 255 153 255 230 230 138 255 255 255 153 255 179 179 107 255 +[TAIGA] 71 150 69 255 64 135 62 255 71 150 69 255 50 105 48 255 +[DESERT] 225 217 159 255 203 195 143 255 225 217 159 255 158 152 111 255 +[PLAINS] 238 200 27 255 214 180 24 255 238 200 27 255 167 140 19 255 +[ICE_DESERT] 181 181 181 255 163 163 163 255 181 181 181 255 127 127 127 255 +[TUNDRA] 255 255 255 255 230 230 230 255 255 255 255 255 179 179 179 255 +[HELL] 191 148 149 255 172 133 134 255 191 148 149 255 134 104 104 255 + diff --git a/colorschemes/flames.txt b/colorschemes/flames.txt index af440b79..51bfe752 100644 --- a/colorschemes/flames.txt +++ b/colorschemes/flames.txt @@ -227,3 +227,15 @@ Locked Chest 95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255 Trap Door 96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255 +[RAINFOREST] 0 153 0 255 0 138 0 255 0 153 0 255 0 107 0 255 +[SWAMPLAND] 0 166 186 255 0 149 167 255 0 166 186 255 0 116 130 255 +[SEASONAL_FOREST] 0 189 84 255 0 170 76 255 0 189 84 255 0 132 59 255 +[FOREST] 151 207 176 255 136 186 158 255 151 207 176 255 106 145 123 255 +[SAVANNA] 192 220 192 255 173 198 173 255 192 220 192 255 134 154 134 255 +[SHRUBLAND] 255 255 153 255 230 230 138 255 255 255 153 255 179 179 107 255 +[TAIGA] 71 150 69 255 64 135 62 255 71 150 69 255 50 105 48 255 +[DESERT] 225 217 159 255 203 195 143 255 225 217 159 255 158 152 111 255 +[PLAINS] 238 200 27 255 214 180 24 255 238 200 27 255 167 140 19 255 +[ICE_DESERT] 181 181 181 255 163 163 163 255 181 181 181 255 127 127 127 255 +[TUNDRA] 255 255 255 255 230 230 230 255 255 255 255 255 179 179 179 255 +[HELL] 191 148 149 255 172 133 134 255 191 148 149 255 134 104 104 255 diff --git a/colorschemes/ovocean.txt b/colorschemes/ovocean.txt index fd889dba..51ec8703 100644 --- a/colorschemes/ovocean.txt +++ b/colorschemes/ovocean.txt @@ -227,4 +227,16 @@ Locked Chest 95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255 Trap Door 96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255 +[RAINFOREST] 0 153 0 255 0 138 0 255 0 153 0 255 0 107 0 255 +[SWAMPLAND] 0 166 186 255 0 149 167 255 0 166 186 255 0 116 130 255 +[SEASONAL_FOREST] 0 189 84 255 0 170 76 255 0 189 84 255 0 132 59 255 +[FOREST] 151 207 176 255 136 186 158 255 151 207 176 255 106 145 123 255 +[SAVANNA] 192 220 192 255 173 198 173 255 192 220 192 255 134 154 134 255 +[SHRUBLAND] 255 255 153 255 230 230 138 255 255 255 153 255 179 179 107 255 +[TAIGA] 71 150 69 255 64 135 62 255 71 150 69 255 50 105 48 255 +[DESERT] 225 217 159 255 203 195 143 255 225 217 159 255 158 152 111 255 +[PLAINS] 238 200 27 255 214 180 24 255 238 200 27 255 167 140 19 255 +[ICE_DESERT] 181 181 181 255 163 163 163 255 181 181 181 255 127 127 127 255 +[TUNDRA] 255 255 255 255 230 230 230 255 255 255 255 255 179 179 179 255 +[HELL] 191 148 149 255 172 133 134 255 191 148 149 255 134 104 104 255 diff --git a/colorschemes/sk89q.txt b/colorschemes/sk89q.txt index 23854832..3613d508 100644 --- a/colorschemes/sk89q.txt +++ b/colorschemes/sk89q.txt @@ -112,4 +112,16 @@ 93 159 127 80 255 72 56 25 0 181 140 64 255 144 112 51 0 94 159 127 80 255 102 0 0 0 255 0 0 255 204 0 0 0 95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255 -96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255 \ No newline at end of file +96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255 +[RAINFOREST] 0 153 0 255 0 138 0 255 0 153 0 255 0 107 0 255 +[SWAMPLAND] 0 166 186 255 0 149 167 255 0 166 186 255 0 116 130 255 +[SEASONAL_FOREST] 0 189 84 255 0 170 76 255 0 189 84 255 0 132 59 255 +[FOREST] 151 207 176 255 136 186 158 255 151 207 176 255 106 145 123 255 +[SAVANNA] 192 220 192 255 173 198 173 255 192 220 192 255 134 154 134 255 +[SHRUBLAND] 255 255 153 255 230 230 138 255 255 255 153 255 179 179 107 255 +[TAIGA] 71 150 69 255 64 135 62 255 71 150 69 255 50 105 48 255 +[DESERT] 225 217 159 255 203 195 143 255 225 217 159 255 158 152 111 255 +[PLAINS] 238 200 27 255 214 180 24 255 238 200 27 255 167 140 19 255 +[ICE_DESERT] 181 181 181 255 163 163 163 255 181 181 181 255 127 127 127 255 +[TUNDRA] 255 255 255 255 230 230 230 255 255 255 255 255 179 179 179 255 +[HELL] 191 148 149 255 172 133 134 255 191 148 149 255 134 104 104 255 diff --git a/configuration.txt b/configuration.txt index 80fb53f8..762e3351 100644 --- a/configuration.txt +++ b/configuration.txt @@ -178,7 +178,14 @@ templates: # background: "#000000" # # Sets the icon to 'images/block_custom.png' # icon: custom - + # # Biome-based mapping + # - class: org.dynmap.kzedmap.DefaultTileRenderer + # name: biome + # title: "Biome" + # prefix: b + # maximumheight: 127 + # colorscheme: default + # biomecolored: true # - class: org.dynmap.kzedmap.HighlightTileRenderer # prefix: ht # maximumheight: 127 diff --git a/src/main/java/org/dynmap/ColorScheme.java b/src/main/java/org/dynmap/ColorScheme.java index 8b606eb6..87ac652b 100644 --- a/src/main/java/org/dynmap/ColorScheme.java +++ b/src/main/java/org/dynmap/ColorScheme.java @@ -8,19 +8,22 @@ import java.util.HashMap; import java.util.Scanner; import org.dynmap.debug.Debug; +import org.bukkit.block.Biome; public class ColorScheme { private static final HashMap cache = new HashMap(); public String name; /* Switch to arrays - faster than map */ - public Color[][] colors; /* [blk-type][step] */ - public Color[][][] datacolors; /* [bkt-type][blk-dat][step] */ + public final Color[][] colors; /* [blk-type][step] */ + public final Color[][][] datacolors; /* [bkt-type][blk-dat][step] */ + public final Color[][] biomecolors; /* [Biome.ordinal][step] */ - public ColorScheme(String name, Color[][] colors, Color[][][] datacolors) { + public ColorScheme(String name, Color[][] colors, Color[][][] datacolors, Color[][] biomecolors) { this.name = name; this.colors = colors; this.datacolors = datacolors; + this.biomecolors = biomecolors; } private static File getColorSchemeDirectory() { @@ -42,6 +45,7 @@ public class ColorScheme { File colorSchemeFile = new File(getColorSchemeDirectory(), name + ".txt"); Color[][] colors = new Color[256][]; Color[][][] datacolors = new Color[256][][]; + Color[][] biomecolors = new Color[Biome.values().length][]; InputStream stream; try { Debug.debug("Loading colors from '" + colorSchemeFile + "'..."); @@ -54,18 +58,38 @@ public class ColorScheme { if (line.startsWith("#") || line.equals("")) { continue; } - - String[] split = line.split("\t"); + /* Make parser less pedantic - tabs or spaces should be fine */ + String[] split = line.split("[\t ]"); + int cnt = 0; + for(String s: split) { if(s.length() > 0) cnt++; } + String[] nsplit = new String[cnt]; + cnt = 0; + for(String s: split) { if(s.length() > 0) { nsplit[cnt] = s; cnt++; } } + split = nsplit; if (split.length < 17) { continue; } Integer id; Integer dat = null; + boolean isbiome = false; int idx = split[0].indexOf(':'); if(idx > 0) { /* ID:data - data color */ id = new Integer(split[0].substring(0, idx)); dat = new Integer(split[0].substring(idx+1)); } + else if(split[0].charAt(0) == '[') { /* Biome color data */ + String bio = split[0].substring(1); + idx = bio.indexOf(']'); + if(idx >= 0) bio = bio.substring(0, idx); + isbiome = true; + id = -1; + for(Biome b : Biome.values()) { + if(b.toString().equalsIgnoreCase(bio)) { + id = b.ordinal(); + break; + } + } + } else { id = new Integer(split[0]); } @@ -78,8 +102,12 @@ public class ColorScheme { c[2] = new Color(Integer.parseInt(split[13]), Integer.parseInt(split[14]), Integer.parseInt(split[15]), Integer.parseInt(split[16])); /* Blended color - for 'smooth' option on flat map */ c[4] = new Color((c[0].getRed()+c[2].getRed())/2, (c[0].getGreen()+c[2].getGreen())/2, (c[0].getBlue()+c[2].getBlue())/2, (c[0].getAlpha()+c[2].getAlpha())/2); - - if(dat != null) { + + if(isbiome) { + if((id >= 0) && (id < biomecolors.length)) + biomecolors[id] = c; + } + else if(dat != null) { Color[][] dcolor = datacolors[id]; /* Existing list? */ if(dcolor == null) { dcolor = new Color[16][]; /* Make 16 index long list */ @@ -115,6 +143,6 @@ public class ColorScheme { } catch (FileNotFoundException e) { Log.severe("Could not load colors '" + name + "' ('" + colorSchemeFile + "'): File not found.", e); } - return new ColorScheme(name, colors, datacolors); + return new ColorScheme(name, colors, datacolors, biomecolors); } } diff --git a/src/main/java/org/dynmap/MapManager.java b/src/main/java/org/dynmap/MapManager.java index 36054875..be548053 100644 --- a/src/main/java/org/dynmap/MapManager.java +++ b/src/main/java/org/dynmap/MapManager.java @@ -180,8 +180,11 @@ public class MapManager { } World w = world.world; /* Fetch chunk cache from server thread */ - List requiredChunks = tile.getMap().getRequiredChunks(tile); - MapChunkCache cache = createMapChunkCache(world, requiredChunks); + MapType mt = tile.getMap(); + List requiredChunks = mt.getRequiredChunks(tile); + MapChunkCache cache = createMapChunkCache(world, requiredChunks, mt.isBlockTypeDataNeeded(), + mt.isHightestBlockYDataNeeded(), mt.isBiomeDataNeeded(), + mt.isRawBiomeDataNeeded()); if(cache == null) { cleanup(); return; /* Cancelled/aborted */ @@ -476,7 +479,8 @@ public class MapManager { /** * Render processor helper - used by code running on render threads to request chunk snapshot cache from server/sync thread */ - public MapChunkCache createMapChunkCache(final DynmapWorld w, final List chunks) { + public MapChunkCache createMapChunkCache(DynmapWorld w, List chunks, + boolean blockdata, boolean highesty, boolean biome, boolean rawbiome) { MapChunkCache c = null; try { if(!use_legacy) @@ -493,6 +497,9 @@ public class MapManager { c.setHiddenFillStyle(w.hiddenchunkstyle); } c.setChunks(w.world, chunks); + if(c.setChunkDataTypes(blockdata, biome, highesty, rawbiome) == false) + Log.severe("CraftBukkit build does not support biome APIs"); + synchronized(c) { chunkloads.add(c); try { diff --git a/src/main/java/org/dynmap/MapType.java b/src/main/java/org/dynmap/MapType.java index 3aa68b19..e5c0c979 100644 --- a/src/main/java/org/dynmap/MapType.java +++ b/src/main/java/org/dynmap/MapType.java @@ -22,4 +22,10 @@ public abstract class MapType { } public abstract String getName(); + + public boolean isBiomeDataNeeded() { return false; } + public boolean isHightestBlockYDataNeeded() { return false; } + public boolean isRawBiomeDataNeeded() { return false; } + public boolean isBlockTypeDataNeeded() { return true; } + } diff --git a/src/main/java/org/dynmap/flat/FlatMap.java b/src/main/java/org/dynmap/flat/FlatMap.java index c003415f..4a12b507 100644 --- a/src/main/java/org/dynmap/flat/FlatMap.java +++ b/src/main/java/org/dynmap/flat/FlatMap.java @@ -117,6 +117,11 @@ public class FlatMap extends MapType { return result; } + @Override + public boolean isHightestBlockYDataNeeded() { + return true; + } + @Override public boolean render(MapChunkCache cache, MapTile tile, File outputFile) { FlatMapTile t = (FlatMapTile) tile; diff --git a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java b/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java index d7628a33..6f15a6ef 100644 --- a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java +++ b/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java @@ -11,6 +11,7 @@ import javax.imageio.ImageIO; import org.bukkit.World; import org.bukkit.World.Environment; +import org.bukkit.block.Biome; import org.dynmap.Client; import org.dynmap.Color; import org.dynmap.ColorScheme; @@ -38,6 +39,7 @@ public class DefaultTileRenderer implements MapTileRenderer { protected int lightscale[]; /* scale skylight level (light = lightscale[skylight] */ protected boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */ protected boolean transparency; /* Is transparency support active? */ + protected boolean biomecolored; /* Use biome for coloring */ @Override public String getName() { return name; @@ -81,7 +83,9 @@ public class DefaultTileRenderer implements MapTileRenderer { colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme")); night_and_day = configuration.getBoolean("night-and-day", false); transparency = configuration.getBoolean("transparency", true); /* Default on */ + biomecolored = configuration.getBoolean("biomecolored", false); } + public boolean isBiomeDataNeeded() { return biomecolored; } public boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile) { World world = tile.getWorld(); @@ -360,6 +364,7 @@ public class DefaultTileRenderer implements MapTileRenderer { MapIterator mapiter) { int lightlevel = 15; int lightlevel_day = 15; + Biome bio = null; result.setTransparent(); if(result_day != null) result_day.setTransparent(); @@ -384,6 +389,8 @@ public class DefaultTileRenderer implements MapTileRenderer { if(colorScheme.datacolors[id] != null) { /* If data colored */ data = mapiter.getBlockData(); } + if(biomecolored) + bio = mapiter.getBiome(); if((shadowscale != null) && (mapiter.getY() < 127)) { /* Find light level of previous chunk */ switch(seq) { @@ -442,7 +449,13 @@ public class DefaultTileRenderer implements MapTileRenderer { return; } Color[] colors; - if(data != 0) + if(biomecolored) { + if(bio != null) + colors = colorScheme.biomecolors[bio.ordinal()]; + else + colors = null; + } + else if(data != 0) colors = colorScheme.datacolors[id][data]; else colors = colorScheme.colors[id]; diff --git a/src/main/java/org/dynmap/kzedmap/KzedMap.java b/src/main/java/org/dynmap/kzedmap/KzedMap.java index c7183092..3e2876c9 100644 --- a/src/main/java/org/dynmap/kzedmap/KzedMap.java +++ b/src/main/java/org/dynmap/kzedmap/KzedMap.java @@ -310,6 +310,14 @@ public class KzedMap extends MapType { } } + public boolean isBiomeDataNeeded() { + for(MapTileRenderer r : renderers) { + if(r.isBiomeDataNeeded()) + return true; + } + return false; + } + public String getName() { return "KzedMap"; } diff --git a/src/main/java/org/dynmap/kzedmap/MapTileRenderer.java b/src/main/java/org/dynmap/kzedmap/MapTileRenderer.java index 96f42c0e..eb7da52d 100644 --- a/src/main/java/org/dynmap/kzedmap/MapTileRenderer.java +++ b/src/main/java/org/dynmap/kzedmap/MapTileRenderer.java @@ -12,4 +12,6 @@ public interface MapTileRenderer { boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile); void buildClientConfiguration(JSONObject worldObject); + + boolean isBiomeDataNeeded(); } diff --git a/src/main/java/org/dynmap/utils/LegacyMapChunkCache.java b/src/main/java/org/dynmap/utils/LegacyMapChunkCache.java index 054ce8dd..8c139667 100644 --- a/src/main/java/org/dynmap/utils/LegacyMapChunkCache.java +++ b/src/main/java/org/dynmap/utils/LegacyMapChunkCache.java @@ -4,8 +4,11 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.ListIterator; import java.lang.reflect.Field; + +import org.bukkit.ChunkSnapshot; import org.bukkit.World; import org.bukkit.Chunk; +import org.bukkit.block.Biome; import org.bukkit.entity.Entity; import org.dynmap.DynmapChunk; import org.dynmap.Log; @@ -68,6 +71,16 @@ public class LegacyMapChunkCache implements MapChunkCache { public final int getBlockEmittedLight() { return snap.getBlockEmittedLight(x & 0xF, y, z & 0xF); } + public Biome getBiome() { + return null; + } + public double getRawBiomeTemperature() { + return 0.0; + } + public double getRawBiomeRainfall() { + return 0.0; + } + public final void incrementX() { x++; if((x & 0xF) == 0) { /* Next chunk? */ @@ -377,6 +390,16 @@ public class LegacyMapChunkCache implements MapChunkCache { LegacyChunkSnapshot ss = snaparray[((x>>4) - x_min) + ((z>>4) - z_min) * x_dim]; return ss.getBlockEmittedLight(x & 0xF, y, z & 0xF); } + public Biome getBiome(int x, int z) { + return null; + } + public double getRawBiomeTemperature(int x, int z) { + return 0.0; + } + public double getRawBiomeRainfall(int x, int z) { + return 0.0; + } + /** * Get cache iterator */ @@ -412,4 +435,10 @@ public class LegacyMapChunkCache implements MapChunkCache { visible_limits = new ArrayList(); visible_limits.add(limit); } + @Override + public boolean setChunkDataTypes(boolean blockdata, boolean biome, boolean highestblocky, boolean rawbiome) { + if(biome || rawbiome) /* Legacy doesn't support these */ + return false; + return true; + } } diff --git a/src/main/java/org/dynmap/utils/MapChunkCache.java b/src/main/java/org/dynmap/utils/MapChunkCache.java index 226cfdb5..dc1ec80b 100644 --- a/src/main/java/org/dynmap/utils/MapChunkCache.java +++ b/src/main/java/org/dynmap/utils/MapChunkCache.java @@ -1,5 +1,7 @@ package org.dynmap.utils; import org.bukkit.World; +import org.bukkit.block.Biome; + import java.util.List; import org.dynmap.DynmapChunk; @@ -16,6 +18,15 @@ public interface MapChunkCache { * Set chunks to load, and world to load from */ void setChunks(World w, List chunks); + /** + * Set chunk data type needed + * @param blockdata - need block type and data for chunk + * @param biome - need biome data + * @param highestblocky - need highest-block-y data + * @param rawbiome - need raw biome temp/rain data + * @return true if all data types can be retrieved, false if not + */ + boolean setChunkDataTypes(boolean blockdata, boolean biome, boolean highestblocky, boolean rawbiome); /** * Load chunks into cache * @param maxToLoad - maximum number to load at once @@ -50,6 +61,18 @@ public interface MapChunkCache { * Get emitted light level */ int getBlockEmittedLight(int x, int y, int z); + /** + * Get biome at coordinates + */ + public Biome getBiome(int x, int z); + /** + * Get raw temperature data (0.0-1.0) + */ + public double getRawBiomeTemperature(int x, int z); + /** + * Get raw rainfall data (0.0-1.0) + */ + public double getRawBiomeRainfall(int x, int z); /** * Get cache iterator */ diff --git a/src/main/java/org/dynmap/utils/MapIterator.java b/src/main/java/org/dynmap/utils/MapIterator.java index ce20d20b..d8bba2da 100644 --- a/src/main/java/org/dynmap/utils/MapIterator.java +++ b/src/main/java/org/dynmap/utils/MapIterator.java @@ -1,5 +1,7 @@ package org.dynmap.utils; +import org.bukkit.block.Biome; + /** * Iterator for traversing map chunk cache (base is for non-snapshot) */ @@ -38,6 +40,18 @@ public interface MapIterator { * @return emitted light level */ int getBlockEmittedLight(); + /** + * Get biome at coordinates + */ + public Biome getBiome(); + /** + * Get raw temperature data (0.0-1.0) + */ + public double getRawBiomeTemperature(); + /** + * Get raw rainfall data (0.0-1.0) + */ + public double getRawBiomeRainfall(); /** * Increment X of current position */ diff --git a/src/main/java/org/dynmap/utils/NewMapChunkCache.java b/src/main/java/org/dynmap/utils/NewMapChunkCache.java index 1c666696..0e347488 100644 --- a/src/main/java/org/dynmap/utils/NewMapChunkCache.java +++ b/src/main/java/org/dynmap/utils/NewMapChunkCache.java @@ -1,5 +1,6 @@ package org.dynmap.utils; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; @@ -17,13 +18,17 @@ import org.dynmap.Log; * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread */ public class NewMapChunkCache implements MapChunkCache { + private static boolean init = false; private static Method poppreservedchunk = null; + private static Method getsnapshot2 = null; + private static Method getemptysnapshot = null; private World w; private List chunks; private ListIterator iterator; private int x_min, x_max, z_min, z_max; private int x_dim; + private boolean biome, biomeraw, highesty, blockdata; private HiddenChunkStyle hidestyle = HiddenChunkStyle.FILL_AIR; private List visible_limits = null; @@ -64,6 +69,15 @@ public class NewMapChunkCache implements MapChunkCache { public final int getBlockEmittedLight() { return snap.getBlockEmittedLight(x & 0xF, y, z & 0xF); } + public Biome getBiome() { + return snap.getBiome(x & 0xF, z & 0xF); + } + public double getRawBiomeTemperature() { + return snap.getRawBiomeTemperature(x & 0xf, z & 0xf); + } + public double getRawBiomeRainfall() { + return snap.getRawBiomeRainfall(x & 0xf, z & 0xf); + } public final void incrementX() { x++; if((x & 0xF) == 0) { /* Next chunk? */ @@ -126,9 +140,6 @@ public class NewMapChunkCache implements MapChunkCache { public int getX() { return 0; } public int getZ() { return 0; } public String getWorldName() { return ""; } - public Biome getBiome(int x, int z) { return null; } - public double getRawBiomeTemperature(int x, int z) { return 0.0; } - public double getRawBiomeRainfall(int x, int z) { return 0.0; } public long getCaptureFullTime() { return 0; } public final int getBlockTypeId(int x, int y, int z) { @@ -146,6 +157,15 @@ public class NewMapChunkCache implements MapChunkCache { public final int getHighestBlockYAt(int x, int z) { return 0; } + public Biome getBiome(int x, int z) { + return null; + } + public double getRawBiomeTemperature(int x, int z) { + return 0.0; + } + public double getRawBiomeRainfall(int x, int z) { + return 0.0; + } } /** @@ -186,12 +206,36 @@ public class NewMapChunkCache implements MapChunkCache { private static final EmptyChunk EMPTY = new EmptyChunk(); private static final PlainChunk STONE = new PlainChunk(1); private static final PlainChunk OCEAN = new PlainChunk(9); - - + /** * Construct empty cache */ + @SuppressWarnings({ "rawtypes", "unchecked" }) public NewMapChunkCache() { + if(!init) { + /* Get CraftWorld.popPreservedChunk(x,z) - reduces memory bloat from map traversals (optional) */ + try { + Class c = Class.forName("org.bukkit.craftbukkit.CraftWorld"); + poppreservedchunk = c.getDeclaredMethod("popPreservedChunk", new Class[] { int.class, int.class }); + /* getEmptyChunkSnapshot(int x, int z, boolean includeBiome, boolean includeBiomeTempRain) */ + getemptysnapshot = c.getDeclaredMethod("getEmptyChunkSnapshot", new Class[] { int.class, int.class, + boolean.class, boolean.class }); + } catch (ClassNotFoundException cnfx) { + } catch (NoSuchMethodException nsmx) { + } + /* Get CraftChunk.getChunkSnapshot(boolean,boolean,boolean) */ + try { + Class c = Class.forName("org.bukkit.craftbukkit.CraftChunk"); + getsnapshot2 = c.getDeclaredMethod("getChunkSnapshot", new Class[] { boolean.class, boolean.class, boolean.class }); + } catch (ClassNotFoundException cnfx) { + } catch (NoSuchMethodException nsmx) { + } + if(getsnapshot2 != null) + Log.info("Biome data support is enabled"); + else + Log.info("Biome data support is disabled"); + init = true; + } } @SuppressWarnings({ "unchecked", "rawtypes" }) public void setChunks(World w, List chunks) { @@ -266,7 +310,19 @@ public class NewMapChunkCache implements MapChunkCache { } else { Chunk c = w.getChunkAt(chunk.x, chunk.z); - ss = c.getChunkSnapshot(); + if(getsnapshot2 != null) { + try { + if(blockdata || highesty) + ss = (ChunkSnapshot)getsnapshot2.invoke(c, highesty, biome, biomeraw); + else + ss = (ChunkSnapshot)getemptysnapshot.invoke(w, chunk.x, chunk.z, biome, biomeraw); + } catch (InvocationTargetException itx) { + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } + } + else + ss = c.getChunkSnapshot(); } snaparray[(chunk.x-x_min) + (chunk.z - z_min)*x_dim] = ss; } @@ -355,6 +411,19 @@ public class NewMapChunkCache implements MapChunkCache { ChunkSnapshot ss = snaparray[((x>>4) - x_min) + ((z>>4) - z_min) * x_dim]; return ss.getBlockEmittedLight(x & 0xF, y, z & 0xF); } + public Biome getBiome(int x, int z) { + ChunkSnapshot ss = snaparray[((x>>4) - x_min) + ((z>>4) - z_min) * x_dim]; + return ss.getBiome(x & 0xF, z & 0xF); + } + public double getRawBiomeTemperature(int x, int z) { + ChunkSnapshot ss = snaparray[((x>>4) - x_min) + ((z>>4) - z_min) * x_dim]; + return ss.getRawBiomeTemperature(x & 0xF, z & 0xF); + } + public double getRawBiomeRainfall(int x, int z) { + ChunkSnapshot ss = snaparray[((x>>4) - x_min) + ((z>>4) - z_min) * x_dim]; + return ss.getRawBiomeRainfall(x & 0xF, z & 0xF); + } + /** * Get cache iterator */ @@ -390,4 +459,14 @@ public class NewMapChunkCache implements MapChunkCache { visible_limits = new ArrayList(); visible_limits.add(limit); } + @Override + public boolean setChunkDataTypes(boolean blockdata, boolean biome, boolean highestblocky, boolean rawbiome) { + if((getsnapshot2 == null) && (biome || rawbiome)) + return false; + this.biome = biome; + this.biomeraw = rawbiome; + this.highesty = highestblocky; + this.blockdata = blockdata; + return true; + } }