Add biome-based coloring option for surface map

This commit is contained in:
Mike Primm 2011-06-20 00:09:22 -05:00
parent 2bc9b410a6
commit edf7d4f5c8
16 changed files with 290 additions and 20 deletions

View File

@ -227,3 +227,16 @@ Locked Chest
95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255 95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Trap Door Trap Door
96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255 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

View File

@ -227,3 +227,15 @@ Locked Chest
95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255 95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Trap Door Trap Door
96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255 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

View File

@ -227,4 +227,16 @@ Locked Chest
95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255 95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Trap Door Trap Door
96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255 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

View File

@ -113,3 +113,15 @@
94 159 127 80 255 102 0 0 0 255 0 0 255 204 0 0 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 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 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

View File

@ -178,7 +178,14 @@ templates:
# background: "#000000" # background: "#000000"
# # Sets the icon to 'images/block_custom.png' # # Sets the icon to 'images/block_custom.png'
# icon: custom # 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 # - class: org.dynmap.kzedmap.HighlightTileRenderer
# prefix: ht # prefix: ht
# maximumheight: 127 # maximumheight: 127

View File

@ -8,19 +8,22 @@ import java.util.HashMap;
import java.util.Scanner; import java.util.Scanner;
import org.dynmap.debug.Debug; import org.dynmap.debug.Debug;
import org.bukkit.block.Biome;
public class ColorScheme { public class ColorScheme {
private static final HashMap<String, ColorScheme> cache = new HashMap<String, ColorScheme>(); private static final HashMap<String, ColorScheme> cache = new HashMap<String, ColorScheme>();
public String name; public String name;
/* Switch to arrays - faster than map */ /* Switch to arrays - faster than map */
public Color[][] colors; /* [blk-type][step] */ public final Color[][] colors; /* [blk-type][step] */
public Color[][][] datacolors; /* [bkt-type][blk-dat][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.name = name;
this.colors = colors; this.colors = colors;
this.datacolors = datacolors; this.datacolors = datacolors;
this.biomecolors = biomecolors;
} }
private static File getColorSchemeDirectory() { private static File getColorSchemeDirectory() {
@ -42,6 +45,7 @@ public class ColorScheme {
File colorSchemeFile = new File(getColorSchemeDirectory(), name + ".txt"); File colorSchemeFile = new File(getColorSchemeDirectory(), name + ".txt");
Color[][] colors = new Color[256][]; Color[][] colors = new Color[256][];
Color[][][] datacolors = new Color[256][][]; Color[][][] datacolors = new Color[256][][];
Color[][] biomecolors = new Color[Biome.values().length][];
InputStream stream; InputStream stream;
try { try {
Debug.debug("Loading colors from '" + colorSchemeFile + "'..."); Debug.debug("Loading colors from '" + colorSchemeFile + "'...");
@ -54,18 +58,38 @@ public class ColorScheme {
if (line.startsWith("#") || line.equals("")) { if (line.startsWith("#") || line.equals("")) {
continue; continue;
} }
/* Make parser less pedantic - tabs or spaces should be fine */
String[] split = line.split("\t"); 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) { if (split.length < 17) {
continue; continue;
} }
Integer id; Integer id;
Integer dat = null; Integer dat = null;
boolean isbiome = false;
int idx = split[0].indexOf(':'); int idx = split[0].indexOf(':');
if(idx > 0) { /* ID:data - data color */ if(idx > 0) { /* ID:data - data color */
id = new Integer(split[0].substring(0, idx)); id = new Integer(split[0].substring(0, idx));
dat = new Integer(split[0].substring(idx+1)); 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 { else {
id = new Integer(split[0]); id = new Integer(split[0]);
} }
@ -79,7 +103,11 @@ public class ColorScheme {
/* Blended color - for 'smooth' option on flat map */ /* 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); 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? */ Color[][] dcolor = datacolors[id]; /* Existing list? */
if(dcolor == null) { if(dcolor == null) {
dcolor = new Color[16][]; /* Make 16 index long list */ dcolor = new Color[16][]; /* Make 16 index long list */
@ -115,6 +143,6 @@ public class ColorScheme {
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Log.severe("Could not load colors '" + name + "' ('" + colorSchemeFile + "'): File not found.", 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);
} }
} }

View File

@ -180,8 +180,11 @@ public class MapManager {
} }
World w = world.world; World w = world.world;
/* Fetch chunk cache from server thread */ /* Fetch chunk cache from server thread */
List<DynmapChunk> requiredChunks = tile.getMap().getRequiredChunks(tile); MapType mt = tile.getMap();
MapChunkCache cache = createMapChunkCache(world, requiredChunks); List<DynmapChunk> requiredChunks = mt.getRequiredChunks(tile);
MapChunkCache cache = createMapChunkCache(world, requiredChunks, mt.isBlockTypeDataNeeded(),
mt.isHightestBlockYDataNeeded(), mt.isBiomeDataNeeded(),
mt.isRawBiomeDataNeeded());
if(cache == null) { if(cache == null) {
cleanup(); cleanup();
return; /* Cancelled/aborted */ 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 * 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<DynmapChunk> chunks) { public MapChunkCache createMapChunkCache(DynmapWorld w, List<DynmapChunk> chunks,
boolean blockdata, boolean highesty, boolean biome, boolean rawbiome) {
MapChunkCache c = null; MapChunkCache c = null;
try { try {
if(!use_legacy) if(!use_legacy)
@ -493,6 +497,9 @@ public class MapManager {
c.setHiddenFillStyle(w.hiddenchunkstyle); c.setHiddenFillStyle(w.hiddenchunkstyle);
} }
c.setChunks(w.world, chunks); c.setChunks(w.world, chunks);
if(c.setChunkDataTypes(blockdata, biome, highesty, rawbiome) == false)
Log.severe("CraftBukkit build does not support biome APIs");
synchronized(c) { synchronized(c) {
chunkloads.add(c); chunkloads.add(c);
try { try {

View File

@ -22,4 +22,10 @@ public abstract class MapType {
} }
public abstract String getName(); public abstract String getName();
public boolean isBiomeDataNeeded() { return false; }
public boolean isHightestBlockYDataNeeded() { return false; }
public boolean isRawBiomeDataNeeded() { return false; }
public boolean isBlockTypeDataNeeded() { return true; }
} }

View File

@ -117,6 +117,11 @@ public class FlatMap extends MapType {
return result; return result;
} }
@Override
public boolean isHightestBlockYDataNeeded() {
return true;
}
@Override @Override
public boolean render(MapChunkCache cache, MapTile tile, File outputFile) { public boolean render(MapChunkCache cache, MapTile tile, File outputFile) {
FlatMapTile t = (FlatMapTile) tile; FlatMapTile t = (FlatMapTile) tile;

View File

@ -11,6 +11,7 @@ import javax.imageio.ImageIO;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.World.Environment; import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
import org.dynmap.Client; import org.dynmap.Client;
import org.dynmap.Color; import org.dynmap.Color;
import org.dynmap.ColorScheme; import org.dynmap.ColorScheme;
@ -38,6 +39,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
protected int lightscale[]; /* scale skylight level (light = lightscale[skylight] */ 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 night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */
protected boolean transparency; /* Is transparency support active? */ protected boolean transparency; /* Is transparency support active? */
protected boolean biomecolored; /* Use biome for coloring */
@Override @Override
public String getName() { public String getName() {
return name; return name;
@ -81,7 +83,9 @@ public class DefaultTileRenderer implements MapTileRenderer {
colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme")); colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme"));
night_and_day = configuration.getBoolean("night-and-day", false); night_and_day = configuration.getBoolean("night-and-day", false);
transparency = configuration.getBoolean("transparency", true); /* Default on */ 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) { public boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile) {
World world = tile.getWorld(); World world = tile.getWorld();
@ -360,6 +364,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
MapIterator mapiter) { MapIterator mapiter) {
int lightlevel = 15; int lightlevel = 15;
int lightlevel_day = 15; int lightlevel_day = 15;
Biome bio = null;
result.setTransparent(); result.setTransparent();
if(result_day != null) if(result_day != null)
result_day.setTransparent(); result_day.setTransparent();
@ -384,6 +389,8 @@ public class DefaultTileRenderer implements MapTileRenderer {
if(colorScheme.datacolors[id] != null) { /* If data colored */ if(colorScheme.datacolors[id] != null) { /* If data colored */
data = mapiter.getBlockData(); data = mapiter.getBlockData();
} }
if(biomecolored)
bio = mapiter.getBiome();
if((shadowscale != null) && (mapiter.getY() < 127)) { if((shadowscale != null) && (mapiter.getY() < 127)) {
/* Find light level of previous chunk */ /* Find light level of previous chunk */
switch(seq) { switch(seq) {
@ -442,7 +449,13 @@ public class DefaultTileRenderer implements MapTileRenderer {
return; return;
} }
Color[] colors; 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]; colors = colorScheme.datacolors[id][data];
else else
colors = colorScheme.colors[id]; colors = colorScheme.colors[id];

View File

@ -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() { public String getName() {
return "KzedMap"; return "KzedMap";
} }

View File

@ -12,4 +12,6 @@ public interface MapTileRenderer {
boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile); boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile);
void buildClientConfiguration(JSONObject worldObject); void buildClientConfiguration(JSONObject worldObject);
boolean isBiomeDataNeeded();
} }

View File

@ -4,8 +4,11 @@ import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.ListIterator; import java.util.ListIterator;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import org.bukkit.ChunkSnapshot;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.block.Biome;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.dynmap.DynmapChunk; import org.dynmap.DynmapChunk;
import org.dynmap.Log; import org.dynmap.Log;
@ -68,6 +71,16 @@ public class LegacyMapChunkCache implements MapChunkCache {
public final int getBlockEmittedLight() { public final int getBlockEmittedLight() {
return snap.getBlockEmittedLight(x & 0xF, y, z & 0xF); 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() { public final void incrementX() {
x++; x++;
if((x & 0xF) == 0) { /* Next chunk? */ 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]; LegacyChunkSnapshot ss = snaparray[((x>>4) - x_min) + ((z>>4) - z_min) * x_dim];
return ss.getBlockEmittedLight(x & 0xF, y, z & 0xF); 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 * Get cache iterator
*/ */
@ -412,4 +435,10 @@ public class LegacyMapChunkCache implements MapChunkCache {
visible_limits = new ArrayList<VisibilityLimit>(); visible_limits = new ArrayList<VisibilityLimit>();
visible_limits.add(limit); 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;
}
} }

View File

@ -1,5 +1,7 @@
package org.dynmap.utils; package org.dynmap.utils;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome;
import java.util.List; import java.util.List;
import org.dynmap.DynmapChunk; import org.dynmap.DynmapChunk;
@ -16,6 +18,15 @@ public interface MapChunkCache {
* Set chunks to load, and world to load from * Set chunks to load, and world to load from
*/ */
void setChunks(World w, List<DynmapChunk> chunks); void setChunks(World w, List<DynmapChunk> 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 * Load chunks into cache
* @param maxToLoad - maximum number to load at once * @param maxToLoad - maximum number to load at once
@ -50,6 +61,18 @@ public interface MapChunkCache {
* Get emitted light level * Get emitted light level
*/ */
int getBlockEmittedLight(int x, int y, int z); 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 * Get cache iterator
*/ */

View File

@ -1,5 +1,7 @@
package org.dynmap.utils; package org.dynmap.utils;
import org.bukkit.block.Biome;
/** /**
* Iterator for traversing map chunk cache (base is for non-snapshot) * Iterator for traversing map chunk cache (base is for non-snapshot)
*/ */
@ -38,6 +40,18 @@ public interface MapIterator {
* @return emitted light level * @return emitted light level
*/ */
int getBlockEmittedLight(); 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 * Increment X of current position
*/ */

View File

@ -1,5 +1,6 @@
package org.dynmap.utils; package org.dynmap.utils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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 * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread
*/ */
public class NewMapChunkCache implements MapChunkCache { public class NewMapChunkCache implements MapChunkCache {
private static boolean init = false;
private static Method poppreservedchunk = null; private static Method poppreservedchunk = null;
private static Method getsnapshot2 = null;
private static Method getemptysnapshot = null;
private World w; private World w;
private List<DynmapChunk> chunks; private List<DynmapChunk> chunks;
private ListIterator<DynmapChunk> iterator; private ListIterator<DynmapChunk> iterator;
private int x_min, x_max, z_min, z_max; private int x_min, x_max, z_min, z_max;
private int x_dim; private int x_dim;
private boolean biome, biomeraw, highesty, blockdata;
private HiddenChunkStyle hidestyle = HiddenChunkStyle.FILL_AIR; private HiddenChunkStyle hidestyle = HiddenChunkStyle.FILL_AIR;
private List<VisibilityLimit> visible_limits = null; private List<VisibilityLimit> visible_limits = null;
@ -64,6 +69,15 @@ public class NewMapChunkCache implements MapChunkCache {
public final int getBlockEmittedLight() { public final int getBlockEmittedLight() {
return snap.getBlockEmittedLight(x & 0xF, y, z & 0xF); 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() { public final void incrementX() {
x++; x++;
if((x & 0xF) == 0) { /* Next chunk? */ if((x & 0xF) == 0) { /* Next chunk? */
@ -126,9 +140,6 @@ public class NewMapChunkCache implements MapChunkCache {
public int getX() { return 0; } public int getX() { return 0; }
public int getZ() { return 0; } public int getZ() { return 0; }
public String getWorldName() { return ""; } 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 long getCaptureFullTime() { return 0; }
public final int getBlockTypeId(int x, int y, int z) { 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) { public final int getHighestBlockYAt(int x, int z) {
return 0; 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;
}
} }
/** /**
@ -187,11 +207,35 @@ public class NewMapChunkCache implements MapChunkCache {
private static final PlainChunk STONE = new PlainChunk(1); private static final PlainChunk STONE = new PlainChunk(1);
private static final PlainChunk OCEAN = new PlainChunk(9); private static final PlainChunk OCEAN = new PlainChunk(9);
/** /**
* Construct empty cache * Construct empty cache
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" })
public NewMapChunkCache() { 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" }) @SuppressWarnings({ "unchecked", "rawtypes" })
public void setChunks(World w, List<DynmapChunk> chunks) { public void setChunks(World w, List<DynmapChunk> chunks) {
@ -266,6 +310,18 @@ public class NewMapChunkCache implements MapChunkCache {
} }
else { else {
Chunk c = w.getChunkAt(chunk.x, chunk.z); Chunk c = w.getChunkAt(chunk.x, chunk.z);
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(); ss = c.getChunkSnapshot();
} }
snaparray[(chunk.x-x_min) + (chunk.z - z_min)*x_dim] = ss; 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]; ChunkSnapshot ss = snaparray[((x>>4) - x_min) + ((z>>4) - z_min) * x_dim];
return ss.getBlockEmittedLight(x & 0xF, y, z & 0xF); 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 * Get cache iterator
*/ */
@ -390,4 +459,14 @@ public class NewMapChunkCache implements MapChunkCache {
visible_limits = new ArrayList<VisibilityLimit>(); visible_limits = new ArrayList<VisibilityLimit>();
visible_limits.add(limit); 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;
}
} }