From ca18e223c1d6d5493c1c4b578c91c88a9005e2a9 Mon Sep 17 00:00:00 2001 From: TropheusJ Date: Tue, 11 Feb 2025 15:07:02 -0500 Subject: [PATCH 1/6] handle legacy data, better BlockEntity deserialization --- .../content/contraptions/Contraption.java | 77 +++++++++++++------ 1 file changed, 53 insertions(+), 24 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 60b0735b08..9a595c5b98 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/Contraption.java @@ -91,7 +91,6 @@ import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; import net.minecraft.network.protocol.game.DebugPackets; -import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ai.village.poi.PoiTypes; @@ -103,11 +102,11 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.ButtonBlock; import net.minecraft.world.level.block.ChestBlock; import net.minecraft.world.level.block.DoorBlock; +import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.PressurePlateBlock; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.SimpleWaterloggedBlock; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.ChestType; @@ -652,9 +651,8 @@ public abstract class Contraption { if (be != null) { CompoundTag updateTag = be.getUpdateTag(); - // the ID needs to be in the tag so the client can properly add the BlockEntity - ResourceLocation id = Objects.requireNonNull(BlockEntityType.getKey(be.getType())); - updateTag.putString("id", id.toString()); + // empty tags are intentionally kept, see writeBlocksCompound + // for testing, this line can be commented to emulate legacy behavior updateTags.put(localPos, updateTag); } @@ -904,10 +902,12 @@ public abstract class Contraption { // for client sync, treat the updateTag as the data if (updateTag != null) { c.put("Data", updateTag); - } - // legacy: use full data if update tag is not available - if (updateTag == null && block.nbt() != null) { + } else if (block.nbt() != null) { + // an updateTag is saved for all BlockEntities, even when empty. + // this case means that the contraption was assembled pre-updateTags. + // in this case, we need to use the full BlockEntity data. c.put("Data", block.nbt()); + NBTHelper.putMarker(c, "Legacy"); } } else { // otherwise, write actual data as the data, save updateTag on its own @@ -962,29 +962,17 @@ public abstract class Contraption { if (c.contains("UpdateTag", Tag.TAG_COMPOUND)) { CompoundTag updateTag = c.getCompound("UpdateTag"); - if (!updateTag.isEmpty()) { - this.updateTags.put(info.pos(), updateTag); - } + // it's very important that empty tags are read here. see writeBlocksCompound + this.updateTags.put(info.pos(), updateTag); } if (!world.isClientSide) return; - CompoundTag tag = info.nbt(); - if (tag == null) - return; - - tag.putInt("x", info.pos().getX()); - tag.putInt("y", info.pos().getY()); - tag.putInt("z", info.pos().getZ()); - - BlockEntity be = BlockEntity.loadStatic(info.pos(), info.state(), tag); + // create the BlockEntity client-side for rendering + BlockEntity be = readBlockEntity(world, info, c); if (be == null) return; - be.setLevel(world); - if (be instanceof KineticBlockEntity kbe) - kbe.setSpeed(0); - be.getBlockState(); presentBlockEntities.put(info.pos(), be); modelData.put(info.pos(), be.getModelData()); @@ -996,6 +984,47 @@ public abstract class Contraption { }); } + @Nullable + private static BlockEntity readBlockEntity(Level level, StructureBlockInfo info, CompoundTag tag) { + BlockState state = info.state(); + BlockPos pos = info.pos(); + CompoundTag nbt = info.nbt(); + + if (tag.contains("Legacy")) { + // for contraptions that were assembled pre-updateTags, we need to use the old strategy. + if (nbt == null) + return null; + + nbt.putInt("x", pos.getX()); + nbt.putInt("y", pos.getY()); + nbt.putInt("z", pos.getZ()); + + BlockEntity be = BlockEntity.loadStatic(pos, state, nbt); + postprocessReadBlockEntity(level, be); + return be; + } + + if (!state.hasBlockEntity() || !(state.getBlock() instanceof EntityBlock entityBlock)) + return null; + + BlockEntity be = entityBlock.newBlockEntity(pos, state); + postprocessReadBlockEntity(level, be); + if (be != null && nbt != null) { + be.handleUpdateTag(nbt); + } + + return be; + } + + private static void postprocessReadBlockEntity(Level level, @Nullable BlockEntity be) { + if (be != null) { + be.setLevel(level); + if (be instanceof KineticBlockEntity kbe) { + kbe.setSpeed(0); + } + } + } + private static StructureBlockInfo readStructureBlockInfo(CompoundTag blockListEntry, HashMapPalette palette) { return new StructureBlockInfo(BlockPos.of(blockListEntry.getLong("Pos")), From 772d5c106e8d8e7024dc045f22d74eb456e53ec6 Mon Sep 17 00:00:00 2001 From: TropheusJ Date: Tue, 11 Feb 2025 15:09:57 -0500 Subject: [PATCH 2/6] avoid NPE in ContraptionVisual when the contraption can't be synced --- .../create/content/contraptions/render/ContraptionVisual.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java b/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java index 37df2c080e..6a2b0606ab 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java @@ -48,6 +48,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; + import net.minecraftforge.client.model.data.ModelData; public class ContraptionVisual extends AbstractEntityVisual implements DynamicVisual, TickableVisual, LightUpdatedVisual, ShaderLightVisual { @@ -74,6 +75,8 @@ public class ContraptionVisual extends Abst setEmbeddingMatrices(partialTick); Contraption contraption = entity.getContraption(); + if (contraption == null) + return; setupModel(contraption); From cc4e272392131dc124853a018eae329352198131 Mon Sep 17 00:00:00 2001 From: TropheusJ Date: Tue, 11 Feb 2025 15:16:20 -0500 Subject: [PATCH 3/6] add comment to ContraptionVisual --- .../create/content/contraptions/render/ContraptionVisual.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java b/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java index 6a2b0606ab..1292a4d77f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java @@ -75,6 +75,7 @@ public class ContraptionVisual extends Abst setEmbeddingMatrices(partialTick); Contraption contraption = entity.getContraption(); + // The contraption could be null if it wasn't synced (ex. too much data) if (contraption == null) return; From b18e28a86c16ebc356c4d22262b5904babab154b Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Wed, 12 Feb 2025 10:51:40 +0100 Subject: [PATCH 4/6] The gaming wont end - Re-packagers can no longer unpack into another packager - Added a message when trying to connect a packager to a PSI - Fixed key presses triggering ui events when a text input is focused - Added redstone dust to packager recipe - Made category hiding in stock keeper UI less hacky --- .../2d64935085b86659cb7857bad9701dbf9bab6e4c | 6 +++--- .../82992cbf8f2794d83ac94034835eac0acd7915b9 | 4 ++-- .../resources/assets/create/lang/en_ud.json | 1 + .../resources/assets/create/lang/en_us.json | 1 + .../recipes/crafting/logistics/packager.json | 5 ++++- .../logistics/packager/PackagerBlock.java | 17 +++++++++++++++-- .../packager/PackagerBlockEntity.java | 2 -- .../repackager/RepackagerBlockEntity.java | 2 +- .../stockTicker/StockKeeperRequestScreen.java | 19 +++++++++++-------- .../data/recipe/StandardRecipeGen.java | 3 ++- .../gui/menu/AbstractSimiContainerScreen.java | 8 ++++---- .../assets/create/lang/default/interface.json | 2 ++ 12 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/generated/resources/.cache/2d64935085b86659cb7857bad9701dbf9bab6e4c b/src/generated/resources/.cache/2d64935085b86659cb7857bad9701dbf9bab6e4c index efbd4da21c..90e0a41dcb 100644 --- a/src/generated/resources/.cache/2d64935085b86659cb7857bad9701dbf9bab6e4c +++ b/src/generated/resources/.cache/2d64935085b86659cb7857bad9701dbf9bab6e4c @@ -1,4 +1,4 @@ -// 1.20.1 2025-02-07T14:33:10.4318818 Registrate Provider for create [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)] +// 1.20.1 2025-02-12T10:49:57.1047644 Registrate Provider for create [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)] 60bbdf92d2ac9824ea6144955c74043a6005f79d assets/create/blockstates/acacia_window.json 6a67703c2697d81b7dc83e9d72a66f9c9ff08383 assets/create/blockstates/acacia_window_pane.json c3ae87b62e81d8e9476eccd793bb1548d74c66a1 assets/create/blockstates/adjustable_chain_gearshift.json @@ -642,8 +642,8 @@ b0d8f08968763a5f74e5cd5644377a76a9f39753 assets/create/blockstates/yellow_toolbo fe8c497aacc641c2f01cec90bba9f19e59cc2ed2 assets/create/blockstates/yellow_valve_handle.json e819e93fdcbe9fd9c050a052d2718ff3b3539365 assets/create/blockstates/zinc_block.json 64121dcb216381c83b4fe28aa361ea07c24c9ad0 assets/create/blockstates/zinc_ore.json -99c03ec65894ea7d88e3346c5e0c086a7acec6af assets/create/lang/en_ud.json -5f0262b9f6c1139659f6dab4d9c371be50503c0b assets/create/lang/en_us.json +443742f2bb4fc520ec7db483fd22425884cb95be assets/create/lang/en_ud.json +282779fe7ecc64cd99c08e3a7397646af9f500c4 assets/create/lang/en_us.json a97e1060e00ae701a02e39cd4ef8054cf345fac4 assets/create/models/block/acacia_window.json 103e032c0b1a0a6a27c67da8c91179a564bd281c assets/create/models/block/acacia_window_pane_noside.json fb00b627abda76ad4fea867ca57dbfadd24fffa3 assets/create/models/block/acacia_window_pane_noside_alt.json diff --git a/src/generated/resources/.cache/82992cbf8f2794d83ac94034835eac0acd7915b9 b/src/generated/resources/.cache/82992cbf8f2794d83ac94034835eac0acd7915b9 index 450f76f1a1..17c7de3f6c 100644 --- a/src/generated/resources/.cache/82992cbf8f2794d83ac94034835eac0acd7915b9 +++ b/src/generated/resources/.cache/82992cbf8f2794d83ac94034835eac0acd7915b9 @@ -1,4 +1,4 @@ -// 1.20.1 2025-02-07T11:36:36.6037564 Create's Standard Recipes +// 1.20.1 2025-02-12T10:49:57.1801346 Create's Standard Recipes a8cc4af26f6c7c45a9eef12e92af1452fe042454 data/create/advancements/recipes/combat/crafting/appliances/netherite_backtank.json 2c2639c7b307ee7c7a4e97e5efebf496788998ad data/create/advancements/recipes/combat/crafting/appliances/netherite_backtank_from_netherite.json 81dcf0cb1aa99e39bc7d1a386e07cad4cee7d8b9 data/create/advancements/recipes/combat/crafting/appliances/netherite_diving_boots.json @@ -466,7 +466,7 @@ d994ef262b16357984d3ed62f6563d2f37266193 data/create/recipes/crafting/logistics/ 4daadd2c67fe8bbf5594fb50dcf051dad7f9997a data/create/recipes/crafting/logistics/factory_gauge.json 2fb7722137990b9b9be967a1f766e138678d0573 data/create/recipes/crafting/logistics/factory_gauge_clear.json f3ba21e8979256fb78cd618ac4f1082b0b2f9e0c data/create/recipes/crafting/logistics/item_hatch.json -38c6236d7ac157a75ac5a98ab9b712eabb0c78c4 data/create/recipes/crafting/logistics/packager.json +7d66c3b5d704f583e32617b37620e749462eaa1f data/create/recipes/crafting/logistics/packager.json 6b51fa6a5bd1e9dc8e7387269d985cd622ab8ada data/create/recipes/crafting/logistics/packager_from_conversion.json 6852cb8ff6916981920ab9c987c6e357e9236511 data/create/recipes/crafting/logistics/package_frogport.json dd28b63ceb46a1e9071549c4f8ff32f520c667f6 data/create/recipes/crafting/logistics/powered_latch.json diff --git a/src/generated/resources/assets/create/lang/en_ud.json b/src/generated/resources/assets/create/lang/en_ud.json index e35475712a..052a39400c 100644 --- a/src/generated/resources/assets/create/lang/en_ud.json +++ b/src/generated/resources/assets/create/lang/en_ud.json @@ -1580,6 +1580,7 @@ "create.package_port.cannot_reach_down": "pɹɐʍuʍop ʇɔǝuuoɔ ʇouuɐƆ", "create.package_port.too_far": "ʎɐʍɐ ɹɐɟ oo⟘", "create.package_port.valid": "✔ ʇɔǝuuoƆ uɐƆ", + "create.packager.no_portable_storage": "ʎןʇɔǝɹıp ǝbɐɹoʇS ǝןqɐʇɹoԀ ɥʇıʍ ǝɔɐɟɹǝʇuı ʇouuɐɔ sɹǝbɐʞɔɐԀ", "create.packager_link.clear": "uoıʇɔǝןǝs pǝɹɐǝןƆ", "create.packager_link.set": "pǝʇɔǝןǝs ʇǝbɹɐ⟘", "create.packager_link.success": "ʇǝbɹɐʇ oʇ punoq ʎןןnɟssǝɔɔnS", diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 9420d12373..b335fbbb2c 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -1580,6 +1580,7 @@ "create.package_port.cannot_reach_down": "Cannot connect downward", "create.package_port.too_far": "Too far away", "create.package_port.valid": "Can Connect ✔", + "create.packager.no_portable_storage": "Packagers cannot interface with Portable Storage directly", "create.packager_link.clear": "Cleared selection", "create.packager_link.set": "Target selected", "create.packager_link.success": "Successfully bound to target", diff --git a/src/generated/resources/data/create/recipes/crafting/logistics/packager.json b/src/generated/resources/data/create/recipes/crafting/logistics/packager.json index 9a2af88c13..ded5731192 100644 --- a/src/generated/resources/data/create/recipes/crafting/logistics/packager.json +++ b/src/generated/resources/data/create/recipes/crafting/logistics/packager.json @@ -7,12 +7,15 @@ }, "C": { "tag": "forge:ingots/iron" + }, + "R": { + "tag": "forge:dusts/redstone" } }, "pattern": [ " C ", "CAC", - " C " + "RCR" ], "result": { "item": "create:packager" diff --git a/src/main/java/com/simibubi/create/content/logistics/packager/PackagerBlock.java b/src/main/java/com/simibubi/create/content/logistics/packager/PackagerBlock.java index 1879ed74ea..dff5c7f707 100644 --- a/src/main/java/com/simibubi/create/content/logistics/packager/PackagerBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/packager/PackagerBlock.java @@ -9,6 +9,7 @@ import com.simibubi.create.content.logistics.box.PackageItem; import com.simibubi.create.foundation.advancement.AdvancementBehaviour; import com.simibubi.create.foundation.block.IBE; import com.simibubi.create.foundation.block.WrenchableDirectionalBlock; +import com.simibubi.create.foundation.utility.CreateLang; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -33,6 +34,7 @@ import net.minecraft.world.level.pathfinder.PathComputationType; import net.minecraft.world.phys.BlockHitResult; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ForgeCapabilities; +import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.items.IItemHandler; public class PackagerBlock extends WrenchableDirectionalBlock implements IBE, IWrenchable { @@ -70,13 +72,24 @@ public class PackagerBlock extends WrenchableDirectionalBlock implements IBE