From d6c9a887ace16d6e77eedecc644492a9d9c9c999 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Mon, 14 Sep 2020 14:19:23 +0100 Subject: [PATCH] Fixlighting now also calculates heightmaps Fixes #386 and #438 seems fixed, but that might be something else that fixed? --- .../adapter/mc1_14/BukkitGetBlocks_1_14.java | 15 ++++ .../mc1_15_2/BukkitGetBlocks_1_15_2.java | 16 +++- .../mc1_16_1/BukkitAdapter_1_16_1.java | 2 +- .../mc1_16_1/BukkitGetBlocks_1_16_1.java | 17 +++- .../mc1_16_2/BukkitAdapter_1_16_2.java | 2 +- .../mc1_16_2/BukkitGetBlocks_1_16_2.java | 17 +++- .../main/java/com/boydti/fawe/FaweAPI.java | 2 +- .../main/java/com/boydti/fawe/FaweCache.java | 2 +- .../java/com/boydti/fawe/beta/IChunkGet.java | 4 + .../java/com/boydti/fawe/beta/IChunkSet.java | 10 +++ .../implementation/blocks/BitSetBlocks.java | 3 + .../implementation/blocks/CharSetBlocks.java | 15 ++++ .../blocks/FallbackChunkGet.java | 5 ++ .../implementation/blocks/NullChunkGet.kt | 5 ++ .../implementation/chunk/ChunkHolder.java | 60 +++++++++++++- .../beta/implementation/chunk/NullChunk.kt | 9 +++ .../lighting/HeightMapType.java | 5 ++ .../implementation/lighting/NMSRelighter.java | 81 ++++++++++++++++--- .../java/com/boydti/fawe/config/Settings.java | 2 + .../com/boydti/fawe/jnbt/anvil/MCAChunk.java | 9 +++ .../fawe/object/clipboard/EmptyClipboard.kt | 5 ++ .../collection/BitArrayUnstretched.java | 20 +++-- .../sk89q/worldedit/extent/InputExtent.java | 26 +++--- .../sk89q/worldedit/extent/OutputExtent.java | 4 + 24 files changed, 295 insertions(+), 41 deletions(-) create mode 100644 worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/HeightMapType.java diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java index 4df159b0b..d0feaf48f 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java @@ -5,6 +5,7 @@ import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.beta.implementation.queue.QueueHandler; import com.boydti.fawe.bukkit.adapter.DelegateLock; import com.boydti.fawe.bukkit.adapter.mc1_14.nbt.LazyCompoundTag_1_14; @@ -38,6 +39,7 @@ import net.minecraft.server.v1_14_R1.DataPaletteLinear; import net.minecraft.server.v1_14_R1.Entity; import net.minecraft.server.v1_14_R1.EntityTypes; import net.minecraft.server.v1_14_R1.EnumSkyBlock; +import net.minecraft.server.v1_14_R1.HeightMap; import net.minecraft.server.v1_14_R1.IBlockData; import net.minecraft.server.v1_14_R1.LightEngine; import net.minecraft.server.v1_14_R1.NBTTagCompound; @@ -187,6 +189,12 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { SectionPosition.b(BlockPosition.d(l))); } + @Override public int[] getHeightMap(HeightMapType type) { + long[] longArray = getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a(); + BitArray bitArray = new BitArray(9, 256, longArray); + return bitArray.toRaw(new int[256]); + } + @Override public CompoundTag getEntity(UUID uuid) { Entity entity = world.getEntity(uuid); @@ -402,6 +410,13 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { } } + Map heightMaps = set.getHeightMaps(); + for (Map.Entry entry : heightMaps.entrySet()) { + BitArray bitArray = new BitArray(9, 256); + bitArray.fromRaw(entry.getValue()); + nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData()); + } + boolean lightUpdate = false; // Lighting diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java index a48a7922f..5d986758c 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java @@ -5,6 +5,7 @@ import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.beta.implementation.queue.QueueHandler; import com.boydti.fawe.bukkit.adapter.DelegateLock; import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2; @@ -15,7 +16,6 @@ import com.google.common.base.Suppliers; import com.google.common.collect.Iterables; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.LongTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -39,6 +39,7 @@ import net.minecraft.server.v1_15_R1.DataPaletteLinear; import net.minecraft.server.v1_15_R1.Entity; import net.minecraft.server.v1_15_R1.EntityTypes; import net.minecraft.server.v1_15_R1.EnumSkyBlock; +import net.minecraft.server.v1_15_R1.HeightMap; import net.minecraft.server.v1_15_R1.IBlockData; import net.minecraft.server.v1_15_R1.LightEngine; import net.minecraft.server.v1_15_R1.NBTTagCompound; @@ -177,6 +178,12 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l))); } + @Override public int[] getHeightMap(HeightMapType type) { + long[] longArray = getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a(); + BitArray bitArray = new BitArray(9, 256, longArray); + return bitArray.toRaw(new int[256]); + } + @Override public CompoundTag getEntity(UUID uuid) { Entity entity = world.getEntity(uuid); @@ -391,6 +398,13 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { } } + Map heightMaps = set.getHeightMaps(); + for (Map.Entry entry : heightMaps.entrySet()) { + BitArray bitArray = new BitArray(9, 256); + bitArray.fromRaw(entry.getValue()); + nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData()); + } + boolean lightUpdate = false; // Lighting diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java index f799a4e12..aa8e20d18 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java @@ -238,7 +238,7 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { if (num_palette == 1) { for (int i = 0; i < blockBitArrayEnd; i++) blockStates[i] = 0; } else { - final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, blockStates); + final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, 4096, blockStates); bitArray.fromRaw(blocksCopy); } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index 92ddc7e41..95c7f312a 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -5,11 +5,13 @@ import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.beta.implementation.queue.QueueHandler; import com.boydti.fawe.bukkit.adapter.DelegateLock; import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.collection.AdaptedMap; +import com.boydti.fawe.object.collection.BitArray; import com.boydti.fawe.object.collection.BitArrayUnstretched; import com.google.common.base.Suppliers; import com.google.common.collect.Iterables; @@ -143,6 +145,12 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l))); } + @Override public int[] getHeightMap(HeightMapType type) { + long[] longArray = getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a(); + BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray); + return bitArray.toRaw(new int[256]); + } + @Override public CompoundTag getEntity(UUID uuid) { Entity entity = world.getEntity(uuid); @@ -359,6 +367,13 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { } } + Map heightMaps = set.getHeightMaps(); + for (Map.Entry entry : heightMaps.entrySet()) { + BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256); + bitArray.fromRaw(entry.getValue()); + nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData()); + } + boolean lightUpdate = false; // Lighting @@ -567,7 +582,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { final int bitsPerEntry = (int) BukkitAdapter_1_16_1.fieldBitsPerEntry.get(bits); final long[] blockStates = bits.a(); - new BitArrayUnstretched(bitsPerEntry, blockStates).toRaw(data); + new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data); int num_palette; if (palette instanceof DataPaletteLinear) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java index 88699edfa..7363160bc 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java @@ -253,7 +253,7 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { if (num_palette == 1) { for (int i = 0; i < blockBitArrayEnd; i++) blockStates[i] = 0; } else { - final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, blockStates); + final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, 4096, blockStates); bitArray.fromRaw(blocksCopy); } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java index 05772624d..32ea97d44 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java @@ -5,11 +5,13 @@ import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.beta.implementation.queue.QueueHandler; import com.boydti.fawe.bukkit.adapter.DelegateLock; import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.collection.AdaptedMap; +import com.boydti.fawe.object.collection.BitArray; import com.boydti.fawe.object.collection.BitArrayUnstretched; import com.google.common.base.Suppliers; import com.google.common.collect.Iterables; @@ -143,6 +145,12 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l))); } + @Override public int[] getHeightMap(HeightMapType type) { + long[] longArray = getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a(); + BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray); + return bitArray.toRaw(new int[256]); + } + @Override public CompoundTag getEntity(UUID uuid) { Entity entity = world.getEntity(uuid); @@ -359,6 +367,13 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { } } + Map heightMaps = set.getHeightMaps(); + for (Map.Entry entry : heightMaps.entrySet()) { + BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256); + bitArray.fromRaw(entry.getValue()); + nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData()); + } + boolean lightUpdate = false; // Lighting @@ -567,7 +582,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { final int bitsPerEntry = (int) BukkitAdapter_1_16_2.fieldBitsPerEntry.get(bits); final long[] blockStates = bits.a(); - new BitArrayUnstretched(bitsPerEntry, blockStates).toRaw(data); + new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data); int num_palette; if (palette instanceof DataPaletteLinear) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java b/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java index 8a75076a4..3267eab57 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java @@ -373,7 +373,7 @@ public class FaweAPI { } } - NMSRelighter relighter = new NMSRelighter(queue); + NMSRelighter relighter = new NMSRelighter(queue, Settings.IMP.LIGHTING.DO_HEIGHTMAPS); for (int x = minX; x <= maxX; x++) { for (int z = minZ; z <= maxZ; z++) { relighter.addChunk(x, z, null, 65535); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java b/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java index 3e83b3fd1..27544b581 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java @@ -375,7 +375,7 @@ public enum FaweCache implements Trimable { blockStates[0] = 0; blockBitArrayEnd = 1; } else { - BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, blockStates); + BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, 4096, blockStates); bitArray.fromRaw(blocksCopy); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGet.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGet.java index 43d60af11..fcde4889b 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGet.java @@ -1,5 +1,6 @@ package com.boydti.fawe.beta; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.extent.InputExtent; import com.sk89q.worldedit.world.biome.BiomeType; @@ -29,6 +30,9 @@ public interface IChunkGet extends IBlocks, Trimable, InputExtent, ITileInput { @Override int getEmmittedLight(int x, int y, int z); + @Override + int[] getHeightMap(HeightMapType type); + default void optimize() { } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkSet.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkSet.java index 46ee3e69b..16b6e61c8 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkSet.java @@ -1,11 +1,14 @@ package com.boydti.fawe.beta; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.extent.OutputExtent; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockStateHolder; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import java.util.UUID; import javax.annotation.Nullable; @@ -34,6 +37,9 @@ public interface IChunkSet extends IBlocks, OutputExtent { @Override void setSkyLight(int x, int y, int z, int value); + @Override + void setHeightMap(HeightMapType type, int[] heightMap); + void setLightLayer(int layer, char[] toSet); void setSkyLightLayer(int layer, char[] toSet); @@ -76,6 +82,10 @@ public interface IChunkSet extends IBlocks, OutputExtent { return -1; } + default Map getHeightMaps() { + return new HashMap<>(); + } + @Override IChunkSet reset(); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java index b143c744e..ae28aac4e 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java @@ -2,6 +2,7 @@ package com.boydti.fawe.beta.implementation.blocks; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkSet; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.object.collection.MemBlockSet; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.math.BlockVector3; @@ -71,6 +72,8 @@ public class BitSetBlocks implements IChunkSet { @Override public void setSkyLight(int x, int y, int z, int value) {} + @Override public void setHeightMap(HeightMapType type, int[] heightMap) {} + @Override public void setLightLayer(int layer, char[] toSet) {} @Override public void setSkyLightLayer(int layer, char[] toSet) {} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java index 80c13563d..8f7dffee3 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java @@ -2,6 +2,7 @@ package com.boydti.fawe.beta.implementation.blocks; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkSet; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.beta.implementation.queue.Pool; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.collection.BlockVector3ChunkMap; @@ -14,6 +15,7 @@ import org.jetbrains.annotations.Range; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -32,6 +34,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { public BlockVector3ChunkMap tiles; public HashSet entities; public HashSet entityRemoves; + public Map heightMaps; private boolean fastMode = false; private int bitMask = -1; @@ -73,6 +76,11 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { return entityRemoves == null ? Collections.emptySet() : entityRemoves; } + @Override + public Map getHeightMaps() { + return heightMaps == null ? new HashMap<>() : heightMaps; + } + @Override public boolean setBiome(int x, int y, int z, BiomeType biome) { if (biomes == null) { @@ -138,6 +146,13 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { skyLight[y >> 4][index] = (char) value; } + @Override public void setHeightMap(HeightMapType type, int[] heightMap) { + if (heightMaps == null) { + heightMaps = new HashMap<>(); + } + heightMaps.put(type, heightMap); + } + @Override public void setLightLayer(int layer, char[] toSet) { if (light == null) { light = new char[16][]; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/FallbackChunkGet.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/FallbackChunkGet.java index b70c5a0a2..d407f14c1 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/FallbackChunkGet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/FallbackChunkGet.java @@ -4,6 +4,7 @@ import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IBlocks; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkSet; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; @@ -50,6 +51,10 @@ public class FallbackChunkGet implements IChunkGet { return extent.getSkyLight(bx + x, y, bz + z); } + @Override public int[] getHeightMap(HeightMapType type) { + return extent.getHeightMap(type); + } + @Override public int getEmmittedLight(int x, int y, int z) { return extent.getEmmittedLight(bx + x, y, bz + z); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/NullChunkGet.kt b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/NullChunkGet.kt index 3d938ea06..86cbbe198 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/NullChunkGet.kt +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/NullChunkGet.kt @@ -4,6 +4,7 @@ import com.boydti.fawe.FaweCache import com.boydti.fawe.beta.IBlocks import com.boydti.fawe.beta.IChunkGet import com.boydti.fawe.beta.IChunkSet +import com.boydti.fawe.beta.implementation.lighting.HeightMapType import com.sk89q.jnbt.CompoundTag import com.sk89q.worldedit.math.BlockVector3 import com.sk89q.worldedit.world.biome.BiomeType @@ -72,6 +73,10 @@ object NullChunkGet : IChunkGet { return 15 } + override fun getHeightMap(type: HeightMapType?): IntArray { + return IntArray(256) + } + override fun reset(): IBlocks? { return null } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/ChunkHolder.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/ChunkHolder.java index fb7e8b989..6c311b0e9 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/ChunkHolder.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/ChunkHolder.java @@ -8,6 +8,7 @@ import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IQueueChunk; import com.boydti.fawe.beta.IQueueExtent; import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.beta.implementation.queue.Pool; import com.boydti.fawe.config.Settings; import com.sk89q.jnbt.CompoundTag; @@ -192,6 +193,10 @@ public class ChunkHolder> implements IQueueChunk { chunk.chunkSet.setSkyLightLayer(layer, toSet); } + @Override public void setHeightMap(ChunkHolder chunk, HeightMapType type, int[] heightMap) { + chunk.chunkSet.setHeightMap(type, heightMap); + } + @Override public BiomeType getBiome(ChunkHolder chunk, int x, int y, int z) { return chunk.chunkExisting.getBiomeType(x, y, z); @@ -245,8 +250,12 @@ public class ChunkHolder> implements IQueueChunk { public int getOpacity(ChunkHolder chunk, int x, int y, int z) { return chunk.chunkExisting.getOpacity(x, y, z); } + + @Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) { + return chunk.chunkExisting.getHeightMap(type); + } }; - + private static final IBlockDelegate GET = new IBlockDelegate() { @Override public IChunkGet get(ChunkHolder chunk) { @@ -318,6 +327,12 @@ public class ChunkHolder> implements IQueueChunk { chunk.setSkyLightLayer(layer, toSet); } + @Override public void setHeightMap(ChunkHolder chunk, HeightMapType type, int[] heightMap) { + chunk.getOrCreateSet(); + chunk.delegate = BOTH; + chunk.setHeightMap(type, heightMap); + } + @Override public BiomeType getBiome(ChunkHolder chunk, int x, int y, int z) { return chunk.chunkExisting.getBiomeType(x, y, z); @@ -353,8 +368,12 @@ public class ChunkHolder> implements IQueueChunk { public int getOpacity(ChunkHolder chunk, int x, int y, int z) { return chunk.chunkExisting.getOpacity(x, y, z); } + + @Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) { + return chunk.chunkExisting.getHeightMap(type); + } }; - + private static final IBlockDelegate SET = new IBlockDelegate() { @Override public IChunkGet get(ChunkHolder chunk) { @@ -409,6 +428,10 @@ public class ChunkHolder> implements IQueueChunk { chunk.chunkSet.setSkyLightLayer(layer, toSet); } + @Override public void setHeightMap(ChunkHolder chunk, HeightMapType type, int[] heightMap) { + chunk.chunkSet.setHeightMap(type, heightMap); + } + @Override public BiomeType getBiome(ChunkHolder chunk, int x, int y, int z) { chunk.getOrCreateGet(); @@ -476,8 +499,14 @@ public class ChunkHolder> implements IQueueChunk { chunk.delegate = BOTH; return chunk.getOpacity(x, y, z); } + + @Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) { + chunk.getOrCreateGet(); + chunk.delegate = BOTH; + return chunk.getHeightMap(type); + } }; - + private static final IBlockDelegate NULL = new IBlockDelegate() { @Override public IChunkGet get(ChunkHolder chunk) { @@ -575,6 +604,12 @@ public class ChunkHolder> implements IQueueChunk { chunk.setSkyLightLayer(layer, toSet); } + @Override public void setHeightMap(ChunkHolder chunk, HeightMapType type, int[] heightMap) { + chunk.getOrCreateSet(); + chunk.delegate = SET; + chunk.setHeightMap(type, heightMap); + } + @Override public int getSkyLight(ChunkHolder chunk, int x, int y, int z) { chunk.getOrCreateGet(); @@ -606,6 +641,13 @@ public class ChunkHolder> implements IQueueChunk { chunk.chunkExisting.trim(false); return chunk.getOpacity(x, y, z); } + + @Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) { + chunk.getOrCreateGet(); + chunk.delegate = GET; + chunk.chunkExisting.trim(false); + return chunk.getHeightMap(type); + } }; @Override @@ -791,6 +833,10 @@ public class ChunkHolder> implements IQueueChunk { delegate.setSkyLight(this, x, y, z, value); } + @Override public void setHeightMap(HeightMapType type, int[] heightMap) { + delegate.setHeightMap(this, type, heightMap); + } + @Override public void removeSectionLighting(int layer, boolean sky) { delegate.removeSectionLighting(this, layer, sky); } @@ -834,6 +880,10 @@ public class ChunkHolder> implements IQueueChunk { return delegate.getOpacity(this, x, y, z); } + @Override public int[] getHeightMap(HeightMapType type) { + return delegate.getHeightMap(this, type); + } + public interface IBlockDelegate { > IChunkGet get(ChunkHolder chunk); IChunkSet set(ChunkHolder chunk); @@ -860,6 +910,8 @@ public class ChunkHolder> implements IQueueChunk { void setSkyLightLayer(ChunkHolder chunk, int layer, char[] toSet); + void setHeightMap(ChunkHolder chunk, HeightMapType type, int[] heightMap); + int getSkyLight(ChunkHolder chunk, int x, int y, int z); int getEmmittedLight(ChunkHolder chunk, int x, int y, int z); @@ -867,5 +919,7 @@ public class ChunkHolder> implements IQueueChunk { int getBrightness(ChunkHolder chunk, int x, int y, int z); int getOpacity(ChunkHolder chunk, int x, int y, int z); + + int[] getHeightMap(ChunkHolder chunk, HeightMapType type); } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/NullChunk.kt b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/NullChunk.kt index 301cb4f4a..305877e07 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/NullChunk.kt +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/NullChunk.kt @@ -4,6 +4,7 @@ import com.boydti.fawe.beta.Filter import com.boydti.fawe.beta.IChunkSet import com.boydti.fawe.beta.IQueueChunk import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock +import com.boydti.fawe.beta.implementation.lighting.HeightMapType import com.sk89q.jnbt.CompoundTag import com.sk89q.worldedit.math.BlockVector3 import com.sk89q.worldedit.regions.Region @@ -74,6 +75,10 @@ object NullChunk : IQueueChunk { return emptyArray() } + override fun getHeightMap(type: HeightMapType?): IntArray { + return IntArray(256) + } + override fun getEmmittedLight(x: Int, y: Int, z: Int): Int { return 15 } @@ -82,6 +87,10 @@ object NullChunk : IQueueChunk { } + override fun setHeightMap(type: HeightMapType?, heightMap: IntArray?) { + + } + override fun fullySupports3DBiomes(): Boolean { return false } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/HeightMapType.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/HeightMapType.java new file mode 100644 index 000000000..0ff367285 --- /dev/null +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/HeightMapType.java @@ -0,0 +1,5 @@ +package com.boydti.fawe.beta.implementation.lighting; + +public enum HeightMapType { + MOTION_BLOCKING, MOTION_BLOCKING_NO_LEAVES, OCEAN_FLOOR, WORLD_SURFACE +} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java index 1c515fd60..b4b7b131c 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java @@ -5,6 +5,7 @@ import com.boydti.fawe.beta.IQueueExtent; import com.boydti.fawe.beta.implementation.chunk.ChunkHolder; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.RunnableVal; +import com.boydti.fawe.object.collection.BitArray; import com.boydti.fawe.object.collection.BlockVectorSet; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.TaskManager; @@ -14,6 +15,7 @@ import com.sk89q.worldedit.registry.state.EnumProperty; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.registry.BlockMaterial; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -50,20 +52,24 @@ public class NMSRelighter implements Relighter { private final Map skyToRelight; private final Object present = new Object(); private final Map chunksToSend; + private final Map> heightMaps; private final ConcurrentLinkedQueue extentdSkyToRelight = new ConcurrentLinkedQueue<>(); private final Map lightQueue; private final AtomicBoolean lightLock = new AtomicBoolean(false); private final ConcurrentHashMap concurrentLightQueue; private final int maxY; + private final boolean calculateHeightMaps; private boolean removeFirst; - public NMSRelighter(IQueueExtent queue) { + public NMSRelighter(IQueueExtent queue, boolean calculateHeightMaps) { this.queue = queue; this.skyToRelight = new Long2ObjectOpenHashMap<>(12); this.lightQueue = new Long2ObjectOpenHashMap<>(12); this.chunksToSend = new Long2ObjectOpenHashMap<>(12); this.concurrentLightQueue = new ConcurrentHashMap<>(12); + this.heightMaps = new Long2ObjectOpenHashMap<>(12); this.maxY = queue.getMaxY(); + this.calculateHeightMaps = calculateHeightMaps; } @Override public boolean isEmpty() { @@ -93,7 +99,7 @@ public class NMSRelighter implements Relighter { if (m2 == null) { m2 = m1[x] = new long[4]; } - long value = m2[y >> 6] |= 1l << y; + m2[y >> 6] |= 1L << y; } public void addLightUpdate(int x, int y, int z) { @@ -125,11 +131,12 @@ public class NMSRelighter implements Relighter { extentdSkyToRelight.clear(); skyToRelight.clear(); chunksToSend.clear(); + heightMaps.clear(); lightQueue.clear(); } 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, calculateHeightMaps); extentdSkyToRelight.add(toPut); return true; } @@ -791,6 +798,14 @@ public class NMSRelighter implements Relighter { int z = MathMan.unpairIntY(pair); ChunkHolder chunk = (ChunkHolder) queue.getOrCreateChunk(x, z); chunk.setBitMask(bitMask); + if (calculateHeightMaps && heightMaps != null) { + Map heightMapList = heightMaps.get(pair); + if (heightMapList != null) { + for (Map.Entry heightMapEntry : heightMapList.entrySet()){ + chunk.setHeightMap(heightMapEntry.getKey(), heightMapEntry.getValue()); + } + } + } iter.remove(); } if (Settings.IMP.LIGHTING.ASYNC) { @@ -856,18 +871,33 @@ public class NMSRelighter implements Relighter { private void fixSkyLighting(List sorted) { RelightSkyEntry[] chunks = sorted.toArray(new RelightSkyEntry[sorted.size()]); boolean remove = this.removeFirst; + boolean heightMaps = this.calculateHeightMaps; BlockVectorSet chunkSet = null; - if (remove) { - chunkSet = new BlockVectorSet(); + if (remove || heightMaps) { BlockVectorSet tmpSet = new BlockVectorSet(); - for (RelightSkyEntry chunk : chunks) { - tmpSet.add(chunk.x, 0, chunk.z); + if (remove) { + chunkSet = new BlockVectorSet(); + for (RelightSkyEntry chunk : chunks) { + tmpSet.add(chunk.x, 0, chunk.z); + } } for (RelightSkyEntry chunk : chunks) { - int x = chunk.x; - int z = chunk.z; - if (tmpSet.contains(x + 1, 0, z) && tmpSet.contains(x - 1, 0, z) && tmpSet.contains(x, 0, z + 1) && tmpSet.contains(x, 0, z - 1)) { - chunkSet.add(x, 0, z); + if (remove) { + int x = chunk.x; + int z = chunk.z; + if (tmpSet.contains(x + 1, 0, z) && tmpSet.contains(x - 1, 0, z) && tmpSet.contains(x, 0, z + 1) && tmpSet + .contains(x, 0, z - 1)) { + chunkSet.add(x, 0, z); + } + } + if (heightMaps) { + long pair = MathMan.pairInt(chunk.x, chunk.z); + this.heightMaps.putIfAbsent(pair, new HashMap<>()); + Map heightMapList = this.heightMaps.get(pair); + heightMapList.putIfAbsent(HeightMapType.WORLD_SURFACE, new int[256]); + heightMapList.putIfAbsent(HeightMapType.OCEAN_FLOOR, new int[256]); + heightMapList.putIfAbsent(HeightMapType.MOTION_BLOCKING, new int[256]); + heightMapList.putIfAbsent(HeightMapType.MOTION_BLOCKING_NO_LEAVES, new int[256]); } } } @@ -893,17 +923,42 @@ public class NMSRelighter implements Relighter { iChunk.removeSectionLighting(y >> 4, true); } + Map heightMapList = null; + if (heightMaps) { + long pair = MathMan.pairInt(chunk.x, chunk.z); + heightMapList = this.heightMaps.get(pair); + } + for (int j = 0; j < 256; j++) { int x = j & 15; int z = j >> 4; byte value = mask[j]; - BlockMaterial material = iChunk.getBlock(x, y, z).getBlockType().getMaterial(); + BlockType type = iChunk.getBlock(x, y, z).getBlockType(); + BlockMaterial material = type.getMaterial(); int opacity = material.getLightOpacity(); int brightness = iChunk.getBrightness(x, y, z); boolean solidNeedsLight = (!material.isSolid() || !material.isFullCube()) && material.getLightOpacity() > 0; if (brightness > 1) { addLightUpdate(bx + x, y, bz + z); } + + if (heightMaps) { + if (heightMapList.get(HeightMapType.WORLD_SURFACE)[j] == 0 && !material.isAir()) { + // MC Requires y+1 + heightMapList.get(HeightMapType.WORLD_SURFACE)[j] = y + 1; + } + if (heightMapList.get(HeightMapType.OCEAN_FLOOR)[j] == 0 && material.isSolid()) { + heightMapList.get(HeightMapType.OCEAN_FLOOR)[j] = y + 1; + } + if (heightMapList.get(HeightMapType.MOTION_BLOCKING)[j] == 0 && (material.isSolid() || material.isLiquid())) { + heightMapList.get(HeightMapType.MOTION_BLOCKING)[j] = y + 1; + } + if (heightMapList.get(HeightMapType.MOTION_BLOCKING_NO_LEAVES)[j] == 0 && (material.isSolid() || material.isLiquid()) && !type + .getId().toLowerCase().contains("leaves")) { + heightMapList.get(HeightMapType.MOTION_BLOCKING_NO_LEAVES)[j] = y + 1; + } + } + switch (value) { case 0: if (opacity > 1) { @@ -1081,7 +1136,7 @@ public class NMSRelighter implements Relighter { public int bitmask; public boolean smooth; - public RelightSkyEntry(int x, int z, byte[] fix, int bitmask) { + public RelightSkyEntry(int x, int z, byte[] fix, int bitmask, boolean heightmaps) { this.x = x; this.z = z; byte[] array = new byte[256]; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java b/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java index 5707e9d60..7bb4bf232 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java @@ -481,6 +481,8 @@ public class Settings extends Config { public int MODE = 1; @Comment({"If existing lighting should be removed before relighting"}) public boolean REMOVE_FIRST = true; + @Comment({"Calculate and set heightmaps when relighting"}) + public boolean DO_HEIGHTMAPS = true; } public void reload(File file) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java index c2178dd4a..5ad437a09 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java @@ -6,6 +6,7 @@ import com.boydti.fawe.beta.IChunk; import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IQueueExtent; import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.jnbt.streamer.StreamDelegate; import com.boydti.fawe.jnbt.streamer.ValueReader; import com.boydti.fawe.object.collection.BitArray; @@ -443,6 +444,10 @@ public class MCAChunk implements IChunk { } + @Override public void setHeightMap(HeightMapType type, int[] heightMap) { + + } + @Override public void removeSectionLighting(int layer, boolean sky) {} @Override public void setFullBright(int layer) {} @@ -533,6 +538,10 @@ public class MCAChunk implements IChunk { return 0; } + @Override public int[] getHeightMap(HeightMapType type) { + return new int[256]; + } + @Override public BaseBlock getFullBlock(int x, int y, int z) { BlockState block = getBlock(x, y, z); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/EmptyClipboard.kt b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/EmptyClipboard.kt index 185b79a65..95664bcbe 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/EmptyClipboard.kt +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/EmptyClipboard.kt @@ -1,5 +1,6 @@ package com.boydti.fawe.`object`.clipboard +import com.boydti.fawe.beta.implementation.lighting.HeightMapType import com.sk89q.jnbt.CompoundTag import com.sk89q.worldedit.WorldEditException import com.sk89q.worldedit.entity.Entity @@ -49,6 +50,10 @@ object EmptyClipboard : Clipboard { return null } + override fun getHeightMap(type: HeightMapType?): IntArray { + return IntArray(256) + } + @Throws(WorldEditException::class) override fun ?> setBlock(position: BlockVector3, block: T): Boolean { return false diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/BitArrayUnstretched.java b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/BitArrayUnstretched.java index 9572eecc9..d5af50a0a 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/BitArrayUnstretched.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/BitArrayUnstretched.java @@ -11,13 +11,13 @@ public final class BitArrayUnstretched { private final long mask; private final int longLen; - public BitArrayUnstretched(int bitsPerEntry, long[] buffer) { + public BitArrayUnstretched(int bitsPerEntry, int arraySize, long[] buffer) { this.bitsPerEntry = bitsPerEntry; this.mask = (1L << bitsPerEntry) - 1L; this.emptyBitCount = 64 % bitsPerEntry; this.maxSeqLocIndex = 64 - (bitsPerEntry + emptyBitCount); final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry); - this.longLen = MathMan.ceilZero((float) 4096 / blocksPerLong); + this.longLen = MathMan.ceilZero((float) arraySize / blocksPerLong); if (buffer.length < longLen) { this.data = new long[longLen]; } else { @@ -25,6 +25,16 @@ public final class BitArrayUnstretched { } } + public BitArrayUnstretched(int bitsPerEntry, int arraySize) { + this.bitsPerEntry = bitsPerEntry; + this.mask = (1L << bitsPerEntry) - 1L; + this.emptyBitCount = 64 % bitsPerEntry; + this.maxSeqLocIndex = 64 - bitsPerEntry; + final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry); + this.longLen = MathMan.ceilZero((float) arraySize / blocksPerLong); + this.data = new long[longLen]; + } + public long[] getData() { return data; } @@ -61,7 +71,7 @@ public final class BitArrayUnstretched { long l = 0; for (int i = 0; i < longLen; i++) { int lastVal; - for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) { + for (; localStart <= maxSeqLocIndex && arrI < arr.length; localStart += bitsPerEntry) { lastVal = arr[arrI++]; l |= ((long) lastVal << localStart); } @@ -85,7 +95,7 @@ public final class BitArrayUnstretched { for (int i = 0; i < longLen; i++) { long l = data[i]; char lastVal; - for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) { + for (; localStart <= maxSeqLocIndex && arrI < buffer.length; localStart += bitsPerEntry) { lastVal = (char) (l >>> localStart & this.mask); buffer[arrI++] = lastVal; } @@ -104,7 +114,7 @@ public final class BitArrayUnstretched { for (int i = 0; i < longLen; i++) { long l = data[i]; char lastVal; - for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) { + for (; localStart <= maxSeqLocIndex && arrI < buffer.length; localStart += bitsPerEntry) { lastVal = (char) (l >>> localStart & this.mask); buffer[arrI++] = lastVal; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java index 39a538982..b7bec77d2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.extent; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.internal.util.DeprecationUtil; import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility; @@ -80,8 +81,7 @@ public interface InputExtent { * @return the biome at the location * @deprecated Biomes in Minecraft are 3D now, use {@link InputExtent#getBiome(BlockVector3)} */ - @Deprecated - default BiomeType getBiome(BlockVector2 position) { + @Deprecated default BiomeType getBiome(BlockVector2 position) { return getBiomeType(position.getX(), 0, position.getZ()); } @@ -93,26 +93,22 @@ public interface InputExtent { * Get the biome at the given location. * *

