From b989ccdd33364d923d12ef8815b7d8d89a5bc6e3 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Sun, 14 Apr 2024 15:38:38 +0200 Subject: [PATCH] Clean up item component example --- cardinal-components-base/build.gradle | 3 -- cardinal-components-base/build.gradle.kts | 3 ++ .../ladysnake/cca/test/base/EmptyVita.java | 39 +++++++++++++++++++ .../item/ItemComponentMigrationRegistry.java | 6 ++- .../MixinItemStackComponentizationFix.java | 22 +++++++++++ changelog.md | 3 ++ .../content/CardinalComponentsTest.java | 10 ++--- .../componenttest/content/TestComponents.java | 4 +- .../content/VitalityStickItem.java | 6 +-- .../componenttest/content/vita/ItemVita.java | 31 ++++++++++----- 10 files changed, 101 insertions(+), 26 deletions(-) delete mode 100644 cardinal-components-base/build.gradle create mode 100644 cardinal-components-base/build.gradle.kts create mode 100644 cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/EmptyVita.java diff --git a/cardinal-components-base/build.gradle b/cardinal-components-base/build.gradle deleted file mode 100644 index 08bc57a86..000000000 --- a/cardinal-components-base/build.gradle +++ /dev/null @@ -1,3 +0,0 @@ -dependencies { - testCompileOnly "com.google.code.findbugs:jsr305:3.0.2" -} diff --git a/cardinal-components-base/build.gradle.kts b/cardinal-components-base/build.gradle.kts new file mode 100644 index 000000000..6bcd74c3e --- /dev/null +++ b/cardinal-components-base/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies { + testCompileOnly("com.google.code.findbugs:jsr305:3.0.2") +} diff --git a/cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/EmptyVita.java b/cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/EmptyVita.java new file mode 100644 index 000000000..b0a56e55b --- /dev/null +++ b/cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/EmptyVita.java @@ -0,0 +1,39 @@ +/* + * Cardinal-Components-API + * Copyright (C) 2019-2024 Ladysnake + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE + * OR OTHER DEALINGS IN THE SOFTWARE. + */ +package org.ladysnake.cca.test.base; + +import org.ladysnake.cca.api.v3.component.TransientComponent; + +public class EmptyVita implements Vita, TransientComponent { + public static final EmptyVita INSTANCE = new EmptyVita(); + + @Override + public int getVitality() { + return 0; + } + + @Override + public void setVitality(int value) { + throw new UnsupportedOperationException(); + } +} diff --git a/cardinal-components-item/src/main/java/org/ladysnake/cca/api/v3/item/ItemComponentMigrationRegistry.java b/cardinal-components-item/src/main/java/org/ladysnake/cca/api/v3/item/ItemComponentMigrationRegistry.java index 39ba2def0..c2b168f37 100644 --- a/cardinal-components-item/src/main/java/org/ladysnake/cca/api/v3/item/ItemComponentMigrationRegistry.java +++ b/cardinal-components-item/src/main/java/org/ladysnake/cca/api/v3/item/ItemComponentMigrationRegistry.java @@ -27,11 +27,13 @@ import org.ladysnake.cca.api.v3.component.ComponentKey; /** - * Allows registering a migration for an item + * Allows registering migrations from {@linkplain org.ladysnake.cca.api.v3.component.Component CCA components} to {@linkplain net.minecraft.component.Component vanilla components}. */ public interface ItemComponentMigrationRegistry { /** - * Registers an item component migration from the specified {@link ComponentKey#getId() CCA Component ID} to an equivalent {@link DataComponentType} + * Registers an item component migration from the specified {@link ComponentKey#getId() CCA Component ID} to an equivalent {@link DataComponentType}. + * + *

This hooks into the vanilla datafixing process and may therefore not correctly migrate data for stacks stored in modded containers. * * @param oldComponentId the item component ID from CCA days * @param mcComponentType the new vanilla component type diff --git a/cardinal-components-item/src/main/java/org/ladysnake/cca/mixin/item/common/MixinItemStackComponentizationFix.java b/cardinal-components-item/src/main/java/org/ladysnake/cca/mixin/item/common/MixinItemStackComponentizationFix.java index 75ad1942f..fe8977cc0 100644 --- a/cardinal-components-item/src/main/java/org/ladysnake/cca/mixin/item/common/MixinItemStackComponentizationFix.java +++ b/cardinal-components-item/src/main/java/org/ladysnake/cca/mixin/item/common/MixinItemStackComponentizationFix.java @@ -1,3 +1,25 @@ +/* + * Cardinal-Components-API + * Copyright (C) 2019-2024 Ladysnake + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE + * OR OTHER DEALINGS IN THE SOFTWARE. + */ package org.ladysnake.cca.mixin.item.common; import com.mojang.serialization.Dynamic; diff --git a/changelog.md b/changelog.md index 5c09a1710..974700247 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,8 @@ Version 6.0.0 ------------------------------------------------------ Updated to 1.20.5 +This update introduces multiple breaking changes - a migration guide is available on [the Ladysnake website](https://ladysnake.org/wiki/cardinal-components-api/upgrade-instructions/CCA-6-changes). + **Additions** - Added a `PacketCodec` for component keys @@ -12,6 +14,7 @@ Updated to 1.20.5 - Update documentation and licenses to reflect package change **Removals** +- *Removed item components.* The `cardinal-components-item` module now contains an `ItemComponentMigrationRegistry`, which is used to help you migrate to vanilla components. - Removed `PlayerCopyCallback` - if you were using it, you can switch to `ServerPlayerEvents.COPY_FROM` from Fabric API ------------------------------------------------------ diff --git a/src/testmod/java/org/ladysnake/componenttest/content/CardinalComponentsTest.java b/src/testmod/java/org/ladysnake/componenttest/content/CardinalComponentsTest.java index ac847904d..fa5301dba 100644 --- a/src/testmod/java/org/ladysnake/componenttest/content/CardinalComponentsTest.java +++ b/src/testmod/java/org/ladysnake/componenttest/content/CardinalComponentsTest.java @@ -22,12 +22,9 @@ */ package org.ladysnake.componenttest.content; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; -import net.fabricmc.fabric.api.lookup.v1.item.ItemApiLookup; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; @@ -78,7 +75,6 @@ public class CardinalComponentsTest { // inline self component callback registration public static final VitalityStickItem VITALITY_STICK = Registry.register(Registries.ITEM, VITA_STICK_ID, new VitalityStickItem(new Item.Settings().maxDamage(50))); - public static final ItemApiLookup ITEM_VITA_LOOKUP = ItemApiLookup.get(id("vita"), Vita.class, Void.class); public static final VitalityCondenser VITALITY_CONDENSER = new VitalityCondenser(FabricBlockSettings.copyOf(Blocks.STONE).dropsNothing().luminance(s -> 5).ticksRandomly()); @@ -93,14 +89,14 @@ public static void init() { LOGGER.info("Hello, Components!"); Registry.register(Registries.ITEM_GROUP, ITEM_GROUP_KEY, ITEM_GROUP); - Registry.register(Registries.DATA_COMPONENT_TYPE, id("vita"), ItemVita.COMPONENT_TYPE); - Registry.register(Registries.DATA_COMPONENT_TYPE, id("alt_vita"), ItemVita.ALT_COMPONENT_TYPE); + Registry.register(Registries.DATA_COMPONENT_TYPE, id("vita"), ItemVita.Data.COMPONENT_TYPE); + Registry.register(Registries.DATA_COMPONENT_TYPE, id("alt_vita"), ItemVita.Data.ALT_COMPONENT_TYPE); Registry.register(Registries.BLOCK, "componenttest:vita_condenser", VITALITY_CONDENSER); CommandRegistrationCallback.EVENT.register((dispatcher, reg, dedicated) -> VitaCommand.register(dispatcher)); FabricDefaultAttributeRegistry.register(VITALITY_ZOMBIE, ZombieEntity.createZombieAttributes()); - ITEM_VITA_LOOKUP.registerForItems((stack, ctx) -> new ItemVita(ItemVita.COMPONENT_TYPE, stack), VITALITY_STICK); + ItemVita.LOOKUP.registerForItems((stack, ctx) -> new ItemVita(ItemVita.Data.COMPONENT_TYPE, stack), VITALITY_STICK); ComponentContainer.Factory.Builder factoryBuilder = ComponentContainer.Factory.builder(Integer.class) .component(Vita.KEY, BaseVita::new); diff --git a/src/testmod/java/org/ladysnake/componenttest/content/TestComponents.java b/src/testmod/java/org/ladysnake/componenttest/content/TestComponents.java index 7bdc5f1f4..33bd1bc9c 100644 --- a/src/testmod/java/org/ladysnake/componenttest/content/TestComponents.java +++ b/src/testmod/java/org/ladysnake/componenttest/content/TestComponents.java @@ -74,8 +74,8 @@ public void registerBlockComponentFactories(BlockComponentFactoryRegistry regist @Override public void registerItemComponentMigrations(ItemComponentMigrationRegistry registry) { - registry.registerMigration(ALT_VITA.getId(), ItemVita.ALT_COMPONENT_TYPE); - registry.registerMigration(Vita.KEY.getId(), ItemVita.COMPONENT_TYPE); + registry.registerMigration(ALT_VITA.getId(), ItemVita.Data.ALT_COMPONENT_TYPE); + registry.registerMigration(Vita.KEY.getId(), ItemVita.Data.COMPONENT_TYPE); } @Override diff --git a/src/testmod/java/org/ladysnake/componenttest/content/VitalityStickItem.java b/src/testmod/java/org/ladysnake/componenttest/content/VitalityStickItem.java index 3ecb40177..a08a9e9d3 100644 --- a/src/testmod/java/org/ladysnake/componenttest/content/VitalityStickItem.java +++ b/src/testmod/java/org/ladysnake/componenttest/content/VitalityStickItem.java @@ -56,7 +56,7 @@ public VitalityStickItem(Settings settings) { @Override public TypedActionResult use(World world, PlayerEntity player, Hand hand) { ItemStack stack = player.getStackInHand(hand); - Vita vita = CardinalComponentsTest.ITEM_VITA_LOOKUP.find(stack, null); + Vita vita = ItemVita.maybeGet(stack).orElseThrow(); if (!world.isClient) { if (player.isSneaking()) { Vita src = vita.getVitality() > 0 ? vita : Vita.get(player); @@ -95,7 +95,7 @@ public ActionResult useOnBlock(ItemUsageContext context) { public boolean postHit(ItemStack stack, LivingEntity target, LivingEntity holder) { // The entity may not have the component, but the stack always does. Vita.KEY.maybeGet(target) - .ifPresent(v -> v.transferTo(Vita.get(stack), 1)); + .ifPresent(src -> ItemVita.maybeGet(stack).ifPresent(dest -> src.transferTo(dest, 1))); AbstractTeam team = holder.getScoreboardTeam(); if (team != null) { @@ -113,7 +113,7 @@ public boolean postHit(ItemStack stack, LivingEntity target, LivingEntity holder @Override public void appendTooltip(ItemStack stack, TooltipContext context, List tooltip, TooltipType type) { super.appendTooltip(stack, context, tooltip, type); - tooltip.add(Text.translatable("componenttest:tooltip.vitality", stack.getOrDefault(ItemVita.COMPONENT_TYPE, ItemVita.Data.EMPTY).vitality())); + tooltip.add(Text.translatable("componenttest:tooltip.vitality", ItemVita.getOrEmpty(stack).getVitality())); ClientPlayerEntity holder = MinecraftClient.getInstance().player; if (holder != null) { tooltip.add(Text.translatable("componenttest:tooltip.self_vitality", Vita.KEY.get(holder).getVitality())); diff --git a/src/testmod/java/org/ladysnake/componenttest/content/vita/ItemVita.java b/src/testmod/java/org/ladysnake/componenttest/content/vita/ItemVita.java index bbe6562cf..732395186 100644 --- a/src/testmod/java/org/ladysnake/componenttest/content/vita/ItemVita.java +++ b/src/testmod/java/org/ladysnake/componenttest/content/vita/ItemVita.java @@ -24,24 +24,29 @@ import com.mojang.serialization.Codec; import io.netty.buffer.ByteBuf; +import net.fabricmc.fabric.api.lookup.v1.item.ItemApiLookup; import net.minecraft.component.DataComponentType; import net.minecraft.item.ItemStack; import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.PacketCodecs; -import org.jetbrains.annotations.Nullable; import org.ladysnake.cca.api.v3.component.TransientComponent; +import org.ladysnake.cca.test.base.EmptyVita; import org.ladysnake.cca.test.base.Vita; +import org.ladysnake.componenttest.content.CardinalComponentsTest; + +import java.util.Optional; public class ItemVita implements Vita, TransientComponent { - public static final DataComponentType COMPONENT_TYPE = DataComponentType.builder() - .codec(Data.CODEC) - .packetCodec(Data.PACKET_CODEC) - .build(); + public static final ItemApiLookup LOOKUP = ItemApiLookup.get(CardinalComponentsTest.id("vita"), Vita.class, Void.class); + + public static Vita getOrEmpty(ItemStack stack) { + Vita vita = LOOKUP.find(stack, null); + return vita == null ? EmptyVita.INSTANCE : vita; + } - public static final DataComponentType ALT_COMPONENT_TYPE = DataComponentType.builder() - .codec(Data.CODEC) - .packetCodec(Data.PACKET_CODEC) - .build(); + public static Optional maybeGet(ItemStack stack) { + return Optional.ofNullable(LOOKUP.find(stack, null)); + } private final DataComponentType componentType; private final ItemStack stack; @@ -65,5 +70,13 @@ public record Data(int vitality) { public static final Data EMPTY = new Data(0); public static final Codec CODEC = Codec.INT.xmap(Data::new, Data::vitality); public static final PacketCodec PACKET_CODEC = PacketCodecs.INTEGER.xmap(Data::new, Data::vitality); + public static final DataComponentType COMPONENT_TYPE = DataComponentType.builder() + .codec(CODEC) + .packetCodec(PACKET_CODEC) + .build(); + public static final DataComponentType ALT_COMPONENT_TYPE = DataComponentType.builder() + .codec(CODEC) + .packetCodec(PACKET_CODEC) + .build(); } }