diff --git a/src/main/java/org/dynmap/DynmapPlugin.java b/src/main/java/org/dynmap/DynmapPlugin.java index 87787ab8..f97f8744 100644 --- a/src/main/java/org/dynmap/DynmapPlugin.java +++ b/src/main/java/org/dynmap/DynmapPlugin.java @@ -87,6 +87,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { boolean swampshading = false; boolean waterbiomeshading = false; boolean fencejoin = false; + boolean bettergrass = false; public CompassMode compassmode = CompassMode.PRE19; private int config_hashcode; /* Used to signal need to reload web configuration (world changes, config update, etc) */ private int fullrenderplayerlimit; /* Number of online players that will cause fullrender processing to pause */ @@ -283,6 +284,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { compassmode = CompassMode.NEWROSE; else compassmode = CompassMode.PRE19; + /* Default better-grass */ + bettergrass = configuration.getBoolean("better-grass", false); /* Load full render processing player limit */ fullrenderplayerlimit = configuration.getInteger("fullrenderplayerlimit", 0); /* If we're persisting ids-by-ip, load it */ diff --git a/src/main/java/org/dynmap/MapManager.java b/src/main/java/org/dynmap/MapManager.java index bb40b4a8..c6c17877 100644 --- a/src/main/java/org/dynmap/MapManager.java +++ b/src/main/java/org/dynmap/MapManager.java @@ -1330,7 +1330,11 @@ public class MapManager { public boolean getFenceJoin() { return plug_in.fencejoin; } - + + public boolean getBetterGrass() { + return plug_in.bettergrass; + } + public CompassMode getCompassMode() { return plug_in.compassmode; } diff --git a/src/main/java/org/dynmap/hdmap/TexturePack.java b/src/main/java/org/dynmap/hdmap/TexturePack.java index fb54262e..2e089a29 100644 --- a/src/main/java/org/dynmap/hdmap/TexturePack.java +++ b/src/main/java/org/dynmap/hdmap/TexturePack.java @@ -21,6 +21,7 @@ import java.util.zip.ZipFile; import javax.imageio.ImageIO; +import org.bukkit.Material; import org.bukkit.block.Biome; import org.dynmap.Color; import org.dynmap.ConfigurationNode; @@ -81,7 +82,10 @@ public class TexturePack { /* Special tile index values */ private static final int BLOCKINDEX_BLANK = -1; + private static final int BLOCKINDEX_GRASS = 0; private static final int BLOCKINDEX_GRASSMASK = 38; + private static final int BLOCKINDEX_SNOW = 66; + private static final int BLOCKINDEX_SNOWSIDE = 68; private static final int BLOCKINDEX_PISTONSIDE = 108; private static final int BLOCKINDEX_GLASSPANETOP = 148; private static final int BLOCKINDEX_AIRFRAME = 158; @@ -1038,11 +1042,13 @@ public class TexturePack { } } + private static final int BLOCKID_GRASS = 2; + private static final int BLOCKID_SNOW = 78; /** * Read color for given subblock coordinate, with given block id and data and face */ public final void readColor(final HDPerspectiveState ps, final MapIterator mapiter, final Color rslt, final int blkid, final int lastblocktype, - final boolean biome_shaded, final boolean swamp_shaded, final boolean water_shaded) { + TexturePackHDShader.ShaderState ss) { int blkdata = ps.getBlockData(); HDTextureMap map = HDTextureMap.getMap(blkid, blkdata, ps.getBlockRenderData()); BlockStep laststep = ps.getLastBlockStep(); @@ -1164,17 +1170,42 @@ public class TexturePack { if(u > native_scale/2) u = native_scale/2; break; case COLORMOD_GRASSSIDE: + boolean do_grass_side = false; + boolean do_snow_side = false; + if(ss.do_better_grass) { + mapiter.unstepPosition(laststep); + if(mapiter.getBlockTypeID() == BLOCKID_SNOW) + do_snow_side = true; + if(mapiter.getBlockTypeIDAt(BlockStep.Y_MINUS) == BLOCKID_GRASS) + do_grass_side = true; + mapiter.stepPosition(laststep); + } + /* Check if snow above block */ - if(mapiter.getBlockTypeIDAt(BlockStep.Y_PLUS) == 78) { - texture = terrain_argb[68]; /* Snow block */ - textid = 68; + if(mapiter.getBlockTypeIDAt(BlockStep.Y_PLUS) == BLOCKID_SNOW) { + if(do_snow_side) { + texture = terrain_argb[BLOCKINDEX_SNOW]; /* Snow full side block */ + textid = BLOCKINDEX_SNOW; + } + else { + texture = terrain_argb[BLOCKINDEX_SNOWSIDE]; /* Snow block */ + textid = BLOCKINDEX_SNOWSIDE; + } + textop = 0; } else { /* Else, check the grass color overlay */ - int ovclr = terrain_argb[BLOCKINDEX_GRASSMASK][v*native_scale+u]; - if((ovclr & 0xFF000000) != 0) { /* Hit? */ - texture = terrain_argb[BLOCKINDEX_GRASSMASK]; /* Use it */ + if(do_grass_side) { + texture = terrain_argb[BLOCKINDEX_GRASS]; /* Grass block */ + textid = BLOCKINDEX_GRASS; textop = COLORMOD_GRASSTONED; /* Force grass toning */ } + else { + int ovclr = terrain_argb[BLOCKINDEX_GRASSMASK][v*native_scale+u]; + if((ovclr & 0xFF000000) != 0) { /* Hit? */ + texture = terrain_argb[BLOCKINDEX_GRASSMASK]; /* Use it */ + textop = COLORMOD_GRASSTONED; /* Force grass toning */ + } + } } break; case COLORMOD_CLEARINSIDE: @@ -1213,7 +1244,7 @@ public class TexturePack { li = imgs[IMG_FOLIAGECOLOR]; break; case COLORMOD_WATERTONED: - if(swamp_shaded && (mapiter.getBiome() == Biome.SWAMPLAND)) + if(ss.do_swamp_shading && (mapiter.getBiome() == Biome.SWAMPLAND)) clrmult = 0xFFE0FF70; break; case COLORMOD_BIRCHTONED: @@ -1227,13 +1258,13 @@ public class TexturePack { break; } if(li != null) { - if((li.argb == null) || (!biome_shaded)) { + if((li.argb == null) || (!ss.do_biome_shading)) { clrmult = li.trivial_color; } else { clrmult = biomeLookup(li.argb, li.width, mapiter.getRawBiomeRainfall(), mapiter.getRawBiomeTemperature()); } - if(swamp_shaded && (mapiter.getBiome() == Biome.SWAMPLAND)) + if(ss.do_swamp_shading && (mapiter.getBiome() == Biome.SWAMPLAND)) clrmult = (clrmult & 0xFF000000) | (((clrmult & 0x00FEFEFE) + 0x4E0E4E) / 2); } if((clrmult != -1) && (clrmult != 0)) { diff --git a/src/main/java/org/dynmap/hdmap/TexturePackHDShader.java b/src/main/java/org/dynmap/hdmap/TexturePackHDShader.java index 0590339f..719b5c22 100644 --- a/src/main/java/org/dynmap/hdmap/TexturePackHDShader.java +++ b/src/main/java/org/dynmap/hdmap/TexturePackHDShader.java @@ -18,6 +18,7 @@ public class TexturePackHDShader implements HDShader { private boolean biome_shaded; private boolean swamp_shaded; private boolean waterbiomeshaded; + private boolean bettergrass; public TexturePackHDShader(ConfigurationNode configuration) { tpname = configuration.getString("texturepack", "minecraft"); @@ -26,6 +27,7 @@ public class TexturePackHDShader implements HDShader { biome_shaded = configuration.getBoolean("biomeshaded", true); swamp_shaded = configuration.getBoolean("swampshaded", MapManager.mapman.getSwampShading()); waterbiomeshaded = configuration.getBoolean("waterbiomeshaded", MapManager.mapman.getWaterBiomeShading()); + bettergrass = configuration.getBoolean("better-grass", MapManager.mapman.getBetterGrass()); if(tp == null) { Log.severe("Error: shader '" + name + "' cannot load texture pack '" + tpname + "'"); } @@ -66,7 +68,7 @@ public class TexturePackHDShader implements HDShader { return name; } - private class OurShaderState implements HDShaderState { + class ShaderState implements HDShaderState { private Color color[]; private Color tmpcolor[]; private Color c; @@ -75,12 +77,13 @@ public class TexturePackHDShader implements HDShader { private TexturePack scaledtp; private HDLighting lighting; private int lastblkid; - private boolean do_biome_shading; - private boolean do_swamp_shading; - private boolean do_water_shading; + boolean do_biome_shading; + boolean do_swamp_shading; + boolean do_water_shading; + boolean do_better_grass; private boolean has_hit; - private OurShaderState(MapIterator mapiter, HDMap map, MapChunkCache cache) { + private ShaderState(MapIterator mapiter, HDMap map, MapChunkCache cache) { this.mapiter = mapiter; this.map = map; this.lighting = map.getLighting(); @@ -98,6 +101,7 @@ public class TexturePackHDShader implements HDShader { do_biome_shading = biome_shaded; // && (cache.getWorld().getEnvironment() == Environment.NORMAL); do_swamp_shading = do_biome_shading && swamp_shaded; do_water_shading = do_biome_shading && waterbiomeshaded; + do_better_grass = bettergrass; has_hit = false; } /** @@ -145,7 +149,7 @@ public class TexturePackHDShader implements HDShader { } /* Get color from textures */ - scaledtp.readColor(ps, mapiter, c, blocktype, lastblocktype, do_biome_shading, do_swamp_shading, do_water_shading); + scaledtp.readColor(ps, mapiter, c, blocktype, lastblocktype, ShaderState.this); if (c.getAlpha() > 0) { has_hit = true; @@ -231,7 +235,7 @@ public class TexturePackHDShader implements HDShader { * @return state object to use for all rays in tile */ public HDShaderState getStateInstance(HDMap map, MapChunkCache cache, MapIterator mapiter) { - return new OurShaderState(mapiter, map, cache); + return new ShaderState(mapiter, map, cache); } /* Add shader's contributions to JSON for map object */ diff --git a/src/main/resources/configuration.txt b/src/main/resources/configuration.txt index 4f8d8d0a..b076978e 100644 --- a/src/main/resources/configuration.txt +++ b/src/main/resources/configuration.txt @@ -182,6 +182,9 @@ enabletilehash: true # Optional - control rendering of fences (joining to blocks, as in 1.9+) - default is true for 1.9+, false for 1.8.x #fence-to-block-join: true +# Optional - enabled BetterGrass style rendering of grass and snow block sides +#better-grass: true + # Control loading of player faces (if set to false, skins are never fetched) #fetchskins: false