diff --git a/src/main/java/com/ldtteam/structurize/api/RotationMirror.java b/src/main/java/com/ldtteam/structurize/api/RotationMirror.java index 5a5bbc39e..806308265 100644 --- a/src/main/java/com/ldtteam/structurize/api/RotationMirror.java +++ b/src/main/java/com/ldtteam/structurize/api/RotationMirror.java @@ -205,7 +205,7 @@ public BlockState applyToBlockState(BlockState blockState) * @param pos where the given blockState is in given level * @return transformed blockState using this rot+mir */ - public BlockState applyToBlockState(BlockState blockState, Level level, BlockPos pos) + public BlockState applyToBlockState(BlockState blockState, final Level level, final BlockPos pos) { if (isMirrored()) { diff --git a/src/main/java/com/ldtteam/structurize/blockentities/BlockEntityTagSubstitution.java b/src/main/java/com/ldtteam/structurize/blockentities/BlockEntityTagSubstitution.java index aaf5f3340..c7f93b764 100644 --- a/src/main/java/com/ldtteam/structurize/blockentities/BlockEntityTagSubstitution.java +++ b/src/main/java/com/ldtteam/structurize/blockentities/BlockEntityTagSubstitution.java @@ -8,11 +8,14 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.core.component.DataComponentMap; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtOps; +import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.util.Tuple; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.NotNull; @@ -25,6 +28,10 @@ public class BlockEntityTagSubstitution extends BlockEntity implements IBlueprintDataProviderBE { public static final String CAPTURED_BLOCK_TAG = "captured_block"; + /** + * Up to 1.21.1 + */ + public static final String CAPTURED_BLOCK_TAG_OLD = "replacement"; /** * The schematic name of the block. @@ -124,31 +131,49 @@ public CapturedBlock getReplacement() public void loadAdditional( @NotNull final CompoundTag compound, final HolderLookup.Provider provider) { super.loadAdditional(compound, provider); - final DynamicOps dynamicops = provider.createSerializationContext(NbtOps.INSTANCE); + final DynamicOps dynamicOps = provider.createSerializationContext(NbtOps.INSTANCE); IBlueprintDataProviderBE.super.readSchematicDataFromNBT(compound); - replacement = deserializeReplacement(compound, dynamicops); + if (compound.contains(CAPTURED_BLOCK_TAG_OLD, Tag.TAG_COMPOUND)) + { + final CompoundTag oldNbt = compound.getCompound(CAPTURED_BLOCK_TAG_OLD); + replacement = new CapturedBlock(NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), oldNbt.getCompound("b")), + Optional.of(oldNbt.getCompound("e")), + oldNbt.contains("i") ? ItemStack.parseOptional(provider, oldNbt.getCompound("i")) : ItemStack.EMPTY); + } + else + { + replacement = deserializeReplacement(compound, dynamicOps); + } } - public static CapturedBlock deserializeReplacement(final CompoundTag compound, final DynamicOps dynamicops) + public static CapturedBlock deserializeReplacement(final CompoundTag compound, final DynamicOps dynamicOps) { - return CapturedBlock.CODEC.parse(dynamicops, compound.get(CAPTURED_BLOCK_TAG)).resultOrPartial(Log.getLogger()::error).orElse(CapturedBlock.EMPTY); + if (compound.getCompound(CAPTURED_BLOCK_TAG).isEmpty()) + { + return CapturedBlock.EMPTY; + } + return CapturedBlock.CODEC.parse(dynamicOps, compound.get(CAPTURED_BLOCK_TAG)).resultOrPartial(error -> { + Log.getLogger() + .error("Parsing {} with data {}: {}", ModBlockEntities.TAG_SUBSTITUTION.getRegisteredName(), compound, error); + Log.getLogger().error("", new RuntimeException()); + }).orElse(CapturedBlock.EMPTY); } @Override public void saveAdditional(@NotNull final CompoundTag compound, final HolderLookup.Provider provider) { super.saveAdditional(compound, provider); - final DynamicOps dynamicops = provider.createSerializationContext(NbtOps.INSTANCE); + final DynamicOps dynamicOps = provider.createSerializationContext(NbtOps.INSTANCE); writeSchematicDataToNBT(compound); // this is still needed even with data components as of 1.21 - serializeReplacement(compound, dynamicops, replacement); + serializeReplacement(compound, dynamicOps, replacement); } - public static void serializeReplacement(final CompoundTag compound, final DynamicOps dynamicops, final CapturedBlock replacement) + public static void serializeReplacement(final CompoundTag compound, final DynamicOps dynamicOps, final CapturedBlock replacement) { - compound.put(CAPTURED_BLOCK_TAG, CapturedBlock.CODEC.encodeStart(dynamicops, replacement).getOrThrow()); + compound.put(CAPTURED_BLOCK_TAG, CapturedBlock.CODEC.encodeStart(dynamicOps, replacement).getOrThrow()); } @Override diff --git a/src/main/java/com/ldtteam/structurize/client/TagSubstitutionRenderer.java b/src/main/java/com/ldtteam/structurize/client/TagSubstitutionRenderer.java index dd4fa86c1..ce8fbc729 100644 --- a/src/main/java/com/ldtteam/structurize/client/TagSubstitutionRenderer.java +++ b/src/main/java/com/ldtteam/structurize/client/TagSubstitutionRenderer.java @@ -91,6 +91,10 @@ private void render(@NotNull final CapturedBlock replacement, return; } + poseStack.pushPose(); + poseStack.scale(0.995f, 0.995f, 0.995f); + poseStack.translate(0.0025f, 0.0025f, 0.0025f); + if (replacement.hasBlockEntity()) { final BlockEntityRenderDispatcher entityDispatcher = this.context.getBlockEntityRenderDispatcher(); @@ -99,14 +103,28 @@ private void render(@NotNull final CapturedBlock replacement, { renderLevel = new SingleBlockFakeLevel(realLevel); } - + renderLevel.withFakeLevelContext(replacement.blockState(), BlockEntity.loadStatic(BlockPos.ZERO, replacement.blockState(), replacement.serializedBE().get(), realLevel.registryAccess()), realLevel, - fakeLevel -> entityDispatcher.render(renderLevel.getLevelSource().blockEntity, partialTick, poseStack, buffers)); + fakeLevel -> { + context.getBlockRenderDispatcher() + .renderSingleBlock(replacement.blockState(), + poseStack, + buffers, + packedLight, + packedOverlay, + renderLevel.getLevelSource().blockEntity.getModelData(), + renderType); + entityDispatcher.render(renderLevel.getLevelSource().blockEntity, partialTick, poseStack, buffers); + }); + } + else + { + context.getBlockRenderDispatcher() + .renderSingleBlock(replacement.blockState(), poseStack, buffers, packedLight, packedOverlay, ModelData.EMPTY, renderType); } - final BlockRenderDispatcher dispatcher = this.context.getBlockRenderDispatcher(); - dispatcher.renderSingleBlock(replacement.blockState(), poseStack, buffers, packedLight, packedOverlay, ModelData.EMPTY, renderType); + poseStack.popPose(); } } diff --git a/src/main/java/com/ldtteam/structurize/client/fakelevel/BlueprintBlockAccess.java b/src/main/java/com/ldtteam/structurize/client/fakelevel/BlueprintBlockAccess.java index b5f521159..ea9b137a9 100644 --- a/src/main/java/com/ldtteam/structurize/client/fakelevel/BlueprintBlockAccess.java +++ b/src/main/java/com/ldtteam/structurize/client/fakelevel/BlueprintBlockAccess.java @@ -58,7 +58,7 @@ else if (state.getBlock() == ModBlocks.blockSubstitution.get()) } else if (state.getBlock() == ModBlocks.blockTagSubstitution.get()) { - if (super.getBlockEntity(pos) instanceof final BlockEntityTagSubstitution tag && !tag.getReplacement().blockState().isAir()) + if (super.getBlockEntity(pos) instanceof final BlockEntityTagSubstitution tag) { return tag.getReplacement().blockState(); } diff --git a/src/main/java/com/ldtteam/structurize/component/CapturedBlock.java b/src/main/java/com/ldtteam/structurize/component/CapturedBlock.java index bf7238f19..4890ed694 100644 --- a/src/main/java/com/ldtteam/structurize/component/CapturedBlock.java +++ b/src/main/java/com/ldtteam/structurize/component/CapturedBlock.java @@ -45,6 +45,14 @@ public record CapturedBlock(BlockState blockState, Optional seriali CapturedBlock::itemStack, CapturedBlock::new); + /** + * Serializes given BE. + * + * @param blockState state of captured block + * @param blockEntity related blockEntity data if needed + * @param provider registry access + * @param itemStack itemStack representing both block and blockEntity + */ public CapturedBlock(final BlockState blockState, @Nullable final BlockEntity blockEntity, final HolderLookup.Provider provider, @@ -53,6 +61,10 @@ public CapturedBlock(final BlockState blockState, this(blockState, blockEntity == null ? Optional.empty() : Optional.of(blockEntity.saveWithId(provider)), itemStack); } + /** + * @param rotationMirror relative rotation and mirror + * @param level registry access + */ public CapturedBlock applyRotationMirror(final RotationMirror rotationMirror, final Level level) { if (serializedBE.isEmpty()) diff --git a/src/main/java/com/ldtteam/structurize/items/ItemTagSubstitution.java b/src/main/java/com/ldtteam/structurize/items/ItemTagSubstitution.java index fd83e898d..8e2cdf857 100644 --- a/src/main/java/com/ldtteam/structurize/items/ItemTagSubstitution.java +++ b/src/main/java/com/ldtteam/structurize/items/ItemTagSubstitution.java @@ -23,7 +23,6 @@ import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; @@ -65,7 +64,7 @@ public InteractionResult onBlockPick(@NotNull Player player, { if (!player.level().isClientSide()) { - clearAbsorbedBlock(stack); + CapturedBlock.EMPTY.writeToItemStack(stack); } return InteractionResult.SUCCESS; } @@ -76,7 +75,7 @@ public InteractionResult onBlockPick(@NotNull Player player, // this way lies madness, and/or Sparta... if (!player.level().isClientSide()) { - clearAbsorbedBlock(stack); + CapturedBlock.EMPTY.writeToItemStack(stack); } return InteractionResult.SUCCESS; } @@ -98,11 +97,6 @@ private ItemStack getPickedBlock(@NotNull Player player, @NotNull BlockPos pos, return blockstate.getCloneItemStack(Minecraft.getInstance().hitResult, player.level(), pos, player); } - private void clearAbsorbedBlock(@NotNull ItemStack stack) - { - CapturedBlock.EMPTY.writeToItemStack(stack); - } - public void onAbsorbBlock(@NotNull final ServerPlayer player, @NotNull final ItemStack stack, @NotNull final BlockPos pos, @@ -123,7 +117,6 @@ else if (!isAllowed(blockentity)) } else { - // replacement = new BlockEntityTagSubstitution.ReplacementBlock(blockstate, blockentity.saveWithoutMetadata(player.level().registryAccess()), absorbItem); replacement = new CapturedBlock(blockstate, blockentity, player.level().registryAccess(), absorbItem); } @@ -166,11 +159,4 @@ public Optional getTooltipImage(@NotNull final ItemStack stack return super.getTooltipImage(stack); } - - @Nullable - @Override - protected BlockState getPlacementState(@NotNull final BlockPlaceContext context) - { - return super.getPlacementState(context); - } }