diff --git a/configuration.txt b/configuration.txt
index c765f162..b02ad709 100644
--- a/configuration.txt
+++ b/configuration.txt
@@ -1,195 +1,197 @@
-# All paths in this configuration file are relative to Dynmap's data-folder: minecraft_server/plugins/dynmap/
-
-# Treat hiddenplayers.txt as a whitelist for players to be shown on the map? (Default false)
-display-whitelist: false
-
-# How often a tile gets rendered (in seconds).
-renderinterval: 1
-
-# Do render on main thread - may generate more server load, but safer and fixes broken tiles
-renderonsync: true
-
-render-triggers:
-# - chunkloaded
-# - playermove
-# - playerjoin
- - blockplaced
- - blockbreak
-
-# The path where the tile-files are placed.
-tilespath: web/tiles
-
-# The path where the web-files are located.
-webpath: web
-
-# The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access).
-webserver-bindaddress: 0.0.0.0
-
-# The TCP-port the webserver will listen on.
-webserver-port: 8123
-
-# Disables Webserver portion of Dynmap (Advanced users only)
-disable-webserver: false
-
-# Writes JSON to file in the webpath
-jsonfile: false
-
-# How often the json file gets written to(in seconds)
-jsonfile-interval: 1
-
-# Output player health for web usage
-health-in-json: false
-
-# Use timesliced fullrender - takes a bit longer, but much more polite for server
-timeslicerender: true
-
-# Period between tile renders for timesliced fullrender, in seconds
-timesliceinterval: 0.5
-
-# The maptypes Dynmap will use to render.
-worlds:
- - name: world
- maps:
- - class: org.dynmap.flat.FlatMap
- prefix: flat
- colorscheme: default
- - class: org.dynmap.kzedmap.KzedMap
- renderers:
- - class: org.dynmap.kzedmap.DefaultTileRenderer
- prefix: t
- maximumheight: 127
- colorscheme: default
- #- class: org.dynmap.kzedmap.HighlightTileRenderer
- # prefix: ht
- # maximumheight: 127
- # colorscheme: default
- # highlight: # For highlighting multiple block-types.
- # - 56 # Highlight diamond-ore
- # - 66 # Highlight minecart track
- # highlight: 56 # For highlighting a single block-type.
- - class: org.dynmap.kzedmap.CaveTileRenderer
- prefix: ct
- maximumheight: 127
- - name: nether
- maps:
- - class: org.dynmap.flat.FlatMap
- prefix: flat
- colorscheme: default
- - class: org.dynmap.kzedmap.KzedMap
- renderers:
- - class: org.dynmap.kzedmap.DefaultTileRenderer
- prefix: nt
- maximumheight: 127
- colorscheme: default
-
-web:
- # Handles the clientside updates differently only enable if using jsonfile
- jsonfile: false
-
- # Interval the browser should poll for updates.
- updaterate: 2000
-
- allowchat: true
- allowwebchat: true
- webchat-interval: 5
- # Set to true to enable HeroChat support
- enableherochat: false
- # Control which HeroChat channel messages from web are directed to
- herochatwebchannel: Global
- # Control which channels are monitored and reported to the web
- herochatchannels:
- - Global
- #- Trade
- #- Haggle
-
- showplayerfacesinmenu: true
-
- joinmessage: "%playername% joined"
- quitmessage: "%playername% quit"
- spammessage: "You may only chat once every %interval% seconds."
-
- components:
- - type: chat
- - type: chatballoon
- focuschatballoons: false
- - type: chatbox
- showplayerfaces: true
- messagettl: 5
- - type: playermarkers
- showplayerfaces: true
- showplayerhealth: false
- #- type: digitalclock
- - type: timeofdayclock
- showdigitalclock: true
- #showweather: true
- #- type: regions
- # name: WorldGuard
- # useworldpath: true
- # filename: regions.yml
- # basenode: regions
- # use3dregions: true
- # infowindow: '
%regionname% - %priority% (%parent%)
Owners %playerowners% %groupowners%
Members %playermembers% %groupmembers%
Flags
%flags%
'
- # regionstyle:
- # strokeColor: "#FF0000"
- # strokeOpacity: 0.8
- # strokeWeight: 3
- # fillColor: "#FF0000"
- # fillOpacity: 0.35
-
- defaultzoom: 0
- defaultworld: world
- worlds:
- - title: World
- name: world
- center:
- x: 0
- y: 64
- z: 0
- maps:
- - type: FlatMapType
- title: Flat
- name: flat
- prefix: flat
- - type: KzedMapType
- title: Surface
- name: surface
- prefix: t
- #- type: KzedMapType
- # title: Highlighted Map
- # name: highlight
- # prefix: ht
- - type: KzedMapType
- title: Cave
- name: cave
- prefix: ct
- - title: Nether
- name: nether
- center:
- x: 0
- y: 64
- z: 0
- maps:
- - type: FlatMapType
- title: Flat
- name: flat
- prefix: flat
- - type: KzedMapType
- title: Surface
- name: nether
- prefix: nt
- # Example:
- #- title: Other World # With what name the world is displayed.
- # name: world_other # The actual name of the world (equal to your directory-name).
- # maps:
- # - type: KzedMapType # The type (or perspective) of the map. At the moment, there are no others than KzedMapType.
- # title: Surface # The name of the map that will be displayed.
- # name: surface # The actual name of the map (should be unique for this world).
- # prefix: t # The prefix of the tile-files that are generated.
- # icon: images/block_other.png # Sets a custom icon for the map. (optional)
- # - type: KzedMapType
- # title: Cave
- # name: cave
- # prefix: ct
-# Enables debugging.
-#debuggers:
-# - class: org.dynmap.debug.LogDebugger
+# All paths in this configuration file are relative to Dynmap's data-folder: minecraft_server/plugins/dynmap/
+
+# Treat hiddenplayers.txt as a whitelist for players to be shown on the map? (Default false)
+display-whitelist: false
+
+# How often a tile gets rendered (in seconds).
+renderinterval: 1
+
+# Do render on main thread - may generate more server load, but safer and fixes broken tiles
+renderonsync: true
+
+render-triggers:
+# - chunkloaded
+# - playermove
+# - playerjoin
+ - blockplaced
+ - blockbreak
+
+# The path where the tile-files are placed.
+tilespath: web/tiles
+
+# The path where the web-files are located.
+webpath: web
+
+# The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access).
+webserver-bindaddress: 0.0.0.0
+
+# The TCP-port the webserver will listen on.
+webserver-port: 8123
+
+# Disables Webserver portion of Dynmap (Advanced users only)
+disable-webserver: false
+
+# Writes JSON to file in the webpath
+jsonfile: false
+
+# How often the json file gets written to(in seconds)
+jsonfile-interval: 1
+
+# Output player health for web usage
+health-in-json: false
+
+# Use timesliced fullrender - takes a bit longer, but much more polite for server
+timeslicerender: true
+
+# Period between tile renders for timesliced fullrender, in seconds
+timesliceinterval: 0.5
+
+# The maptypes Dynmap will use to render.
+worlds:
+ - name: world
+ maps:
+ - class: org.dynmap.flat.FlatMap
+ prefix: flat
+ colorscheme: default
+ - class: org.dynmap.kzedmap.KzedMap
+ renderers:
+ - class: org.dynmap.kzedmap.DefaultTileRenderer
+ prefix: t
+ maximumheight: 127
+ colorscheme: default
+ # Add shadows to world (based on top-down shadows from chunk data)
+ # shadowstrength: 1.0
+ #- class: org.dynmap.kzedmap.HighlightTileRenderer
+ # prefix: ht
+ # maximumheight: 127
+ # colorscheme: default
+ # highlight: # For highlighting multiple block-types.
+ # - 56 # Highlight diamond-ore
+ # - 66 # Highlight minecart track
+ # highlight: 56 # For highlighting a single block-type.
+ - class: org.dynmap.kzedmap.CaveTileRenderer
+ prefix: ct
+ maximumheight: 127
+ - name: nether
+ maps:
+ - class: org.dynmap.flat.FlatMap
+ prefix: flat
+ colorscheme: default
+ - class: org.dynmap.kzedmap.KzedMap
+ renderers:
+ - class: org.dynmap.kzedmap.DefaultTileRenderer
+ prefix: nt
+ maximumheight: 127
+ colorscheme: default
+
+web:
+ # Handles the clientside updates differently only enable if using jsonfile
+ jsonfile: false
+
+ # Interval the browser should poll for updates.
+ updaterate: 2000
+
+ allowchat: true
+ allowwebchat: true
+ webchat-interval: 5
+ # Set to true to enable HeroChat support
+ enableherochat: false
+ # Control which HeroChat channel messages from web are directed to
+ herochatwebchannel: Global
+ # Control which channels are monitored and reported to the web
+ herochatchannels:
+ - Global
+ #- Trade
+ #- Haggle
+
+ showplayerfacesinmenu: true
+
+ joinmessage: "%playername% joined"
+ quitmessage: "%playername% quit"
+ spammessage: "You may only chat once every %interval% seconds."
+
+ components:
+ - type: chat
+ - type: chatballoon
+ focuschatballoons: false
+ - type: chatbox
+ showplayerfaces: true
+ messagettl: 5
+ - type: playermarkers
+ showplayerfaces: true
+ showplayerhealth: false
+ #- type: digitalclock
+ - type: timeofdayclock
+ showdigitalclock: true
+ #showweather: true
+ #- type: regions
+ # name: WorldGuard
+ # useworldpath: true
+ # filename: regions.yml
+ # basenode: regions
+ # use3dregions: true
+ # infowindow: '%regionname% - %priority% (%parent%)
Owners %playerowners% %groupowners%
Members %playermembers% %groupmembers%
Flags
%flags%
'
+ # regionstyle:
+ # strokeColor: "#FF0000"
+ # strokeOpacity: 0.8
+ # strokeWeight: 3
+ # fillColor: "#FF0000"
+ # fillOpacity: 0.35
+
+ defaultzoom: 0
+ defaultworld: world
+ worlds:
+ - title: World
+ name: world
+ center:
+ x: 0
+ y: 64
+ z: 0
+ maps:
+ - type: FlatMapType
+ title: Flat
+ name: flat
+ prefix: flat
+ - type: KzedMapType
+ title: Surface
+ name: surface
+ prefix: t
+ #- type: KzedMapType
+ # title: Highlighted Map
+ # name: highlight
+ # prefix: ht
+ - type: KzedMapType
+ title: Cave
+ name: cave
+ prefix: ct
+ - title: Nether
+ name: nether
+ center:
+ x: 0
+ y: 64
+ z: 0
+ maps:
+ - type: FlatMapType
+ title: Flat
+ name: flat
+ prefix: flat
+ - type: KzedMapType
+ title: Surface
+ name: nether
+ prefix: nt
+ # Example:
+ #- title: Other World # With what name the world is displayed.
+ # name: world_other # The actual name of the world (equal to your directory-name).
+ # maps:
+ # - type: KzedMapType # The type (or perspective) of the map. At the moment, there are no others than KzedMapType.
+ # title: Surface # The name of the map that will be displayed.
+ # name: surface # The actual name of the map (should be unique for this world).
+ # prefix: t # The prefix of the tile-files that are generated.
+ # icon: images/block_other.png # Sets a custom icon for the map. (optional)
+ # - type: KzedMapType
+ # title: Cave
+ # name: cave
+ # prefix: ct
+# Enables debugging.
+#debuggers:
+# - class: org.dynmap.debug.LogDebugger
diff --git a/src/main/java/org/dynmap/MapChunkCache.java b/src/main/java/org/dynmap/MapChunkCache.java
index 1649e457..bd4efb10 100644
--- a/src/main/java/org/dynmap/MapChunkCache.java
+++ b/src/main/java/org/dynmap/MapChunkCache.java
@@ -89,8 +89,8 @@ public class MapChunkCache {
Object cc = gethandle.invoke(c);
byte[] buf = new byte[32768 + 16384 + 16384 + 16384]; /* Get big enough buffer for whole chunk */
getchunkdata.invoke(cc, buf, 0, 0, 0, 16, 128, 16, 0);
- snaparray[(chunk.x-x_min) + (chunk.z - z_min)*x_dim] =
- new CraftChunkSnapshot(chunk.x, chunk.z, buf);
+ CraftChunkSnapshot ss = new CraftChunkSnapshot(chunk.x, chunk.z, buf);
+ snaparray[(chunk.x-x_min) + (chunk.z - z_min)*x_dim] = ss;
} catch (Exception x) {
}
}
@@ -195,4 +195,19 @@ public class MapChunkCache {
return w.getHighestBlockYAt(x, z);
}
}
+ /* Get sky light level
+ */
+ public int getBlockSkyLight(int x, int y, int z) {
+ if(snaparray != null) {
+ CraftChunkSnapshot ss = snaparray[((x>>4) - x_min) + ((z>>4) - z_min) * x_dim];
+ if(ss == null) {
+ return 15;
+ }
+ else
+ return ss.getBlockSkyLight(x & 0xF, y, z & 0xF);
+ }
+ else {
+ return 15;
+ }
+ }
}
diff --git a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java b/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java
index f7d1efae..4c10b118 100644
--- a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java
+++ b/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java
@@ -29,6 +29,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
protected HashSet highlightBlocks = new HashSet();
protected Color highlightColor = new Color(255, 0, 0);
+ protected int shadowscale[]; /* index=skylight level, value = 256 * scaling value */
@Override
public String getName() {
return name;
@@ -42,6 +43,19 @@ public class DefaultTileRenderer implements MapTileRenderer {
if (maximumHeight > 127)
maximumHeight = 127;
}
+ o = configuration.get("shadowstrength");
+ if(o != null) {
+ double shadowweight = Double.parseDouble(String.valueOf(o));
+ if(shadowweight > 0.0) {
+ shadowscale = new int[16];
+ for(int i = 0; i < 16; i++) {
+ double v = 256.0 * (1.0 - (shadowweight * (15-i) / 15.0));
+ shadowscale[i] = (int)v;
+ if(shadowscale[i] > 256) shadowscale[i] = 256;
+ if(shadowscale[i] < 0) shadowscale[i] = 0;
+ }
+ }
+ }
colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme"));
}
@@ -210,9 +224,14 @@ public class DefaultTileRenderer implements MapTileRenderer {
new Client.Tile(zmtile.getFilename()));
}
-
protected void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result,
MapChunkCache cache) {
+ scan(world, x, y, z, seq, isnether, result, cache, 15);
+ }
+
+ private void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result,
+ MapChunkCache cache, int lightlevel) {
+ int newlightlevel = 15;
result.setTransparent();
for (;;) {
if (y < 0) {
@@ -234,6 +253,10 @@ public class DefaultTileRenderer implements MapTileRenderer {
if(colorScheme.datacolors[id] != null) { /* If data colored */
data = cache.getBlockData(x, y, z);
}
+ if(shadowscale != null) {
+ newlightlevel = cache.getBlockSkyLight(x, y, z); /* Remember this - light path for next block */
+ }
+
switch (seq) {
case 0:
x--;
@@ -268,16 +291,25 @@ public class DefaultTileRenderer implements MapTileRenderer {
if (c.getAlpha() == 255) {
/* it's opaque - the ray ends here */
result.setColor(c);
+ if(lightlevel < 15) { /* Not full light? */
+ shadowColor(result, lightlevel);
+ }
return;
}
/* this block is transparent, so recurse */
- scan(world, x, y, z, seq, isnether, result, cache);
+ scan(world, x, y, z, seq, isnether, result, cache, newlightlevel);
int cr = c.getRed();
int cg = c.getGreen();
int cb = c.getBlue();
int ca = c.getAlpha();
+ if(lightlevel < 15) {
+ int scale = shadowscale[lightlevel];
+ cr = (cr * scale) >> 8;
+ cg = (cg * scale) >> 8;
+ cb = (cb * scale) >> 8;
+ }
cr *= ca;
cg *= ca;
cb *= ca;
@@ -287,6 +319,15 @@ public class DefaultTileRenderer implements MapTileRenderer {
}
}
}
+ lightlevel = newlightlevel; /* Advance - next block uses last block's light */
}
}
+ private final void shadowColor(Color c, int lightlevel) {
+ int scale = shadowscale[lightlevel];
+ if(scale == 0)
+ c.setRGBA(0, 0, 0, c.getAlpha());
+ else if(scale < 256)
+ c.setRGBA((c.getRed() * scale) >> 8, (c.getGreen() * scale) >> 8,
+ (c.getBlue() * scale) >> 8, c.getAlpha());
+ }
}