From d3639bd4a61f6f20877d119b7e22bc5c9a6af449 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Sat, 4 Dec 2021 03:01:39 -0600 Subject: [PATCH] Add generic chunk, and builder --- .../org/dynmap/common/chunk/DynmapChunk.java | 100 ++++++++++++++++++ .../common/chunk/DynmapChunkSection.java | 4 + 2 files changed, 104 insertions(+) create mode 100644 DynmapCore/src/main/java/org/dynmap/common/chunk/DynmapChunk.java diff --git a/DynmapCore/src/main/java/org/dynmap/common/chunk/DynmapChunk.java b/DynmapCore/src/main/java/org/dynmap/common/chunk/DynmapChunk.java new file mode 100644 index 00000000..af25034a --- /dev/null +++ b/DynmapCore/src/main/java/org/dynmap/common/chunk/DynmapChunk.java @@ -0,0 +1,100 @@ +package org.dynmap.common.chunk; + +import java.util.Arrays; + +import org.dynmap.renderer.DynmapBlockState; +import org.dynmap.common.BiomeMap; + +// Generic chunk representation +public class DynmapChunk { + public final int cx, cz; // Chunk coord (world coord / 16) + public final DynmapChunkSection[] sections; + public final int cy_min; // CY value of first section in sections list (index = (Y >> 4) - cy_min + public final long inhabitedTicks; + + private DynmapChunk(int cx, int cz, int cy_min, DynmapChunkSection[] sections, long inhabTicks) { + this.cx = cx; + this.cz = cz; + this.inhabitedTicks = inhabTicks; + this.sections = new DynmapChunkSection[sections.length + 2]; // Add one empty at top and bottom + this.cy_min = cy_min - 1; // Include empty at bottom + Arrays.fill(this.sections, DynmapChunkSection.EMPTY); // Fill all spots with empty, including pad on bottom/top + for (int off = 0; off < sections.length; off++) { + if (sections[off] != null) { // If defined, set the section + this.sections[off+1] = sections[off]; + } + } + } + // Get section for given block Y coord + public final DynmapChunkSection getSection(int y) { + try { + return this.sections[(y >> 4) - cy_min]; + } catch (IndexOutOfBoundsException ioobx) { // Builder and padding should be avoiding this, but be safe + return DynmapChunkSection.EMPTY; + } + } + + public final DynmapBlockState getBlockType(int x, int y, int z) { + return getSection(y).blocks.getBlock(x, y, z); + } + + public final int getBlockSkyLight(int x, int y, int z) { + return getSection(y).sky.getLight(x, y, z); + } + + public final int getBlockEmittedLight(int x, int y, int z) { + return getSection(y).emitted.getLight(x, y, z); + } + + public final BiomeMap getBiome(int x, int y, int z) { + return getSection(y).biomes.getBiome(x, y, z); + } + + public final boolean isSectionEmpty(int sy) { + return getSection(sy << 4).isEmpty; + } + + public final long getInhabitedTicks() { + return inhabitedTicks; + } + // Builder for fabricating finalized chunk + public static class Builder { + int x; + int z; + int y_min; + DynmapChunkSection[] sections; + long inhabTicks; + + public Builder(int world_ymin, int world_ymax) { + reset(world_ymin, world_ymax); + } + public void reset(int world_ymin, int world_ymax) { + x = 0; z = 0; + y_min = world_ymin >> 4; + int y_max = (world_ymax + 15) >> 4; // Round up + sections = new DynmapChunkSection[y_max - y_min]; // Range for all potential sections + } + // Set inhabited ticks + public Builder inhabitedTicks(long inh) { + this.inhabTicks = inh; + return this; + } + // Set section + public Builder addSection(int sy, DynmapChunkSection sect) { + if ((sy >= y_min) && ((sy - y_min) < sections.length)) { + this.sections[sy - y_min] = sect; + } + return this; + } + // Set coordinates + public Builder coords(int sx, int sz) { + this.x = sx; + this.z = sz; + return this; + } + // Build chunk + public DynmapChunk build() { + return new DynmapChunk(x, z, y_min, sections, inhabTicks); + } + } +} diff --git a/DynmapCore/src/main/java/org/dynmap/common/chunk/DynmapChunkSection.java b/DynmapCore/src/main/java/org/dynmap/common/chunk/DynmapChunkSection.java index af09fd08..abe0b492 100644 --- a/DynmapCore/src/main/java/org/dynmap/common/chunk/DynmapChunkSection.java +++ b/DynmapCore/src/main/java/org/dynmap/common/chunk/DynmapChunkSection.java @@ -131,6 +131,10 @@ public class DynmapChunkSection { private static BlockStateAccess defaultBlockState = new BlockStateAccessSingle(DynmapBlockState.AIR); private static LightingAccess defaultSky = new LightingAccessSingle(15); private static LightingAccess defaultEmit = new LightingAccessSingle(0); + + // Shared default empty section + public static final DynmapChunkSection EMPTY = new DynmapChunkSection(defaultBlockState, defaultBiome, defaultSky, defaultEmit, true); + // Factory for building section public static class Builder { private BiomeAccess ba;