From 809e45631c33d84876fd0ef72ac88a2e8e253db1 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Sat, 21 Aug 2021 18:03:07 -0500 Subject: [PATCH] Add support for experimental Caves and Caverns data pack --- .../src/main/java/org/dynmap/DynmapWorld.java | 21 +++++--- .../dynmap/exporter/DynmapExpCommands.java | 2 +- .../java/org/dynmap/exporter/OBJExport.java | 2 +- .../org/dynmap/hdmap/IsoHDPerspective.java | 32 ++++++------ build.gradle | 2 +- .../v117/BukkitVersionHelperSpigot117.java | 8 ++- .../bukkit/helper/AbstractMapChunkCache.java | 36 ++++++++------ .../bukkit/helper/BukkitVersionHelper.java | 4 ++ .../org/dynmap/bukkit/helper/BukkitWorld.java | 11 +++-- .../dynmap/fabric_1_17_1/DynmapPlugin.java | 5 +- .../fabric_1_17_1/FabricMapChunkCache.java | 49 ++++++++++--------- .../org/dynmap/fabric_1_17_1/FabricWorld.java | 13 +++-- .../org/dynmap/forge_1_16_5/ForgeWorld.java | 2 +- .../org/dynmap/forge_1_17_1/DynmapPlugin.java | 10 ++-- .../forge_1_17_1/ForgeMapChunkCache.java | 48 +++++++++--------- .../org/dynmap/forge_1_17_1/ForgeWorld.java | 14 ++++-- oldbuilds/build.gradle | 2 +- 17 files changed, 152 insertions(+), 109 deletions(-) diff --git a/DynmapCore/src/main/java/org/dynmap/DynmapWorld.java b/DynmapCore/src/main/java/org/dynmap/DynmapWorld.java index e116ff97..a186c8f7 100644 --- a/DynmapCore/src/main/java/org/dynmap/DynmapWorld.java +++ b/DynmapCore/src/main/java/org/dynmap/DynmapWorld.java @@ -52,22 +52,27 @@ public abstract class DynmapWorld { private MapStorage storage; // Storage handler for this world's maps /* World height data */ - public final int worldheight; - public final int heightshift; - public final int heightmask; + public int worldheight; // really maxY+1 + public int minY; public int sealevel; + protected void updateWorldHeights(int worldheight, int minY, int sealevel) { + this.worldheight = worldheight; + this.minY = minY; + this.sealevel = sealevel; + } + protected DynmapWorld(String wname, int worldheight, int sealevel) { + this(wname, worldheight, sealevel, 0); + } + protected DynmapWorld(String wname, int worldheight, int sealevel, int miny) { this.raw_wname = wname; this.wname = normalizeWorldName(wname); this.hashcode = this.wname.hashCode(); this.title = wname; this.worldheight = worldheight; + this.minY = miny; this.sealevel = sealevel; - int shift; - for(shift = 0; ((1 << shift) < worldheight); shift++) {} - heightshift = shift; - heightmask = (1 << shift) - 1; /* Generate default brightness table for surface world */ for (int i = 0; i <= 15; ++i) { float f1 = 1.0F - (float)i / 15.0F; @@ -319,7 +324,7 @@ public abstract class DynmapWorld { } title = worldconfig.getString("title", title); ConfigurationNode ctr = worldconfig.getNode("center"); - int mid_y = worldheight/2; + int mid_y = (worldheight + minY)/2; if(ctr != null) center = new DynmapLocation(wname, ctr.getDouble("x", 0.0), ctr.getDouble("y", mid_y), ctr.getDouble("z", 0)); else diff --git a/DynmapCore/src/main/java/org/dynmap/exporter/DynmapExpCommands.java b/DynmapCore/src/main/java/org/dynmap/exporter/DynmapExpCommands.java index 80d51a5f..25a80870 100644 --- a/DynmapCore/src/main/java/org/dynmap/exporter/DynmapExpCommands.java +++ b/DynmapCore/src/main/java/org/dynmap/exporter/DynmapExpCommands.java @@ -198,7 +198,7 @@ public class DynmapExpCommands { ctx.xmax = (int)Math.ceil(loc.x) + radius; ctx.zmin = (int)Math.floor(loc.z) - radius; ctx.zmax = (int)Math.ceil(loc.z) + radius; - ctx.ymin = 0; + ctx.ymin = world.minY; ctx.ymax = world.worldheight - 1; ctx.world = world.getName(); return handleInfo(sender, args, ctx, core); diff --git a/DynmapCore/src/main/java/org/dynmap/exporter/OBJExport.java b/DynmapCore/src/main/java/org/dynmap/exporter/OBJExport.java index 9506bc35..180221e7 100644 --- a/DynmapCore/src/main/java/org/dynmap/exporter/OBJExport.java +++ b/DynmapCore/src/main/java/org/dynmap/exporter/OBJExport.java @@ -170,7 +170,7 @@ public class OBJExport { else { minZ = maxz; maxZ = minz; } - if (minY < 0) minY = 0; + if (minY < world.minY) minY = world.minY; if (maxY >= world.worldheight) maxY = world.worldheight - 1; if (centerOrigin) { originX = (maxX + minX) / 2.0; diff --git a/DynmapCore/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java b/DynmapCore/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java index 1b8772fa..5e213c8a 100644 --- a/DynmapCore/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java +++ b/DynmapCore/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java @@ -136,7 +136,6 @@ public class IsoHDPerspective implements HDPerspective { final boolean isnether; boolean skiptoair; final int worldheight; - final int heightmask; final LightLevels llcache[]; /* Cache for custom model patch lists */ @@ -147,9 +146,6 @@ public class IsoHDPerspective implements HDPerspective { mapiter = mi; this.isnether = isnether; worldheight = mapiter.getWorldHeight(); - int shift; - for(shift = 0; (1<> 4; while(cache.isEmptySection(sx, sy, sz)) { /* If Y step is next best */ if((st_next_y <= st_next_x) && (st_next_y <= st_next_z)) { @@ -634,7 +631,7 @@ public class IsoHDPerspective implements HDPerspective { t = st_next_y; st_next_y += sdt_dy; laststep = stepy; - if(sy < 0) + if (sy < minsy) return false; } /* If X step is next best */ @@ -658,7 +655,7 @@ public class IsoHDPerspective implements HDPerspective { /** * Step block iterator: false if done */ - private final boolean raytraceStepIterator() { + private final boolean raytraceStepIterator(int miny, int maxy) { /* If Y step is next best */ if ((t_next_y <= t_next_x) && (t_next_y <= t_next_z)) { y += y_inc; @@ -667,7 +664,7 @@ public class IsoHDPerspective implements HDPerspective { laststep = stepy; mapiter.stepPosition(laststep); /* If outside 0-(height-1) range */ - if((y & (~heightmask)) != 0) { + if ((y < miny) || (y > maxy)) { return false; } } @@ -694,6 +691,9 @@ public class IsoHDPerspective implements HDPerspective { * Trace ray, based on "Voxel Tranversal along a 3D line" */ private final void raytrace(MapChunkCache cache, HDShaderState[] shaderstate, boolean[] shaderdone) { + int minY = cache.getWorld().minY; + int height = cache.getWorld().worldheight; + /* Initialize raytrace state variables */ raytrace_init(); @@ -703,7 +703,7 @@ public class IsoHDPerspective implements HDPerspective { raytrace_section_init(); - if (y < 0) + if (y < minY) return; mapiter.initialize(x, y, z); @@ -712,7 +712,7 @@ public class IsoHDPerspective implements HDPerspective { if (visit_block(shaderstate, shaderdone)) { return; } - if (!raytraceStepIterator()) { + if (!raytraceStepIterator(minY, height)) { return; } } @@ -978,9 +978,7 @@ public class IsoHDPerspective implements HDPerspective { /* Get max and min height */ maxheight = configuration.getInteger("maximumheight", -1); - int minh = configuration.getInteger("minimumheight", 0); - if(minh < 0) minh = 0; - minheight = minh; + minheight = configuration.getInteger("minimumheight", Integer.MIN_VALUE); /* Generate transform matrix for world-to-tile coordinate mapping */ /* First, need to fix basic coordinate mismatches before rotation - we want zero azimuth to have north to top * (world -X -> tile +Y) and east to right (world -Z to tile +X), with height being up (world +Y -> tile +Z) @@ -1129,7 +1127,9 @@ public class IsoHDPerspective implements HDPerspective { for(int y = t.ty; y <= (t.ty+1); y++) { for(int z = 0; z <= 1; z++) { corners[idx] = new Vector3D(); - corners[idx].x = x*tileWidth + dx; corners[idx].y = y*tileHeight + dy; corners[idx].z = z*t.getDynmapWorld().worldheight; + corners[idx].x = x*tileWidth + dx; + corners[idx].y = y*tileHeight + dy; + corners[idx].z = (z == 1) ? t.getDynmapWorld().worldheight : t.getDynmapWorld().minY; map_to_world.transform(corners[idx]); /* Compute chunk coordinates of corner */ int cx = fastFloor(corners[idx].x / 16); @@ -1240,13 +1240,17 @@ public class IsoHDPerspective implements HDPerspective { else height = tile.getDynmapWorld().worldheight - 1; } + double miny = minheight; + if (miny == Integer.MIN_VALUE) { /* Not set - assume world height - 1 */ + miny = tile.getDynmapWorld().minY; + } for(int x = 0; x < tileWidth * sizescale; x++) { ps.px = x; for(int y = 0; y < tileHeight * sizescale; y++) { ps.top.x = ps.bottom.x = xbase + ((double)x)/sizescale + 0.5; /* Start at center of pixel at Y=height+0.5, bottom at Y=-0.5 */ ps.top.y = ps.bottom.y = ybase + ((double)y)/sizescale + 0.5; - ps.top.z = height + 0.5; ps.bottom.z = minheight - 0.5; + ps.top.z = height + 0.5; ps.bottom.z = miny - 0.5; map_to_world.transform(ps.top); /* Transform to world coordinates */ map_to_world.transform(ps.bottom); ps.direction.set(ps.bottom); diff --git a/build.gradle b/build.gradle index 93c4a54d..ac691e37 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ allprojects { apply plugin: 'java' group = 'us.dynmap' - version = '3.2-beta-3' + version = '3.2-SNAPSHOT' } diff --git a/bukkit-helper-117/src/main/java/org/dynmap/bukkit/helper/v117/BukkitVersionHelperSpigot117.java b/bukkit-helper-117/src/main/java/org/dynmap/bukkit/helper/v117/BukkitVersionHelperSpigot117.java index 1580c7ba..d6ff32d9 100644 --- a/bukkit-helper-117/src/main/java/org/dynmap/bukkit/helper/v117/BukkitVersionHelperSpigot117.java +++ b/bukkit-helper-117/src/main/java/org/dynmap/bukkit/helper/v117/BukkitVersionHelperSpigot117.java @@ -2,6 +2,7 @@ package org.dynmap.bukkit.helper.v117; import org.bukkit.*; import org.bukkit.craftbukkit.v1_17_R1.CraftChunk; +import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; import org.bukkit.entity.Player; import org.dynmap.DynmapChunk; @@ -399,5 +400,10 @@ public class BukkitVersionHelperSpigot117 extends BukkitVersionHelper { } return url; } - + // Get minY for world + @Override + public int getWorldMinY(World w) { + CraftWorld cw = (CraftWorld) w; + return cw.getMinHeight(); + } } diff --git a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/AbstractMapChunkCache.java b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/AbstractMapChunkCache.java index d6a69717..f1bbf742 100644 --- a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/AbstractMapChunkCache.java +++ b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/AbstractMapChunkCache.java @@ -48,6 +48,7 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { protected World w; protected DynmapWorld dw; private int nsect; + private int sectoff; protected List chunks; protected ListIterator iterator; protected int x_min; @@ -98,6 +99,7 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { private BlockStep laststep; private DynmapBlockState type = null; private final int worldheight; + private final int ymin; private final int x_base; private final int z_base; @@ -108,6 +110,7 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { biomePrep(); initialize(x0, y0, z0); worldheight = w.getMaxHeight(); + ymin = dw.minY; } @Override @@ -126,7 +129,7 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { snap = snaparray[chunkindex]; } laststep = BlockStep.Y_MINUS; - if((y >= 0) && (y < worldheight)) + if((y >= ymin) && (y < worldheight)) type = null; else type = DynmapBlockState.AIR; @@ -452,7 +455,7 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { break; case 4: y--; - if(y < 0) { + if(y < ymin) { type = DynmapBlockState.AIR; } break; @@ -498,7 +501,7 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { else laststep = BlockStep.Y_MINUS; this.y = y; - if((y < 0) || (y >= worldheight)) { + if((y < ymin) || (y >= worldheight)) { type = DynmapBlockState.AIR; } else { @@ -520,7 +523,7 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { @Override public final DynmapBlockState getBlockTypeAt(BlockStep s) { if(s == BlockStep.Y_MINUS) { - if(y > 0) + if(y > ymin) return snap.getBlockType(bx, y-1, bz); } else if(s == BlockStep.Y_PLUS) { @@ -547,16 +550,16 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { } @Override public long getBlockKey() { - return (((chunkindex * worldheight) + y) << 8) | (bx << 4) | bz; + return (((chunkindex * (worldheight - ymin)) + (y - ymin)) << 8) | (bx << 4) | bz; } @Override public final boolean isEmptySection() { - try { - return !isSectionNotEmpty[chunkindex][y >> 4]; - } catch (Exception x) { + boolean[] flags = isSectionNotEmpty[chunkindex]; + if (flags == null) { initSectionData(chunkindex); - return !isSectionNotEmpty[chunkindex][y >> 4]; - } + flags = isSectionNotEmpty[chunkindex]; + } + return !flags[(y >> 4) + sectoff]; } @Override public RenderPatchFactory getPatchFactory() { @@ -677,7 +680,7 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { } @Override public boolean isSectionEmpty(int sy) { - return (sy < 4); + return (sy >= 4); } @Override public Object[] getBiomeBaseFromSnapshot() { @@ -705,7 +708,8 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { if(this.w == null) { this.chunks = new ArrayList(); } - nsect = dw.worldheight >> 4; + nsect = (dw.worldheight - dw.minY) >> 4; + sectoff = (-dw.minY) >> 4; this.chunks = chunks; /* Compute range */ if(chunks.size() == 0) { @@ -966,7 +970,7 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { isSectionNotEmpty[idx] = new boolean[nsect + 1]; if(snaparray[idx] != EMPTY) { for(int i = 0; i < nsect; i++) { - if(snaparray[idx].isSectionEmpty(i) == false) { + if(snaparray[idx].isSectionEmpty(i - sectoff) == false) { isSectionNotEmpty[idx][i] = true; } } @@ -974,10 +978,12 @@ public abstract class AbstractMapChunkCache extends MapChunkCache { } public boolean isEmptySection(int sx, int sy, int sz) { int idx = (sx - x_min) + (sz - z_min) * x_dim; - if(isSectionNotEmpty[idx] == null) { + boolean[] flags = isSectionNotEmpty[idx]; + if(flags == null) { initSectionData(idx); + flags = isSectionNotEmpty[idx]; } - return !isSectionNotEmpty[idx][sy]; + return !flags[sy + sectoff]; } /** 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 b1df6650..0c4d7182 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 @@ -120,6 +120,10 @@ public abstract class BukkitVersionHelper { * Get world border */ public Polygon getWorldBorder(World world) { return null; } + /** + * Get world minY + */ + public int getWorldMinY(World world) { return 0; } /** * Test if broken unloadChunk */ diff --git a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitWorld.java b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitWorld.java index 7603a531..fb812a31 100644 --- a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitWorld.java +++ b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitWorld.java @@ -27,12 +27,13 @@ public class BukkitWorld extends DynmapWorld { private DynmapLocation spawnloc = new DynmapLocation(); public BukkitWorld(World w) { - this(w.getName(), w.getMaxHeight(), w.getSeaLevel(), w.getEnvironment()); + this(w.getName(), w.getMaxHeight(), w.getSeaLevel(), w.getEnvironment(), + BukkitVersionHelper.helper.getWorldMinY(w)); setWorldLoaded(w); new Permission("dynmap.world." + getName(), "Dynmap access for world " + getName(), PermissionDefault.OP); } - public BukkitWorld(String name, int height, int sealevel, World.Environment env) { - super(name, height, sealevel); + public BukkitWorld(String name, int height, int sealevel, World.Environment env, int miny) { + super(name, height, sealevel, miny); world = null; this.env = env; skylight = (env == World.Environment.NORMAL); @@ -125,7 +126,7 @@ public class BukkitWorld extends DynmapWorld { @Override public int getLightLevel(int x, int y, int z) { if(world != null) { - if ((y >= 0) && (y < this.worldheight)) { + if ((y >= minY) && (y < this.worldheight)) { return world.getBlockAt(x, y, z).getLightLevel(); } return 0; @@ -153,7 +154,7 @@ public class BukkitWorld extends DynmapWorld { @Override public int getSkyLightLevel(int x, int y, int z) { if(world != null) { - if ((y >= 0) && (y < this.worldheight)) { + if ((y >= minY) && (y < this.worldheight)) { return world.getBlockAt(x, y, z).getLightFromSky(); } else { diff --git a/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/DynmapPlugin.java b/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/DynmapPlugin.java index dfbef97f..02a8ef35 100644 --- a/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/DynmapPlugin.java +++ b/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/DynmapPlugin.java @@ -821,6 +821,7 @@ public class DynmapPlugin { if (!fw.isLoaded()) { fw.setWorldLoaded(w); } + fw.updateWorld(w); return fw; } } @@ -843,6 +844,7 @@ public class DynmapPlugin { HashMap vals = new HashMap(); vals.put("name", fw.getRawName()); vals.put("height", fw.worldheight); + vals.put("miny", fw.minY); vals.put("sealevel", fw.sealevel); vals.put("nether", fw.isNether()); vals.put("the_end", ((FabricWorld) fw).isTheEnd()); @@ -881,12 +883,13 @@ public class DynmapPlugin { try { String name = (String) world.get("name"); int height = (Integer) world.get("height"); + Integer miny = (Integer) world.get("miny"); int sealevel = (Integer) world.get("sealevel"); boolean nether = (Boolean) world.get("nether"); boolean theend = (Boolean) world.get("the_end"); String title = (String) world.get("title"); if (name != null) { - FabricWorld fw = new FabricWorld(this, name, height, sealevel, nether, theend, title); + FabricWorld fw = new FabricWorld(this, name, height, sealevel, nether, theend, title, (miny != null) ? miny : 0); fw.setWorldUnloaded(); core.processWorldLoad(fw); worlds.put(fw.getName(), fw); diff --git a/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/FabricMapChunkCache.java b/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/FabricMapChunkCache.java index dc832ada..d72cd488 100644 --- a/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/FabricMapChunkCache.java +++ b/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/FabricMapChunkCache.java @@ -43,6 +43,7 @@ public class FabricMapChunkCache extends MapChunkCache { private DynmapWorld dw; private ServerChunkManager cps; private int nsect; + private int sectoff; private List chunks; private ListIterator iterator; private int x_min, x_max, z_min, z_max; @@ -59,7 +60,6 @@ public class FabricMapChunkCache extends MapChunkCache { private BiomeMap[][] biomemap; private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */ - private static final BlockStep unstep[] = {BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS, BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS }; @@ -111,6 +111,7 @@ public class FabricMapChunkCache extends MapChunkCache { private BlockStep laststep; private DynmapBlockState blk; private final int worldheight; + private final int miny; private final int x_base; private final int z_base; @@ -124,6 +125,7 @@ public class FabricMapChunkCache extends MapChunkCache { initialize(x0, y0, z0); worldheight = w.getHeight(); + miny = dw.minY; } @Override @@ -143,7 +145,7 @@ public class FabricMapChunkCache extends MapChunkCache { laststep = BlockStep.Y_MINUS; - if ((y >= 0) && (y < worldheight)) { + if ((y >= miny) && (y < worldheight)) { blk = null; } else { blk = DynmapBlockState.AIR; @@ -481,7 +483,7 @@ public class FabricMapChunkCache extends MapChunkCache { case 4: y--; - if (y < 0) { + if (y < miny) { blk = DynmapBlockState.AIR; } @@ -534,7 +536,7 @@ public class FabricMapChunkCache extends MapChunkCache { this.y = y; - if ((y < 0) || (y >= worldheight)) { + if ((y < miny) || (y >= worldheight)) { blk = DynmapBlockState.AIR; } else { blk = null; @@ -559,7 +561,7 @@ public class FabricMapChunkCache extends MapChunkCache { @Override public final DynmapBlockState getBlockTypeAt(BlockStep s) { if (s == BlockStep.Y_MINUS) { - if (y > 0) { + if (y > miny) { return snap.getBlockType(bx, y - 1, bz); } } else if (s == BlockStep.Y_PLUS) { @@ -590,18 +592,18 @@ public class FabricMapChunkCache extends MapChunkCache { @Override public long getBlockKey() { - return (((chunkindex * worldheight) + y) << 8) | (bx << 4) | bz; + return (((chunkindex * (worldheight - miny)) + (y - miny)) << 8) | (bx << 4) | bz; } - @Override - public final boolean isEmptySection() { - try { - return !isSectionNotEmpty[chunkindex][y >> 4]; - } catch (Exception x) { - initSectionData(chunkindex); - return !isSectionNotEmpty[chunkindex][y >> 4]; - } - } + @Override + public final boolean isEmptySection() { + boolean[] flags = isSectionNotEmpty[chunkindex]; + if(flags == null) { + initSectionData(chunkindex); + flags = isSectionNotEmpty[chunkindex]; + } + return !flags[(y >> 4) + sectoff]; + } @Override public RenderPatchFactory getPatchFactory() { @@ -778,7 +780,7 @@ public class FabricMapChunkCache extends MapChunkCache { @Override public boolean isSectionEmpty(int sy) { - return (sy < 4); + return (sy > 3); } } @@ -836,7 +838,8 @@ public class FabricMapChunkCache extends MapChunkCache { } else { chunks = new ArrayList(); } - nsect = dw.worldheight >> 4; + nsect = (dw.worldheight - dw.minY) >> 4; + sectoff = (-dw.minY) >> 4; this.chunks = chunks; /* Compute range */ @@ -1261,7 +1264,7 @@ public class FabricMapChunkCache extends MapChunkCache { if (snaparray[idx] != EMPTY) { for (int i = 0; i < nsect; i++) { - if (snaparray[idx].isSectionEmpty(i) == false) { + if (snaparray[idx].isSectionEmpty(i - sectoff) == false) { isSectionNotEmpty[idx][i] = true; } } @@ -1270,12 +1273,12 @@ public class FabricMapChunkCache extends MapChunkCache { public boolean isEmptySection(int sx, int sy, int sz) { int idx = (sx - x_min) + (sz - z_min) * x_dim; - - if (isSectionNotEmpty[idx] == null) { - initSectionData(idx); + boolean[] flags = isSectionNotEmpty[idx]; + if (flags == null) { + initSectionData(idx); + flags = isSectionNotEmpty[idx]; } - - return !isSectionNotEmpty[idx][sy]; + return !flags[sy + sectoff]; } /** diff --git a/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/FabricWorld.java b/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/FabricWorld.java index 483df7fb..79ec123b 100644 --- a/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/FabricWorld.java +++ b/fabric-1.17.1/src/main/java/org/dynmap/fabric_1_17_1/FabricWorld.java @@ -25,7 +25,7 @@ public class FabricWorld extends DynmapWorld { private final boolean istheend; private final String env; private DynmapLocation spawnloc = new DynmapLocation(); - private static int maxWorldHeight = 256; // Maximum allows world height + private static int maxWorldHeight = 320; // Maximum allows world height public static int getMaxWorldHeight() { return maxWorldHeight; @@ -47,18 +47,23 @@ public class FabricWorld extends DynmapWorld { return rk.getValue().getNamespace() + "_" + rk.getValue().getPath(); } } + + public void updateWorld(World w) { + this.updateWorldHeights(w.getHeight(), w.getDimension().getMinimumY(), w.getSeaLevel()); + } public FabricWorld(DynmapPlugin plugin, World w) { this(plugin, getWorldName(plugin, w), w.getHeight(), w.getSeaLevel(), w.getRegistryKey() == World.NETHER, w.getRegistryKey() == World.END, - w.getRegistryKey().getValue().getPath()); + w.getRegistryKey().getValue().getPath(), + w.getDimension().getMinimumY()); setWorldLoaded(w); } - public FabricWorld(DynmapPlugin plugin, String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle) { - super(name, (height > maxWorldHeight) ? maxWorldHeight : height, sealevel); + public FabricWorld(DynmapPlugin plugin, String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle, int miny) { + super(name, (height > maxWorldHeight) ? maxWorldHeight : height, sealevel, miny); this.plugin = plugin; world = null; setTitle(deftitle); diff --git a/forge-1.16.5/src/main/java/org/dynmap/forge_1_16_5/ForgeWorld.java b/forge-1.16.5/src/main/java/org/dynmap/forge_1_16_5/ForgeWorld.java index aceab5cd..1cdcede8 100644 --- a/forge-1.16.5/src/main/java/org/dynmap/forge_1_16_5/ForgeWorld.java +++ b/forge-1.16.5/src/main/java/org/dynmap/forge_1_16_5/ForgeWorld.java @@ -63,7 +63,7 @@ public class ForgeWorld extends DynmapWorld } public ForgeWorld(String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle) { - super(name, (height > maxWorldHeight)?maxWorldHeight:height, sealevel); + super(name, (height > maxWorldHeight)?maxWorldHeight:height, sealevel, 0); world = null; setTitle(deftitle); isnether = nether; diff --git a/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/DynmapPlugin.java b/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/DynmapPlugin.java index 58d43327..59a5f8a2 100644 --- a/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/DynmapPlugin.java +++ b/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/DynmapPlugin.java @@ -1537,11 +1537,6 @@ public class DynmapPlugin /* Initialized the currently loaded worlds */ for (ServerLevel world : server.getAllLevels()) { ForgeWorld w = this.getWorld(world); - /*NOTYET - need rest of forge - if(DimensionManager.getWorld(world.provider.getDimensionId()) == null) { // If not loaded - w.setWorldUnloaded(); - } - */ } for(ForgeWorld w : worlds.values()) { if (core.processWorldLoad(w)) { /* Have core process load first - fire event listeners if good load after */ @@ -1858,6 +1853,7 @@ public class DynmapPlugin if(fw.isLoaded() == false) { fw.setWorldLoaded(w); } + fw.updateWorld(w); return fw; } } @@ -1880,6 +1876,7 @@ public class DynmapPlugin HashMap vals = new HashMap(); vals.put("name", fw.getRawName()); vals.put("height", fw.worldheight); + vals.put("miny", fw.minY); vals.put("sealevel", fw.sealevel); vals.put("nether", fw.isNether()); vals.put("the_end", ((ForgeWorld)fw).isTheEnd()); @@ -1917,12 +1914,13 @@ public class DynmapPlugin try { String name = (String)world.get("name"); int height = (Integer)world.get("height"); + Integer miny = (Integer) world.get("miny"); int sealevel = (Integer)world.get("sealevel"); boolean nether = (Boolean)world.get("nether"); boolean theend = (Boolean)world.get("the_end"); String title = (String)world.get("title"); if(name != null) { - ForgeWorld fw = new ForgeWorld(name, height, sealevel, nether, theend, title); + ForgeWorld fw = new ForgeWorld(name, height, sealevel, nether, theend, title, (miny != null) ? miny : 0); fw.setWorldUnloaded(); core.processWorldLoad(fw); worlds.put(fw.getName(), fw); diff --git a/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/ForgeMapChunkCache.java b/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/ForgeMapChunkCache.java index 781d5399..010ccd39 100644 --- a/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/ForgeMapChunkCache.java +++ b/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/ForgeMapChunkCache.java @@ -53,6 +53,7 @@ public class ForgeMapChunkCache extends MapChunkCache { private DynmapWorld dw; private ServerChunkCache cps; private int nsect; + private int sectoff; // Offset for sake of negative section indexes private List chunks; private ListIterator iterator; private int x_min, x_max, z_min, z_max; @@ -87,6 +88,7 @@ public class ForgeMapChunkCache extends MapChunkCache { private BlockStep laststep; private DynmapBlockState blk; private final int worldheight; + private final int ymin; private final int x_base; private final int z_base; @@ -100,6 +102,7 @@ public class ForgeMapChunkCache extends MapChunkCache { initialize(x0, y0, z0); worldheight = w.getHeight(); + ymin = dw.minY; } @Override @@ -119,7 +122,7 @@ public class ForgeMapChunkCache extends MapChunkCache { laststep = BlockStep.Y_MINUS; - if ((y >= 0) && (y < worldheight)) { + if ((y >= ymin) && (y < worldheight)) { blk = null; } else { blk = DynmapBlockState.AIR; @@ -481,7 +484,7 @@ public class ForgeMapChunkCache extends MapChunkCache { case 4: y--; - if (y < 0) { + if (y < ymin) { blk = DynmapBlockState.AIR; } @@ -535,7 +538,7 @@ public class ForgeMapChunkCache extends MapChunkCache { this.y = y; - if ((y < 0) || (y >= worldheight)) { + if ((y < ymin) || (y >= worldheight)) { blk = DynmapBlockState.AIR; } else { blk = null; @@ -560,7 +563,7 @@ public class ForgeMapChunkCache extends MapChunkCache { @Override public final DynmapBlockState getBlockTypeAt(BlockStep s) { if (s == BlockStep.Y_MINUS) { - if (y > 0) { + if (y > ymin) { return snap.getBlockType(bx, y - 1, bz); } } else if (s == BlockStep.Y_PLUS) { @@ -591,17 +594,17 @@ public class ForgeMapChunkCache extends MapChunkCache { @Override public long getBlockKey() { - return (((chunkindex * worldheight) + y) << 8) | (bx << 4) | bz; + return (((chunkindex * (worldheight - ymin)) + (y - ymin)) << 8) | (bx << 4) | bz; } @Override public final boolean isEmptySection() { - try { - return !isSectionNotEmpty[chunkindex][y >> 4]; - } catch (Exception x) { + boolean[] flags = isSectionNotEmpty[chunkindex]; + if(flags == null) { initSectionData(chunkindex); - return !isSectionNotEmpty[chunkindex][y >> 4]; - } + flags = isSectionNotEmpty[chunkindex]; + } + return !flags[(y >> 4) + sectoff]; } @Override @@ -778,7 +781,7 @@ public class ForgeMapChunkCache extends MapChunkCache { @Override public boolean isSectionEmpty(int sy) { - return (sy < 4); + return (sy > 3); } } @@ -808,7 +811,8 @@ public class ForgeMapChunkCache extends MapChunkCache { } else { chunks = new ArrayList(); } - nsect = dw.worldheight >> 4; + nsect = (dw.worldheight - dw.minY) >> 4; + sectoff = (-dw.minY) >> 4; this.chunks = chunks; /* Compute range */ @@ -1227,22 +1231,22 @@ public class ForgeMapChunkCache extends MapChunkCache { if (snaparray[idx] != EMPTY) { for (int i = 0; i < nsect; i++) { - if (snaparray[idx].isSectionEmpty(i) == false) { + if (snaparray[idx].isSectionEmpty(i - sectoff) == false) { isSectionNotEmpty[idx][i] = true; } } } } - public boolean isEmptySection(int sx, int sy, int sz) { - int idx = (sx - x_min) + (sz - z_min) * x_dim; - - if (isSectionNotEmpty[idx] == null) { - initSectionData(idx); - } - - return !isSectionNotEmpty[idx][sy]; - } + public boolean isEmptySection(int sx, int sy, int sz) { + int idx = (sx - x_min) + (sz - z_min) * x_dim; + boolean[] flags = isSectionNotEmpty[idx]; + if(flags == null) { + initSectionData(idx); + flags = isSectionNotEmpty[idx]; + } + return !flags[sy + sectoff]; + } /** * Get cache iterator diff --git a/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/ForgeWorld.java b/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/ForgeWorld.java index 21036966..159ee7fc 100644 --- a/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/ForgeWorld.java +++ b/forge-1.17.1/src/main/java/org/dynmap/forge_1_17_1/ForgeWorld.java @@ -18,7 +18,6 @@ import org.dynmap.DynmapLocation; import org.dynmap.DynmapWorld; import org.dynmap.utils.MapChunkCache; import org.dynmap.utils.Polygon; -//import org.dynmap.Log; public class ForgeWorld extends DynmapWorld { @@ -28,7 +27,7 @@ public class ForgeWorld extends DynmapWorld private final boolean istheend; private final String env; private DynmapLocation spawnloc = new DynmapLocation(); - private static int maxWorldHeight = 256; // Maximum allows world height + private static int maxWorldHeight = 320; // Maximum allows world height public static int getMaxWorldHeight() { return maxWorldHeight; @@ -50,6 +49,10 @@ public class ForgeWorld extends DynmapWorld } } + public void updateWorld(ServerLevelAccessor w) { + this.updateWorldHeights(w.getLevel().getHeight(), w.getLevel().dimensionType().minY(), w.getLevel().getSeaLevel()); + } + public ForgeWorld(ServerLevelAccessor w) { this(getWorldName(w), @@ -57,12 +60,13 @@ public class ForgeWorld extends DynmapWorld w.getLevel().getSeaLevel(), w.getLevel().dimension() == Level.NETHER, w.getLevel().dimension() == Level.END, - getWorldName(w)); + getWorldName(w), + w.getLevel().dimensionType().minY()); setWorldLoaded(w); } - public ForgeWorld(String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle) + public ForgeWorld(String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle, int miny) { - super(name, (height > maxWorldHeight)?maxWorldHeight:height, sealevel); + super(name, (height > maxWorldHeight)?maxWorldHeight:height, sealevel, miny); world = null; setTitle(deftitle); isnether = nether; diff --git a/oldbuilds/build.gradle b/oldbuilds/build.gradle index 93c4a54d..ac691e37 100644 --- a/oldbuilds/build.gradle +++ b/oldbuilds/build.gradle @@ -17,7 +17,7 @@ allprojects { apply plugin: 'java' group = 'us.dynmap' - version = '3.2-beta-3' + version = '3.2-SNAPSHOT' }