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 extends Value> apiKey,
+ DataComponentType componentType,
+ Function getter,
+ Function setter
+ ) {
+ return new FunctionalProvider<>(apiKey, componentType, getter, setter);
+ }
+
+ public static KeyComponentProvider transformedWith(
+ Key extends Value> 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 extends Value> 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 extends Value> 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 extends Value> 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 extends Value> apiKey,
DataComponentType> componentType,
ResourceKey> resourceKey
) implements KeyComponentProvider {
@@ -85,7 +180,7 @@ public void applyToRegistrator(DataProviderRegistrator.Mutabl
@SuppressWarnings("unchecked")
record EnumProvider>(
- Key> apiKey,
+ Key extends Value> apiKey,
DataComponentType componentType
) implements KeyComponentProvider {
public void applyToRegistrator(DataProviderRegistrator.MutableRegistrator registrator) {