diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeData.java b/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeData.java index 59d06e8ee..a3b0d4c0e 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeData.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeData.java @@ -143,7 +143,7 @@ public final class UpgradeData { if (obj == this) return true; return obj instanceof UpgradeData that && upgrade == that.upgrade && data.equals(that.data) - && ((stack == null && that.stack == null) || ItemStack.isSameItemSameComponents(getStack(), that.getStack())); + && ((stack == null && that.stack == null) || ItemStack.matches(getStack(), that.getStack())); } @Override @@ -153,6 +153,6 @@ public final class UpgradeData { @Override public String toString() { - return "UpgradeData[upgrade=" + upgrade.key().location() + ", data=" + data + ", stack=" + stack + "]"; + return "UpgradeData[upgrade=" + upgrade.key().location() + ", data=" + data + ", stack=" + (stack == null ? "null" : stack.getItem().toString() + stack.getComponentsPatch()) + "]"; } } diff --git a/projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java b/projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java index 747800701..38ae8c2ad 100644 --- a/projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java +++ b/projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java @@ -5,9 +5,9 @@ package dan200.computercraft.mixin; import com.llamalad7.mixinextras.sugar.Local; -import com.mojang.datafixers.DataFixUtils; import com.mojang.datafixers.DataFixerBuilder; import com.mojang.datafixers.schemas.Schema; +import dan200.computercraft.shared.datafix.ComponentizationFixers; import dan200.computercraft.shared.datafix.TurtleUpgradeComponentizationFix; import net.minecraft.util.datafix.DataFixers; import net.minecraft.util.datafix.fixes.ItemStackComponentizationFix; @@ -37,7 +37,7 @@ abstract class DataFixersMixin { ) @SuppressWarnings("UnusedMethod") private static Schema addComponentizationFixes(Schema schema, @Local DataFixerBuilder builder) { - assertSchemaVersion(schema, DataFixUtils.makeKey(3818, 5)); + assertSchemaVersion(schema, ComponentizationFixers.SCHEMA_VERSION); builder.addFixer(new TurtleUpgradeComponentizationFix(schema)); return schema; } diff --git a/projects/common/src/main/java/dan200/computercraft/mixin/V1460Mixin.java b/projects/common/src/main/java/dan200/computercraft/mixin/V1460Mixin.java index 67abbfe42..2b3940f12 100644 --- a/projects/common/src/main/java/dan200/computercraft/mixin/V1460Mixin.java +++ b/projects/common/src/main/java/dan200/computercraft/mixin/V1460Mixin.java @@ -7,6 +7,7 @@ package dan200.computercraft.mixin; import com.mojang.datafixers.DSL; import com.mojang.datafixers.schemas.Schema; import com.mojang.datafixers.types.templates.TypeTemplate; +import dan200.computercraft.shared.datafix.ComponentizationFixers; import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveBlockEntity; import dan200.computercraft.shared.peripheral.printer.PrinterBlockEntity; import dan200.computercraft.shared.turtle.blocks.TurtleBlockEntity; @@ -24,7 +25,7 @@ import java.util.Map; import java.util.function.Supplier; /** - * Register our item-contianing block entities. + * Register our item-containing block entities. * * @see DiskDriveBlockEntity * @see PrinterBlockEntity @@ -48,24 +49,27 @@ abstract class V1460Mixin { )); } - private static TypeTemplate upgradeData(Schema schema) { - return DSL.or( - // Pre-1.20.5 we just use the upgrade ID. - DSL.constType(NamespacedSchema.namespacedString()), - // In newer versions this is represented as a component. - DSL.optionalFields( - "item", References.ITEM_STACK.in(schema), - "components", References.DATA_COMPONENTS.in(schema) - ) - ); + private static TypeTemplate upgradeData(Schema schema, ComponentizationFixers.UpgradeKeys keys) { + if (schema.getVersionKey() >= ComponentizationFixers.SCHEMA_VERSION) { + // In newer versions this is represented in one field. + return DSL.optional(DSL.field(keys.id(), ComponentizationFixers.upgradeDataType(schema))); + } else { + // Pre-1.20.5 we store the upgrade ID and item separately + return DSL.and( + DSL.optional(DSL.field(keys.id(), DSL.constType(NamespacedSchema.namespacedString()))), + DSL.optional(DSL.field(keys.item(), References.ITEM_STACK.in(schema))) + ); + } } @Unique private static void registerTurtle(Schema schema, Map> map, String name) { - schema.register(map, name, () -> DSL.optionalFields( - "LeftUpgrade", upgradeData(schema), - "RightUpgrade", upgradeData(schema), - "Items", DSL.list(References.ITEM_STACK.in(schema)) + schema.register(map, name, () -> DSL.and( + upgradeData(schema, ComponentizationFixers.TURTLE_UPGRADE_LEFT), + upgradeData(schema, ComponentizationFixers.TURTLE_UPGRADE_RIGHT), + DSL.optionalFields( + "Items", DSL.list(References.ITEM_STACK.in(schema)) + ) )); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/datafix/ComponentizationFixers.java b/projects/common/src/main/java/dan200/computercraft/shared/datafix/ComponentizationFixers.java index 52336ff5b..567154594 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/datafix/ComponentizationFixers.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/datafix/ComponentizationFixers.java @@ -5,6 +5,7 @@ package dan200.computercraft.shared.datafix; import com.mojang.datafixers.DSL; +import com.mojang.datafixers.DataFixUtils; import com.mojang.datafixers.Typed; import com.mojang.datafixers.schemas.Schema; import com.mojang.datafixers.types.templates.TypeTemplate; @@ -17,6 +18,8 @@ import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.media.items.PrintoutData; import net.minecraft.util.datafix.fixes.ItemStackComponentizationFix; import net.minecraft.util.datafix.fixes.References; +import net.minecraft.util.datafix.schemas.NamespacedSchema; +import net.minecraft.util.datafix.schemas.V3818_5; import java.util.ArrayList; import java.util.Arrays; @@ -26,12 +29,19 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import static net.minecraft.Util.writeAndReadTypedOrThrow; + /** * Additional fixers to convert CC's item NBT to use components. * * @see ItemStackComponentizationFix */ public class ComponentizationFixers { + /** + * The version of the {@link V3818_5} schema where we apply our changes. + */ + public static final int SCHEMA_VERSION = DataFixUtils.makeKey(3818, 5); + private static final String TURTLE_NORMAL = "computercraft:turtle_normal"; private static final String TURTLE_ADVANCED = "computercraft:turtle_advanced"; @@ -51,6 +61,16 @@ public class ComponentizationFixers { Stream.of(DISK) ).collect(Collectors.toUnmodifiableSet()); + public static final UpgradeKeys POCKET_UPGRADE = new UpgradeKeys("Upgrade", "UpgradeInfo"); + public static final UpgradeKeys TURTLE_UPGRADE_LEFT = new UpgradeKeys("LeftUpgrade", "LeftUpgradeNbt"); + public static final UpgradeKeys TURTLE_UPGRADE_RIGHT = new UpgradeKeys("RightUpgrade", "RightUpgradeNbt"); + + public record UpgradeKeys(String id, String item, String data) { + private UpgradeKeys(String id, String data) { + this(id, id + "Item", data); + } + } + /** * Fix components in item stacks. * @@ -67,7 +87,7 @@ public class ComponentizationFixers { if (item.is(POCKET_COMPUTERS)) { item.moveTagToComponent("On", "computercraft:on"); - moveUpgradeToComponent(item, ops, "Upgrade", "UpgradeInfo", "computercraft:pocket_upgrade"); + moveUpgradeToComponent(item, ops, POCKET_UPGRADE, "computercraft:pocket_upgrade"); // Remove instance/session, so they don't end up in minecraft:custom_data. item.removeTag("InstanceId"); @@ -79,8 +99,8 @@ public class ComponentizationFixers { item.removeTag("Overlay").result().ifPresent(x -> item.setComponent("computercraft:overlay", fixOverlay(x))); - moveUpgradeToComponent(item, ops, "LeftUpgrade", "LeftUpgradeNbt", "computercraft:left_turtle_upgrade"); - moveUpgradeToComponent(item, ops, "RightUpgrade", "RightUpgradeNbt", "computercraft:right_turtle_upgrade"); + moveUpgradeToComponent(item, ops, TURTLE_UPGRADE_LEFT, "computercraft:left_turtle_upgrade"); + moveUpgradeToComponent(item, ops, TURTLE_UPGRADE_RIGHT, "computercraft:right_turtle_upgrade"); } if (item.is(DISK)) item.moveTagToComponent("DiskId", "computercraft:disk_id"); @@ -100,11 +120,11 @@ public class ComponentizationFixers { if (item.is(PRINTOUTS)) movePrintoutToComponent(item, ops); } - private static void moveUpgradeToComponent(ItemStackComponentizationFix.ItemStackData data, Dynamic ops, String key, String dataKey, String component) { - // Rewrite {Upgrade:"foo",UpgradeData:...} to {cc:upgrade:{id:"foo", components:...}} - var upgrade = data.removeTag(key).asString(null); + private static void moveUpgradeToComponent(ItemStackComponentizationFix.ItemStackData data, Dynamic ops, UpgradeKeys keys, String component) { + // Rewrite {Upgrade:"foo",UpgradeItem:...UpgradeData:...} to {cc:upgrade:{id:"foo", "item": ..., components:...}} + var upgrade = data.removeTag(keys.id()).asString(null); if (upgrade == null) return; - data.setComponent(component, createUpgradeData(ops, upgrade, data.removeTag(dataKey))); + data.setComponent(component, createUpgradeData(ops, upgrade, data.removeTag(keys.item()), true, data.removeTag(keys.data()))); } private static void moveColourToComponent(ItemStackComponentizationFix.ItemStackData item, Dynamic ops, String key) { @@ -154,20 +174,20 @@ public class ComponentizationFixers { var input = DSL.namedChoice(name, inputSchema.getChoiceType(References.BLOCK_ENTITY, name)); var output = outputSchema.getChoiceType(References.BLOCK_ENTITY, name); - return typed -> typed.updateTyped(input, output, typed2 -> typed2.update(DSL.remainderFinder(), x -> { - x = moveUpgradeData(x, "LeftUpgrade", "LeftUpgradeNbt"); - x = moveUpgradeData(x, "RightUpgrade", "RightUpgradeNbt"); + return beData -> beData.updateTyped(input, output, turtleData -> writeAndReadTypedOrThrow(turtleData, output, x -> { + x = moveUpgradeData(x, TURTLE_UPGRADE_LEFT); + x = moveUpgradeData(x, TURTLE_UPGRADE_RIGHT); x = x.update("Overlay", ComponentizationFixers::fixOverlay); return x; })); } - private static Dynamic moveUpgradeData(Dynamic ops, String key, String dataKey) { - // Rewrite {Upgrade:"foo",UpgradeData:...} to {Upgrade:{id:"foo", components:...}} - var upgradeId = ops.get(key).asString(null); + private static Dynamic moveUpgradeData(Dynamic ops, UpgradeKeys keys) { + // Rewrite {Upgrade:"foo",UpgradeItem:...,UpgradeData:...} to {Upgrade:{id:"foo", item: ..., components:...}} + var upgradeId = ops.get(keys.id()).asString(null); if (upgradeId == null) return ops; - return ops.set(key, createUpgradeData(ops, upgradeId, ops.get(dataKey))).remove(dataKey); + return ops.set(keys.id(), createUpgradeData(ops, upgradeId, ops.get(keys.item()), false, ops.get(keys.data()))).remove(keys.item()).remove(keys.data()); } private static Dynamic fixOverlay(Dynamic overlay) { @@ -189,12 +209,23 @@ public class ComponentizationFixers { * * @param ops A {@link Dynamic} instance, for creating new dynamic values. * @param upgradeId The upgrade ID + * @param upgradeItem The item for this upgrade. + * @param convertItem Whether to also apply item-stack fixes to the upgrade item. When converting an upgrade on + * an item, DFUs are *not* applied to the nested item (as the ItemStack info does not contain + * sufficient information). However, they *are* applied when converting an upgrade on a BE, so we + * need to avoid the double-conversion. * @param upgradeData Additional upgrade data * @return The newly created {@link UpgradeData}-compatible value. */ - private static Dynamic createUpgradeData(Dynamic ops, String upgradeId, OptionalDynamic upgradeData) { + private static Dynamic createUpgradeData(Dynamic ops, String upgradeId, OptionalDynamic upgradeItem, boolean convertItem, OptionalDynamic upgradeData) { var newUpgrade = ops.emptyMap().set("id", ops.createString(upgradeId)); + // Migrate upgrade item + var item = upgradeItem.result().orElse(null); + if (item != null) { + newUpgrade = newUpgrade.set("item", convertItem ? fixItem(item) : item); + } + var data = upgradeData.result().orElse(null); if (data != null && !data.equals(ops.emptyMap())) { // Migrate all existing data to minecraft:custom_data @@ -204,6 +235,15 @@ public class ComponentizationFixers { return newUpgrade; } + private static Dynamic fixItem(Dynamic dynamic) { + var parsedData = ItemStackComponentizationFix.ItemStackData.read(dynamic); + if (parsedData.isEmpty()) return dynamic; + + var data = parsedData.get(); + ItemStackComponentizationFix.fixItemStack(data, data.tag); + return data.write(); + } + /** * Add our custom data components to the datafixer system. * @@ -217,8 +257,7 @@ public class ComponentizationFixers { */ public static TypeTemplate addExtraTypes(TypeTemplate type, Schema schema) { // Create a codec for UpgradeData - var upgradeData = DSL.optionalFields("components", References.DATA_COMPONENTS.in(schema)); - + var upgradeData = upgradeDataType(schema); return extraOptionalFields(type, Pair.of("computercraft:pocket_upgrade", upgradeData), Pair.of("computercraft:left_turtle_upgrade", upgradeData), @@ -226,6 +265,20 @@ public class ComponentizationFixers { ); } + /** + * Get the {@link TypeTemplate} for our {@link UpgradeData}. + * + * @param schema The current schema + * @return The upgrade data. + */ + public static TypeTemplate upgradeDataType(Schema schema) { + return DSL.optionalFields( + "id", DSL.constType(NamespacedSchema.namespacedString()), + "item", References.ITEM_STACK.in(schema), + "components", References.DATA_COMPONENTS.in(schema) + ); + } + @SafeVarargs @SuppressWarnings("varargs") private static TypeTemplate extraOptionalFields(TypeTemplate base, Pair... fields) { diff --git a/projects/common/src/main/resources/computercraft.accesswidener b/projects/common/src/main/resources/computercraft.accesswidener index 081b21533..243dd3d01 100644 --- a/projects/common/src/main/resources/computercraft.accesswidener +++ b/projects/common/src/main/resources/computercraft.accesswidener @@ -33,4 +33,7 @@ accessible field net/minecraft/client/sounds/SoundEngine executor Lnet/minecraft # Turtle model accessible method net/minecraft/client/renderer/block/model/ItemOverrides ()V +# Data fixers +accessible method net/minecraft/util/datafix/fixes/ItemStackComponentizationFix fixItemStack (Lnet/minecraft/util/datafix/fixes/ItemStackComponentizationFix$ItemStackData;Lcom/mojang/serialization/Dynamic;)V accessible class net/minecraft/util/datafix/fixes/ItemStackComponentizationFix$ItemStackData +accessible field net/minecraft/util/datafix/fixes/ItemStackComponentizationFix$ItemStackData tag Lcom/mojang/serialization/Dynamic; diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Pocket_Computer_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Pocket_Computer_Test.kt index f396a8599..0cf20c23f 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Pocket_Computer_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Pocket_Computer_Test.kt @@ -24,6 +24,7 @@ import net.minecraft.gametest.framework.GameTest import net.minecraft.gametest.framework.GameTestHelper import net.minecraft.gametest.framework.GameTestSequence import net.minecraft.network.chat.Component +import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceLocation import net.minecraft.world.item.ItemStack import org.junit.jupiter.api.Assertions.assertEquals @@ -119,9 +120,13 @@ class Pocket_Computer_Test { @GameTest fun Data_fixers(helper: GameTestHelper) = helper.sequence { thenExecute { - val upgrade = helper.level.registryAccess().registryOrThrow(IPocketUpgrade.REGISTRY) - .getHolder(ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "wireless_modem_normal")) - .orElseThrow() + val upgrade = UpgradeData.of( + helper.level.registryAccess().getOrThrow( + ResourceKey.create(IPocketUpgrade.REGISTRY, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "wireless_modem_advanced")), + ), + DataComponentUtil.createStack(ModRegistry.Items.WIRELESS_MODEM_ADVANCED.get(), DataComponents.CUSTOM_NAME, Component.literal("My favourite modem")), + DataComponentPatch.EMPTY, + ) helper.assertContainerExactly( BlockPos(2, 2, 2), @@ -131,7 +136,8 @@ class Pocket_Computer_Test { it.applyComponents( DataComponentPatch.builder() .set(ModRegistry.DataComponents.COMPUTER_ID.get(), NonNegativeId(123)) - .set(ModRegistry.DataComponents.POCKET_UPGRADE.get(), UpgradeData.ofDefault(upgrade)) + .set(ModRegistry.DataComponents.POCKET_UPGRADE.get(), upgrade) + .set(ModRegistry.DataComponents.ON.get(), false) .build(), ) }, diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Recipe_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Recipe_Test.kt index 919b13bdd..327164c0a 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Recipe_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Recipe_Test.kt @@ -67,6 +67,9 @@ class Recipe_Test { val pocketUpgrades = registries.lookupOrThrow(IPocketUpgrade.REGISTRY) val generator = UpgradeRecipeGenerator({ it }, registries) + println("Got packs => " + context.level.server.packRepository.selectedIds) + println("Got items => " + turtleUpgrades.listElementIds().toList()) + fun checkUsage(message: String, size: Int, item: ItemStack) { val recipes = generator.findRecipesWithInput(item) assertEquals(size, recipes.size, message) diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt index 1ca31b151..369849552 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt @@ -28,21 +28,26 @@ import dan200.computercraft.shared.turtle.TurtleOverlay import dan200.computercraft.shared.turtle.apis.TurtleAPI import dan200.computercraft.shared.turtle.core.TurtleCraftCommand import dan200.computercraft.shared.turtle.items.TurtleItem +import dan200.computercraft.shared.util.DataComponentUtil import dan200.computercraft.shared.util.WaterloggableHelpers import dan200.computercraft.test.core.assertArrayEquals import dan200.computercraft.test.core.computer.LuaTaskContext import dan200.computercraft.test.core.computer.getApi import dan200.computercraft.test.shared.ItemStackMatcher.isStack import net.minecraft.core.BlockPos +import net.minecraft.core.component.DataComponentPatch +import net.minecraft.core.component.DataComponents import net.minecraft.core.registries.Registries import net.minecraft.gametest.framework.GameTest import net.minecraft.gametest.framework.GameTestHelper +import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.EntityType import net.minecraft.world.entity.item.PrimedTnt import net.minecraft.world.item.BlockItem import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items +import net.minecraft.world.item.component.ItemContainerContents import net.minecraft.world.item.enchantment.Enchantments import net.minecraft.world.level.block.BeehiveBlock import net.minecraft.world.level.block.Blocks @@ -324,8 +329,7 @@ class Turtle_Test { val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()).access val upgrade = turtle.getUpgrade(TurtleSide.LEFT) assertEquals( - helper.level.registryAccess().registryOrThrow(ITurtleUpgrade.REGISTRY) - .get(ResourceLocation.fromNamespaceAndPath("cctest", "wooden_pickaxe")), + helper.level.registryAccess().getOrThrow(WOODEN_PICKAXE).value(), upgrade, "Upgrade is a wooden pickaxe", ) @@ -352,10 +356,7 @@ class Turtle_Test { helper.assertUpgradeItem( ItemStack(Items.WOODEN_PICKAXE), - UpgradeData.ofDefault( - helper.level.registryAccess().registryOrThrow(ITurtleUpgrade.REGISTRY) - .getHolder(ResourceLocation.fromNamespaceAndPath("cctest", "wooden_pickaxe")).orElseThrow(), - ), + UpgradeData.ofDefault(helper.level.registryAccess().getOrThrow(WOODEN_PICKAXE)), ) } } @@ -773,16 +774,27 @@ class Turtle_Test { thenExecute { val overlay = helper.level.registryAccess().registryOrThrow(TurtleOverlay.REGISTRY) .get(ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "trans_flag"))!! - val upgrade = helper.level.registryAccess().registryOrThrow(ITurtleUpgrade.REGISTRY) - .get(ResourceLocation.withDefaultNamespace("diamond_pickaxe"))!! + + val pickaxeUpgrade = UpgradeData.ofDefault( + helper.level.registryAccess().getOrThrow(id(ResourceLocation.withDefaultNamespace("diamond_pickaxe"))), + ) + + val shulkerUpgrade = UpgradeData.of( + helper.level.registryAccess() + .getOrThrow(id(ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "shulker"))), + DataComponentUtil.createStack(Items.SHULKER_BOX, DataComponents.CONTAINER, ItemContainerContents.fromItems(listOf(ItemStack(Items.DIRT)))), + DataComponentPatch.EMPTY, + ) val turtleBe = helper.getBlockEntity(BlockPos(1, 2, 1), ModRegistry.BlockEntities.TURTLE_NORMAL.get()) assertEquals(overlay, turtleBe.overlay) - assertEquals(upgrade, turtleBe.getUpgrade(TurtleSide.LEFT)) + assertEquals(pickaxeUpgrade, turtleBe.access.getUpgradeWithData(TurtleSide.LEFT)) + assertEquals(shulkerUpgrade, turtleBe.access.getUpgradeWithData(TurtleSide.RIGHT)) val turtleItem = turtleBe.getItem(0) assertEquals(overlay, TurtleItem.getOverlay(turtleItem)) - assertEquals(upgrade, TurtleItem.getUpgrade(turtleItem, TurtleSide.LEFT)) + assertEquals(pickaxeUpgrade, TurtleItem.getUpgradeWithData(turtleItem, TurtleSide.LEFT)) + assertEquals(shulkerUpgrade, TurtleItem.getUpgradeWithData(turtleItem, TurtleSide.RIGHT)) } } @@ -1070,6 +1082,13 @@ class Turtle_Test { thenExecute { helper.positionAtArmorStand() } thenScreenshot() } + + companion object { + private fun id(key: ResourceLocation): ResourceKey = + ResourceKey.create(ITurtleUpgrade.REGISTRY, key) + + private val WOODEN_PICKAXE = id(ResourceLocation.fromNamespaceAndPath("cctest", "wooden_pickaxe")) + } } private val LuaTaskContext.turtle get() = getApi() diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/api/TestExtensions.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/api/TestExtensions.kt index ecc70d6f8..54481f368 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/api/TestExtensions.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/api/TestExtensions.kt @@ -13,11 +13,10 @@ import dan200.computercraft.shared.util.RegistryHelper import dan200.computercraft.test.core.computer.LuaTaskContext import dan200.computercraft.test.shared.ItemStackMatcher.isStack import net.minecraft.commands.arguments.blocks.BlockInput -import net.minecraft.core.BlockPos -import net.minecraft.core.Direction -import net.minecraft.core.NonNullList +import net.minecraft.core.* import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.gametest.framework.* +import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceLocation import net.minecraft.world.Container import net.minecraft.world.InteractionHand @@ -423,3 +422,7 @@ inline fun tryMultipleTimes(count: Int, action: () -> Unit) { } } } + +/** Find an entry in a registry provider. */ +fun HolderLookup.Provider.getOrThrow(key: ResourceKey): Holder.Reference = + lookupOrThrow(key.registryKey()).getOrThrow(key) diff --git a/projects/common/src/testMod/resources/data/cctest/structures/pocket_computer_test.data_fixers.snbt b/projects/common/src/testMod/resources/data/cctest/structures/pocket_computer_test.data_fixers.snbt index 55b386357..91a7f82a4 100644 --- a/projects/common/src/testMod/resources/data/cctest/structures/pocket_computer_test.data_fixers.snbt +++ b/projects/common/src/testMod/resources/data/cctest/structures/pocket_computer_test.data_fixers.snbt @@ -27,7 +27,7 @@ {pos: [4, 0, 2], state: "minecraft:polished_andesite"}, {pos: [4, 0, 3], state: "minecraft:polished_andesite"}, {pos: [4, 0, 4], state: "minecraft:polished_andesite"}, - {pos: [2, 1, 2], state: "minecraft:chest{facing:north,type:single,waterlogged:false}", nbt: {Items: [{Count: 1b, Slot: 0b, id: "computercraft:pocket_computer_advanced", tag: {ComputerId: 123, Upgrade: "computercraft:wireless_modem_normal", display: {Name: '{"text":"Test"}'}}}], id: "minecraft:chest"}} + {pos: [2, 1, 2], state: "minecraft:chest{facing:north,type:single,waterlogged:false}", nbt: {Items: [{Count: 1b, Slot: 0b, id: "computercraft:pocket_computer_advanced", tag: {ComputerId: 123, InstanceId: [I; -1496601984, 1527793399, -1542736776, 2137516638], On: 0b, SessionId: 1591798634, Upgrade: "computercraft:wireless_modem_advanced", UpgradeItem: {Count: 1b, id: "computercraft:wireless_modem_advanced", tag: {RepairCost: 0, display: {Name: '{"text":"My favourite modem"}'}}}, display: {Name: '{"text":"Test"}'}}}], id: "minecraft:chest"}} ], entities: [], palette: [ diff --git a/projects/common/src/testMod/resources/data/cctest/structures/turtle_test.data_fixers.snbt b/projects/common/src/testMod/resources/data/cctest/structures/turtle_test.data_fixers.snbt index 49aae1e36..4c161a0a8 100644 --- a/projects/common/src/testMod/resources/data/cctest/structures/turtle_test.data_fixers.snbt +++ b/projects/common/src/testMod/resources/data/cctest/structures/turtle_test.data_fixers.snbt @@ -11,7 +11,7 @@ {pos: [2, 0, 0], state: "minecraft:polished_andesite"}, {pos: [2, 0, 1], state: "minecraft:polished_andesite"}, {pos: [2, 0, 2], state: "minecraft:polished_andesite"}, - {pos: [1, 1, 1], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 123, Fuel: 0, Items: [{Count: 1b, Slot: 0b, id: "computercraft:turtle_normal", tag: {ComputerId: 123, LeftUpgrade: "minecraft:diamond_pickaxe", Overlay: "computercraft:block/turtle_trans_overlay"}}], LeftUpgrade: "minecraft:diamond_pickaxe", LeftUpgradeNbt: {}, On: 0b, Overlay: "computercraft:block/turtle_trans_overlay", Owner: {LowerId: -4770154215762454977L, Name: "Player436", UpperId: 114963728012426084L}, Slot: 0, id: "computercraft:turtle_normal"}}, + {pos: [1, 1, 1], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 123, Fuel: 0, Items: [{Count: 1b, Slot: 0b, id: "computercraft:turtle_normal", tag: {ComputerId: 123, LeftUpgrade: "minecraft:diamond_pickaxe", LeftUpgradeItem: {Count: 1b, id: "minecraft:diamond_pickaxe", tag: {Damage: 0}}, Overlay: "computercraft:block/turtle_trans_overlay", RightUpgrade: "computercraft:shulker", RightUpgradeItem: {Count: 1b, id: "minecraft:shulker_box", tag: {BlockEntityTag: {Items: [{Count: 1b, Slot: 0b, id: "minecraft:dirt"}], id: "minecraft:shulker_box"}}}}}], LeftUpgrade: "minecraft:diamond_pickaxe", LeftUpgradeItem: {Count: 1b, id: "minecraft:diamond_pickaxe", tag: {Damage: 0}}, On: 1b, Overlay: "computercraft:block/turtle_trans_overlay", Owner: {LowerId: -4770154215762454977L, Name: "Player436", UpperId: 114963728012426084L}, RightUpgrade: "computercraft:shulker", RightUpgradeItem: {Count: 1b, id: "minecraft:shulker_box", tag: {BlockEntityTag: {Items: [{Count: 1b, Slot: 0b, id: "minecraft:dirt"}], id: "minecraft:shulker_box"}}}, Slot: 0, id: "computercraft:turtle_normal"}} ], entities: [], palette: [ diff --git a/projects/forge/src/main/resources/META-INF/accesstransformer.cfg b/projects/forge/src/main/resources/META-INF/accesstransformer.cfg index dcfea532f..297bfe7ad 100644 --- a/projects/forge/src/main/resources/META-INF/accesstransformer.cfg +++ b/projects/forge/src/main/resources/META-INF/accesstransformer.cfg @@ -33,4 +33,7 @@ public net.minecraft.data.models.ItemModelGenerators generateFlatItem(Lnet/minec public net.minecraft.data.models.ItemModelGenerators generateFlatItem(Lnet/minecraft/world/item/Item;Ljava/lang/String;Lnet/minecraft/data/models/model/ModelTemplate;)V public net.minecraft.data.models.model.TextureSlot create(Ljava/lang/String;)Lnet/minecraft/data/models/model/TextureSlot; +# Data fixers +public net.minecraft.util.datafix.fixes.ItemStackComponentizationFix fixItemStack(Lnet/minecraft/util/datafix/fixes/ItemStackComponentizationFix$ItemStackData;Lcom/mojang/serialization/Dynamic;)V public net.minecraft.util.datafix.fixes.ItemStackComponentizationFix$ItemStackData +public net.minecraft.util.datafix.fixes.ItemStackComponentizationFix$ItemStackData tag