diff --git a/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/FluidStateRenderer.java b/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/FluidStateRenderer.java index 9ea5f0f4..029c4979 100644 --- a/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/FluidStateRenderer.java +++ b/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/FluidStateRenderer.java @@ -30,7 +30,7 @@ public class FluidStateRenderer extends CustomRenderer { // Create meshes for flat topped blocks for (int i = 0; i < 8; i++) { list.clear(); - CustomRenderer.addBox(rpf, list, 0.0, 1.0, 0.0, 0.875 - (0.12 * i), 0.0, 1.0, still_patches); + CustomRenderer.addBox(rpf, list, 0.0, 1.0, 0.0, 1.0 - ((i + 1) / 9.0), 0.0, 1.0, still_patches); flat_meshes[i] = list.toArray(new RenderPatch[list.size()]); } list.clear(); @@ -44,20 +44,57 @@ public class FluidStateRenderer extends CustomRenderer { public int getMaximumTextureCount() { return 2; } - + + private DynmapBlockState getFluidState(MapDataContext ctx, int dx, int dy, int dz) { + DynmapBlockState bs; + if ((dx == 0) && (dy == 0) && (dz == 0)) { + bs = ctx.getBlockType(); + } + else { + bs = ctx.getBlockTypeAt(dx, dy, dz); + } + DynmapBlockState fbs = bs.getLiquidState(); + return (fbs != null) ? fbs : bs; + } + + private double getCornerHeight(DynmapBlockState b0, DynmapBlockState b1, DynmapBlockState b2, DynmapBlockState b3, + DynmapBlockState u0, DynmapBlockState u1, DynmapBlockState u2, DynmapBlockState u3) { + // If any above blocks are match, return full height + if (b0.matchingBaseState(u0) || b0.matchingBaseState(u1) || b0.matchingBaseState(u2) || b0.matchingBaseState(u3)) { + return 1.0; + } + return 0; + } + + @Override public RenderPatch[] getRenderPatchList(MapDataContext ctx) { - DynmapBlockState bs = ctx.getBlockType(); - DynmapBlockState fbs = bs.getLiquidState(); - if (fbs == null) - fbs = bs; - int idx = fbs.stateIndex; - if ((idx == 0) || (idx >= 8)) { - DynmapBlockState up = ctx.getBlockTypeAt(0, 1, 0); - if (up.isWaterFilled()) { - return full_mesh; - } - } + DynmapBlockState bs_0_0_0 = getFluidState(ctx, 0, 0, 0); // Get own state + // Check above block - if matching fluid, block will be full + DynmapBlockState bs_0_1_0 = getFluidState(ctx, 0, 1, 0); + if (bs_0_1_0.matchingBaseState(bs_0_0_0)) { + return full_mesh; + } + // Get other above blocks + DynmapBlockState bs_0_1_1 = getFluidState(ctx, 0, 1, 1); + DynmapBlockState bs_1_1_0 = getFluidState(ctx, 1, 1, 0); + DynmapBlockState bs_1_1_1 = getFluidState(ctx, 1, 1, 1); + DynmapBlockState bs_0_1_n1 = getFluidState(ctx, 0, 1, -1); + DynmapBlockState bs_n1_1_0 = getFluidState(ctx, -1, 1, 0); + DynmapBlockState bs_n1_1_n1 = getFluidState(ctx, -1, 1, -1); + DynmapBlockState bs_1_1_n1 = getFluidState(ctx, 1, 1, -1); + DynmapBlockState bs_n1_1_1 = getFluidState(ctx, -1, 1, 1); + // Get other neighbors + DynmapBlockState bs_0_0_1 = getFluidState(ctx, 0, 0, 1); + DynmapBlockState bs_1_0_0 = getFluidState(ctx, 1, 0, 0); + DynmapBlockState bs_1_0_1 = getFluidState(ctx, 1, 0, 1); + DynmapBlockState bs_0_0_n1 = getFluidState(ctx, 0, 0, -1); + DynmapBlockState bs_n1_0_0 = getFluidState(ctx, -1, 0, 0); + DynmapBlockState bs_n1_0_n1 = getFluidState(ctx, -1, 0, -1); + DynmapBlockState bs_1_0_n1 = getFluidState(ctx, 1, 0, -1); + DynmapBlockState bs_n1_0_1 = getFluidState(ctx, -1, 0, 1); + // Get each corner height + int idx = bs_0_0_0.stateIndex; return (idx < 8) ? flat_meshes[idx] : flat_meshes[0]; } } diff --git a/DynmapCoreAPI/src/main/java/org/dynmap/renderer/DynmapBlockState.java b/DynmapCoreAPI/src/main/java/org/dynmap/renderer/DynmapBlockState.java index 2d5bfd26..4ab2ef36 100644 --- a/DynmapCoreAPI/src/main/java/org/dynmap/renderer/DynmapBlockState.java +++ b/DynmapCoreAPI/src/main/java/org/dynmap/renderer/DynmapBlockState.java @@ -35,6 +35,7 @@ public class DynmapBlockState { private static int MATCH_GRASS = 1 << 4; private static int MATCH_WATERLOGGED = 1 << 5; private static int MATCH_LEAVES = 1 << 6; + private static int MATCH_SOLID = 1 << 7; // Map of base blocks by name private static HashMap blocksByName = new HashMap(); @@ -331,6 +332,18 @@ public class DynmapBlockState { } return null; } + /** + * Test if block is solid + */ + public boolean isSolid() { + return (matchflags & MATCH_SOLID) != 0; + } + /** + * Set to solid + */ + public void setSolid() { + matchflags |= MATCH_SOLID; + } /** * To printable string */ diff --git a/bukkit-helper-113-1/src/main/java/org/dynmap/bukkit/helper/v113_1/BukkitVersionHelperSpigot113_1.java b/bukkit-helper-113-1/src/main/java/org/dynmap/bukkit/helper/v113_1/BukkitVersionHelperSpigot113_1.java index 7ab7fdfa..2f0dd5a8 100644 --- a/bukkit-helper-113-1/src/main/java/org/dynmap/bukkit/helper/v113_1/BukkitVersionHelperSpigot113_1.java +++ b/bukkit-helper-113-1/src/main/java/org/dynmap/bukkit/helper/v113_1/BukkitVersionHelperSpigot113_1.java @@ -139,6 +139,9 @@ public class BukkitVersionHelperSpigot113_1 extends BukkitVersionHelperCB { if (bd.getBlock() instanceof BlockLogAbstract) { bs.setLog(); } + if (bd.getMaterial().isSolid()) { + bs.setSolid(); + } dataToState.put(bd, bs); lastBlockState.put(bname, (lastbs == null) ? bs : lastbs); Log.verboseinfo(i + ": blk=" + bname + ", idx=" + idx + ", state=" + sb + ", waterlogged=" + bs.isWaterlogged()); diff --git a/bukkit-helper-113/src/main/java/org/dynmap/bukkit/helper/v113/BukkitVersionHelperSpigot113.java b/bukkit-helper-113/src/main/java/org/dynmap/bukkit/helper/v113/BukkitVersionHelperSpigot113.java index 06ae3b6a..5fe8f7d2 100644 --- a/bukkit-helper-113/src/main/java/org/dynmap/bukkit/helper/v113/BukkitVersionHelperSpigot113.java +++ b/bukkit-helper-113/src/main/java/org/dynmap/bukkit/helper/v113/BukkitVersionHelperSpigot113.java @@ -133,6 +133,9 @@ public class BukkitVersionHelperSpigot113 extends BukkitVersionHelperCB { if (bd.getBlock() instanceof BlockLogAbstract) { bs.setLog(); } + if (bd.getMaterial().isSolid()) { + bs.setSolid(); + } dataToState.put(bd, bs); lastBlockState.put(bname, (lastbs == null) ? bs : lastbs); Log.verboseinfo(i + ": blk=" + bname + ", idx=" + idx + ", state=" + sb + ", waterlogged=" + bs.isWaterlogged()); diff --git a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitMaterial.java b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitMaterial.java new file mode 100644 index 00000000..3bb3e4c0 --- /dev/null +++ b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitMaterial.java @@ -0,0 +1,12 @@ +package org.dynmap.bukkit.helper; + +public class BukkitMaterial { + public final String name; + public final boolean isSolid; + private final boolean isLiquid; + public BukkitMaterial(String n, boolean sol, boolean liq) { + name = n; + isSolid = sol; + isLiquid = liq; + } +} diff --git a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java index 8db5408f..d693020f 100644 --- a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java +++ b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java @@ -130,11 +130,16 @@ public abstract class BukkitVersionHelper { * @param player */ public String getSkinURL(Player player) { return null; } + /** + * Get material map by block ID + */ + public abstract BukkitMaterial[] getMaterialList(); /** * Initialize block states (org.dynmap.blockstate.DynmapBlockState) */ public void initializeBlockStates() { String[] blkname = getBlockNames(); + BukkitMaterial[] blkmat = getMaterialList(); // Keep it simple for now - just assume 16 meta states for each stateByID = new DynmapBlockState[16*blkname.length]; Arrays.fill(stateByID, DynmapBlockState.AIR); @@ -148,9 +153,24 @@ public abstract class BukkitVersionHelper { if (!bn.equals(DynmapBlockState.AIR_BLOCK)) { DynmapBlockState basebs = new DynmapBlockState(null, 0, bn, "meta=0"); stateByID[i << 4] = basebs; + BukkitMaterial mat = blkmat[i]; for (int m = 1; m < 16; m++) { DynmapBlockState bs = new DynmapBlockState(basebs, m, bn, "meta=" + m); stateByID[(i << 4) + m] = bs; + if (mat != null) { + if (mat.name.equals("AIR")) { + bs.setAir(); + } + if (mat.name.equals("LEAVES")) { + bs.setLeaves(); + } + if (mat.name.equals("WOOD")) { + bs.setLog(); + } + if (mat.isSolid) { + bs.setSolid(); + } + } } } } diff --git a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperCB.java b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperCB.java index 37560401..bf4b4a94 100644 --- a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperCB.java +++ b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperCB.java @@ -25,6 +25,8 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { private Class nmsmaterial; private Field blockbyid; private Field material; + private Method material_issolid; + private Method material_isliquid; private Method blockbyidfunc; // 1.7+ method for getting block by id private Method getworldborder; // 1.8+ method for getting world border private Class nmsworldborder; @@ -77,6 +79,10 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { } material = getPrivateField(nmsblock, new String[] { "material" }, nmsmaterial); + // Get material methods + material_issolid = getMethod(nmsmaterial, new String[] { "isSolid" }, nulltypes); + material_isliquid = getMethod(nmsmaterial, new String[] { "isLiquid" }, nulltypes); + /* Set up biomebase fields */ biomebase = getNMSClass("net.minecraft.server.BiomeBase"); biomebasearray = getNMSClass("[Lnet.minecraft.server.BiomeBase;"); @@ -305,6 +311,48 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { } return new int[0]; } + /** + * Get material map by block ID + */ + @Override + public BukkitMaterial[] getMaterialList() { + try { + BukkitMaterial[] map = new BukkitMaterial[4096]; + if (blockbyid != null) { + Object[] byid = (Object[])blockbyid.get(nmsblock); + for (int i = 0; i < map.length; i++) { + if (byid[i] != null) { + Object mat = (Object)material.get(byid[i]); + if (mat != null) { + Boolean solid = (Boolean) material_issolid.invoke(mat); + Boolean liquid = (Boolean) material_isliquid.invoke(mat); + map[i] = new BukkitMaterial(mat.toString(), solid, liquid); + } + } + } + } + else if (blockbyidfunc != null) { + ArrayList mats = new ArrayList(); + for (int i = 0; i < map.length; i++) { + Object blk = blockbyidfunc.invoke(nmsblock, i); + if (blk != null) { + Object mat = (Object)material.get(blk); + if (mat != null) { + Boolean solid = (Boolean) material_issolid.invoke(mat); + Boolean liquid = (Boolean) material_isliquid.invoke(mat); + map[i] = new BukkitMaterial(mat.toString(), solid, liquid); + } + } + } + } + return map; + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } catch (InvocationTargetException e) { + } + return new BukkitMaterial[0]; + } + @Override public Polygon getWorldBorder(World world) { Polygon p = null; diff --git a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGlowstone.java b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGlowstone.java index eac48097..9b233916 100644 --- a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGlowstone.java +++ b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGlowstone.java @@ -414,6 +414,11 @@ public class BukkitVersionHelperGlowstone extends BukkitVersionHelper { // TODO Auto-generated method stub return null; } + @Override + public BukkitMaterial[] getMaterialList() { + // TODO Auto-generated method stub + return null; + } /** * Get list of online players diff --git a/forge-1.10.2/src/main/java/org/dynmap/forge_1_10_2/DynmapPlugin.java b/forge-1.10.2/src/main/java/org/dynmap/forge_1_10_2/DynmapPlugin.java index 1515cdaa..91225dcd 100644 --- a/forge-1.10.2/src/main/java/org/dynmap/forge_1_10_2/DynmapPlugin.java +++ b/forge-1.10.2/src/main/java/org/dynmap/forge_1_10_2/DynmapPlugin.java @@ -176,6 +176,20 @@ public class DynmapPlugin for (int m = 1; m < 16; m++) { DynmapBlockState bs = new DynmapBlockState(basebs, m, bn, "meta=" + m); stateByID[(i << 4) + m] = bs; + IBlockState blkstate = b.getStateFromMeta(m); + Material mat = blkstate.getMaterial(); + if (mat.isSolid()) { + bs.setSolid(); + } + if (mat == Material.AIR) { + bs.setAir(); + } + if (mat == Material.WOOD) { + bs.setLog(); + } + if (mat == Material.LEAVES) { + bs.setLeaves(); + } } } } diff --git a/forge-1.11.2/src/main/java/org/dynmap/forge_1_11_2/DynmapPlugin.java b/forge-1.11.2/src/main/java/org/dynmap/forge_1_11_2/DynmapPlugin.java index f46e5c43..62590a3e 100644 --- a/forge-1.11.2/src/main/java/org/dynmap/forge_1_11_2/DynmapPlugin.java +++ b/forge-1.11.2/src/main/java/org/dynmap/forge_1_11_2/DynmapPlugin.java @@ -176,6 +176,20 @@ public class DynmapPlugin for (int m = 1; m < 16; m++) { DynmapBlockState bs = new DynmapBlockState(basebs, m, bn, "meta=" + m); stateByID[(i << 4) + m] = bs; + IBlockState blkstate = b.getStateFromMeta(m); + Material mat = blkstate.getMaterial(); + if (mat.isSolid()) { + bs.setSolid(); + } + if (mat == Material.AIR) { + bs.setAir(); + } + if (mat == Material.WOOD) { + bs.setLog(); + } + if (mat == Material.LEAVES) { + bs.setLeaves(); + } } } } diff --git a/forge-1.12.2/src/main/java/org/dynmap/forge_1_12_2/DynmapPlugin.java b/forge-1.12.2/src/main/java/org/dynmap/forge_1_12_2/DynmapPlugin.java index cfba5082..cc00f5f3 100644 --- a/forge-1.12.2/src/main/java/org/dynmap/forge_1_12_2/DynmapPlugin.java +++ b/forge-1.12.2/src/main/java/org/dynmap/forge_1_12_2/DynmapPlugin.java @@ -176,6 +176,20 @@ public class DynmapPlugin for (int m = 1; m < 16; m++) { DynmapBlockState bs = new DynmapBlockState(basebs, m, bn, "meta=" + m); stateByID[(i << 4) + m] = bs; + IBlockState blkstate = b.getStateFromMeta(m); + Material mat = blkstate.getMaterial(); + if (mat.isSolid()) { + bs.setSolid(); + } + if (mat == Material.AIR) { + bs.setAir(); + } + if (mat == Material.WOOD) { + bs.setLog(); + } + if (mat == Material.LEAVES) { + bs.setLeaves(); + } } } } diff --git a/forge-1.8.9/src/main/java/org/dynmap/forge_1_8_9/DynmapPlugin.java b/forge-1.8.9/src/main/java/org/dynmap/forge_1_8_9/DynmapPlugin.java index 5fcf7635..6a0e1716 100644 --- a/forge-1.8.9/src/main/java/org/dynmap/forge_1_8_9/DynmapPlugin.java +++ b/forge-1.8.9/src/main/java/org/dynmap/forge_1_8_9/DynmapPlugin.java @@ -178,6 +178,19 @@ public class DynmapPlugin for (int m = 1; m < 16; m++) { DynmapBlockState bs = new DynmapBlockState(basebs, m, bn, "meta=" + m); stateByID[(i << 4) + m] = bs; + Material mat = b.getMaterial(); + if (mat.isSolid()) { + bs.setSolid(); + } + if (mat == Material.air) { + bs.setAir(); + } + if (mat == Material.wood) { + bs.setLog(); + } + if (mat == Material.leaves) { + bs.setLeaves(); + } } } } diff --git a/forge-1.9.4/src/main/java/org/dynmap/forge_1_9_4/DynmapPlugin.java b/forge-1.9.4/src/main/java/org/dynmap/forge_1_9_4/DynmapPlugin.java index 6749dc89..c806a451 100644 --- a/forge-1.9.4/src/main/java/org/dynmap/forge_1_9_4/DynmapPlugin.java +++ b/forge-1.9.4/src/main/java/org/dynmap/forge_1_9_4/DynmapPlugin.java @@ -176,6 +176,20 @@ public class DynmapPlugin for (int m = 1; m < 16; m++) { DynmapBlockState bs = new DynmapBlockState(basebs, m, bn, "meta=" + m); stateByID[(i << 4) + m] = bs; + IBlockState blkstate = b.getStateFromMeta(m); + Material mat = blkstate.getMaterial(); + if (mat.isSolid()) { + bs.setSolid(); + } + if (mat == Material.AIR) { + bs.setAir(); + } + if (mat == Material.WOOD) { + bs.setLog(); + } + if (mat == Material.LEAVES) { + bs.setLeaves(); + } } } }