mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-09-27 13:22:34 +02:00
Add handling for Y=negative
This commit is contained in:
parent
453783731c
commit
c5906166a1
@ -25,6 +25,7 @@ import net.minecraft.world.level.chunk.storage.ChunkRegionLoader;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread
|
* Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread
|
||||||
@ -40,6 +41,7 @@ public class MapChunkCache117 extends AbstractMapChunkCache {
|
|||||||
}
|
}
|
||||||
private final int x, z;
|
private final int x, z;
|
||||||
private final Section[] section;
|
private final Section[] section;
|
||||||
|
private final int sectionOffset;
|
||||||
private final int[] hmap; // Height map
|
private final int[] hmap; // Height map
|
||||||
private final int[] biome;
|
private final int[] biome;
|
||||||
private final Object[] biomebase;
|
private final Object[] biomebase;
|
||||||
@ -135,7 +137,7 @@ public class MapChunkCache117 extends AbstractMapChunkCache {
|
|||||||
this.sectionCnt = worldheight / 16;
|
this.sectionCnt = worldheight / 16;
|
||||||
/* Allocate arrays indexed by section */
|
/* Allocate arrays indexed by section */
|
||||||
this.section = new Section[this.sectionCnt+1];
|
this.section = new Section[this.sectionCnt+1];
|
||||||
|
this.sectionOffset = 0;
|
||||||
/* Fill with empty data */
|
/* Fill with empty data */
|
||||||
for (int i = 0; i <= this.sectionCnt; i++) {
|
for (int i = 0; i <= this.sectionCnt; i++) {
|
||||||
this.section[i] = empty_section;
|
this.section[i] = empty_section;
|
||||||
@ -160,26 +162,34 @@ public class MapChunkCache117 extends AbstractMapChunkCache {
|
|||||||
this.inhabitedTicks = 0;
|
this.inhabitedTicks = 0;
|
||||||
}
|
}
|
||||||
/* Allocate arrays indexed by section */
|
/* Allocate arrays indexed by section */
|
||||||
this.section = new Section[this.sectionCnt+1];
|
LinkedList<Section> sections = new LinkedList<Section>();
|
||||||
|
int sectoff = 0; // Default to zero
|
||||||
|
int sectcnt = 0;
|
||||||
/* Fill with empty data */
|
/* Fill with empty data */
|
||||||
for (int i = 0; i <= this.sectionCnt; i++) {
|
for (int i = 0; i <= this.sectionCnt; i++) {
|
||||||
this.section[i] = empty_section;
|
sections.add(empty_section);
|
||||||
|
sectcnt++;
|
||||||
}
|
}
|
||||||
/* Get sections */
|
/* Get sections */
|
||||||
NBTTagList sect = nbt.getList("Sections", 10);
|
NBTTagList sect = nbt.getList("Sections", 10);
|
||||||
for (int i = 0; i < sect.size(); i++) {
|
for (int i = 0; i < sect.size(); i++) {
|
||||||
NBTTagCompound sec = sect.getCompound(i);
|
NBTTagCompound sec = sect.getCompound(i);
|
||||||
int secnum = sec.getByte("Y");
|
int secnum = sec.getByte("Y");
|
||||||
if (secnum >= this.sectionCnt) {
|
// Beyond end - extend up
|
||||||
//Log.info("Section " + (int) secnum + " above world height " + worldheight);
|
while (secnum >= (sectcnt - sectoff)) {
|
||||||
continue;
|
sections.addLast(empty_section); // Pad with empty
|
||||||
|
sectcnt++;
|
||||||
}
|
}
|
||||||
if (secnum < 0)
|
// Negative - see if we need to extend sectionOffset
|
||||||
continue;
|
while ((secnum + sectoff) < 0) {
|
||||||
|
sections.addFirst(empty_section); // Pad with empty
|
||||||
|
sectoff++;
|
||||||
|
sectcnt++;
|
||||||
|
}
|
||||||
//System.out.println("section(" + secnum + ")=" + sec.asString());
|
//System.out.println("section(" + secnum + ")=" + sec.asString());
|
||||||
// Create normal section to initialize
|
// Create normal section to initialize
|
||||||
StdSection cursect = new StdSection();
|
StdSection cursect = new StdSection();
|
||||||
this.section[secnum] = cursect;
|
sections.set(secnum + sectoff, cursect);
|
||||||
DynmapBlockState[] states = cursect.states;
|
DynmapBlockState[] states = cursect.states;
|
||||||
DynmapBlockState[] palette = null;
|
DynmapBlockState[] palette = null;
|
||||||
// If we've got palette and block states list, process non-empty section
|
// If we've got palette and block states list, process non-empty section
|
||||||
@ -264,6 +274,9 @@ public class MapChunkCache117 extends AbstractMapChunkCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Finalize sections array
|
||||||
|
this.section = sections.toArray(new Section[sections.size()]);
|
||||||
|
this.sectionOffset = sectoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getX()
|
public int getX()
|
||||||
@ -278,17 +291,23 @@ public class MapChunkCache117 extends AbstractMapChunkCache {
|
|||||||
|
|
||||||
public DynmapBlockState getBlockType(int x, int y, int z)
|
public DynmapBlockState getBlockType(int x, int y, int z)
|
||||||
{
|
{
|
||||||
return section[y >> 4].getBlockType(x, y, z);
|
int idx = (y >> 4) + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return DynmapBlockState.AIR;
|
||||||
|
return section[idx].getBlockType(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBlockSkyLight(int x, int y, int z)
|
public int getBlockSkyLight(int x, int y, int z)
|
||||||
{
|
{
|
||||||
return section[y >> 4].getBlockSkyLight(x, y, z);
|
int idx = (y >> 4) + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return 15;
|
||||||
|
return section[idx].getBlockSkyLight(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBlockEmittedLight(int x, int y, int z)
|
public int getBlockEmittedLight(int x, int y, int z)
|
||||||
{
|
{
|
||||||
return section[y >> 4].getBlockEmittedLight(x, y, z);
|
int idx = (y >> 4) + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return 0;
|
||||||
|
return section[idx].getBlockEmittedLight(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHighestBlockYAt(int x, int z)
|
public int getHighestBlockYAt(int x, int z)
|
||||||
@ -303,7 +322,9 @@ public class MapChunkCache117 extends AbstractMapChunkCache {
|
|||||||
|
|
||||||
public boolean isSectionEmpty(int sy)
|
public boolean isSectionEmpty(int sy)
|
||||||
{
|
{
|
||||||
return section[sy].isEmpty();
|
int idx = sy + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return true;
|
||||||
|
return section[idx].isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getInhabitedTicks() {
|
public long getInhabitedTicks() {
|
||||||
|
@ -9,6 +9,7 @@ import org.dynmap.Log;
|
|||||||
import org.dynmap.renderer.DynmapBlockState;
|
import org.dynmap.renderer.DynmapBlockState;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a static, thread-safe snapshot of chunk of blocks
|
* Represents a static, thread-safe snapshot of chunk of blocks
|
||||||
@ -27,6 +28,7 @@ public class ChunkSnapshot {
|
|||||||
|
|
||||||
private final int x, z;
|
private final int x, z;
|
||||||
private final Section[] section;
|
private final Section[] section;
|
||||||
|
private final int sectionOffset;
|
||||||
private final int[] hmap; // Height map
|
private final int[] hmap; // Height map
|
||||||
private final int[] biome;
|
private final int[] biome;
|
||||||
private final long captureFulltime;
|
private final long captureFulltime;
|
||||||
@ -115,7 +117,7 @@ public class ChunkSnapshot {
|
|||||||
this.sectionCnt = worldheight / 16;
|
this.sectionCnt = worldheight / 16;
|
||||||
/* Allocate arrays indexed by section */
|
/* Allocate arrays indexed by section */
|
||||||
this.section = new Section[this.sectionCnt+1];
|
this.section = new Section[this.sectionCnt+1];
|
||||||
|
this.sectionOffset = 0;
|
||||||
/* Fill with empty data */
|
/* Fill with empty data */
|
||||||
for (int i = 0; i <= this.sectionCnt; i++) {
|
for (int i = 0; i <= this.sectionCnt; i++) {
|
||||||
this.section[i] = empty_section;
|
this.section[i] = empty_section;
|
||||||
@ -153,26 +155,34 @@ public class ChunkSnapshot {
|
|||||||
this.inhabitedTicks = 0;
|
this.inhabitedTicks = 0;
|
||||||
}
|
}
|
||||||
/* Allocate arrays indexed by section */
|
/* Allocate arrays indexed by section */
|
||||||
this.section = new Section[this.sectionCnt+1];
|
LinkedList<Section> sections = new LinkedList<Section>();
|
||||||
|
int sectoff = 0; // Default to zero
|
||||||
|
int sectcnt = 0;
|
||||||
/* Fill with empty data */
|
/* Fill with empty data */
|
||||||
for (int i = 0; i <= this.sectionCnt; i++) {
|
for (int i = 0; i <= this.sectionCnt; i++) {
|
||||||
this.section[i] = empty_section;
|
sections.add(empty_section);
|
||||||
|
sectcnt++;
|
||||||
}
|
}
|
||||||
/* Get sections */
|
/* Get sections */
|
||||||
NbtList sect = nbt.getList("Sections", 10);
|
NbtList sect = nbt.getList("Sections", 10);
|
||||||
for (int i = 0; i < sect.size(); i++) {
|
for (int i = 0; i < sect.size(); i++) {
|
||||||
NbtCompound sec = sect.getCompound(i);
|
NbtCompound sec = sect.getCompound(i);
|
||||||
int secnum = sec.getByte("Y");
|
int secnum = sec.getByte("Y");
|
||||||
if (secnum >= this.sectionCnt) {
|
// Beyond end - extend up
|
||||||
//Log.info("Section " + (int) secnum + " above world height " + worldheight);
|
while (secnum >= (sectcnt - sectoff)) {
|
||||||
continue;
|
sections.addLast(empty_section); // Pad with empty
|
||||||
|
sectcnt++;
|
||||||
}
|
}
|
||||||
if (secnum < 0)
|
// Negative - see if we need to extend sectionOffset
|
||||||
continue;
|
while ((secnum + sectoff) < 0) {
|
||||||
|
sections.addFirst(empty_section); // Pad with empty
|
||||||
|
sectoff++;
|
||||||
|
sectcnt++;
|
||||||
|
}
|
||||||
//System.out.println("section(" + secnum + ")=" + sec.asString());
|
//System.out.println("section(" + secnum + ")=" + sec.asString());
|
||||||
// Create normal section to initialize
|
// Create normal section to initialize
|
||||||
StdSection cursect = new StdSection();
|
StdSection cursect = new StdSection();
|
||||||
this.section[secnum] = cursect;
|
sections.set(secnum + sectoff, cursect);
|
||||||
DynmapBlockState[] states = cursect.states;
|
DynmapBlockState[] states = cursect.states;
|
||||||
DynmapBlockState[] palette = null;
|
DynmapBlockState[] palette = null;
|
||||||
// If we've got palette and block states list, process non-empty section
|
// If we've got palette and block states list, process non-empty section
|
||||||
@ -258,6 +268,9 @@ public class ChunkSnapshot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Finalize sections array
|
||||||
|
this.section = sections.toArray(new Section[sections.size()]);
|
||||||
|
this.sectionOffset = sectoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getX() {
|
public int getX() {
|
||||||
@ -268,16 +281,25 @@ public class ChunkSnapshot {
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynmapBlockState getBlockType(int x, int y, int z) {
|
public DynmapBlockState getBlockType(int x, int y, int z)
|
||||||
return section[y >> 4].getBlockType(x, y, z);
|
{
|
||||||
|
int idx = (y >> 4) + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return DynmapBlockState.AIR;
|
||||||
|
return section[idx].getBlockType(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBlockSkyLight(int x, int y, int z) {
|
public int getBlockSkyLight(int x, int y, int z)
|
||||||
return section[y >> 4].getBlockSkyLight(x, y, z);
|
{
|
||||||
|
int idx = (y >> 4) + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return 15;
|
||||||
|
return section[idx].getBlockSkyLight(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBlockEmittedLight(int x, int y, int z) {
|
public int getBlockEmittedLight(int x, int y, int z)
|
||||||
return section[y >> 4].getBlockEmittedLight(x, y, z);
|
{
|
||||||
|
int idx = (y >> 4) + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return 0;
|
||||||
|
return section[idx].getBlockEmittedLight(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHighestBlockYAt(int x, int z) {
|
public int getHighestBlockYAt(int x, int z) {
|
||||||
@ -292,8 +314,11 @@ public class ChunkSnapshot {
|
|||||||
return captureFulltime;
|
return captureFulltime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSectionEmpty(int sy) {
|
public boolean isSectionEmpty(int sy)
|
||||||
return section[sy].isEmpty();
|
{
|
||||||
|
int idx = sy + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return true;
|
||||||
|
return section[idx].isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getInhabitedTicks() {
|
public long getInhabitedTicks() {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.dynmap.forge_1_17_1;
|
package org.dynmap.forge_1_17_1;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import org.dynmap.renderer.DynmapBlockState;
|
import org.dynmap.renderer.DynmapBlockState;
|
||||||
import org.dynmap.utils.DataBitsPacked;
|
import org.dynmap.utils.DataBitsPacked;
|
||||||
@ -25,7 +26,8 @@ public class ChunkSnapshot
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final int x, z;
|
private final int x, z;
|
||||||
private final Section[] section;
|
private final Section[] section; // Section, indexed by (Y/16) + sectionOffset (to handle negatives)
|
||||||
|
private final int sectionOffset; // Offset - section[N] = section for Y = N-sectionOffset
|
||||||
private final int[] hmap; // Height map
|
private final int[] hmap; // Height map
|
||||||
private final int[] biome;
|
private final int[] biome;
|
||||||
private final long captureFulltime;
|
private final long captureFulltime;
|
||||||
@ -109,6 +111,7 @@ public class ChunkSnapshot
|
|||||||
this.sectionCnt = worldheight / 16;
|
this.sectionCnt = worldheight / 16;
|
||||||
/* Allocate arrays indexed by section */
|
/* Allocate arrays indexed by section */
|
||||||
this.section = new Section[this.sectionCnt+1];
|
this.section = new Section[this.sectionCnt+1];
|
||||||
|
this.sectionOffset = 0;
|
||||||
|
|
||||||
/* Fill with empty data */
|
/* Fill with empty data */
|
||||||
for (int i = 0; i <= this.sectionCnt; i++) {
|
for (int i = 0; i <= this.sectionCnt; i++) {
|
||||||
@ -134,26 +137,34 @@ public class ChunkSnapshot
|
|||||||
this.inhabitedTicks = 0;
|
this.inhabitedTicks = 0;
|
||||||
}
|
}
|
||||||
/* Allocate arrays indexed by section */
|
/* Allocate arrays indexed by section */
|
||||||
this.section = new Section[this.sectionCnt+1];
|
LinkedList<Section> sections = new LinkedList<Section>();
|
||||||
|
int sectoff = 0; // Default to zero
|
||||||
|
int sectcnt = 0;
|
||||||
/* Fill with empty data */
|
/* Fill with empty data */
|
||||||
for (int i = 0; i <= this.sectionCnt; i++) {
|
for (int i = 0; i <= this.sectionCnt; i++) {
|
||||||
this.section[i] = empty_section;
|
sections.add(empty_section);
|
||||||
|
sectcnt++;
|
||||||
}
|
}
|
||||||
/* Get sections */
|
/* Get sections */
|
||||||
ListTag sect = nbt.getList("Sections", 10);
|
ListTag sect = nbt.getList("Sections", 10);
|
||||||
for (int i = 0; i < sect.size(); i++) {
|
for (int i = 0; i < sect.size(); i++) {
|
||||||
CompoundTag sec = sect.getCompound(i);
|
CompoundTag sec = sect.getCompound(i);
|
||||||
int secnum = sec.getByte("Y");
|
int secnum = sec.getByte("Y");
|
||||||
if (secnum >= this.sectionCnt) {
|
// Beyond end - extend up
|
||||||
//Log.info("Section " + (int) secnum + " above world height " + worldheight);
|
while (secnum >= (sectcnt - sectoff)) {
|
||||||
continue;
|
sections.addLast(empty_section); // Pad with empty
|
||||||
|
sectcnt++;
|
||||||
}
|
}
|
||||||
if (secnum < 0)
|
// Negative - see if we need to extend sectionOffset
|
||||||
continue;
|
while ((secnum + sectoff) < 0) {
|
||||||
|
sections.addFirst(empty_section); // Pad with empty
|
||||||
|
sectoff++;
|
||||||
|
sectcnt++;
|
||||||
|
}
|
||||||
//System.out.println("section(" + secnum + ")=" + sec.asString());
|
//System.out.println("section(" + secnum + ")=" + sec.asString());
|
||||||
// Create normal section to initialize
|
// Create normal section to initialize
|
||||||
StdSection cursect = new StdSection();
|
StdSection cursect = new StdSection();
|
||||||
this.section[secnum] = cursect;
|
sections.set(secnum + sectoff, cursect);
|
||||||
DynmapBlockState[] states = cursect.states;
|
DynmapBlockState[] states = cursect.states;
|
||||||
DynmapBlockState[] palette = null;
|
DynmapBlockState[] palette = null;
|
||||||
// If we've got palette and block states list, process non-empty section
|
// If we've got palette and block states list, process non-empty section
|
||||||
@ -234,6 +245,9 @@ public class ChunkSnapshot
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Finalize sections array
|
||||||
|
this.section = sections.toArray(new Section[sections.size()]);
|
||||||
|
this.sectionOffset = sectoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getX()
|
public int getX()
|
||||||
@ -248,17 +262,23 @@ public class ChunkSnapshot
|
|||||||
|
|
||||||
public DynmapBlockState getBlockType(int x, int y, int z)
|
public DynmapBlockState getBlockType(int x, int y, int z)
|
||||||
{
|
{
|
||||||
return section[y >> 4].getBlockType(x, y, z);
|
int idx = (y >> 4) + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return DynmapBlockState.AIR;
|
||||||
|
return section[idx].getBlockType(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBlockSkyLight(int x, int y, int z)
|
public int getBlockSkyLight(int x, int y, int z)
|
||||||
{
|
{
|
||||||
return section[y >> 4].getBlockSkyLight(x, y, z);
|
int idx = (y >> 4) + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return 15;
|
||||||
|
return section[idx].getBlockSkyLight(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBlockEmittedLight(int x, int y, int z)
|
public int getBlockEmittedLight(int x, int y, int z)
|
||||||
{
|
{
|
||||||
return section[y >> 4].getBlockEmittedLight(x, y, z);
|
int idx = (y >> 4) + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return 0;
|
||||||
|
return section[idx].getBlockEmittedLight(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHighestBlockYAt(int x, int z)
|
public int getHighestBlockYAt(int x, int z)
|
||||||
@ -278,7 +298,9 @@ public class ChunkSnapshot
|
|||||||
|
|
||||||
public boolean isSectionEmpty(int sy)
|
public boolean isSectionEmpty(int sy)
|
||||||
{
|
{
|
||||||
return section[sy].isEmpty();
|
int idx = sy + sectionOffset;
|
||||||
|
if ((idx < 0) || (idx >= section.length)) return true;
|
||||||
|
return section[idx].isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getInhabitedTicks() {
|
public long getInhabitedTicks() {
|
||||||
|
Loading…
Reference in New Issue
Block a user