From 4b59528b31612b6c32429c62933ba98a5e039a48 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Wed, 11 Sep 2024 00:23:14 +0100 Subject: [PATCH 01/10] Fix race in Contraption simplifiedEntityColliders update This issue is most obvious in elevators with multiple doors. When the collider gets invalidated multiple times in quick succession, multiple futures are created. If a future which was started before all door state updates were finalized completed after all other futures, the final simplifiedEntityColliders would be outdated and invalid (containing ghost doors, or in the case of an elevator in motion, missing door collisions). This commit addresses this issue in two ways: First by cancelling any existing future to ensure that any future which completes was started after the most recent invalidation. Second by removing the null assignment of simplifiedEntityColliderProvider from the future. This prevents the future from becoming null after a null check and before a cancellation (the only time where the null value matters). Cancelling a future twice is not an issue so there's no need to track if the future is null other than to avoid a null dereference. --- .../com/simibubi/create/content/contraptions/Contraption.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/Contraption.java index f38e1c78ee..d004d9ae23 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/Contraption.java @@ -1386,6 +1386,9 @@ public void invalidateColliders() { private void gatherBBsOffThread() { getContraptionWorld(); + if (simplifiedEntityColliderProvider != null) { + simplifiedEntityColliderProvider.cancel(false); + } simplifiedEntityColliderProvider = CompletableFuture.supplyAsync(() -> { VoxelShape combinedShape = Shapes.empty(); for (Entry entry : blocks.entrySet()) { @@ -1402,7 +1405,6 @@ private void gatherBBsOffThread() { }) .thenAccept(r -> { simplifiedEntityColliders = Optional.of(r); - simplifiedEntityColliderProvider = null; }); } From ac61d249cce3b93a06b4e67f6ce2e3c1729ba933 Mon Sep 17 00:00:00 2001 From: IThundxr Date: Mon, 16 Sep 2024 17:29:10 -0400 Subject: [PATCH 02/10] fix blocks having unsafe nbt values --- .../foundation/utility/NBTProcessors.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java b/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java index f685969c95..eab6099065 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java +++ b/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java @@ -58,7 +58,7 @@ public static synchronized void addSurvivalProcessor(BlockEntityType type, addProcessor(AllBlockEntityTypes.CREATIVE_CRATE.get(), itemProcessor("Filter")); addProcessor(AllBlockEntityTypes.PLACARD.get(), itemProcessor("Item")); } - + // Triggered by block tag, not BE type private static final UnaryOperator signProcessor = data -> { for (int i = 0; i < 4; ++i) @@ -86,14 +86,22 @@ public static UnaryOperator itemProcessor(String tagKey) { } public static ItemStack withUnsafeNBTDiscarded(ItemStack stack) { - if (stack.getTag() == null) + CompoundTag tag = stack.getTag(); + if (tag == null) return stack; ItemStack copy = stack.copy(); - stack.getTag() - .getAllKeys() + copy.setTag(withUnsafeNBTDiscarded(tag)); + return copy; + } + + public static CompoundTag withUnsafeNBTDiscarded(CompoundTag tag) { + if (tag == null) + return null; + CompoundTag copy = tag.copy(); + tag.getAllKeys() .stream() .filter(NBTProcessors::isUnsafeItemNBTKey) - .forEach(copy::removeTagKey); + .forEach(copy::remove); return copy; } @@ -136,7 +144,7 @@ public static CompoundTag process(BlockState blockState, BlockEntity blockEntity return signProcessor.apply(compound); if (blockEntity.onlyOpCanSetNbt()) return null; - return compound; + return withUnsafeNBTDiscarded(compound); } } From c59c749ed54d9769232d4b7b94e32fd9c90dd58d Mon Sep 17 00:00:00 2001 From: IThundxr Date: Wed, 4 Sep 2024 18:20:13 -0400 Subject: [PATCH 03/10] fix: items in ponders being culled incorrectly - Items shouldn't be culled in ponder worlds, the cullingFrustum is wrong and ponders are unpredictable --- .../create/content/kinetics/belt/BeltRenderer.java | 2 +- .../blockEntity/renderer/SafeBlockEntityRenderer.java | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java index cd5af645f8..469a839f23 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java @@ -233,7 +233,7 @@ protected void renderItems(BeltBlockEntity be, float partialTicks, PoseStack ms, be.getBlockPos().getZ()) .add(offsetVec); - if (this.shouldCullItem(itemPos)) { + if (this.shouldCullItem(itemPos, be.getLevel())) { continue; } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java b/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java index f26940d4cf..d9b8d4c699 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java @@ -2,10 +2,13 @@ import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.foundation.ponder.PonderWorld; + import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.renderer.culling.Frustum; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.phys.AABB; @@ -28,7 +31,10 @@ public boolean isInvalid(T be) { .getBlock() == Blocks.AIR; } - public boolean shouldCullItem(Vec3 itemPos) { + public boolean shouldCullItem(Vec3 itemPos, Level level) { + if (level instanceof PonderWorld) + return false; + Frustum frustum = Minecraft.getInstance().levelRenderer.capturedFrustum != null ? Minecraft.getInstance().levelRenderer.capturedFrustum : Minecraft.getInstance().levelRenderer.cullingFrustum; From 84911a3de5b38153d96330224f7066a6dcc9d06d Mon Sep 17 00:00:00 2001 From: IThundxr Date: Fri, 6 Sep 2024 16:10:15 -0400 Subject: [PATCH 04/10] Fix #6906 --- .../com/simibubi/create/foundation/mixin/BlockItemMixin.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java index a9c6d514b6..f4031bcb23 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java @@ -9,7 +9,6 @@ import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import org.spongepowered.asm.mixin.Mixin; @@ -22,7 +21,7 @@ public class BlockItemMixin { @Inject(method = "place", at = @At("HEAD"), cancellable = true) private void create$fixDeployerPlacement(BlockPlaceContext pContext, CallbackInfoReturnable cir) { BlockState state = pContext.getLevel().getBlockState(((UseOnContextAccessor) pContext).create$getHitResult().getBlockPos()); - if (state != Blocks.AIR.defaultBlockState() && pContext.getPlayer() instanceof DeployerFakePlayer) { + if (!state.canBeReplaced() && pContext.getPlayer() instanceof DeployerFakePlayer) { cir.setReturnValue(InteractionResult.PASS); } } From 5905e8bc931434c7d178c83442f153eed315a2a7 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue, 8 Oct 2024 12:48:36 +0200 Subject: [PATCH 05/10] Bringing the Cheat - Clipboards now validate their data item #6928 - Backport #6911 --- gradle.properties | 2 +- src/main/java/com/simibubi/create/Create.java | 2 +- .../content/equipment/clipboard/ClipboardBlockEntity.java | 2 ++ .../com/simibubi/create/foundation/mixin/BlockItemMixin.java | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 4c75a885be..6bb0ec39d8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.jvmargs = -Xmx3G org.gradle.daemon = false # mod version info -mod_version = 0.5.1.h +mod_version = 0.5.1.i artifact_minecraft_version = 1.18.2 minecraft_version = 1.18.2 diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java index b4657f70fc..145b1c4db5 100644 --- a/src/main/java/com/simibubi/create/Create.java +++ b/src/main/java/com/simibubi/create/Create.java @@ -61,7 +61,7 @@ public class Create { public static final String ID = "create"; public static final String NAME = "Create"; - public static final String VERSION = "0.5.1h"; + public static final String VERSION = "0.5.1i"; public static final Logger LOGGER = LogUtils.getLogger(); diff --git a/src/main/java/com/simibubi/create/content/equipment/clipboard/ClipboardBlockEntity.java b/src/main/java/com/simibubi/create/content/equipment/clipboard/ClipboardBlockEntity.java index 7d1afe661b..2537f6a88e 100644 --- a/src/main/java/com/simibubi/create/content/equipment/clipboard/ClipboardBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/equipment/clipboard/ClipboardBlockEntity.java @@ -68,6 +68,8 @@ protected void write(CompoundTag tag, boolean clientPacket) { protected void read(CompoundTag tag, boolean clientPacket) { super.read(tag, clientPacket); dataContainer = ItemStack.of(tag.getCompound("Item")); + if (!AllBlocks.CLIPBOARD.isIn(dataContainer)) + dataContainer = AllBlocks.CLIPBOARD.asStack(); if (clientPacket) DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> readClientSide(tag)); diff --git a/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java index f4031bcb23..afeaad404b 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java @@ -21,7 +21,7 @@ public class BlockItemMixin { @Inject(method = "place", at = @At("HEAD"), cancellable = true) private void create$fixDeployerPlacement(BlockPlaceContext pContext, CallbackInfoReturnable cir) { BlockState state = pContext.getLevel().getBlockState(((UseOnContextAccessor) pContext).create$getHitResult().getBlockPos()); - if (!state.canBeReplaced() && pContext.getPlayer() instanceof DeployerFakePlayer) { + if (!state.getMaterial().isReplaceable() && pContext.getPlayer() instanceof DeployerFakePlayer) { cir.setReturnValue(InteractionResult.PASS); } } From 8f5c91c1950e215a5987e2f6de6c427e13368583 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:22:12 +0200 Subject: [PATCH 06/10] I 2 didn't C the 'i' in that id - Fixed incorrect IC2 compatibility recipes #6917 #6916 --- src/generated/resources/.cache/cache | 10 +++++----- ...compat_ic2.json => ingot_aluminium_compat_ic2.json} | 4 ++-- ...compat_ic2.json => ingot_aluminium_compat_ic2.json} | 4 ++-- ...compat_ic2.json => ingot_aluminium_compat_ic2.json} | 2 +- ...compat_ic2.json => ingot_aluminium_compat_ic2.json} | 2 +- .../recipes/splashing/ic2/crushed_raw_aluminum.json | 2 +- .../create/foundation/data/recipe/CompatMetals.java | 6 ++++++ .../foundation/data/recipe/StandardRecipeGen.java | 2 +- .../foundation/data/recipe/WashingRecipeGen.java | 2 +- 9 files changed, 20 insertions(+), 14 deletions(-) rename src/generated/resources/data/create/advancements/recipes/building_blocks/blasting/{ingot_aluminum_compat_ic2.json => ingot_aluminium_compat_ic2.json} (82%) rename src/generated/resources/data/create/advancements/recipes/building_blocks/smelting/{ingot_aluminum_compat_ic2.json => ingot_aluminium_compat_ic2.json} (82%) rename src/generated/resources/data/create/recipes/blasting/{ingot_aluminum_compat_ic2.json => ingot_aluminium_compat_ic2.json} (86%) rename src/generated/resources/data/create/recipes/smelting/{ingot_aluminum_compat_ic2.json => ingot_aluminium_compat_ic2.json} (86%) diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 5910315fa4..56c7550b67 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -2359,7 +2359,7 @@ aec7192be51a921f7c2f9e52ca64e65cf92abf1f data/create/advancements/pipe_organ.jso abf054890da41c46221fddc2474e18d077b3c1a2 data/create/advancements/precision_mechanism.json 9eb2508128ae938f0e654f3b316aa324dd6a18e8 data/create/advancements/pulley_maxed.json 99361c643eb6fd9e0a97420f6b5d3df8bf7dbc3f data/create/advancements/recipes/building_blocks/andesite_from_stone_types_andesite_stonecutting.json -0989187987645c6b13ed453e0499a59962b8c767 data/create/advancements/recipes/building_blocks/blasting/ingot_aluminum_compat_ic2.json +28d60ca8f6505017965426f65d842facafe44fec data/create/advancements/recipes/building_blocks/blasting/ingot_aluminium_compat_ic2.json 29a2f29f50306abaac8aa361102d3a30677fcd85 data/create/advancements/recipes/building_blocks/blasting/ingot_aluminum_compat_immersiveengineering.json c6095aa02996b040d7a1ead9d32d720cd311ae7e data/create/advancements/recipes/building_blocks/blasting/ingot_lead_compat_immersiveengineering.json 60e56e5c1d38762c04634f9c8e43c5e42a002046 data/create/advancements/recipes/building_blocks/blasting/ingot_lead_compat_mekanism.json @@ -2389,7 +2389,7 @@ d252ea6ae1f88ab2286357d3a05a643eec7d92c3 data/create/advancements/recipes/buildi 78972bdf05d79e5357ff5771caa13d631e2c2740 data/create/advancements/recipes/building_blocks/smelting/glass_from_horizontal_framed_glass.json c8edb1be5163aaeebdd94f4c25ef45bf839200c0 data/create/advancements/recipes/building_blocks/smelting/glass_from_tiled_glass.json c70af1a552a80137cf25780b481387a585e551f3 data/create/advancements/recipes/building_blocks/smelting/glass_from_vertical_framed_glass.json -96fdd3a575b158b657ddd0709a05ffa7ab4b0457 data/create/advancements/recipes/building_blocks/smelting/ingot_aluminum_compat_ic2.json +9a36450a9b8f0752202eb4dfb48d0c10051270c5 data/create/advancements/recipes/building_blocks/smelting/ingot_aluminium_compat_ic2.json 4b86c2a3784cc837ab8b49c678517b53db188916 data/create/advancements/recipes/building_blocks/smelting/ingot_aluminum_compat_immersiveengineering.json cd59dee91b03d293a8e6501acc734261858cdb56 data/create/advancements/recipes/building_blocks/smelting/ingot_lead_compat_immersiveengineering.json 80e276bd06ac555aa9203247a24f97c779cb80db data/create/advancements/recipes/building_blocks/smelting/ingot_lead_compat_mekanism.json @@ -3864,7 +3864,7 @@ a133d4d2542c0b9309873d06a72e7efff4cee219 data/create/recipes/asurine_pillar_from 288d80210f7efb4664e2e9c9d9111049863e5f60 data/create/recipes/birch_window_pane.json 70b34d9573875b9bc15f8d71baac81ecd7c0ab60 data/create/recipes/blasting/copper_ingot_from_crushed.json 9f9f50e6f65d3077ee7c39403fffb31fea3bb408 data/create/recipes/blasting/gold_ingot_from_crushed.json -1002fb0e5f3ab0068c381ebc6488b868671d9f66 data/create/recipes/blasting/ingot_aluminum_compat_ic2.json +7f7f9f631e3c96af0446ad5d87ac47fb7f70d08d data/create/recipes/blasting/ingot_aluminium_compat_ic2.json 172904335190876e7b52bad7031b7d8f3fba426e data/create/recipes/blasting/ingot_aluminum_compat_immersiveengineering.json 9ba4fc584e7a275cf5b3785fead3dd21fd0d2172 data/create/recipes/blasting/ingot_lead_compat_immersiveengineering.json 020618b989b39ab6e6d5ce5fcf786afc23fb0dc0 data/create/recipes/blasting/ingot_lead_compat_mekanism.json @@ -5752,7 +5752,7 @@ daaa640dbfaa86685de636b89afe2fdd74cd0cf9 data/create/recipes/smelting/glass_pane 48bdeff8ca1ae7bf732fc870fb0fa294de56188a data/create/recipes/smelting/glass_pane_from_tiled_glass_pane.json 7035be7cce5a38c794d9cc872801329af81bac46 data/create/recipes/smelting/glass_pane_from_vertical_framed_glass_pane.json a4fb256e4cc6cd9e450b054e8489f26655f6a1d2 data/create/recipes/smelting/gold_ingot_from_crushed.json -1d173fd2909e08c70d52051789e838757df6a1fa data/create/recipes/smelting/ingot_aluminum_compat_ic2.json +373278db29392d1a9823e71f09b28ed55789cd2b data/create/recipes/smelting/ingot_aluminium_compat_ic2.json 57996aea2f6456c936e248e4fd84fa5387fd3c4f data/create/recipes/smelting/ingot_aluminum_compat_immersiveengineering.json cadbfc99cab88f87a431cc8853e280d3871c4542 data/create/recipes/smelting/ingot_lead_compat_immersiveengineering.json 1b029da974db92f0bfa456c6aae9ffb709441ea7 data/create/recipes/smelting/ingot_lead_compat_mekanism.json @@ -5803,7 +5803,7 @@ fa9294fb2fbe22110ae122a616379b73ccf1d5c3 data/create/recipes/splashing/galospher c4d680eed98791fe45fa93aeeae9e8dbd508d6f5 data/create/recipes/splashing/gravel.json 7af4d9ae50af13da0d4fc814687f9586ff872798 data/create/recipes/splashing/gray_concrete_powder.json 23fb61c0e4bcca58fa7241db9cbef07bf4bd9a9b data/create/recipes/splashing/green_concrete_powder.json -82707bd9a72c35926ebf116fea1c4d9aea9a127a data/create/recipes/splashing/ic2/crushed_raw_aluminum.json +2c934a49e7766b12dd708e557a8b0ebc5600753b data/create/recipes/splashing/ic2/crushed_raw_aluminum.json f18f823c0274518a13da3be2850b916a6ece2900 data/create/recipes/splashing/ic2/crushed_raw_silver.json 71b4e6a4d62ec437f02bd2029455eb7ba5bb3943 data/create/recipes/splashing/ic2/crushed_raw_tin.json 8da1397c440f27a5af4cbfc169bcf74f83bf3c8a data/create/recipes/splashing/ic2/crushed_raw_uranium.json diff --git a/src/generated/resources/data/create/advancements/recipes/building_blocks/blasting/ingot_aluminum_compat_ic2.json b/src/generated/resources/data/create/advancements/recipes/building_blocks/blasting/ingot_aluminium_compat_ic2.json similarity index 82% rename from src/generated/resources/data/create/advancements/recipes/building_blocks/blasting/ingot_aluminum_compat_ic2.json rename to src/generated/resources/data/create/advancements/recipes/building_blocks/blasting/ingot_aluminium_compat_ic2.json index 8d7973e25f..6d99a05259 100644 --- a/src/generated/resources/data/create/advancements/recipes/building_blocks/blasting/ingot_aluminum_compat_ic2.json +++ b/src/generated/resources/data/create/advancements/recipes/building_blocks/blasting/ingot_aluminium_compat_ic2.json @@ -2,7 +2,7 @@ "parent": "minecraft:recipes/root", "rewards": { "recipes": [ - "create:blasting/ingot_aluminum_compat_ic2" + "create:blasting/ingot_aluminium_compat_ic2" ] }, "criteria": { @@ -21,7 +21,7 @@ "has_the_recipe": { "trigger": "minecraft:recipe_unlocked", "conditions": { - "recipe": "create:blasting/ingot_aluminum_compat_ic2" + "recipe": "create:blasting/ingot_aluminium_compat_ic2" } } }, diff --git a/src/generated/resources/data/create/advancements/recipes/building_blocks/smelting/ingot_aluminum_compat_ic2.json b/src/generated/resources/data/create/advancements/recipes/building_blocks/smelting/ingot_aluminium_compat_ic2.json similarity index 82% rename from src/generated/resources/data/create/advancements/recipes/building_blocks/smelting/ingot_aluminum_compat_ic2.json rename to src/generated/resources/data/create/advancements/recipes/building_blocks/smelting/ingot_aluminium_compat_ic2.json index abf18f1400..7abca1eaf8 100644 --- a/src/generated/resources/data/create/advancements/recipes/building_blocks/smelting/ingot_aluminum_compat_ic2.json +++ b/src/generated/resources/data/create/advancements/recipes/building_blocks/smelting/ingot_aluminium_compat_ic2.json @@ -2,7 +2,7 @@ "parent": "minecraft:recipes/root", "rewards": { "recipes": [ - "create:smelting/ingot_aluminum_compat_ic2" + "create:smelting/ingot_aluminium_compat_ic2" ] }, "criteria": { @@ -21,7 +21,7 @@ "has_the_recipe": { "trigger": "minecraft:recipe_unlocked", "conditions": { - "recipe": "create:smelting/ingot_aluminum_compat_ic2" + "recipe": "create:smelting/ingot_aluminium_compat_ic2" } } }, diff --git a/src/generated/resources/data/create/recipes/blasting/ingot_aluminum_compat_ic2.json b/src/generated/resources/data/create/recipes/blasting/ingot_aluminium_compat_ic2.json similarity index 86% rename from src/generated/resources/data/create/recipes/blasting/ingot_aluminum_compat_ic2.json rename to src/generated/resources/data/create/recipes/blasting/ingot_aluminium_compat_ic2.json index 326a583690..08f0c18ddb 100644 --- a/src/generated/resources/data/create/recipes/blasting/ingot_aluminum_compat_ic2.json +++ b/src/generated/resources/data/create/recipes/blasting/ingot_aluminium_compat_ic2.json @@ -3,7 +3,7 @@ "ingredient": { "item": "create:crushed_raw_aluminum" }, - "result": "ic2:ingot_aluminum", + "result": "ic2:ingot_aluminium", "experience": 0.1, "cookingtime": 100, "conditions": [ diff --git a/src/generated/resources/data/create/recipes/smelting/ingot_aluminum_compat_ic2.json b/src/generated/resources/data/create/recipes/smelting/ingot_aluminium_compat_ic2.json similarity index 86% rename from src/generated/resources/data/create/recipes/smelting/ingot_aluminum_compat_ic2.json rename to src/generated/resources/data/create/recipes/smelting/ingot_aluminium_compat_ic2.json index 6fb0e09de3..92152e36c3 100644 --- a/src/generated/resources/data/create/recipes/smelting/ingot_aluminum_compat_ic2.json +++ b/src/generated/resources/data/create/recipes/smelting/ingot_aluminium_compat_ic2.json @@ -3,7 +3,7 @@ "ingredient": { "item": "create:crushed_raw_aluminum" }, - "result": "ic2:ingot_aluminum", + "result": "ic2:ingot_aluminium", "experience": 0.1, "cookingtime": 200, "conditions": [ diff --git a/src/generated/resources/data/create/recipes/splashing/ic2/crushed_raw_aluminum.json b/src/generated/resources/data/create/recipes/splashing/ic2/crushed_raw_aluminum.json index 26e5bbfd33..8871bb3ca5 100644 --- a/src/generated/resources/data/create/recipes/splashing/ic2/crushed_raw_aluminum.json +++ b/src/generated/resources/data/create/recipes/splashing/ic2/crushed_raw_aluminum.json @@ -7,7 +7,7 @@ ], "results": [ { - "item": "ic2:nugget_aluminum", + "item": "ic2:nugget_aluminium", "count": 9 } ], diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/CompatMetals.java b/src/main/java/com/simibubi/create/foundation/data/recipe/CompatMetals.java index 5a87e23a5c..bb1b7ea54e 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/CompatMetals.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/CompatMetals.java @@ -32,6 +32,12 @@ public enum CompatMetals { public String getName() { return name; } + + public String getName(Mods mod) { + if (this == ALUMINUM && mod == IC2) // include in mods.builder if this happens again + return "aluminium"; + return name; + } /** * These mods must provide an ingot and nugget variant of the corresponding metal. diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java index 1dae805e92..08cf018d21 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java @@ -1223,8 +1223,8 @@ GeneratedRecipe blastCrushedMetal(Supplier result, Supplier< } GeneratedRecipe blastModdedCrushedMetal(ItemEntry ingredient, CompatMetals metal) { - String metalName = metal.getName(); for (Mods mod : metal.getMods()) { + String metalName = metal.getName(mod); ResourceLocation ingot = mod.ingotOf(metalName); String modId = mod.getId(); create(ingot).withSuffix("_compat_" + modId) diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/WashingRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/WashingRecipeGen.java index 6811c36070..4940ba3e6e 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/WashingRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/WashingRecipeGen.java @@ -133,8 +133,8 @@ public GeneratedRecipe crushedOre(ItemEntry crushed, Supplier nu } public GeneratedRecipe moddedCrushedOre(ItemEntry crushed, CompatMetals metal) { - String metalName = metal.getName(); for (Mods mod : metal.getMods()) { + String metalName = metal.getName(mod); ResourceLocation nugget = mod.nuggetOf(metalName); create(mod.getId() + "/" + crushed.getId() .getPath(), From a99f05d8b0da4188f4fc3da9bde6fad3ff015aac Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue, 8 Oct 2024 15:56:13 +0200 Subject: [PATCH 07/10] Toolbugs - Attempt to improve handling of toolbox storage on contraptions #6940 --- .../content/contraptions/MountedStorage.java | 6 ++++++ .../equipment/toolbox/ToolboxInventory.java | 16 ++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/MountedStorage.java b/src/main/java/com/simibubi/create/content/contraptions/MountedStorage.java index ad9b0c859c..3b86dafc6a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/MountedStorage.java +++ b/src/main/java/com/simibubi/create/content/contraptions/MountedStorage.java @@ -2,6 +2,7 @@ import com.simibubi.create.AllBlockEntityTypes; import com.simibubi.create.AllTags.AllBlockTags; +import com.simibubi.create.content.equipment.toolbox.ToolboxInventory; import com.simibubi.create.content.kinetics.crafter.MechanicalCrafterBlockEntity; import com.simibubi.create.content.logistics.crate.BottomlessItemHandler; import com.simibubi.create.content.logistics.vault.ItemVaultBlockEntity; @@ -177,6 +178,8 @@ public CompoundTag serialize() { CompoundTag tag = handler.serializeNBT(); if (noFuel) NBTHelper.putMarker(tag, "NoFuel"); + if (handler instanceof ToolboxInventory) + NBTHelper.putMarker(tag, "Toolbox"); if (!(handler instanceof BottomlessItemHandler)) return tag; @@ -191,6 +194,9 @@ public static MountedStorage deserialize(CompoundTag nbt) { storage.handler = new ItemStackHandler(); if (nbt == null) return storage; + if (nbt.contains("Toolbox")) + storage.handler = new ToolboxInventory(null); + storage.valid = true; storage.noFuel = nbt.contains("NoFuel"); diff --git a/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxInventory.java b/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxInventory.java index a9d69e9caa..bb16f4feb9 100644 --- a/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxInventory.java +++ b/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxInventory.java @@ -83,7 +83,7 @@ else if (!stackInSlot.isEmpty()) { } } settling = false; - blockEntity.sendData(); + notifyUpdate(); } @Override @@ -109,7 +109,7 @@ public void setStackInSlot(int slot, ItemStack stack) { if (!stack.isEmpty() && filters.get(compartment) .isEmpty()) { filters.set(compartment, ItemHandlerHelper.copyStackWithSize(stack, 1)); - blockEntity.sendData(); + notifyUpdate(); } } @@ -121,7 +121,7 @@ public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { if (!stack.isEmpty() && filters.get(compartment) .isEmpty()) { filters.set(compartment, ItemHandlerHelper.copyStackWithSize(stack, 1)); - blockEntity.sendData(); + notifyUpdate(); } } return insertItem; @@ -136,10 +136,9 @@ public CompoundTag serializeNBT() { @Override protected void onContentsChanged(int slot) { - if (!settling && !blockEntity.getLevel().isClientSide) + if (!settling && (blockEntity == null || !blockEntity.getLevel().isClientSide)) settle(slot / STACKS_PER_COMPARTMENT); - blockEntity.sendData(); - blockEntity.setChanged(); + notifyUpdate(); super.onContentsChanged(slot); } @@ -208,4 +207,9 @@ public static boolean canItemsShareCompartment(ItemStack stack1, ItemStack stack return ItemHandlerHelper.canItemStacksStack(stack1, stack2); } + private void notifyUpdate() { + if (blockEntity != null) + blockEntity.notifyUpdate(); + } + } From 8e50ad4cfd286dcef741da4c47c5b5161972243a Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:43:50 +0200 Subject: [PATCH 08/10] Stack of Spades - Protect item handlers against invalid item stack sizes - Fix some held or dropped items not updating count when inserted into item handlers --- .../content/fluids/drain/ItemDrainItemHandler.java | 4 +++- .../create/content/kinetics/belt/BeltBlock.java | 2 ++ .../belt/transport/ItemHandlerBeltSegment.java | 5 ++++- .../kinetics/deployer/DeployerItemHandler.java | 4 +++- .../content/logistics/chute/ChuteItemHandler.java | 5 ++++- .../create/content/logistics/funnel/FunnelBlock.java | 2 +- .../logistics/tunnel/BrassTunnelItemHandler.java | 6 +++++- .../simibubi/create/foundation/item/ItemHelper.java | 12 ++++++++++++ 8 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainItemHandler.java b/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainItemHandler.java index d69e16c557..44da916ea3 100644 --- a/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainItemHandler.java +++ b/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainItemHandler.java @@ -2,6 +2,7 @@ import com.simibubi.create.content.fluids.transfer.GenericItemEmptying; import com.simibubi.create.content.kinetics.belt.transport.TransportedItemStack; +import com.simibubi.create.foundation.item.ItemHelper; import net.minecraft.core.Direction; import net.minecraft.world.item.ItemStack; @@ -38,7 +39,8 @@ public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { if (stack.getCount() > 1 && GenericItemEmptying.canItemBeEmptied(blockEntity.getLevel(), stack)) { returned = ItemHandlerHelper.copyStackWithSize(stack, stack.getCount() - 1); stack = ItemHandlerHelper.copyStackWithSize(stack, 1); - } + } else + returned = ItemHelper.limitCountToMaxStackSize(stack, simulate); if (!simulate) { TransportedItemStack heldItem = new TransportedItemStack(stack); diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java index 64c37cc2c8..944e4a3990 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java @@ -218,6 +218,8 @@ public void entityInside(BlockState state, Level worldIn, BlockPos pos, Entity e .copy(), false); if (remainder.isEmpty()) itemEntity.discard(); + else if (remainder.getCount() != itemEntity.getItem().getCount()) + itemEntity.setItem(remainder); }); return; } diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java b/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java index 0a5248c5ff..15f20c86d3 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java @@ -1,5 +1,7 @@ package com.simibubi.create.content.kinetics.belt.transport; +import com.simibubi.create.foundation.item.ItemHelper; + import net.minecraft.world.item.ItemStack; import net.minecraftforge.items.IItemHandler; @@ -29,6 +31,7 @@ public ItemStack getStackInSlot(int slot) { @Override public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { if (this.beltInventory.canInsertAt(offset)) { + ItemStack remainder = ItemHelper.limitCountToMaxStackSize(stack, simulate); if (!simulate) { TransportedItemStack newStack = new TransportedItemStack(stack); newStack.insertedAt = offset; @@ -38,7 +41,7 @@ public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { this.beltInventory.belt.setChanged(); this.beltInventory.belt.sendData(); } - return ItemStack.EMPTY; + return remainder; } return stack; } diff --git a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerItemHandler.java b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerItemHandler.java index ecabcf2ed3..ac106c8255 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerItemHandler.java +++ b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerItemHandler.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.kinetics.deployer; import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour; +import com.simibubi.create.foundation.item.ItemHelper; import net.minecraft.world.InteractionHand; import net.minecraft.world.item.ItemStack; @@ -52,9 +53,10 @@ public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { ItemStack held = getHeld(); if (held.isEmpty()) { + ItemStack remainder = ItemHelper.limitCountToMaxStackSize(stack, simulate); if (!simulate) set(stack); - return ItemStack.EMPTY; + return remainder; } if (!ItemHandlerHelper.canItemStacksStack(held, stack)) diff --git a/src/main/java/com/simibubi/create/content/logistics/chute/ChuteItemHandler.java b/src/main/java/com/simibubi/create/content/logistics/chute/ChuteItemHandler.java index 72a77ff019..7179a1d261 100644 --- a/src/main/java/com/simibubi/create/content/logistics/chute/ChuteItemHandler.java +++ b/src/main/java/com/simibubi/create/content/logistics/chute/ChuteItemHandler.java @@ -1,5 +1,7 @@ package com.simibubi.create.content.logistics.chute; +import com.simibubi.create.foundation.item.ItemHelper; + import net.minecraft.world.item.ItemStack; import net.minecraftforge.items.IItemHandler; @@ -25,9 +27,10 @@ public ItemStack getStackInSlot(int slot) { public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { if (!blockEntity.canAcceptItem(stack)) return stack; + ItemStack remainder = ItemHelper.limitCountToMaxStackSize(stack, simulate); if (!simulate) blockEntity.setItem(stack); - return ItemStack.EMPTY; + return remainder; } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelBlock.java index d617c9e420..460819ad93 100644 --- a/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelBlock.java @@ -93,7 +93,7 @@ public InteractionResult use(BlockState state, Level worldIn, BlockPos pos, Play withBlockEntityDo(worldIn, pos, be -> { ItemStack toInsert = heldItem.copy(); ItemStack remainder = tryInsert(worldIn, pos, toInsert, false); - if (!ItemStack.matches(remainder, toInsert)) + if (!ItemStack.matches(remainder, toInsert) || remainder.getCount() != heldItem.getCount()) player.setItemInHand(handIn, remainder); }); return InteractionResult.SUCCESS; diff --git a/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelItemHandler.java b/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelItemHandler.java index 430755c504..0db27450af 100644 --- a/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelItemHandler.java +++ b/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelItemHandler.java @@ -1,5 +1,7 @@ package com.simibubi.create.content.logistics.tunnel; +import com.simibubi.create.foundation.item.ItemHelper; + import net.minecraft.world.item.ItemStack; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.IItemHandler; @@ -33,9 +35,11 @@ public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { if (!blockEntity.canTakeItems()) return stack; + + ItemStack remainder = ItemHelper.limitCountToMaxStackSize(stack, simulate); if (!simulate) blockEntity.setStackToDistribute(stack, null); - return ItemStack.EMPTY; + return remainder; } @Override diff --git a/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java b/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java index 1f4e09d185..9ea14a53c4 100644 --- a/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java +++ b/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java @@ -276,4 +276,16 @@ public static int findFirstMatchingSlotIndex(IItemHandler inv, Predicate Date: Tue, 8 Oct 2024 17:11:56 +0200 Subject: [PATCH 09/10] I have so much to show you - Prevent basins from endlessly queueing up particle information when no players are near #6837 --- .../create/content/processing/basin/BasinBlockEntity.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java b/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java index 54db269a5e..01592ee973 100644 --- a/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java @@ -412,7 +412,8 @@ private void tryClearingSpoutputOverflow() { if (filter != null && !filter.test(itemStack)) continue; - visualizedOutputItems.add(IntAttached.withZero(itemStack)); + if (visualizedOutputItems.size() < 3) + visualizedOutputItems.add(IntAttached.withZero(itemStack)); update = true; remainder = ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), false); @@ -446,7 +447,8 @@ private void tryClearingSpoutputOverflow() { update = true; iterator.remove(); - visualizedOutputFluids.add(IntAttached.withZero(fluidStack)); + if (visualizedOutputFluids.size() < 3) + visualizedOutputFluids.add(IntAttached.withZero(fluidStack)); } } From 2828c88d80f3183616812525b00440e4ce6bf230 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Wed, 9 Oct 2024 01:17:27 +0200 Subject: [PATCH 10/10] Multiblock Madness - Fixed moving single-tile tanks and vaults leading to corrupt nbt #6915 #6925 #6943 #6979 - Display links now check for click events in transferred components #6942 - Fixed negative values displayed on kinetic generator goggle overlay --- .../content/contraptions/Contraption.java | 4 ++ .../base/GeneratingKineticBlockEntity.java | 3 +- .../displayLink/source/DisplaySource.java | 7 ++++ .../displayLink/target/DisplayTarget.java | 4 ++ .../target/LecternDisplayTarget.java | 5 +++ .../displayLink/target/SignDisplayTarget.java | 5 +++ .../content/schematics/SchematicWorld.java | 22 ++++++++++ .../schematics/client/SchematicHandler.java | 3 ++ .../create/foundation/ponder/PonderWorld.java | 41 ++++++------------- .../foundation/utility/BlockHelper.java | 9 +++- .../foundation/utility/NBTProcessors.java | 29 ++++++++++++- 11 files changed, 97 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/Contraption.java index d004d9ae23..07ba16454d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/Contraption.java @@ -1139,6 +1139,7 @@ public void addBlocksToWorld(Level world, StructureTransform transform) { if (blockEntity instanceof IMultiBlockEntityContainer) { if (tag.contains("LastKnownPos") || capturedMultiblocks.isEmpty()) { tag.put("LastKnownPos", NbtUtils.writeBlockPos(BlockPos.ZERO.below(Integer.MAX_VALUE - 1))); + tag.remove("Controller"); } } @@ -1195,6 +1196,9 @@ protected void translateMultiblockControllers(StructureTransform transform) { // swap nbt data to the new controller position StructureBlockInfo prevControllerInfo = blocks.get(controllerPos); StructureBlockInfo newControllerInfo = blocks.get(otherPos); + if (prevControllerInfo == null || newControllerInfo == null) + return; + blocks.put(otherPos, new StructureBlockInfo(newControllerInfo.pos, newControllerInfo.state, prevControllerInfo.nbt)); blocks.put(controllerPos, new StructureBlockInfo(prevControllerInfo.pos, prevControllerInfo.state, newControllerInfo.nbt)); }); diff --git a/src/main/java/com/simibubi/create/content/kinetics/base/GeneratingKineticBlockEntity.java b/src/main/java/com/simibubi/create/content/kinetics/base/GeneratingKineticBlockEntity.java index b11625687b..724bab243d 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/base/GeneratingKineticBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/kinetics/base/GeneratingKineticBlockEntity.java @@ -73,9 +73,8 @@ public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneak float speed = getTheoreticalSpeed(); if (speed != getGeneratedSpeed() && speed != 0) stressBase *= getGeneratedSpeed() / speed; - speed = Math.abs(speed); - float stressTotal = stressBase * speed; + float stressTotal = Math.abs(stressBase * speed); Lang.number(stressTotal) .translate("generic.unit.stress") diff --git a/src/main/java/com/simibubi/create/content/redstone/displayLink/source/DisplaySource.java b/src/main/java/com/simibubi/create/content/redstone/displayLink/source/DisplaySource.java index b5db5c057d..5441352614 100644 --- a/src/main/java/com/simibubi/create/content/redstone/displayLink/source/DisplaySource.java +++ b/src/main/java/com/simibubi/create/content/redstone/displayLink/source/DisplaySource.java @@ -13,6 +13,7 @@ import com.simibubi.create.content.trains.display.FlapDisplayLayout; import com.simibubi.create.foundation.gui.ModularGuiLineBuilder; import com.simibubi.create.foundation.utility.Components; +import com.simibubi.create.foundation.utility.NBTProcessors; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -38,6 +39,12 @@ public void transferData(DisplayLinkContext context, DisplayTarget activeTarget, List text = provideText(context, stats); if (text.isEmpty()) text = EMPTY; + + if (activeTarget.requiresComponentSanitization()) + for (MutableComponent component : text) + if (NBTProcessors.textComponentHasClickEvent(component)) + return; // Naughty + activeTarget.acceptText(line, text, context); } diff --git a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/DisplayTarget.java b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/DisplayTarget.java index 7732f7be24..79b2e128a7 100644 --- a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/DisplayTarget.java +++ b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/DisplayTarget.java @@ -67,5 +67,9 @@ public boolean isReserved(int line, BlockEntity target, DisplayLinkContext conte tag.remove("DisplayLink"); return false; } + + public boolean requiresComponentSanitization() { + return false; + } } diff --git a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/LecternDisplayTarget.java b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/LecternDisplayTarget.java index fdc087b4f7..15ec2a0726 100644 --- a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/LecternDisplayTarget.java +++ b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/LecternDisplayTarget.java @@ -80,5 +80,10 @@ private ItemStack signBook(ItemStack book) { return written; } + + @Override + public boolean requiresComponentSanitization() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/SignDisplayTarget.java b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/SignDisplayTarget.java index 77efd54364..21e4f224b9 100644 --- a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/SignDisplayTarget.java +++ b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/SignDisplayTarget.java @@ -35,5 +35,10 @@ public void acceptText(int line, List text, DisplayLinkContext public DisplayTargetStats provideStats(DisplayLinkContext context) { return new DisplayTargetStats(4, 15, this); } + + @Override + public boolean requiresComponentSanitization() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java b/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java index 4bbca4a6f2..c637a44731 100644 --- a/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java +++ b/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java @@ -10,6 +10,8 @@ import java.util.stream.Stream; import com.simibubi.create.Create; +import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer; +import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.utility.BBHelper; import com.simibubi.create.foundation.utility.NBTProcessors; import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld; @@ -250,5 +252,25 @@ public ServerLevel getLevel() { } throw new IllegalStateException("Cannot use IServerWorld#getWorld in a client environment"); } + + public void fixControllerBlockEntities() { + for (BlockEntity blockEntity : blockEntities.values()) { + if (!(blockEntity instanceof IMultiBlockEntityContainer multiBlockEntity)) + continue; + BlockPos lastKnown = multiBlockEntity.getLastKnownPos(); + BlockPos current = blockEntity.getBlockPos(); + if (lastKnown == null || current == null) + continue; + if (multiBlockEntity.isController()) + continue; + if (!lastKnown.equals(current)) { + BlockPos newControllerPos = multiBlockEntity.getController() + .offset(current.subtract(lastKnown)); + if (multiBlockEntity instanceof SmartBlockEntity sbe) + sbe.markVirtual(); + multiBlockEntity.setController(newControllerPos); + } + } + } } diff --git a/src/main/java/com/simibubi/create/content/schematics/client/SchematicHandler.java b/src/main/java/com/simibubi/create/content/schematics/client/SchematicHandler.java index cbc9b19582..5cdfac880b 100644 --- a/src/main/java/com/simibubi/create/content/schematics/client/SchematicHandler.java +++ b/src/main/java/com/simibubi/create/content/schematics/client/SchematicHandler.java @@ -168,6 +168,7 @@ private void setupRenderer() { schematic.placeInWorld(w, pos, pos, placementSettings, w.getRandom(), Block.UPDATE_CLIENTS); for (BlockEntity blockEntity : w.getBlockEntities()) blockEntity.setLevel(w); + w.fixControllerBlockEntities(); } catch (Exception e) { Minecraft.getInstance().player.displayClientMessage(Lang.translate("schematic.error") .component(), false); @@ -182,6 +183,7 @@ private void setupRenderer() { placementSettings.getMirror()); for (BlockEntity be : wMirroredFB.getRenderedBlockEntities()) transform.apply(be); + wMirroredFB.fixControllerBlockEntities(); placementSettings.setMirror(Mirror.LEFT_RIGHT); pos = BlockPos.ZERO.south(size.getZ() - 1); @@ -190,6 +192,7 @@ private void setupRenderer() { placementSettings.getMirror()); for (BlockEntity be : wMirroredLR.getRenderedBlockEntities()) transform.apply(be); + wMirroredLR.fixControllerBlockEntities(); renderers.get(0) .display(w); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java index c719fa374c..e6e6e8ccd3 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java @@ -14,7 +14,6 @@ import com.simibubi.create.content.kinetics.belt.BeltBlock; import com.simibubi.create.content.kinetics.belt.BeltBlockEntity; import com.simibubi.create.content.schematics.SchematicWorld; -import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.mixin.accessor.ParticleEngineAccessor; import com.simibubi.create.foundation.ponder.element.WorldSectionElement; @@ -252,38 +251,22 @@ protected void onBEadded(BlockEntity blockEntity, BlockPos pos) { smartBlockEntity.markVirtual(); } + @Override public void fixControllerBlockEntities() { + super.fixControllerBlockEntities(); for (BlockEntity blockEntity : blockEntities.values()) { - - if (blockEntity instanceof BeltBlockEntity) { - BeltBlockEntity beltBlockEntity = (BeltBlockEntity) blockEntity; - if (!beltBlockEntity.isController()) + if (!(blockEntity instanceof BeltBlockEntity beltBlockEntity)) + continue; + if (!beltBlockEntity.isController()) + continue; + BlockPos controllerPos = blockEntity.getBlockPos(); + for (BlockPos blockPos : BeltBlock.getBeltChain(this, controllerPos)) { + BlockEntity blockEntity2 = getBlockEntity(blockPos); + if (!(blockEntity2 instanceof BeltBlockEntity)) continue; - BlockPos controllerPos = blockEntity.getBlockPos(); - for (BlockPos blockPos : BeltBlock.getBeltChain(this, controllerPos)) { - BlockEntity blockEntity2 = getBlockEntity(blockPos); - if (!(blockEntity2 instanceof BeltBlockEntity)) - continue; - BeltBlockEntity belt2 = (BeltBlockEntity) blockEntity2; - belt2.setController(controllerPos); - } + BeltBlockEntity belt2 = (BeltBlockEntity) blockEntity2; + belt2.setController(controllerPos); } - - if (blockEntity instanceof IMultiBlockEntityContainer) { - IMultiBlockEntityContainer multiBlockEntity = (IMultiBlockEntityContainer) blockEntity; - BlockPos lastKnown = multiBlockEntity.getLastKnownPos(); - BlockPos current = blockEntity.getBlockPos(); - if (lastKnown == null || current == null) - continue; - if (multiBlockEntity.isController()) - continue; - if (!lastKnown.equals(current)) { - BlockPos newControllerPos = multiBlockEntity.getController() - .offset(current.subtract(lastKnown)); - multiBlockEntity.setController(newControllerPos); - } - } - } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/BlockHelper.java b/src/main/java/com/simibubi/create/foundation/utility/BlockHelper.java index 11a426e3ff..a07dd895d9 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/BlockHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/BlockHelper.java @@ -12,6 +12,7 @@ import com.simibubi.create.content.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.foundation.blockEntity.IMergeableBE; +import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -19,6 +20,7 @@ import net.minecraft.core.SectionPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; @@ -316,8 +318,11 @@ else if (state.is(BlockTags.CAULDRONS)) data.putInt("x", target.getX()); data.putInt("y", target.getY()); data.putInt("z", target.getZ()); - if (blockEntity instanceof KineticBlockEntity) - ((KineticBlockEntity) blockEntity).warnOfMovement(); + if (blockEntity instanceof KineticBlockEntity kbe) + kbe.warnOfMovement(); + if (blockEntity instanceof IMultiBlockEntityContainer imbe) + if (!imbe.isController()) + data.put("Controller", NbtUtils.writeBlockPos(imbe.getController())); blockEntity.load(data); } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java b/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java index eab6099065..412108c1d0 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java +++ b/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java @@ -2,6 +2,7 @@ import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.function.UnaryOperator; @@ -57,6 +58,24 @@ public static synchronized void addSurvivalProcessor(BlockEntityType type, }); addProcessor(AllBlockEntityTypes.CREATIVE_CRATE.get(), itemProcessor("Filter")); addProcessor(AllBlockEntityTypes.PLACARD.get(), itemProcessor("Item")); + addProcessor(AllBlockEntityTypes.CLIPBOARD.get(), data -> { + if (!data.contains("Item", Tag.TAG_COMPOUND)) + return data; + CompoundTag book = data.getCompound("Item"); + + if (!book.contains("tag", Tag.TAG_COMPOUND)) + return data; + CompoundTag itemData = book.getCompound("tag"); + + for (List entries : NBTHelper.readCompoundList(itemData.getList("Pages", Tag.TAG_COMPOUND), + pageTag -> NBTHelper.readCompoundList(pageTag.getList("Entries", Tag.TAG_COMPOUND), + tag -> tag.getString("Text")))) { + for (String entry : entries) + if (textComponentHasClickEvent(entry)) + return null; + } + return data; + }); } // Triggered by block tag, not BE type @@ -120,7 +139,13 @@ public static boolean isUnsafeItemNBTKey(String name) { } public static boolean textComponentHasClickEvent(String json) { - Component component = Component.Serializer.fromJson(json.isEmpty() ? "\"\"" : json); + return textComponentHasClickEvent(Component.Serializer.fromJson(json.isEmpty() ? "\"\"" : json)); + } + + public static boolean textComponentHasClickEvent(Component component) { + for (Component sibling : component.getSiblings()) + if (textComponentHasClickEvent(sibling)) + return true; return component != null && component.getStyle() != null && component.getStyle() .getClickEvent() != null; } @@ -144,7 +169,7 @@ public static CompoundTag process(BlockState blockState, BlockEntity blockEntity return signProcessor.apply(compound); if (blockEntity.onlyOpCanSetNbt()) return null; - return withUnsafeNBTDiscarded(compound); + return compound; } }