- * If there is no biome available, then the ocean biome should be - * returned. + * If there is no biome available, then the ocean biome should be + * returned. *

* *

- * As implementation varies per Minecraft version, this may not exactly get - * this positions biome. On versions prior to 1.15, this will get the entire - * column. On later versions it will get the 4x4x4 cube's biome. + * As implementation varies per Minecraft version, this may not exactly get + * this positions biome. On versions prior to 1.15, this will get the entire + * column. On later versions it will get the 4x4x4 cube's biome. *

* * @param position the (x, y, z) location to check the biome at * @return the biome at the location * @apiNote This must be overridden by new subclasses. See {@link NonAbstractForCompatibility} - * for details + * for details */ - @NonAbstractForCompatibility( - delegateName = "getBiome", - delegateParams = { BlockVector2.class } - ) - default BiomeType getBiome(BlockVector3 position) { + @NonAbstractForCompatibility(delegateName = "getBiome", delegateParams = {BlockVector2.class}) default BiomeType getBiome(BlockVector3 position) { DeprecationUtil.checkDelegatingOverride(getClass()); return getBiome(position.toBlockVector2()); @@ -161,4 +157,8 @@ public interface InputExtent { default int getOpacity(int x, int y, int z) { return getFullBlock(x, y, z).getMaterial().getLightOpacity(); } + + default int[] getHeightMap(HeightMapType type) { + return new int[256]; + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java index f289b0fa8..6ef2dd34d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.extent; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.function.operation.Operation; @@ -158,6 +159,9 @@ public interface OutputExtent { default void setSkyLight(int x, int y, int z, int value) { } + default void setHeightMap(HeightMapType type, int[] heightMap) { + } + /** * Return an {@link Operation} that should be called to tie up loose ends * (such as to commit changes in a buffer).