From 6d69a3f8edd58c032a6586fe8eaaeadd162de23f Mon Sep 17 00:00:00 2001 From: LudoCrypt <60561627+LudoCrypt@users.noreply.github.com> Date: Sat, 30 Dec 2023 07:13:56 -0600 Subject: [PATCH] Tags --- gradle.properties | 2 +- .../limlib/api/effects/post/PostEffect.java | 5 + .../api/effects/sky/DimensionEffects.java | 11 ++ .../sound/distortion/DistortionEffect.java | 6 + .../effects/sound/reverb/ReverbEffect.java | 4 + .../ludocrypt/limlib/api/skybox/Skybox.java | 5 + .../chunk/AbstractNbtChunkGenerator.java | 51 +++--- .../limlib/api/world/maze/MazeComponent.java | 31 ++-- .../api/world/maze/storage/MazeStorage.java | 5 +- .../api/world/maze/storage/NbtSerializer.java | 11 -- .../api/world/{ => nbt}/FunctionMap.java | 2 +- .../api/world/nbt/ImmutableNbtCompound.java | 162 ++++++++++++++++++ .../api/world/nbt/ImmutableNbtList.java | 145 ++++++++++++++++ .../limlib/api/world/{ => nbt}/NbtGroup.java | 57 +++++- .../api/world/{ => nbt}/NbtPlacerUtil.java | 21 ++- .../limlib/api/world/nbt/NbtSerializer.java | 16 ++ .../limlib/api/world/nbt/NbtTags.java | 78 +++++++++ .../net/ludocrypt/limlib/impl/Limlib.java | 30 +--- .../impl/debug/DebugNbtChunkGenerator.java | 8 +- .../impl/mixin/NbtCompoundAccessor.java | 21 +++ .../limlib/impl/mixin/NbtListAccessor.java | 27 +++ .../limlib/impl/mixin/ServerWorldMixin.java | 7 +- src/main/resources/limlib.mixins.json | 2 + 23 files changed, 622 insertions(+), 85 deletions(-) delete mode 100644 src/main/java/net/ludocrypt/limlib/api/world/maze/storage/NbtSerializer.java rename src/main/java/net/ludocrypt/limlib/api/world/{ => nbt}/FunctionMap.java (96%) create mode 100644 src/main/java/net/ludocrypt/limlib/api/world/nbt/ImmutableNbtCompound.java create mode 100644 src/main/java/net/ludocrypt/limlib/api/world/nbt/ImmutableNbtList.java rename src/main/java/net/ludocrypt/limlib/api/world/{ => nbt}/NbtGroup.java (73%) rename src/main/java/net/ludocrypt/limlib/api/world/{ => nbt}/NbtPlacerUtil.java (96%) create mode 100644 src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtSerializer.java create mode 100644 src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtTags.java create mode 100644 src/main/java/net/ludocrypt/limlib/impl/mixin/NbtCompoundAccessor.java create mode 100644 src/main/java/net/ludocrypt/limlib/impl/mixin/NbtListAccessor.java diff --git a/gradle.properties b/gradle.properties index cf82282..568d229 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ org.gradle.jvmargs = -Xmx1G org.gradle.parallel = true -version = b12.0.3 +version = b12.0.4 maven_group = net.ludocrypt archives_base_name = limlib \ No newline at end of file diff --git a/src/main/java/net/ludocrypt/limlib/api/effects/post/PostEffect.java b/src/main/java/net/ludocrypt/limlib/api/effects/post/PostEffect.java index f8ca14e..47a44b4 100644 --- a/src/main/java/net/ludocrypt/limlib/api/effects/post/PostEffect.java +++ b/src/main/java/net/ludocrypt/limlib/api/effects/post/PostEffect.java @@ -24,6 +24,11 @@ public abstract class PostEffect { public abstract Codec getCodec(); + public static void init() { + Registry.register(PostEffect.POST_EFFECT_CODEC, new Identifier("limlib", "static"), StaticPostEffect.CODEC); + Registry.register(PostEffect.POST_EFFECT_CODEC, new Identifier("limlib", "empty"), EmptyPostEffect.CODEC); + } + public abstract boolean shouldRender(); public abstract void beforeRender(); diff --git a/src/main/java/net/ludocrypt/limlib/api/effects/sky/DimensionEffects.java b/src/main/java/net/ludocrypt/limlib/api/effects/sky/DimensionEffects.java index 90b3e8f..7226b4b 100644 --- a/src/main/java/net/ludocrypt/limlib/api/effects/sky/DimensionEffects.java +++ b/src/main/java/net/ludocrypt/limlib/api/effects/sky/DimensionEffects.java @@ -3,6 +3,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; +import org.quiltmc.loader.api.ModInternal; import org.quiltmc.loader.api.minecraft.ClientOnly; import com.mojang.serialization.Codec; @@ -30,10 +31,20 @@ public abstract class DimensionEffects { public static final RegistryKey> DIMENSION_EFFECTS_KEY = RegistryKey .ofRegistry(new Identifier("limlib/dimension_effects")); + @ModInternal public static final AtomicReference> MIXIN_WORLD_LOOKUP = new AtomicReference>(); public abstract Codec getCodec(); + public static void init() { + Registry + .register(DimensionEffects.DIMENSION_EFFECTS_CODEC, new Identifier("limlib", "static"), + StaticDimensionEffects.CODEC); + Registry + .register(DimensionEffects.DIMENSION_EFFECTS_CODEC, new Identifier("limlib", "empty"), + EmptyDimensionEffects.CODEC); + } + @ClientOnly public abstract DimensionVisualEffects getDimensionEffects(); diff --git a/src/main/java/net/ludocrypt/limlib/api/effects/sound/distortion/DistortionEffect.java b/src/main/java/net/ludocrypt/limlib/api/effects/sound/distortion/DistortionEffect.java index 6296a2b..59dfe3b 100644 --- a/src/main/java/net/ludocrypt/limlib/api/effects/sound/distortion/DistortionEffect.java +++ b/src/main/java/net/ludocrypt/limlib/api/effects/sound/distortion/DistortionEffect.java @@ -27,6 +27,12 @@ public abstract class DistortionEffect { public abstract Codec getCodec(); + public static void init() { + Registry + .register(DistortionEffect.DISTORTION_EFFECT_CODEC, new Identifier("limlib", "static"), + StaticDistortionEffect.CODEC); + } + /** * Whether or not a Sound Event should be ignored * diff --git a/src/main/java/net/ludocrypt/limlib/api/effects/sound/reverb/ReverbEffect.java b/src/main/java/net/ludocrypt/limlib/api/effects/sound/reverb/ReverbEffect.java index 25daa1f..61a78c8 100644 --- a/src/main/java/net/ludocrypt/limlib/api/effects/sound/reverb/ReverbEffect.java +++ b/src/main/java/net/ludocrypt/limlib/api/effects/sound/reverb/ReverbEffect.java @@ -27,6 +27,10 @@ public abstract class ReverbEffect { public abstract Codec getCodec(); + public static void init() { + Registry.register(ReverbEffect.REVERB_EFFECT_CODEC, new Identifier("limlib", "static"), StaticReverbEffect.CODEC); + } + /** * Whether or not a Sound Event should be ignored * diff --git a/src/main/java/net/ludocrypt/limlib/api/skybox/Skybox.java b/src/main/java/net/ludocrypt/limlib/api/skybox/Skybox.java index 1e685b8..f23e9c6 100644 --- a/src/main/java/net/ludocrypt/limlib/api/skybox/Skybox.java +++ b/src/main/java/net/ludocrypt/limlib/api/skybox/Skybox.java @@ -27,6 +27,11 @@ public abstract class Skybox { public abstract Codec getCodec(); + public static void init() { + Registry.register(Skybox.SKYBOX_CODEC, new Identifier("limlib", "empty"), EmptySkybox.CODEC); + Registry.register(Skybox.SKYBOX_CODEC, new Identifier("limlib", "textured"), TexturedSkybox.CODEC); + } + @ClientOnly public abstract void renderSky(WorldRenderer worldRenderer, MinecraftClient client, MatrixStack matrices, Matrix4f projectionMatrix, float tickDelta); diff --git a/src/main/java/net/ludocrypt/limlib/api/world/chunk/AbstractNbtChunkGenerator.java b/src/main/java/net/ludocrypt/limlib/api/world/chunk/AbstractNbtChunkGenerator.java index 6c98fe0..418a058 100644 --- a/src/main/java/net/ludocrypt/limlib/api/world/chunk/AbstractNbtChunkGenerator.java +++ b/src/main/java/net/ludocrypt/limlib/api/world/chunk/AbstractNbtChunkGenerator.java @@ -2,11 +2,12 @@ import java.util.Optional; -import net.ludocrypt.limlib.api.world.FunctionMap; import net.ludocrypt.limlib.api.world.LimlibHelper; import net.ludocrypt.limlib.api.world.Manipulation; -import net.ludocrypt.limlib.api.world.NbtGroup; -import net.ludocrypt.limlib.api.world.NbtPlacerUtil; +import net.ludocrypt.limlib.api.world.nbt.FunctionMap; +import net.ludocrypt.limlib.api.world.nbt.NbtGroup; +import net.ludocrypt.limlib.api.world.nbt.NbtPlacerUtil; +import net.ludocrypt.limlib.api.world.nbt.NbtTags; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -15,6 +16,7 @@ import net.minecraft.loot.LootTables; import net.minecraft.nbt.NbtCompound; import net.minecraft.resource.ResourceManager; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.world.ChunkRegion; @@ -24,6 +26,7 @@ public abstract class AbstractNbtChunkGenerator extends LiminalChunkGenerator { public final NbtGroup nbtGroup; public final FunctionMap structures; + public NbtTags tags; public AbstractNbtChunkGenerator(BiomeSource biomeSource, NbtGroup nbtGroup) { this(biomeSource, nbtGroup, new FunctionMap(NbtPlacerUtil::load)); @@ -37,6 +40,14 @@ public AbstractNbtChunkGenerator(BiomeSource biomeSource, NbtGroup nbtGroup, this.nbtGroup.fill(structures); } + public void loadTags(ServerWorld world) { + + if (this.tags == null) { + this.tags = NbtTags.parse(this.nbtGroup, world.getServer().getResourceManager()); + } + + } + public void generateNbt(ChunkRegion region, BlockPos at, Identifier id) { generateNbt(region, at, id, Manipulation.NONE); } @@ -78,36 +89,32 @@ public void generateNbt(ChunkRegion region, BlockPos offset, BlockPos from, Bloc protected void modifyStructure(ChunkRegion region, BlockPos pos, BlockState state, Optional blockEntityNbt) { - this.modifyStructure(region, pos, state, blockEntityNbt, Block.NOTIFY_ALL); + this.modifyStructure(region, pos, state, blockEntityNbt, Block.NOTIFY_ALL, 1); } protected void modifyStructure(ChunkRegion region, BlockPos pos, BlockState state, Optional blockEntityNbt, - int update) { + int update, int depth) { - if (!state.isAir()) { - - if (state.isOf(Blocks.BARRIER)) { - region.setBlockState(pos, Blocks.AIR.getDefaultState(), update, 1); - } else { - region.setBlockState(pos, state, update, 1); - } + if (state.isOf(Blocks.STRUCTURE_VOID)) { + return; + } - if (blockEntityNbt.isPresent()) { - BlockEntity blockEntity = region.getBlockEntity(pos); + region.setBlockState(pos, state, update, depth); - if (blockEntity != null) { + if (blockEntityNbt.isPresent()) { + BlockEntity blockEntity = region.getBlockEntity(pos); - if (state.isOf(blockEntity.getCachedState().getBlock())) { - blockEntity.readNbt(blockEntityNbt.get()); - } + if (blockEntity != null) { + if (state.isOf(blockEntity.getCachedState().getBlock())) { + blockEntity.readNbt(blockEntityNbt.get()); } - if (blockEntity instanceof LootableContainerBlockEntity lootTable) { - lootTable - .setLootTable(this.getContainerLootTable(lootTable), region.getSeed() + LimlibHelper.blockSeed(pos)); - } + } + if (blockEntity instanceof LootableContainerBlockEntity lootTable) { + lootTable + .setLootTable(this.getContainerLootTable(lootTable), region.getSeed() + LimlibHelper.blockSeed(pos)); } } diff --git a/src/main/java/net/ludocrypt/limlib/api/world/maze/MazeComponent.java b/src/main/java/net/ludocrypt/limlib/api/world/maze/MazeComponent.java index e345e9a..e0e1c3a 100644 --- a/src/main/java/net/ludocrypt/limlib/api/world/maze/MazeComponent.java +++ b/src/main/java/net/ludocrypt/limlib/api/world/maze/MazeComponent.java @@ -6,7 +6,8 @@ import com.google.common.collect.Maps; -import net.ludocrypt.limlib.api.world.maze.storage.NbtSerializer; +import net.ludocrypt.limlib.api.world.nbt.ImmutableNbtCompound; +import net.ludocrypt.limlib.api.world.nbt.NbtSerializer; import net.minecraft.nbt.NbtCompound; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3i; @@ -56,7 +57,6 @@ public String toString() { for (int y = 0; y < height; y++) { row.append(cellState(width - x, y).toString()); - } row.append("\n"); @@ -66,21 +66,22 @@ public String toString() { } @Override - public NbtCompound write(NbtCompound nbt) { + public ImmutableNbtCompound write() { + NbtCompound nbt = new NbtCompound(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { - nbt.put(x + "." + y, this.cellState(x, y).write(new NbtCompound())); + nbt.put(x + "." + y, this.cellState(x, y).write()); } } - return nbt; + return new ImmutableNbtCompound(nbt); } @Override - public MazeComponent read(NbtCompound nbt) { + public MazeComponent read(ImmutableNbtCompound nbt) { for (int x = 0; x < width; x++) { @@ -264,12 +265,14 @@ public String toString() { } @Override - public NbtCompound write(NbtCompound nbt) { + public ImmutableNbtCompound write() { + NbtCompound nbt = new NbtCompound(); + nbt.putBoolean("up", up); nbt.putBoolean("down", down); nbt.putBoolean("left", left); nbt.putBoolean("right", right); - nbt.put("pos", this.position.write(new NbtCompound())); + nbt.put("pos", this.position.write()); NbtCompound extraData = new NbtCompound(); @@ -279,11 +282,11 @@ public NbtCompound write(NbtCompound nbt) { nbt.put("extra", extraData); - return nbt; + return new ImmutableNbtCompound(nbt); } @Override - public CellState read(NbtCompound nbt) { + public CellState read(ImmutableNbtCompound nbt) { this.up = nbt.getBoolean("up"); this.down = nbt.getBoolean("down"); this.left = nbt.getBoolean("left"); @@ -425,15 +428,17 @@ public String toString() { } @Override - public NbtCompound write(NbtCompound nbt) { + public ImmutableNbtCompound write() { + NbtCompound nbt = new NbtCompound(); + nbt.putInt("x", x); nbt.putInt("y", y); - return nbt; + return new ImmutableNbtCompound(nbt); } @Override - public Vec2i read(NbtCompound nbt) { + public Vec2i read(ImmutableNbtCompound nbt) { this.x = nbt.getInt("x"); this.y = nbt.getInt("y"); diff --git a/src/main/java/net/ludocrypt/limlib/api/world/maze/storage/MazeStorage.java b/src/main/java/net/ludocrypt/limlib/api/world/maze/storage/MazeStorage.java index e60a620..d53589e 100644 --- a/src/main/java/net/ludocrypt/limlib/api/world/maze/storage/MazeStorage.java +++ b/src/main/java/net/ludocrypt/limlib/api/world/maze/storage/MazeStorage.java @@ -15,6 +15,7 @@ import net.ludocrypt.limlib.api.world.maze.MazeComponent; import net.ludocrypt.limlib.api.world.maze.MazeComponent.Vec2i; import net.ludocrypt.limlib.api.world.maze.MazeGenerator; +import net.ludocrypt.limlib.api.world.nbt.ImmutableNbtCompound; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtIo; import net.minecraft.util.math.MathHelper; @@ -64,7 +65,7 @@ public void read() { .get(id) .getMazes() .put(regionPos.add(pos), new MazeComponent(mazeRaw.getInt("width"), mazeRaw.getInt("height")) - .read(mazeRaw.getCompound("maze"))); + .read(new ImmutableNbtCompound(mazeRaw.getCompound("maze")))); } } catch (IOException | NullPointerException e) { @@ -99,7 +100,7 @@ public void serialize(String mazeId, Vec2i pos, MazeComponent maze) { } NbtCompound compound = new NbtCompound(); - NbtCompound mazeCompound = maze.write(new NbtCompound()); + NbtCompound mazeCompound = maze.write(); compound.put("maze", mazeCompound); compound.putInt("width", maze.width); diff --git a/src/main/java/net/ludocrypt/limlib/api/world/maze/storage/NbtSerializer.java b/src/main/java/net/ludocrypt/limlib/api/world/maze/storage/NbtSerializer.java deleted file mode 100644 index 0cd952e..0000000 --- a/src/main/java/net/ludocrypt/limlib/api/world/maze/storage/NbtSerializer.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.ludocrypt.limlib.api.world.maze.storage; - -import net.minecraft.nbt.NbtCompound; - -public interface NbtSerializer { - - public NbtCompound write(NbtCompound nbt); - - public T read(NbtCompound nbt); - -} diff --git a/src/main/java/net/ludocrypt/limlib/api/world/FunctionMap.java b/src/main/java/net/ludocrypt/limlib/api/world/nbt/FunctionMap.java similarity index 96% rename from src/main/java/net/ludocrypt/limlib/api/world/FunctionMap.java rename to src/main/java/net/ludocrypt/limlib/api/world/nbt/FunctionMap.java index ce79d71..0b51758 100644 --- a/src/main/java/net/ludocrypt/limlib/api/world/FunctionMap.java +++ b/src/main/java/net/ludocrypt/limlib/api/world/nbt/FunctionMap.java @@ -1,4 +1,4 @@ -package net.ludocrypt.limlib.api.world; +package net.ludocrypt.limlib.api.world.nbt; import java.util.Map; import java.util.Optional; diff --git a/src/main/java/net/ludocrypt/limlib/api/world/nbt/ImmutableNbtCompound.java b/src/main/java/net/ludocrypt/limlib/api/world/nbt/ImmutableNbtCompound.java new file mode 100644 index 0000000..f9a3174 --- /dev/null +++ b/src/main/java/net/ludocrypt/limlib/api/world/nbt/ImmutableNbtCompound.java @@ -0,0 +1,162 @@ +package net.ludocrypt.limlib.api.world.nbt; + +import java.util.List; +import java.util.UUID; + +import com.google.common.collect.ImmutableMap; + +import net.ludocrypt.limlib.impl.mixin.NbtCompoundAccessor; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.nbt.NbtList; + +public class ImmutableNbtCompound extends NbtCompound { + + public ImmutableNbtCompound(NbtCompound from) { + super(ImmutableMap.copyOf(((NbtCompoundAccessor) from).getEntries())); + } + + @Override + @Deprecated + public NbtElement put(String key, NbtElement nbt) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putBoolean(String key, boolean value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putByte(String key, byte value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putByteArray(String key, byte[] value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putByteArray(String key, List value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putDouble(String key, double value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putFloat(String key, float value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putInt(String key, int value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putIntArray(String key, int[] value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putIntArray(String key, List value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putLong(String key, long value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putLongArray(String key, List value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putLongArray(String key, long[] value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putShort(String key, short value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putString(String key, String value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void putUuid(String key, UUID value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void remove(String key) { + throw new UnsupportedOperationException(); + } + + @Override + public ImmutableNbtCompound getCompound(String key) { + return new ImmutableNbtCompound(super.getCompound(key)); + } + + @Override + public ImmutableNbtList getList(String key, int type) { + return new ImmutableNbtList(super.getList(key, type)); + } + + @Override + public NbtElement get(String key) { + NbtElement element = super.get(key); + return element instanceof NbtCompound ? new ImmutableNbtCompound((NbtCompound) element) + : element instanceof NbtList ? new ImmutableNbtList((NbtList) element) : element; + } + + @Override + public byte[] getByteArray(String key) { + byte[] in = super.getByteArray(key); + byte[] bs = new byte[in.length]; + System.arraycopy(in, 0, bs, 0, in.length); + return bs; + } + + @Override + public int[] getIntArray(String key) { + int[] in = super.getIntArray(key); + int[] bs = new int[in.length]; + System.arraycopy(in, 0, bs, 0, in.length); + return bs; + } + + @Override + public long[] getLongArray(String key) { + long[] in = super.getLongArray(key); + long[] bs = new long[in.length]; + System.arraycopy(in, 0, bs, 0, in.length); + return bs; + } + +} diff --git a/src/main/java/net/ludocrypt/limlib/api/world/nbt/ImmutableNbtList.java b/src/main/java/net/ludocrypt/limlib/api/world/nbt/ImmutableNbtList.java new file mode 100644 index 0000000..c07573f --- /dev/null +++ b/src/main/java/net/ludocrypt/limlib/api/world/nbt/ImmutableNbtList.java @@ -0,0 +1,145 @@ +package net.ludocrypt.limlib.api.world.nbt; + +import java.util.Collection; +import java.util.Comparator; +import java.util.function.Predicate; + +import com.google.common.collect.ImmutableList; + +import net.ludocrypt.limlib.impl.mixin.NbtListAccessor; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.nbt.NbtList; + +public class ImmutableNbtList extends NbtList { + + public ImmutableNbtList(NbtList from) { + super(); + ((NbtListAccessor) this).setValue(ImmutableList.copyOf(((NbtListAccessor) this).getValue())); + ((NbtListAccessor) this).setType(((NbtListAccessor) this).getType()); + } + + @Override + @Deprecated + public boolean addAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void add(int i, NbtElement nbtElement) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public boolean add(NbtElement e) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public boolean addAll(int index, Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public boolean addElement(int index, NbtElement nbt) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public boolean removeAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public NbtElement remove(int i) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public boolean removeIf(Predicate filter) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + protected void removeRange(int fromIndex, int toIndex) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public boolean retainAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public NbtElement set(int i, NbtElement nbtElement) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public boolean setElement(int index, NbtElement nbt) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated + public void sort(Comparator c) { + throw new UnsupportedOperationException(); + } + + @Override + public NbtElement get(int i) { + NbtElement element = super.get(i); + return element instanceof NbtCompound ? new ImmutableNbtCompound((NbtCompound) element) + : element instanceof NbtList ? new ImmutableNbtList((NbtList) element) : element; + } + + @Override + public NbtCompound getCompound(int index) { + return new ImmutableNbtCompound(super.getCompound(index)); + } + + @Override + public NbtList getList(int index) { + return new ImmutableNbtList(super.getList(index)); + } + + @Override + public int[] getIntArray(int index) { + int[] in = super.getIntArray(index); + int[] bs = new int[in.length]; + System.arraycopy(in, 0, bs, 0, in.length); + return bs; + } + + @Override + public long[] getLongArray(int index) { + long[] in = super.getLongArray(index); + long[] bs = new long[in.length]; + System.arraycopy(in, 0, bs, 0, in.length); + return bs; + } + +} diff --git a/src/main/java/net/ludocrypt/limlib/api/world/NbtGroup.java b/src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtGroup.java similarity index 73% rename from src/main/java/net/ludocrypt/limlib/api/world/NbtGroup.java rename to src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtGroup.java index a53f424..da2c9cf 100644 --- a/src/main/java/net/ludocrypt/limlib/api/world/NbtGroup.java +++ b/src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtGroup.java @@ -1,8 +1,10 @@ -package net.ludocrypt.limlib.api.world; +package net.ludocrypt.limlib.api.world.nbt; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.NoSuchElementException; import java.util.function.Consumer; import com.google.common.collect.Lists; @@ -97,6 +99,10 @@ public void forEach(Consumer runnable) { } + public Iterator iterator() { + return new NbtIterator(); + } + public void fill(FunctionMap map) { forEach(map::put); } @@ -150,4 +156,53 @@ public NbtGroup build() { } + private class NbtIterator implements Iterator { + + private Iterator>> groupIterator; + private Iterator nbtIterator; + + public NbtIterator() { + groupIterator = groups.entrySet().iterator(); + nbtIterator = getNextNbtIterator(); + } + + private Iterator getNextNbtIterator() { + + while (groupIterator.hasNext()) { + Entry> entry = groupIterator.next(); + List nbtList = entry.getValue(); + + if (nbtList != null && !nbtList.isEmpty()) { + return nbtList.iterator(); + } + + } + + return null; + } + + @Override + public boolean hasNext() { + return nbtIterator != null && nbtIterator.hasNext(); + } + + @Override + public Identifier next() { + + if (!hasNext()) { + throw new NoSuchElementException("No more elements"); + } + + String nbt = nbtIterator.next(); + Identifier id = nbtId(groupIterator.next().getKey(), nbt); + + if (!nbtIterator.hasNext()) { + nbtIterator = getNextNbtIterator(); + } + + return id; + } + + } + } diff --git a/src/main/java/net/ludocrypt/limlib/api/world/NbtPlacerUtil.java b/src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtPlacerUtil.java similarity index 96% rename from src/main/java/net/ludocrypt/limlib/api/world/NbtPlacerUtil.java rename to src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtPlacerUtil.java index 7f3ef8f..6a58e16 100644 --- a/src/main/java/net/ludocrypt/limlib/api/world/NbtPlacerUtil.java +++ b/src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtPlacerUtil.java @@ -1,4 +1,4 @@ -package net.ludocrypt.limlib.api.world; +package net.ludocrypt.limlib.api.world.nbt; import java.io.IOException; import java.io.InputStream; @@ -12,7 +12,9 @@ import com.mojang.datafixers.util.Pair; +import net.ludocrypt.limlib.api.world.Manipulation; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.decoration.AbstractDecorationEntity; @@ -181,6 +183,10 @@ public static Optional loadSafe(Identifier id, ResourceManager ma } + public static NbtCompound loadTags(Identifier id, ResourceManager manager) { + return loadNbtSafe(id, manager).orElseGet(NbtCompound::new).getCompound("limlib_tag"); + } + private static Optional emptyNbt() { return Optional.empty(); } @@ -219,14 +225,15 @@ public NbtPlacerUtil generateNbt(ChunkRegion region, Vec3i offset, BlockPos from BlockPos pos = new BlockPos(xi, yi, zi); Pair> pair = this.positions.get(pos.add(offset)); - if (pair != null) { - BlockState state = pair.getFirst(); - Optional nbt = pair.getSecond(); + if (pair == null) { + pair = Pair.of(Blocks.STRUCTURE_VOID.getDefaultState(), Optional.empty()); + } - if (state != null) { - consumer.accept(from.add(pos), state, nbt); - } + BlockState state = pair.getFirst(); + Optional nbt = pair.getSecond(); + if (state != null) { + consumer.accept(from.add(pos), state, nbt); } } diff --git a/src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtSerializer.java b/src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtSerializer.java new file mode 100644 index 0000000..749a2b8 --- /dev/null +++ b/src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtSerializer.java @@ -0,0 +1,16 @@ +package net.ludocrypt.limlib.api.world.nbt; + +import net.ludocrypt.limlib.impl.mixin.NbtCompoundAccessor; +import net.minecraft.nbt.NbtCompound; + +public interface NbtSerializer { + + public ImmutableNbtCompound write(); + + public default void write(NbtCompound nbt) { + ((NbtCompoundAccessor) nbt).getEntries().putAll(((NbtCompoundAccessor) write()).getEntries()); + } + + public T read(ImmutableNbtCompound nbt); + +} diff --git a/src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtTags.java b/src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtTags.java new file mode 100644 index 0000000..547833a --- /dev/null +++ b/src/main/java/net/ludocrypt/limlib/api/world/nbt/NbtTags.java @@ -0,0 +1,78 @@ +package net.ludocrypt.limlib.api.world.nbt; + +import java.util.Iterator; +import java.util.List; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Lists; + +import net.minecraft.nbt.NbtCompound; +import net.minecraft.resource.ResourceManager; +import net.minecraft.util.Identifier; + +public class NbtTags { + + final ArrayListMultimap tagsForStruct; + final ArrayListMultimap structsForTag; + + public NbtTags(ArrayListMultimap tagsForStruct, + ArrayListMultimap structsForTag) { + this.tagsForStruct = tagsForStruct; + this.structsForTag = structsForTag; + } + + public NbtTags() { + this.tagsForStruct = ArrayListMultimap.create(); + this.structsForTag = ArrayListMultimap.create(); + } + + public static NbtTags parse(NbtGroup group, ResourceManager manager) { + NbtTags tags = new NbtTags(); + + Iterator iterator = group.iterator(); + + while (iterator.hasNext()) { + Identifier id = iterator.next(); + NbtCompound readTags = NbtPlacerUtil.loadTags(id, manager); + + for (String tagKey : readTags.getKeys()) { + ImmutableNbtCompound tag = new ImmutableNbtCompound(readTags.getCompound(tagKey)); + tags.tagsForStruct.put(id, tag); + tags.structsForTag.put(tag, id); + } + + } + + return tags; + } + + public List matching(ImmutableNbtCompound... tags) { + + if (tags.length == 0) { + return Lists.newArrayList(); + } + + List commonItems = null; + + for (int i = 0; i < tags.length; i++) { + + if (commonItems == null) { + + if (this.structsForTag.containsKey(tags[i])) { + commonItems = Lists.newArrayList(this.structsForTag.get(tags[i])); + } + + } else if (commonItems != null) { + commonItems.retainAll(this.structsForTag.get(tags[i])); + } + + } + + if (commonItems == null) { + return Lists.newArrayList(); + } + + return Lists.newArrayList(commonItems); + } + +} diff --git a/src/main/java/net/ludocrypt/limlib/impl/Limlib.java b/src/main/java/net/ludocrypt/limlib/impl/Limlib.java index 8d92c8b..ff05811 100644 --- a/src/main/java/net/ludocrypt/limlib/impl/Limlib.java +++ b/src/main/java/net/ludocrypt/limlib/impl/Limlib.java @@ -8,19 +8,11 @@ import net.ludocrypt.limlib.api.LimlibRegistrar; import net.ludocrypt.limlib.api.LimlibWorld; -import net.ludocrypt.limlib.api.effects.post.EmptyPostEffect; import net.ludocrypt.limlib.api.effects.post.PostEffect; -import net.ludocrypt.limlib.api.effects.post.StaticPostEffect; import net.ludocrypt.limlib.api.effects.sky.DimensionEffects; -import net.ludocrypt.limlib.api.effects.sky.EmptyDimensionEffects; -import net.ludocrypt.limlib.api.effects.sky.StaticDimensionEffects; import net.ludocrypt.limlib.api.effects.sound.distortion.DistortionEffect; -import net.ludocrypt.limlib.api.effects.sound.distortion.StaticDistortionEffect; import net.ludocrypt.limlib.api.effects.sound.reverb.ReverbEffect; -import net.ludocrypt.limlib.api.effects.sound.reverb.StaticReverbEffect; -import net.ludocrypt.limlib.api.skybox.EmptySkybox; import net.ludocrypt.limlib.api.skybox.Skybox; -import net.ludocrypt.limlib.api.skybox.TexturedSkybox; import net.ludocrypt.limlib.impl.debug.DebugNbtChunkGenerator; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; @@ -33,20 +25,14 @@ public class Limlib implements ModInitializer { @Override public void onInitialize(ModContainer mod) { LimlibWorld.load(); - Registry.register(ReverbEffect.REVERB_EFFECT_CODEC, new Identifier("limlib", "static"), StaticReverbEffect.CODEC); - Registry - .register(DistortionEffect.DISTORTION_EFFECT_CODEC, new Identifier("limlib", "static"), - StaticDistortionEffect.CODEC); - Registry - .register(DimensionEffects.DIMENSION_EFFECTS_CODEC, new Identifier("limlib", "static"), - StaticDimensionEffects.CODEC); - Registry - .register(DimensionEffects.DIMENSION_EFFECTS_CODEC, new Identifier("limlib", "empty"), - EmptyDimensionEffects.CODEC); - Registry.register(PostEffect.POST_EFFECT_CODEC, new Identifier("limlib", "static"), StaticPostEffect.CODEC); - Registry.register(PostEffect.POST_EFFECT_CODEC, new Identifier("limlib", "empty"), EmptyPostEffect.CODEC); - Registry.register(Skybox.SKYBOX_CODEC, new Identifier("limlib", "empty"), EmptySkybox.CODEC); - Registry.register(Skybox.SKYBOX_CODEC, new Identifier("limlib", "textured"), TexturedSkybox.CODEC); + + // Effects + ReverbEffect.init(); + DistortionEffect.init(); + DimensionEffects.init(); + PostEffect.init(); + Skybox.init(); + Registry .register(Registries.CHUNK_GENERATOR, new Identifier("limlib", "debug_nbt_chunk_generator"), DebugNbtChunkGenerator.CODEC); diff --git a/src/main/java/net/ludocrypt/limlib/impl/debug/DebugNbtChunkGenerator.java b/src/main/java/net/ludocrypt/limlib/impl/debug/DebugNbtChunkGenerator.java index 9f63bc9..f0b4258 100644 --- a/src/main/java/net/ludocrypt/limlib/impl/debug/DebugNbtChunkGenerator.java +++ b/src/main/java/net/ludocrypt/limlib/impl/debug/DebugNbtChunkGenerator.java @@ -17,9 +17,9 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.ludocrypt.limlib.api.world.NbtGroup; -import net.ludocrypt.limlib.api.world.NbtPlacerUtil; import net.ludocrypt.limlib.api.world.chunk.AbstractNbtChunkGenerator; +import net.ludocrypt.limlib.api.world.nbt.NbtGroup; +import net.ludocrypt.limlib.api.world.nbt.NbtPlacerUtil; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -174,8 +174,8 @@ public int getWorldHeight() { @Override protected void modifyStructure(ChunkRegion region, BlockPos pos, BlockState state, Optional blockEntityNbt, - int update) { - region.setBlockState(pos, state, update, 1); + int update, int depth) { + region.setBlockState(pos, state, Block.FORCE_STATE, 0); blockEntityNbt.ifPresent((nbt) -> { if (region.getBlockEntity(pos) != null) region.getBlockEntity(pos).readNbt(nbt); diff --git a/src/main/java/net/ludocrypt/limlib/impl/mixin/NbtCompoundAccessor.java b/src/main/java/net/ludocrypt/limlib/impl/mixin/NbtCompoundAccessor.java new file mode 100644 index 0000000..2d8c7e4 --- /dev/null +++ b/src/main/java/net/ludocrypt/limlib/impl/mixin/NbtCompoundAccessor.java @@ -0,0 +1,21 @@ +package net.ludocrypt.limlib.impl.mixin; + +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Map; + +@Mixin(NbtCompound.class) +public interface NbtCompoundAccessor { + + @Accessor + Map getEntries(); + + @Mutable + @Accessor + void setEntries(Map entries); + +} diff --git a/src/main/java/net/ludocrypt/limlib/impl/mixin/NbtListAccessor.java b/src/main/java/net/ludocrypt/limlib/impl/mixin/NbtListAccessor.java new file mode 100644 index 0000000..12673fb --- /dev/null +++ b/src/main/java/net/ludocrypt/limlib/impl/mixin/NbtListAccessor.java @@ -0,0 +1,27 @@ +package net.ludocrypt.limlib.impl.mixin; + +import net.minecraft.nbt.NbtElement; +import net.minecraft.nbt.NbtList; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(NbtList.class) +public interface NbtListAccessor { + + @Accessor + List getValue(); + + @Mutable + @Accessor + void setValue(List value); + + @Accessor + byte getType(); + + @Accessor + void setType(byte type); + +} diff --git a/src/main/java/net/ludocrypt/limlib/impl/mixin/ServerWorldMixin.java b/src/main/java/net/ludocrypt/limlib/impl/mixin/ServerWorldMixin.java index cdcd10f..7a12e90 100644 --- a/src/main/java/net/ludocrypt/limlib/impl/mixin/ServerWorldMixin.java +++ b/src/main/java/net/ludocrypt/limlib/impl/mixin/ServerWorldMixin.java @@ -10,6 +10,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import net.ludocrypt.limlib.api.world.chunk.AbstractNbtChunkGenerator; import net.ludocrypt.limlib.api.world.maze.storage.MazeStorage; import net.ludocrypt.limlib.api.world.maze.storage.MazeStorageProvider; import net.ludocrypt.limlib.api.world.maze.storage.ServerWorldMazeAccess; @@ -41,12 +42,16 @@ public class ServerWorldMixin implements ServerWorldMazeAccess { session.getWorldDirectory(registryKey).resolve("maze_region").toFile()); } + if (dimensionOptions.getChunkGenerator() instanceof AbstractNbtChunkGenerator generator) { + generator.loadTags(((ServerWorld) (Object) this)); + } + } @Inject(method = "saveWorld", at = @At("TAIL")) private void limlib$saveWorld(CallbackInfo ci) { - if (mazeStorage != null) { + if (this.mazeStorage != null) { this.mazeStorage.save(); } diff --git a/src/main/resources/limlib.mixins.json b/src/main/resources/limlib.mixins.json index e4d388d..23ba969 100644 --- a/src/main/resources/limlib.mixins.json +++ b/src/main/resources/limlib.mixins.json @@ -8,6 +8,8 @@ "ChunkStatusMixin", "DynamicRegistrySyncMixin", "GeneratorTypeAccessor", + "NbtCompoundAccessor", + "NbtListAccessor", "RegistriesAccessor", "RegistryLoaderMixin", "ServerPlayerEntityMixin",