From 99e38893cab9c9224bc38575c847c88d5c0e8448 Mon Sep 17 00:00:00 2001 From: zontreck Date: Tue, 9 Apr 2024 14:23:03 -0700 Subject: [PATCH] Do more work on implementing a new saved block system --- .../memory/world/PrimitiveBlock.java | 62 ++++++++++++ .../libzontreck/memory/world/SavedBlock.java | 95 +++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 src/main/java/dev/zontreck/libzontreck/memory/world/PrimitiveBlock.java diff --git a/src/main/java/dev/zontreck/libzontreck/memory/world/PrimitiveBlock.java b/src/main/java/dev/zontreck/libzontreck/memory/world/PrimitiveBlock.java new file mode 100644 index 0000000..dff455f --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/memory/world/PrimitiveBlock.java @@ -0,0 +1,62 @@ +package dev.zontreck.libzontreck.memory.world; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; + +public class PrimitiveBlock +{ + public SavedBlock block; + public Block blockType; + public BlockState blockState; + public CompoundTag blockEntity; + public BlockPos position; + public ServerLevel level; + + /** + * Alias method + * @see SavedBlock#serialize() + * @return NBT Tag + */ + public CompoundTag serialize() + { + return block.serialize(); + } + + /** + * Alias Method + * @see SavedBlock#deserialize(CompoundTag) + * @see SavedBlock#getBlockPrimitive() + * @param tag NBT Tag + * @return A Primitive Block + */ + public static PrimitiveBlock deserialize(CompoundTag tag) + { + return SavedBlock.deserialize(tag).getBlockPrimitive(); + } + + /** + * Compare a block with this primitive block + * @param block The block type to compare + * @param state The block state to compare + * @param entity The block entity to compare + * @return True if identical + */ + public boolean is(Block block, BlockState state, BlockEntity entity) + { + if(block == this.blockType) + { + // Check the block state + if(this.blockState.equals(state)) + { + if(blockEntity == null) return true; // Not all blocks have a block entity. + if(blockEntity.equals(entity.serializeNBT())){ + return true; + }else return false; + } else return false; + }else return false; + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/memory/world/SavedBlock.java b/src/main/java/dev/zontreck/libzontreck/memory/world/SavedBlock.java index 45cfa62..7c9e928 100644 --- a/src/main/java/dev/zontreck/libzontreck/memory/world/SavedBlock.java +++ b/src/main/java/dev/zontreck/libzontreck/memory/world/SavedBlock.java @@ -1,12 +1,107 @@ package dev.zontreck.libzontreck.memory.world; +import dev.zontreck.libzontreck.api.Vector3; +import dev.zontreck.libzontreck.exceptions.InvalidDeserialization; +import dev.zontreck.libzontreck.vectors.Vector3i; +import dev.zontreck.libzontreck.vectors.WorldPosition; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.server.ServerLifecycleHooks; public class SavedBlock { private CompoundTag blockState; private CompoundTag blockEntity; private boolean hasBlockEntity; + private WorldPosition position; + /** + * Take a snapshot of the block, and save as primitive type SavedBlock + * @param position The block's position + * @param level The level the position relates to + * @return A instance of the saved block + */ + public static SavedBlock takeSnapshot(Vector3 position, Level level) + { + SavedBlock savedBlock = new SavedBlock(); + BlockPos pos = position.asBlockPos(); + + BlockState state = level.getBlockState(pos); + savedBlock.blockState = NbtUtils.writeBlockState(state); + BlockEntity entity = level.getBlockEntity(pos); + if(entity == null) + { + savedBlock.hasBlockEntity = false; + }else { + savedBlock.hasBlockEntity = true; + savedBlock.blockEntity = entity.serializeNBT(); + } + + savedBlock.position = new WorldPosition(position.asVector3d(), (ServerLevel) level); + + return savedBlock; + } + + /** + * Saves the stored block as a NBT Tag + * @return CompoundTag + */ + public CompoundTag serialize() + { + CompoundTag tag = new CompoundTag(); + tag.put("state", blockState); + if(hasBlockEntity) tag.put("entity", blockEntity); + + tag.put("position", position.serialize()); + + return tag; + } + + /** + * Reads a NBT Tag that represents a stored block, and returns the StoredBlock object + * @param tag Saved NBT + * @return SavedBlock instance + */ + public static SavedBlock deserialize(CompoundTag tag) + { + SavedBlock savedBlock = new SavedBlock(); + savedBlock.blockState = tag.getCompound("state"); + if(tag.contains("entity")) { + savedBlock.blockEntity = tag.getCompound("entity"); + savedBlock.hasBlockEntity=true; + } + + try { + savedBlock.position = new WorldPosition(tag.getCompound("position"), false); + } catch (InvalidDeserialization e) { + throw new RuntimeException(e); + } + + return savedBlock; + } + + public PrimitiveBlock getBlockPrimitive() + { + PrimitiveBlock prim = new PrimitiveBlock(); + ServerLevel level = position.getActualDimension(); + + BlockState state = NbtUtils.readBlockState(level.holderLookup(Registries.BLOCK), blockState); + prim.blockState = state; + prim.block = this; + prim.blockType = state.getBlock(); + prim.blockEntity = blockEntity; + prim.position = position.Position.asBlockPos(); + prim.level = level; + + return prim; + } }