diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/AreaEffectCloudData.java b/src/main/java/org/spongepowered/common/data/provider/entity/AreaEffectCloudData.java index 95ec7d9b635..0113cce620d 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/AreaEffectCloudData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/AreaEffectCloudData.java @@ -25,6 +25,7 @@ package org.spongepowered.common.data.provider.entity; import com.google.common.collect.Streams; +import net.minecraft.core.component.DataComponents; import net.minecraft.world.entity.AreaEffectCloud; import net.minecraft.world.item.alchemy.PotionContents; import org.spongepowered.api.data.Keys; @@ -93,12 +94,6 @@ public static void register(final DataProviderRegistrator registrator) { h.accessor$durationOnUse(SpongeTicks.toSaturatedIntOrInfinite(v)); return true; }) - .create(Keys.POTION_EFFECTS) - .get(h -> PotionEffectUtil.copyAsPotionEffects(Streams.stream(h.accessor$potionContents().getAllEffects()).toList())) - .set((h, v) -> { - final PotionContents contents = h.accessor$potionContents(); - ((AreaEffectCloud) h).setPotionContents(new PotionContents(contents.potion(), contents.customColor(), PotionEffectUtil.copyAsEffectInstances(v), contents.customName())); - }) .create(Keys.REAPPLICATION_DELAY) .get(h -> new SpongeTicks(h.accessor$reapplicationDelay())) .setAnd((h, v) -> { @@ -108,6 +103,14 @@ public static void register(final DataProviderRegistrator registrator) { h.accessor$reapplicationDelay(SpongeTicks.toSaturatedIntOrInfinite(v)); return true; }); + // @formatter:on + final var areaEffectCloud = registrator.asMutable(AreaEffectCloud.class); + final var components = EntityDataProviders.of( + EntityDataProviders.transformedWith(Keys.POTION_EFFECTS, DataComponents.POTION_CONTENTS, + (p) -> PotionEffectUtil.copyAsPotionEffects(Streams.stream(p.getAllEffects()).toList()), + (a, original) -> new PotionContents(original.potion(), original.customColor(), PotionEffectUtil.copyAsEffectInstances(a), original.customName()) + ) + ); + components.forEach(p -> p.applyToRegistrator(areaEffectCloud)); } - // @formatter:on } diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/CatData.java b/src/main/java/org/spongepowered/common/data/provider/entity/CatData.java index b8b0442bc8d..48465d6ed99 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/CatData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/CatData.java @@ -25,6 +25,8 @@ package org.spongepowered.common.data.provider.entity; import net.minecraft.core.Holder; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.Registries; import net.minecraft.world.entity.animal.Cat; import net.minecraft.world.entity.animal.CatVariant; import org.spongepowered.api.data.Keys; @@ -43,12 +45,6 @@ private CatData() { public static void register(final DataProviderRegistrator registrator) { registrator .asMutable(Cat.class) - .create(Keys.CAT_TYPE) - .get(h -> (CatType) (Object) h.getVariant().value()) - .set((h, v) -> ((CatAccessor) h).invoker$setVariant(Holder.direct((CatVariant) (Object) v))) - .create(Keys.DYE_COLOR) - .get(h -> (DyeColor) (Object) h.getCollarColor()) - .set((h, v) -> ((CatAccessor)h).invoker$setCollarColor((net.minecraft.world.item.DyeColor) (Object) v)) .create(Keys.IS_BEGGING_FOR_FOOD) .get(h -> { throw new MissingImplementationException("CatData", "IS_BEGGING_FOR_FOOD::getter"); @@ -75,6 +71,12 @@ public static void register(final DataProviderRegistrator registrator) { .create(Keys.IS_RELAXED) .get(CatAccessor::invoker$isRelaxStateOne) .set(CatAccessor::invoker$setRelaxStateOne); + // @formatter:on + final var cat = registrator.asMutable(Cat.class); + final var components = EntityDataProviders.of( + EntityDataProviders.holderOf(Keys.CAT_TYPE, DataComponents.CAT_VARIANT, Registries.CAT_VARIANT), + EntityDataProviders.enumOf(Keys.DYE_COLOR, DataComponents.CAT_COLLAR) + ); + components.forEach(p -> p.applyToRegistrator(cat)); } - // @formatter:on } diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/ChickenData.java b/src/main/java/org/spongepowered/common/data/provider/entity/ChickenData.java index 04e8dfd8bae..7284546024b 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/ChickenData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/ChickenData.java @@ -48,6 +48,11 @@ public static void register(final DataProviderRegistrator registrator) { h.eggTime = ticks; return true; }); + // @formatter:on + final var chicken = registrator.asMutable(Chicken.class); + final var components = EntityDataProviders.of( + // TODO - EitherHolder is a different kind of thing +// EntityDataProviders.eitherHolderOf() + ); } - // @formatter:on } diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java b/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java index 69937fac579..12360b391a8 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java @@ -25,6 +25,7 @@ package org.spongepowered.common.data.provider.entity; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.minecraft.core.component.DataComponents; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.PortalProcessor; @@ -81,13 +82,6 @@ public static void register(final DataProviderRegistrator registrator) { } return (org.spongepowered.api.entity.Entity) rootVehicle; }) - .create(Keys.CUSTOM_NAME) - .get(h -> h.hasCustomName() ? SpongeAdventure.asAdventure(h.getCustomName()) : null) - .set((h, v) -> h.setCustomName(SpongeAdventure.asVanilla(v))) - .delete(h -> { - h.setCustomName(null); - h.setCustomNameVisible(false); - }) .create(Keys.DISPLAY_NAME) .get(h -> SpongeAdventure.asAdventure(h.getDisplayName())) .create(Keys.EYE_HEIGHT) @@ -266,6 +260,17 @@ public static void register(final DataProviderRegistrator registrator) { dv -> dv.getString(Constants.Entity.CUSTOM_NAME).map(GsonComponentSerializer.gson()::deserialize)); // @formatter:on + final var entity = registrator.asMutable(Entity.class); + final var components = EntityDataProviders.of( + EntityDataProviders.optionalTransformed(Keys.CUSTOM_NAME, DataComponents.CUSTOM_NAME, SpongeAdventure::asAdventure, SpongeAdventure::asVanilla), + EntityDataProviders.deleter(Keys.CUSTOM_NAME, h -> { + h.setCustomName(null); + h.setCustomNameVisible(false); + }) + ); + for (var provider : components) { + provider.applyToRegistrator(entity); + } } } diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java b/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java index 456a124c748..536f27d8354 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java @@ -29,17 +29,25 @@ import net.minecraft.core.component.DataComponentType; import net.minecraft.resources.ResourceKey; import net.minecraft.world.entity.Entity; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.data.DataTransactionResult; import org.spongepowered.api.data.Key; +import org.spongepowered.api.data.Keys; import org.spongepowered.api.data.value.Value; import org.spongepowered.api.registry.DefaultedRegistryValue; +import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.data.provider.DataProviderRegistrator; import org.spongepowered.common.data.provider.DataProviderRegistratorBuilder; import java.util.List; +import java.util.Optional; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; public final class EntityDataProviders extends DataProviderRegistratorBuilder { - public sealed interface KeyComponentProvider { + public sealed interface KeyComponentProvider { void applyToRegistrator(DataProviderRegistrator.MutableRegistrator registrator); } @@ -47,6 +55,40 @@ public sealed interface KeyComponentProvider KeyComponentProvider transformed( + Key> apiKey, + DataComponentType componentType, + Function getter, + Function setter + ) { + return new FunctionalProvider<>(apiKey, componentType, getter, setter); + } + + public static KeyComponentProvider transformedWith( + Key> apiKey, + DataComponentType componentType, + Function getter, + BiFunction setter + ) { + return new BiFunctionProvider<>(apiKey, componentType, getter, setter); + } + + public static KeyComponentProvider optionalTransformed( + Key> apiKey, + DataComponentType componentType, + Function getter, + Function setter + ) { + return new OptionalFunctionProvider<>(apiKey, componentType, getter, setter); + } + + public static KeyComponentProvider deleter( + Key> apiKey, + Consumer deleter + ) { + return new DeletionProvider<>(apiKey, deleter); + } + public static KeyComponentProvider holderOf( Key> apiKey, DataComponentType> componentType, @@ -62,9 +104,62 @@ public static > KeyCompone return new EnumProvider<>(apiKey, componentType); } + record DeletionProvider( + Key> apiKey, + Consumer deleter + ) implements KeyComponentProvider { + public void applyToRegistrator(DataProviderRegistrator.MutableRegistrator registrator) { + registrator.create(this.apiKey) + .delete(deleter::accept); + } + } + + record FunctionalProvider( + Key> apiKey, + DataComponentType componentType, + Function getter, + Function setter + ) implements KeyComponentProvider { + public void applyToRegistrator(DataProviderRegistrator.MutableRegistrator registrator) { + registrator.create(this.apiKey) + .get(h -> this.getter.apply(h.get(this.componentType))) + .set((h, v) -> h.setComponent(this.componentType, this.setter.apply(v))); + } + } + + record BiFunctionProvider( + Key> apiKey, + DataComponentType componentType, + Function getter, + BiFunction setter + ) implements KeyComponentProvider { + public void applyToRegistrator(DataProviderRegistrator.MutableRegistrator registrator) { + registrator.create(this.apiKey) + .get(h -> this.getter.apply(h.get(this.componentType))) + .set((h, v) -> { + final var existing = h.get(this.componentType); + final var newValue = this.setter.apply(v, existing); + h.setComponent(this.componentType, newValue); + }); + } + } + + record OptionalFunctionProvider( + Key> apiKey, + DataComponentType componentType, + Function getter, + Function setter + ) implements KeyComponentProvider { + public void applyToRegistrator(DataProviderRegistrator.MutableRegistrator registrator) { + registrator.create(this.apiKey) + .get(h -> Optional.ofNullable(h.get(this.componentType)).map(this.getter).orElse(null)) + .set((h, v) -> h.setComponent(this.componentType, v == null ? null : this.setter.apply(v))); + } + } + @SuppressWarnings("unchecked") record HolderProvider( - Key> apiKey, + Key> apiKey, DataComponentType> componentType, ResourceKey> resourceKey ) implements KeyComponentProvider { @@ -85,7 +180,7 @@ public void applyToRegistrator(DataProviderRegistrator.Mutabl @SuppressWarnings("unchecked") record EnumProvider>( - Key> apiKey, + Key> apiKey, DataComponentType componentType ) implements KeyComponentProvider { public void applyToRegistrator(DataProviderRegistrator.MutableRegistrator registrator) {