mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-12 08:08:34 +00:00
Remove hardcoding of world limits (#1199)
* Remove hardcoding of world limits - seems to be working fine without the datapack for world height changing - particular attention should be given to LocalBlockVectorSet and MathMan changes * update adapters * Override getMinY in various classes and ensure selections have a world attached to them * no message * Address comments - Fix for lighting mode 1 * A few more changes * Fix LocalBlockVectorSet * Fix range statement * Various fixes/comment-addressing - There's not much point in having a different file name now for history. We've broken it before... - Fix history read/write - Fix range on for loops in CharBlocks * undo bad CharBlocks change * Fix history y level * Fix biome history * Fix lighting * Fix /up * Make regen fail not because of these changes * Fixes for y < 0 * Fix isEmpty where only the uppermost chunksection is edited * Fix javadocs/FAWE annotations * Better explain why BiomeMath is removed * If history task throws an error, it should only be caught and printed if not completing now. * Min|max world heights for new patterns * Load biomes from NMS instead of bukkit (#1200) * Update adapters * Update adapters * Don't initialise BlockTypes when biomes aren't set up yet so all BiomeTypes.BIOME are no longer null thanks. * Address some comments. * rename layer -> sectionIndex to imply inclusivity * Javadoctored. Co-authored-by: NotMyFault <mc.cache@web.de> Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com>
This commit is contained in:
@ -44,7 +44,7 @@ public class ExtentHeightCacher extends PassthroughExtent {
|
||||
index = rx + (rz << 8);
|
||||
}
|
||||
int result = cacheHeights[index] & 0xFF;
|
||||
if (result == 0) {
|
||||
if (result == minY) {
|
||||
cacheHeights[index] = (byte) (result = lastY = super
|
||||
.getNearestSurfaceTerrainBlock(x, z, lastY, minY, maxY));
|
||||
}
|
||||
|
@ -217,6 +217,11 @@ public class NullExtent extends FaweRegionExtent implements IBatchProcessor {
|
||||
throw reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
throw reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockArrayClipboard lazyCopy(Region region) {
|
||||
throw reason;
|
||||
@ -273,21 +278,6 @@ public class NullExtent extends FaweRegionExtent implements IBatchProcessor {
|
||||
throw reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, boolean ignoreAir) {
|
||||
throw reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
||||
throw reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) {
|
||||
throw reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, Mask mask) {
|
||||
throw reason;
|
||||
|
@ -71,7 +71,7 @@ public abstract class ChunkFilterBlock extends AbstractExtentFilterBlock {
|
||||
*/
|
||||
public final IChunkSet filter(IChunk chunk, IChunkGet get, IChunkSet set, Filter filter) {
|
||||
initChunk(chunk.getX(), chunk.getZ());
|
||||
for (int layer = 0; layer < 16; layer++) {
|
||||
for (int layer = get.getMinSectionIndex(); layer <= get.getMaxSectionIndex(); layer++) {
|
||||
if (set.hasSection(layer)) {
|
||||
initLayer(get, set, layer);
|
||||
filter(filter);
|
||||
@ -87,7 +87,7 @@ public abstract class ChunkFilterBlock extends AbstractExtentFilterBlock {
|
||||
if (region != null) {
|
||||
region.filter(chunk, filter, this, get, set, full);
|
||||
} else {
|
||||
for (int layer = 0; layer < 16; layer++) {
|
||||
for (int layer = get.getMinSectionIndex(); layer <= get.getMaxSectionIndex(); layer++) {
|
||||
if ((!full && !get.hasSection(layer)) || !filter.appliesLayer(chunk, layer)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -119,92 +119,92 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
|
||||
@Override
|
||||
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
|
||||
limit.THROW_MAX_CHECKS(FaweCache.IMP.WORLD_HEIGHT);
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getHighestTerrainBlock(x, z, minY, maxY);
|
||||
} catch (FaweException e) {
|
||||
if (!limit.MAX_FAILS()) {
|
||||
throw e;
|
||||
}
|
||||
return 0;
|
||||
return minY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) {
|
||||
limit.THROW_MAX_CHECKS(FaweCache.IMP.WORLD_HEIGHT);
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getHighestTerrainBlock(x, z, minY, maxY, filter);
|
||||
} catch (FaweException e) {
|
||||
if (!limit.MAX_FAILS()) {
|
||||
throw e;
|
||||
}
|
||||
return 0;
|
||||
return minY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
|
||||
limit.THROW_MAX_CHECKS(FaweCache.IMP.WORLD_HEIGHT);
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceLayer(x, z, y, minY, maxY);
|
||||
} catch (FaweException e) {
|
||||
if (!limit.MAX_FAILS()) {
|
||||
throw e;
|
||||
}
|
||||
return 0;
|
||||
return minY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, boolean ignoreAir) {
|
||||
limit.THROW_MAX_CHECKS(FaweCache.IMP.WORLD_HEIGHT);
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, ignoreAir);
|
||||
} catch (FaweException e) {
|
||||
if (!limit.MAX_FAILS()) {
|
||||
throw e;
|
||||
}
|
||||
return 0;
|
||||
return minY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
||||
limit.THROW_MAX_CHECKS(FaweCache.IMP.WORLD_HEIGHT);
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY);
|
||||
} catch (FaweException e) {
|
||||
if (!limit.MAX_FAILS()) {
|
||||
throw e;
|
||||
}
|
||||
return 0;
|
||||
return minY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) {
|
||||
limit.THROW_MAX_CHECKS(FaweCache.IMP.WORLD_HEIGHT);
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax);
|
||||
} catch (FaweException e) {
|
||||
if (!limit.MAX_FAILS()) {
|
||||
throw e;
|
||||
}
|
||||
return 0;
|
||||
return minY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, Mask mask) {
|
||||
limit.THROW_MAX_CHECKS(FaweCache.IMP.WORLD_HEIGHT);
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, mask);
|
||||
} catch (FaweException e) {
|
||||
if (!limit.MAX_FAILS()) {
|
||||
throw e;
|
||||
}
|
||||
return 0;
|
||||
return minY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,14 +219,14 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
int failedMax,
|
||||
boolean ignoreAir
|
||||
) {
|
||||
limit.THROW_MAX_CHECKS(FaweCache.IMP.WORLD_HEIGHT);
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, ignoreAir);
|
||||
} catch (FaweException e) {
|
||||
if (!limit.MAX_FAILS()) {
|
||||
throw e;
|
||||
}
|
||||
return 0;
|
||||
return minY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,15 @@ public class ArrayHeightMap extends ScalableHeightMap {
|
||||
private double rx;
|
||||
private double rz;
|
||||
|
||||
public ArrayHeightMap(byte[][] height) {
|
||||
/**
|
||||
* New height map represented by byte array[][] of values x*z to be scaled given a set size
|
||||
*
|
||||
* @param height array of height values
|
||||
* @param minY min y value allowed to be set. Inclusive.
|
||||
* @param maxY max y value allowed to be set. Inclusive.
|
||||
*/
|
||||
public ArrayHeightMap(byte[][] height, int minY, int maxY) {
|
||||
super(minY, maxY);
|
||||
setSize(5);
|
||||
this.height = height;
|
||||
this.width = height.length;
|
||||
|
@ -2,8 +2,15 @@ package com.fastasyncworldedit.core.extent.processor.heightmap;
|
||||
|
||||
public class FlatScalableHeightMap extends ScalableHeightMap {
|
||||
|
||||
public FlatScalableHeightMap() {
|
||||
super();
|
||||
/**
|
||||
* New height map where the returned height is the minmum height value if outside the size, otherwise returns height equal
|
||||
* to size.
|
||||
*
|
||||
* @param minY min y value allowed to be set. Inclusive.
|
||||
* @param maxY max y value allowed to be set. Inclusive.
|
||||
*/
|
||||
public FlatScalableHeightMap(int minY, int maxY) {
|
||||
super(minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -12,7 +19,7 @@ public class FlatScalableHeightMap extends ScalableHeightMap {
|
||||
int dz = Math.abs(z);
|
||||
int d2 = dx * dx + dz * dz;
|
||||
if (d2 > size2) {
|
||||
return 0;
|
||||
return minY;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ public interface HeightMap {
|
||||
|
||||
void setSize(int size);
|
||||
|
||||
|
||||
default void perform(
|
||||
EditSession session,
|
||||
Mask mask,
|
||||
@ -83,8 +82,8 @@ public interface HeightMap {
|
||||
boolean towards,
|
||||
final boolean layers
|
||||
) {
|
||||
BlockVector3 top = session.getMaximumPoint();
|
||||
int maxY = top.getBlockY();
|
||||
int maxY = session.getMaxY();
|
||||
int minY = session.getMinY();
|
||||
int diameter = 2 * size + 1;
|
||||
int centerX = pos.getBlockX();
|
||||
int centerZ = pos.getBlockZ();
|
||||
@ -121,15 +120,15 @@ public interface HeightMap {
|
||||
}
|
||||
int height;
|
||||
if (layers) {
|
||||
height = tmpY = session.getNearestSurfaceLayer(xx, zz, tmpY, 0, maxY);
|
||||
height = tmpY = session.getNearestSurfaceLayer(xx, zz, tmpY, minY, maxY);
|
||||
} else {
|
||||
height = tmpY = session.getNearestSurfaceTerrainBlock(xx, zz, tmpY, 0, maxY);
|
||||
height = tmpY = session.getNearestSurfaceTerrainBlock(xx, zz, tmpY, minY, maxY);
|
||||
if (height == -1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
oldData[index] = height;
|
||||
if (height == 0) {
|
||||
if (height == minY) {
|
||||
newData[index] = centerY;
|
||||
continue;
|
||||
}
|
||||
@ -137,8 +136,9 @@ public interface HeightMap {
|
||||
int diff = targetY - height;
|
||||
double raiseScaled = diff * (raisePow * sizePowInv);
|
||||
double raiseScaledAbs = Math.abs(raiseScaled);
|
||||
int random = ThreadLocalRandom.current().nextInt(256) < (int) ((Math.ceil(raiseScaledAbs) - Math.floor(
|
||||
raiseScaledAbs)) * 256) ? (diff > 0 ? 1 : -1) : 0;
|
||||
int random =
|
||||
ThreadLocalRandom.current().nextInt(maxY + 1 - minY) - minY < (int) ((Math.ceil(raiseScaledAbs) - Math.floor(
|
||||
raiseScaledAbs)) * (maxY + 1 - minY)) ? (diff > 0 ? 1 : -1) : 0;
|
||||
int raiseScaledInt = (int) raiseScaled + random;
|
||||
newData[index] = height + raiseScaledInt;
|
||||
}
|
||||
@ -166,20 +166,22 @@ public interface HeightMap {
|
||||
break;
|
||||
}
|
||||
if (layers) {
|
||||
height = session.getNearestSurfaceLayer(xx, zz, height, 0, maxY);
|
||||
height = session.getNearestSurfaceLayer(xx, zz, height, minY, maxY);
|
||||
} else {
|
||||
height = session.getNearestSurfaceTerrainBlock(xx, zz, height, 0, maxY);
|
||||
if (height == -1) {
|
||||
height = session.getNearestSurfaceTerrainBlock(xx, zz, height, minY, maxY);
|
||||
if (height == minY - 1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
oldData[index] = height;
|
||||
if (height == 0) {
|
||||
if (height == minY) {
|
||||
newData[index] = centerY;
|
||||
continue;
|
||||
}
|
||||
raise = (yscale * raise);
|
||||
int random = ThreadLocalRandom.current().nextInt(256) < (int) ((raise - (int) raise) * (256)) ? 1 : 0;
|
||||
int random =
|
||||
ThreadLocalRandom.current().nextInt(maxY + 1 - minY) - minY < (int) ((raise - (int) raise) * (maxY - minY + 1))
|
||||
? 1 : 0;
|
||||
int newHeight = height + (int) raise + random;
|
||||
newData[index] = newHeight;
|
||||
}
|
||||
|
@ -18,20 +18,26 @@ public class ScalableHeightMap implements HeightMap {
|
||||
|
||||
public int size2;
|
||||
public int size;
|
||||
protected int minY;
|
||||
protected int maxY;
|
||||
|
||||
public enum Shape {
|
||||
CONE,
|
||||
CYLINDER,
|
||||
}
|
||||
|
||||
public ScalableHeightMap() {
|
||||
/**
|
||||
* New height map.
|
||||
*
|
||||
* @param minY min y value allowed to be set. Inclusive.
|
||||
* @param maxY max y value allowed to be set. Inclusive.
|
||||
*/
|
||||
public ScalableHeightMap(final int minY, final int maxY) {
|
||||
this.minY = minY;
|
||||
this.maxY = maxY;
|
||||
setSize(5);
|
||||
}
|
||||
|
||||
public ScalableHeightMap(int size) {
|
||||
setSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSize(int size) {
|
||||
this.size = size;
|
||||
@ -44,29 +50,29 @@ public class ScalableHeightMap implements HeightMap {
|
||||
int dz = Math.abs(z);
|
||||
int d2 = dx * dx + dz * dz;
|
||||
if (d2 > size2) {
|
||||
return 0;
|
||||
return minY;
|
||||
}
|
||||
return Math.max(0, size - MathMan.sqrtApprox(d2));
|
||||
return Math.max(minY, size - MathMan.sqrtApprox(d2));
|
||||
}
|
||||
|
||||
public static ScalableHeightMap fromShape(Shape shape) {
|
||||
public static ScalableHeightMap fromShape(Shape shape, int minY, int maxY) {
|
||||
switch (shape) {
|
||||
default:
|
||||
case CONE:
|
||||
return new ScalableHeightMap();
|
||||
return new ScalableHeightMap(minY, maxY);
|
||||
case CYLINDER:
|
||||
return new FlatScalableHeightMap();
|
||||
return new FlatScalableHeightMap(minY, maxY);
|
||||
}
|
||||
}
|
||||
|
||||
public static ScalableHeightMap fromClipboard(Clipboard clipboard) {
|
||||
public static ScalableHeightMap fromClipboard(Clipboard clipboard, int minY, int maxY) {
|
||||
BlockVector3 dim = clipboard.getDimensions();
|
||||
byte[][] heightArray = new byte[dim.getBlockX()][dim.getBlockZ()];
|
||||
int minX = clipboard.getMinimumPoint().getBlockX();
|
||||
int minZ = clipboard.getMinimumPoint().getBlockZ();
|
||||
int minY = clipboard.getMinimumPoint().getBlockY();
|
||||
int maxY = clipboard.getMaximumPoint().getBlockY();
|
||||
int clipHeight = maxY - minY + 1;
|
||||
int clipMinX = clipboard.getMinimumPoint().getBlockX();
|
||||
int clipMinZ = clipboard.getMinimumPoint().getBlockZ();
|
||||
int clipMinY = clipboard.getMinimumPoint().getBlockY();
|
||||
int clipMaxY = clipboard.getMaximumPoint().getBlockY();
|
||||
int clipHeight = clipMaxY - clipMinY + 1;
|
||||
HashSet<IntPair> visited = new HashSet<>();
|
||||
MutableBlockVector3 bv = new MutableBlockVector3();
|
||||
for (BlockVector3 pos : clipboard.getRegion()) {
|
||||
@ -77,24 +83,24 @@ public class ScalableHeightMap implements HeightMap {
|
||||
visited.add(pair);
|
||||
int xx = pos.getBlockX();
|
||||
int zz = pos.getBlockZ();
|
||||
int highestY = minY;
|
||||
int highestY = clipMinY;
|
||||
bv.setComponents(pos);
|
||||
for (int y = minY; y <= maxY; y++) {
|
||||
for (int y = clipMinY; y <= clipMaxY; y++) {
|
||||
bv.mutY(y);
|
||||
BlockState block = clipboard.getBlock(bv);
|
||||
if (!block.getBlockType().getMaterial().isAir()) {
|
||||
highestY = y + 1;
|
||||
}
|
||||
}
|
||||
int pointHeight = Math.min(255, (256 * (highestY - minY)) / clipHeight);
|
||||
int x = xx - minX;
|
||||
int z = zz - minZ;
|
||||
int pointHeight = Math.min(clipMaxY, ((maxY - minY + 1 ) * (highestY - clipMinY)) / clipHeight);
|
||||
int x = xx - clipMinX;
|
||||
int z = zz - clipMinZ;
|
||||
heightArray[x][z] = (byte) pointHeight;
|
||||
}
|
||||
return new ArrayHeightMap(heightArray);
|
||||
return new ArrayHeightMap(heightArray, minY, maxY);
|
||||
}
|
||||
|
||||
public static ScalableHeightMap fromPNG(InputStream stream) throws IOException {
|
||||
public static ScalableHeightMap fromPNG(InputStream stream, int minY, int maxY) throws IOException {
|
||||
BufferedImage heightFile = MainUtil.readImage(stream);
|
||||
int width = heightFile.getWidth();
|
||||
int length = heightFile.getHeight();
|
||||
@ -113,7 +119,7 @@ public class ScalableHeightMap implements HeightMap {
|
||||
array[x][z] = (byte) intensity;
|
||||
}
|
||||
}
|
||||
return new ArrayHeightMap(array);
|
||||
return new ArrayHeightMap(array, minY, maxY);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -60,11 +60,12 @@ public class NMSRelighter implements Relighter {
|
||||
private final ConcurrentHashMap<Long, long[][][]> concurrentLightQueue;
|
||||
private final RelightMode relightMode;
|
||||
private final int maxY;
|
||||
private final int minY;
|
||||
private final ReentrantLock lightingLock;
|
||||
private final AtomicBoolean finished = new AtomicBoolean(false);
|
||||
private boolean removeFirst;
|
||||
|
||||
public NMSRelighter(IQueueExtent<IQueueChunk> queue, boolean calculateHeightMaps) {
|
||||
public NMSRelighter(IQueueExtent<IQueueChunk> queue) {
|
||||
this(queue, null);
|
||||
}
|
||||
|
||||
@ -75,6 +76,7 @@ public class NMSRelighter implements Relighter {
|
||||
this.chunksToSend = new Long2ObjectOpenHashMap<>(12);
|
||||
this.concurrentLightQueue = new ConcurrentHashMap<>(12);
|
||||
this.maxY = queue.getMaxY();
|
||||
this.minY = queue.getMinY();
|
||||
this.relightMode = relightMode != null ? relightMode : RelightMode.valueOf(Settings.IMP.LIGHTING.MODE);
|
||||
this.lightingLock = new ReentrantLock();
|
||||
}
|
||||
@ -118,6 +120,8 @@ public class NMSRelighter implements Relighter {
|
||||
if (m2 == null) {
|
||||
m2 = m1[x] = new long[4];
|
||||
}
|
||||
// Account for negative y values by "adding" minY
|
||||
y -= minY;
|
||||
m2[y >> 6] |= 1L << y;
|
||||
}
|
||||
|
||||
@ -132,6 +136,8 @@ public class NMSRelighter implements Relighter {
|
||||
this.lightQueue.put(index, currentMap);
|
||||
}
|
||||
set(x & 15, y, z & 15, currentMap);
|
||||
this.lightQueue.putAll(concurrentLightQueue);
|
||||
concurrentLightQueue.clear();
|
||||
} finally {
|
||||
lightLock.set(false);
|
||||
}
|
||||
@ -154,7 +160,7 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
|
||||
public boolean addChunk(int cx, int cz, byte[] fix, int bitmask) {
|
||||
RelightSkyEntry toPut = new RelightSkyEntry(cx, cz, fix, bitmask);
|
||||
RelightSkyEntry toPut = new RelightSkyEntry(cx, cz, fix, bitmask, minY, maxY);
|
||||
extendSkyToRelight.add(toPut);
|
||||
return true;
|
||||
}
|
||||
@ -188,7 +194,7 @@ public class NMSRelighter implements Relighter {
|
||||
if (!iChunk.isInit()) {
|
||||
iChunk.init(queue, chunk.x, chunk.z);
|
||||
}
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (int i = minY >> 4; i <= maxY >> 4; i++) {
|
||||
iChunk.removeSectionLighting(i, true);
|
||||
}
|
||||
iter.remove();
|
||||
@ -238,7 +244,7 @@ public class NMSRelighter implements Relighter {
|
||||
for (int j = 0; j < 64; j++) {
|
||||
if (((value >> j) & 1) == 1) {
|
||||
int x = lx + bx;
|
||||
int y = yStart + j;
|
||||
int y = yStart + j + minY;
|
||||
int z = lz + bz;
|
||||
int oldLevel = iChunk.getEmittedLight(lx, y, lz);
|
||||
int newLevel = iChunk.getBrightness(lx, y, lz);
|
||||
@ -287,7 +293,7 @@ public class NMSRelighter implements Relighter {
|
||||
removalVisited,
|
||||
visited
|
||||
);
|
||||
if (node.getY() > 0) {
|
||||
if (node.getY() > minY) {
|
||||
this.computeRemoveBlockLight(
|
||||
node.getX(),
|
||||
node.getY() - 1,
|
||||
@ -299,7 +305,7 @@ public class NMSRelighter implements Relighter {
|
||||
visited
|
||||
);
|
||||
}
|
||||
if (node.getY() < 255) {
|
||||
if (node.getY() < maxY) {
|
||||
this.computeRemoveBlockLight(
|
||||
node.getX(),
|
||||
node.getY() + 1,
|
||||
@ -650,7 +656,7 @@ public class NMSRelighter implements Relighter {
|
||||
this.computeSpreadBlockLight(x, y - 1, z, currentLight, queue, visited);
|
||||
}
|
||||
state = this.queue.getBlock(x, y + 1, z);
|
||||
if (y < 255 && !top && isSlabOrTrueValue(state, "top") && isStairOrTrueTop(state, true)) {
|
||||
if (y < maxY && !top && isSlabOrTrueValue(state, "top") && isStairOrTrueTop(state, true)) {
|
||||
this.computeSpreadBlockLight(x, y + 1, z, currentLight, queue, visited);
|
||||
}
|
||||
}
|
||||
@ -696,7 +702,7 @@ public class NMSRelighter implements Relighter {
|
||||
this.computeSpreadBlockLight(x, y - 1, z, currentLight, queue, visited);
|
||||
}
|
||||
state = this.queue.getBlock(x, y + 1, z);
|
||||
if (y < 255 && isSlabOrTrueValue(state, "top") && isStairOrTrueTop(state, false)) {
|
||||
if (y < maxY && isSlabOrTrueValue(state, "top") && isStairOrTrueTop(state, false)) {
|
||||
this.computeSpreadBlockLight(x, y + 1, z, currentLight, queue, visited);
|
||||
}
|
||||
}
|
||||
@ -944,7 +950,7 @@ public class NMSRelighter implements Relighter {
|
||||
int z = MathMan.unpairIntY(pair);
|
||||
ChunkHolder<?> chunk = (ChunkHolder<?>) queue.getOrCreateChunk(x, z);
|
||||
chunk.setBitMask(bitMask);
|
||||
chunk.flushLightToGet(true);
|
||||
chunk.flushLightToGet();
|
||||
Fawe.imp().getPlatformAdapter().sendChunk(chunk.getOrCreateGet(), bitMask, true);
|
||||
iter.remove();
|
||||
}
|
||||
@ -984,7 +990,7 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
}
|
||||
|
||||
public void fill(byte[] mask, int chunkX, int y, int chunkZ, byte reason) {
|
||||
public void fill(byte[] mask, ChunkHolder<?> iChunk, int y, byte reason) {
|
||||
if (y >= 16) {
|
||||
Arrays.fill(mask, (byte) 15);
|
||||
return;
|
||||
@ -995,12 +1001,10 @@ public class NMSRelighter implements Relighter {
|
||||
return;
|
||||
}
|
||||
case SkipReason.AIR: {
|
||||
int bx = chunkX << 4;
|
||||
int bz = chunkZ << 4;
|
||||
int index = 0;
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
mask[index++] = (byte) queue.getSkyLight(bx + x, y, bz + z);
|
||||
mask[index++] = (byte) iChunk.getSkyLight(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1026,19 +1030,19 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int y = 255; y > 0; y--) {
|
||||
for (int y = maxY; y > minY; y--) {
|
||||
for (RelightSkyEntry chunk : chunks) { // Propagate skylight
|
||||
int layer = y >> 4;
|
||||
int layer = (y - minY) >> 4;
|
||||
byte[] mask = chunk.mask;
|
||||
if (chunk.fix[layer] != SkipReason.NONE) {
|
||||
if ((y & 15) == 0 && layer != 0 && chunk.fix[layer - 1] == SkipReason.NONE) {
|
||||
fill(mask, chunk.x, y, chunk.z, chunk.fix[layer]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int bx = chunk.x << 4;
|
||||
int bz = chunk.z << 4;
|
||||
ChunkHolder<?> iChunk = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x, chunk.z);
|
||||
if (chunk.fix[layer] != SkipReason.NONE) {
|
||||
if ((y & 15) == 0 && layer != 0 && chunk.fix[layer - 1] == SkipReason.NONE) {
|
||||
fill(mask, iChunk, y, chunk.fix[layer]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!iChunk.isInit()) {
|
||||
iChunk.init(queue, chunk.x, chunk.z);
|
||||
}
|
||||
@ -1157,29 +1161,29 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
byte value = mask[j];
|
||||
if (x != 0 && z != 0) {
|
||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x - 1, y, z) - 1, value)) >= 14) {
|
||||
} else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z - 1) - 1, value)) >= 14) {
|
||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x - 1, y, z) - 1, value)) < 14) {
|
||||
value = (byte) Math.max(iChunk.getSkyLight(x, y, z - 1) - 1, value);
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else if (x == 0 && z == 0) {
|
||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(15, y, z) - 1, value)) >= 14) {
|
||||
} else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 15) - 1, value)) >= 14) {
|
||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(15, y, z) - 1, value)) < 14) {
|
||||
value = (byte) Math.max(iChunkz.getSkyLight(x, y, 15) - 1, value);
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else if (x == 0) {
|
||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(15, y, z) - 1, value)) >= 14) {
|
||||
} else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z - 1) - 1, value)) >= 14) {
|
||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(15, y, z) - 1, value)) < 14) {
|
||||
value = (byte) Math.max(iChunk.getSkyLight(x, y, z - 1) - 1, value);
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else {
|
||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x - 1, y, z) - 1, value)) >= 14) {
|
||||
} else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 15) - 1, value)) >= 14) {
|
||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x - 1, y, z) - 1, value)) < 14) {
|
||||
value = (byte) Math.max(iChunkz.getSkyLight(x, y, 15) - 1, value);
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
@ -1203,29 +1207,29 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
byte value = mask[j];
|
||||
if (x != 15 && z != 15) {
|
||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x + 1, y, z) - 1, value)) >= 14) {
|
||||
} else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z + 1) - 1, value)) >= 14) {
|
||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x + 1, y, z) - 1, value)) < 14) {
|
||||
value = (byte) Math.max(iChunk.getSkyLight(x, y, z + 1) - 1, value);
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else if (x == 15 && z == 15) {
|
||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(0, y, z) - 1, value)) >= 14) {
|
||||
} else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 0) - 1, value)) >= 14) {
|
||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(0, y, z) - 1, value)) < 14) {
|
||||
value = (byte) Math.max(iChunkz.getSkyLight(x, y, 0) - 1, value);
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else if (x == 15) {
|
||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(0, y, z) - 1, value)) >= 14) {
|
||||
} else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z + 1) - 1, value)) >= 14) {
|
||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(0, y, z) - 1, value)) < 14) {
|
||||
value = (byte) Math.max(iChunk.getSkyLight(x, y, z + 1) - 1, value);
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else {
|
||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x + 1, y, z) - 1, value)) >= 14) {
|
||||
} else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 0) - 1, value)) >= 14) {
|
||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x + 1, y, z) - 1, value)) < 14) {
|
||||
value = (byte) Math.max(iChunkz.getSkyLight(x, y, 0) - 1, value);
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
@ -1235,7 +1239,7 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
}
|
||||
|
||||
private class RelightSkyEntry implements Comparable<RelightSkyEntry> {
|
||||
private static class RelightSkyEntry implements Comparable<RelightSkyEntry> {
|
||||
|
||||
public final int x;
|
||||
public final int z;
|
||||
@ -1244,7 +1248,7 @@ public class NMSRelighter implements Relighter {
|
||||
public int bitmask;
|
||||
public boolean smooth;
|
||||
|
||||
public RelightSkyEntry(int x, int z, byte[] fix, int bitmask) {
|
||||
private RelightSkyEntry(int x, int z, byte[] fix, int bitmask, int minY, int maxY) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
byte[] array = new byte[256];
|
||||
@ -1252,13 +1256,14 @@ public class NMSRelighter implements Relighter {
|
||||
this.mask = array;
|
||||
this.bitmask = bitmask;
|
||||
if (fix == null) {
|
||||
this.fix = new byte[(maxY + 1) >> 4];
|
||||
this.fix = new byte[(maxY - minY + 1) >> 4];
|
||||
Arrays.fill(this.fix, SkipReason.NONE);
|
||||
} else {
|
||||
this.fix = fix;
|
||||
}
|
||||
}
|
||||
|
||||
//Following are public because they are public in Object. NONE of this nested class is API.
|
||||
@Override
|
||||
public String toString() {
|
||||
return x + "," + z;
|
||||
|
@ -28,11 +28,12 @@ public class RelightProcessor implements IBatchProcessor {
|
||||
if (Settings.IMP.LIGHTING.MODE == 2) {
|
||||
relighter.addChunk(chunk.getX(), chunk.getZ(), null, chunk.getBitMask());
|
||||
} else if (Settings.IMP.LIGHTING.MODE == 1) {
|
||||
byte[] fix = new byte[16];
|
||||
byte[] fix = new byte[get.getSectionCount()];
|
||||
boolean relight = false;
|
||||
for (int i = 15; i >= 0; i--) {
|
||||
for (int i = get.getMaxSectionIndex(); i >= get.getMinSectionIndex(); i--) {
|
||||
if (!set.hasSection(i)) {
|
||||
fix[i] = Relighter.SkipReason.AIR;
|
||||
// Array index cannot be < 0 so "add" the min
|
||||
fix[i - get.getMinSectionIndex()] = Relighter.SkipReason.AIR;
|
||||
continue;
|
||||
}
|
||||
relight = true;
|
||||
|
Reference in New Issue
Block a user