Compare commits

..
Author SHA1 Message Date
roro1506HDandLulu13022002 f54bb07269 Rework DataComponentAdapters into generic converters
Extracted from the environmental attributes PR (#13351) so the
converter/adapter rework can be reviewed and merged on its own.

Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
2026-11-11 08:58:36 -08:00
183 changed files with 1306 additions and 3214 deletions

No files matched your search

@@ -1,11 +1,9 @@
package io.papermc.paper.block.pot;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.data.DecoratedPotPatternRegistryEntry;
import org.bukkit.Keyed;
/**
* A pot pattern on a decorated pot.
*/
public interface PotPatternType extends RegistryElement.Buildable<PotPatternType, DecoratedPotPatternRegistryEntry, DecoratedPotPatternRegistryEntry.Builder>, Keyed {
public interface PotPatternType extends Keyed {
}
@@ -1,13 +1,12 @@
package io.papermc.paper.datacomponent;
import io.papermc.paper.registry.RegistryElement;
import org.bukkit.Keyed;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@NullMarked
@ApiStatus.NonExtendable
public interface DataComponentType extends RegistryElement<DataComponentType>, Keyed {
public interface DataComponentType extends Keyed {
/**
* Checks if this data component type is persistent, or
@@ -60,7 +60,6 @@ import org.bukkit.DyeColor;
import org.bukkit.FireworkEffect;
import org.bukkit.MusicInstrument;
import org.bukkit.Registry;
import org.bukkit.Sound;
import org.bukkit.block.banner.PatternType;
import org.bukkit.damage.DamageType;
import org.bukkit.entity.Axolotl;
@@ -366,7 +365,7 @@ public final class DataComponentTypes {
* Holds the unresolved loot table and seed of a container-like block.
*/
public static final DataComponentType.Valued<SeededContainerLoot> CONTAINER_LOOT = valued("container_loot");
public static final DataComponentType.Valued<Sound> BREAK_SOUND = valued("break_sound");
public static final DataComponentType.Valued<Key> BREAK_SOUND = valued("break_sound");
public static final DataComponentType.Valued<MobVisibility> MOB_VISIBILITY = valued("mob_visibility");
public static final DataComponentType.Valued<Villager.Type> VILLAGER_VARIANT = valued("villager/variant");
public static final DataComponentType.Valued<Wolf.Variant> WOLF_VARIANT = valued("wolf/variant");
@@ -6,7 +6,6 @@ import io.papermc.paper.datacomponent.item.blocksattacks.ItemDamageFunction;
import io.papermc.paper.registry.set.RegistryKeySet;
import java.util.List;
import net.kyori.adventure.key.Key;
import org.bukkit.Sound;
import org.bukkit.damage.DamageType;
import org.checkerframework.checker.index.qual.NonNegative;
import org.jetbrains.annotations.ApiStatus;
@@ -69,20 +68,20 @@ public interface BlocksAttacks {
@Nullable RegistryKeySet<DamageType> bypassedBy();
/**
* Gets the sound to play when an attack is successfully blocked.
* Gets the key sound to play when an attack is successfully blocked.
*
* @return the sound
* @return a key of the sound
*/
@Contract(pure = true)
@Nullable Sound blockSound();
@Nullable Key blockSound();
/**
* Gets the sound to play when the item goes on its disabled cooldown due to an attack.
* Gets the key sound to play when the item goes on its disabled cooldown due to an attack.
*
* @return the sound
* @return a key of the sound
*/
@Contract(pure = true)
@Nullable Sound disableSound();
@Nullable Key disableSound();
/**
* Builder for {@link BlocksAttacks}.
@@ -108,26 +107,10 @@ public interface BlocksAttacks {
@Contract(value = "_ -> this", mutates = "this")
Builder bypassedBy(@Nullable RegistryKeySet<DamageType> bypassedBy);
/**
* Sets the sound to play when an attack is successfully blocked.
*
* @param sound the sound, or null to play no sound
* @return the builder for chaining
* @see Sound#create(net.kyori.adventure.key.Key, Float)
* @see Sound#create(java.util.function.Consumer)
*/
@Contract(value = "_ -> this", mutates = "this")
Builder blockSound(@Nullable Sound sound);
Builder blockSound(@Nullable Key sound);
/**
* Sets the sound to play when the item goes on its disabled cooldown due to an attack.
*
* @param sound the sound, or null to play no sound
* @return the builder for chaining
* @see Sound#create(net.kyori.adventure.key.Key, Float)
* @see Sound#create(java.util.function.Consumer)
*/
@Contract(value = "_ -> this", mutates = "this")
Builder disableSound(@Nullable Sound sound);
Builder disableSound(@Nullable Key sound);
}
}
@@ -6,7 +6,6 @@ import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect;
import io.papermc.paper.datacomponent.item.consumable.ItemUseAnimation;
import java.util.List;
import net.kyori.adventure.key.Key;
import org.bukkit.Sound;
import org.checkerframework.checker.index.qual.NonNegative;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
@@ -31,7 +30,7 @@ public interface Consumable extends BuildableDataComponent<Consumable, Consumabl
ItemUseAnimation animation();
@Contract(pure = true)
Sound sound();
Key sound();
@Contract(pure = true)
boolean hasConsumeParticles();
@@ -66,11 +65,11 @@ public interface Consumable extends BuildableDataComponent<Consumable, Consumabl
/**
* Sets the sound played when consuming the item.
*
* @param sound the sound to be used
* @param sound the {@link Key} representing the sound to be used
* @return the builder for chaining
*/
@Contract(value = "_ -> this", mutates = "this")
Builder sound(Sound sound);
Builder sound(Key sound);
/**
* Sets whether consuming the item results in particle effects.
@@ -4,7 +4,6 @@ import io.papermc.paper.datacomponent.BuildableDataComponent;
import io.papermc.paper.datacomponent.DataComponentBuilder;
import io.papermc.paper.registry.set.RegistryKeySet;
import net.kyori.adventure.key.Key;
import org.bukkit.Sound;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.EquipmentSlot;
import org.jetbrains.annotations.ApiStatus;
@@ -38,12 +37,12 @@ public interface Equippable extends BuildableDataComponent<Equippable, Equippabl
EquipmentSlot slot();
/**
* Gets the equip sound.
* Gets the equip sound key.
*
* @return the equip sound
* @return the equip sound key
*/
@Contract(pure = true)
Sound equipSound();
Key equipSound();
/**
* Gets the asset id if present.
@@ -116,7 +115,7 @@ public interface Equippable extends BuildableDataComponent<Equippable, Equippabl
* @return shear sound
*/
@Contract(pure = true)
Sound shearSound();
Key shearSound();
/**
* Builder for {@link Equippable}.
@@ -125,13 +124,13 @@ public interface Equippable extends BuildableDataComponent<Equippable, Equippabl
interface Builder extends DataComponentBuilder<Equippable> {
/**
* Sets the equip sound for this item.
* Sets the equip sound key for this item.
*
* @param sound the equip sound
* @param sound the equip sound key
* @return the builder for chaining
*/
@Contract(value = "_ -> this", mutates = "this")
Builder equipSound(Sound sound);
Builder equipSound(Key sound);
/**
* Sets the asset id for this item.
@@ -208,10 +207,10 @@ public interface Equippable extends BuildableDataComponent<Equippable, Equippabl
/**
* Sets the sound that is played when shearing this equipment off an entity.
*
* @param shearSound the shear sound
* @param shearSound the shear sound key
* @return the builder for chaining
*/
@Contract(value = "_ -> this", mutates = "this")
Builder shearSound(Sound shearSound);
Builder shearSound(Key shearSound);
}
}
@@ -2,7 +2,6 @@ package io.papermc.paper.datacomponent.item;
import io.papermc.paper.datacomponent.DataComponentBuilder;
import net.kyori.adventure.key.Key;
import org.bukkit.Sound;
import org.checkerframework.checker.index.qual.NonNegative;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
@@ -49,10 +48,10 @@ public interface KineticWeapon {
float damageMultiplier();
@Contract(pure = true)
@Nullable Sound sound();
@Nullable Key sound();
@Contract(pure = true)
@Nullable Sound hitSound();
@Nullable Key hitSound();
interface Condition {
@@ -93,26 +92,10 @@ public interface KineticWeapon {
@Contract(value = "_ -> this", mutates = "this")
Builder damageMultiplier(float damageMultiplier);
/**
* Sets the sound to play while this weapon is active.
*
* @param sound the sound, or null to play no sound
* @return the builder for chaining
* @see Sound#create(net.kyori.adventure.key.Key, Float)
* @see Sound#create(java.util.function.Consumer)
*/
@Contract(value = "_ -> this", mutates = "this")
Builder sound(@Nullable Sound sound);
Builder sound(@Nullable Key sound);
/**
* Sets the sound to play when this weapon hits an entity.
*
* @param sound the sound, or null to play no sound
* @return the builder for chaining
* @see Sound#create(net.kyori.adventure.key.Key, Float)
* @see Sound#create(java.util.function.Consumer)
*/
@Contract(value = "_ -> this", mutates = "this")
Builder hitSound(@Nullable Sound sound);
Builder hitSound(@Nullable Key sound);
}
}
@@ -2,7 +2,6 @@ package io.papermc.paper.datacomponent.item;
import io.papermc.paper.datacomponent.DataComponentBuilder;
import net.kyori.adventure.key.Key;
import org.bukkit.Sound;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.Nullable;
@@ -23,9 +22,9 @@ public interface PiercingWeapon {
boolean dismounts();
@Nullable Sound sound();
@Nullable Key sound();
@Nullable Sound hitSound();
@Nullable Key hitSound();
/**
* Builder for {@link PiercingWeapon}.
@@ -39,26 +38,10 @@ public interface PiercingWeapon {
@Contract(value = "_ -> this", mutates = "this")
Builder dismounts(boolean dismounts);
/**
* Sets the sound to play while this weapon is active.
*
* @param sound the sound, or null to play no sound
* @return the builder for chaining
* @see Sound#create(net.kyori.adventure.key.Key, Float)
* @see Sound#create(java.util.function.Consumer)
*/
@Contract(value = "_ -> this", mutates = "this")
Builder sound(@Nullable Sound sound);
Builder sound(@Nullable Key sound);
/**
* Sets the sound to play when this weapon hits an entity.
*
* @param sound the sound, or null to play no sound
* @return the builder for chaining
* @see Sound#create(net.kyori.adventure.key.Key, Float)
* @see Sound#create(java.util.function.Consumer)
*/
@Contract(value = "_ -> this", mutates = "this")
Builder hitSound(@Nullable Sound sound);
Builder hitSound(@Nullable Key sound);
}
}
@@ -2,7 +2,6 @@ package io.papermc.paper.datacomponent.item;
import io.papermc.paper.datacomponent.DataComponentBuilder;
import io.papermc.paper.datacomponent.DataComponentType;
import io.papermc.paper.registry.set.RegistryKeySet;
import java.util.Set;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
@@ -38,8 +37,5 @@ public interface TooltipDisplay {
@Contract(value = "_ -> this", mutates = "this")
Builder hiddenComponents(Set<DataComponentType> components);
@Contract(value = "_ -> this", mutates = "this")
Builder hiddenComponents(RegistryKeySet<DataComponentType> components);
}
}
@@ -5,7 +5,6 @@ import java.util.List;
import java.util.Optional;
import java.util.ServiceLoader;
import net.kyori.adventure.key.Key;
import org.bukkit.Sound;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
@@ -23,7 +22,7 @@ interface ConsumableTypesBridge {
ConsumeEffect.ClearAllStatusEffects clearAllStatusEffects();
ConsumeEffect.PlaySound playSoundEffect(Sound sound);
ConsumeEffect.PlaySound playSoundEffect(Key sound);
ConsumeEffect.TeleportRandomly teleportRandomlyEffect(float diameter, boolean directionalParticles);
}
@@ -3,7 +3,6 @@ package io.papermc.paper.datacomponent.item.consumable;
import io.papermc.paper.registry.set.RegistryKeySet;
import java.util.List;
import net.kyori.adventure.key.Key;
import org.bukkit.Sound;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.ApiStatus;
@@ -53,12 +52,12 @@ public interface ConsumeEffect {
/**
* Creates a consume effect that plays a sound on consumption.
*
* @param sound the sound effect to play
* @param key the key sound effect to play
* @return the effect instance
*/
@Contract(value = "_ -> new", pure = true)
static PlaySound playSoundConsumeEffect(final Sound sound) {
return ConsumableTypesBridge.bridge().playSoundEffect(sound);
static PlaySound playSoundConsumeEffect(final Key key) {
return ConsumableTypesBridge.bridge().playSoundEffect(key);
}
/**
@@ -129,7 +128,7 @@ public interface ConsumeEffect {
*
* @return sound effect
*/
Sound sound();
Key sound();
}
/**
@@ -2,9 +2,8 @@ package io.papermc.paper.dialog;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryBuilderFactory;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.RegistryBuilderProvider;
import io.papermc.paper.registry.data.InlinedRegistryBuilderProvider;
import io.papermc.paper.registry.data.dialog.DialogRegistryEntry;
import java.util.function.Consumer;
import net.kyori.adventure.dialog.DialogLike;
@@ -20,7 +19,7 @@ import org.jetbrains.annotations.ApiStatus;
* Can also be created during bootstrap via {@link io.papermc.paper.registry.event.RegistryEvents#DIALOG}.
*/
@ApiStatus.NonExtendable
public interface Dialog extends RegistryElement.Inlineable<Dialog, DialogRegistryEntry, DialogRegistryEntry.Builder>, Keyed, DialogLike {
public interface Dialog extends Keyed, DialogLike {
/**
* Creates a new dialog using the provided builder.
@@ -29,7 +28,7 @@ public interface Dialog extends RegistryElement.Inlineable<Dialog, DialogRegistr
* @return a new dialog instance
*/
static Dialog create(final Consumer<RegistryBuilderFactory<Dialog, ? extends DialogRegistryEntry.Builder>> value) {
return RegistryBuilderProvider.instance().create(RegistryKey.DIALOG, value);
return InlinedRegistryBuilderProvider.instance().createDialog(value);
}
// Start generate - Dialog
@@ -1,7 +1,6 @@
package io.papermc.paper.entity.poi;
import io.papermc.paper.InternalAPIBridge;
import io.papermc.paper.registry.RegistryElement;
import org.bukkit.Keyed;
import org.bukkit.block.data.BlockData;
@@ -14,7 +13,7 @@ import org.bukkit.block.data.BlockData;
*
* @see PoiTypes
*/
public interface PoiType extends RegistryElement<PoiType>, Keyed {
public interface PoiType extends Keyed {
/**
* Determines whether the provided BlockState is relevant to this
@@ -1,70 +0,0 @@
package io.papermc.paper.registry;
import io.papermc.paper.registry.tag.TagKey;
import net.kyori.adventure.key.Key;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* An element tied to a registry.
* <p>
* For unregistered element, the equality methods exposed here will always return {@code false}
* as there's no way to identify them with a key.
*
* @see RegistryKey
* @see org.bukkit.Registry
* @see org.bukkit.Registry#getKey(org.bukkit.Keyed)
*/
@NullMarked
@ApiStatus.Experimental
public interface RegistryElement<T> {
/**
* Checks whether this element is identified by the given key.
*
* @param type the key
* @return whether this element is identified by the given key.
*/
boolean is(TypedKey<T> type);
/**
* Checks whether this element is identified by the given key.
*
* @param type the key
* @return whether this element is identified by the given key
*/
boolean is(Key type);
/**
* Checks whether this element is contained in the
* tag identified by the given tag key.
*
* @param type the tag key
* @return whether this element is contained in the tag
*/
boolean is(TagKey<T> type);
/**
* Marker interface for registered types that link an API type to its
* registry entry and builder types.
*
* @param <T> the API type
* @param <E> the registry entry type
* @param <B> the builder type
*/
@SuppressWarnings("unused")
@ApiStatus.Experimental
interface Buildable<T, E, B extends RegistryBuilder<T>> extends RegistryElement<T> {
}
/**
* Marker interface for registered types that are valid to be constructed inline.
*
* @param <T> the API type
* @param <E> the registry entry type
* @param <B> the builder type
*/
@ApiStatus.Experimental
interface Inlineable<T, E, B extends RegistryBuilder<T>> extends RegistryElement.Buildable<T, E, B> {
}
}
@@ -2,6 +2,8 @@ package io.papermc.paper.registry;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import net.kyori.adventure.key.Keyed;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -10,13 +12,14 @@ import org.jspecify.annotations.NullMarked;
* @param <T> the value type for the registry
*/
@NullMarked
public sealed interface TypedKey<T> permits TypedKeyImpl {
public sealed interface TypedKey<T> extends Key permits TypedKeyImpl {
/**
* Gets the key for the value in the registry.
*
* @return the value's key
*/
@Override
Key key();
/**
@@ -1,8 +1,26 @@
package io.papermc.paper.registry;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import org.jspecify.annotations.NullMarked;
@NullMarked
record TypedKeyImpl<T>(Key key, RegistryKey<T> registryKey) implements TypedKey<T> {
// Wrap key methods to make this easier to use
@KeyPattern.Namespace
@Override
public String namespace() {
return this.key.namespace();
}
@KeyPattern.Value
@Override
public String value() {
return this.key.value();
}
@Override
public String asString() {
return this.key.asString();
}
}
@@ -1,196 +0,0 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.holder.RegistryHolder;
import org.bukkit.Sound;
import org.bukkit.entity.Cat;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import static io.papermc.paper.registry.data.RegistryBuilderProvider.transientHolder;
/**
* A data-centric version-specific registry entry for the {@link Cat.SoundVariant} type.
*/
@ApiStatus.NonExtendable
public interface CatSoundVariantRegistryEntry {
/**
* {@return the sounds played by adult cats of this variant}
*/
SoundSet adultSounds();
/**
* {@return the sounds played by baby cats of this variant}
*/
SoundSet babySounds();
/**
* The set of sounds played by a cat of a specific age.
*/
@ApiStatus.NonExtendable
interface SoundSet {
/**
* Creates a new sound set based on the passed values.
*
* @param ambientSound the ambient sound, as returned by {@link #ambientSound()}
* @param strayAmbientSound the stray ambient sound, as returned by {@link #strayAmbientSound()}
* @param hissSound the hiss sound, as returned by {@link #hissSound()}
* @param hurtSound the hurt sound, as returned by {@link #hurtSound()}
* @param deathSound the death sound, as returned by {@link #deathSound()}
* @param eatSound the eat sound, as returned by {@link #eatSound()}
* @param begForFoodSound the beg for food sound, as returned by {@link #begForFoodSound()}
* @param purrSound the purr sound, as returned by {@link #purrSound()}
* @param purreowSound the purreow sound, as returned by {@link #purreowSound()}
* @return the created instance
*/
@Contract(value = "_, _, _, _, _, _, _, _, _ -> new", pure = true)
static SoundSet of(
final TypedKey<Sound> ambientSound,
final TypedKey<Sound> strayAmbientSound,
final TypedKey<Sound> hissSound,
final TypedKey<Sound> hurtSound,
final TypedKey<Sound> deathSound,
final TypedKey<Sound> eatSound,
final TypedKey<Sound> begForFoodSound,
final TypedKey<Sound> purrSound,
final TypedKey<Sound> purreowSound
) {
return of(
transientHolder(ambientSound),
transientHolder(strayAmbientSound),
transientHolder(hissSound),
transientHolder(hurtSound),
transientHolder(deathSound),
transientHolder(eatSound),
transientHolder(begForFoodSound),
transientHolder(purrSound),
transientHolder(purreowSound)
);
}
/**
* Creates a new sound set based on the passed values.
* <p>
* {@link RegistryHolder} instances can be created with {@link io.papermc.paper.registry.event.RegistryFactory}.
*
* @param ambientSound the ambient sound, as returned by {@link #ambientSound()}
* @param strayAmbientSound the stray ambient sound, as returned by {@link #strayAmbientSound()}
* @param hissSound the hiss sound, as returned by {@link #hissSound()}
* @param hurtSound the hurt sound, as returned by {@link #hurtSound()}
* @param deathSound the death sound, as returned by {@link #deathSound()}
* @param eatSound the eat sound, as returned by {@link #eatSound()}
* @param begForFoodSound the beg for food sound, as returned by {@link #begForFoodSound()}
* @param purrSound the purr sound, as returned by {@link #purrSound()}
* @param purreowSound the purreow sound, as returned by {@link #purreowSound()}
* @return the created instance
*/
@Contract(value = "_, _, _, _, _, _, _, _, _ -> new", pure = true)
static SoundSet of(
final RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> strayAmbientSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> hissSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> deathSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> eatSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> begForFoodSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> purrSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> purreowSound
) {
record Impl(
RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound,
RegistryHolder<Sound, SoundEventRegistryEntry> strayAmbientSound,
RegistryHolder<Sound, SoundEventRegistryEntry> hissSound,
RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound,
RegistryHolder<Sound, SoundEventRegistryEntry> deathSound,
RegistryHolder<Sound, SoundEventRegistryEntry> eatSound,
RegistryHolder<Sound, SoundEventRegistryEntry> begForFoodSound,
RegistryHolder<Sound, SoundEventRegistryEntry> purrSound,
RegistryHolder<Sound, SoundEventRegistryEntry> purreowSound
) implements SoundSet {
}
return new Impl(ambientSound, strayAmbientSound, hissSound, hurtSound, deathSound, eatSound, begForFoodSound, purrSound, purreowSound);
}
/**
* {@return the sound played randomly while the cat is tamed and idle, unless the purreow sound is played instead}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound();
/**
* {@return the sound played randomly while the cat is untamed and idle}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> strayAmbientSound();
/**
* {@return the sound played when the cat hisses}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> hissSound();
/**
* {@return the sound played when the cat is hurt}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound();
/**
* {@return the sound played when the cat dies}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> deathSound();
/**
* {@return the sound played when the cat eats}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> eatSound();
/**
* {@return the sound played while the cat is untamed and tempted by food}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> begForFoodSound();
/**
* {@return the sound played while the cat is lying down, or instead of the ambient sound while it's tamed and in love}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> purrSound();
/**
* {@return the sound sometimes played instead of the ambient sound while the cat is tamed and idle}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> purreowSound();
}
/**
* A mutable builder for the {@link CatSoundVariantRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #adultSounds(SoundSet)}</li>
* <li>{@link #babySounds(SoundSet)}</li>
* </ul>
*/
@ApiStatus.NonExtendable
interface Builder extends CatSoundVariantRegistryEntry, RegistryBuilder<Cat.SoundVariant> {
/**
* Sets the sounds played by adult cats of this variant.
*
* @param adultSounds the sound set
* @return this builder instance
* @see CatSoundVariantRegistryEntry#adultSounds()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder adultSounds(SoundSet adultSounds);
/**
* Sets the sounds played by baby cats of this variant.
*
* @param babySounds the sound set
* @return this builder instance
* @see CatSoundVariantRegistryEntry#babySounds()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder babySounds(SoundSet babySounds);
}
}
@@ -1,141 +0,0 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.holder.RegistryHolder;
import org.bukkit.Sound;
import org.bukkit.entity.Chicken;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import static io.papermc.paper.registry.data.RegistryBuilderProvider.transientHolder;
/**
* A data-centric version-specific registry entry for the {@link Chicken.SoundVariant} type.
*/
@ApiStatus.NonExtendable
public interface ChickenSoundVariantRegistryEntry {
/**
* {@return the sounds played by adult chickens of this variant}
*/
SoundSet adultSounds();
/**
* {@return the sounds played by baby chickens of this variant}
*/
SoundSet babySounds();
/**
* The set of sounds played by a chicken of a specific age.
*/
@ApiStatus.NonExtendable
interface SoundSet {
/**
* Creates a new sound set based on the passed values.
*
* @param ambientSound the ambient sound, as returned by {@link #ambientSound()}
* @param hurtSound the hurt sound, as returned by {@link #hurtSound()}
* @param deathSound the death sound, as returned by {@link #deathSound()}
* @param stepSound the step sound, as returned by {@link #stepSound()}
* @return the created instance
*/
@Contract(value = "_, _, _, _ -> new", pure = true)
static SoundSet of(
final TypedKey<Sound> ambientSound,
final TypedKey<Sound> hurtSound,
final TypedKey<Sound> deathSound,
final TypedKey<Sound> stepSound
) {
return of(
transientHolder(ambientSound),
transientHolder(hurtSound),
transientHolder(deathSound),
transientHolder(stepSound)
);
}
/**
* Creates a new sound set based on the passed values.
* <p>
* {@link RegistryHolder} instances can be created with {@link io.papermc.paper.registry.event.RegistryFactory}.
*
* @param ambientSound the ambient sound, as returned by {@link #ambientSound()}
* @param hurtSound the hurt sound, as returned by {@link #hurtSound()}
* @param deathSound the death sound, as returned by {@link #deathSound()}
* @param stepSound the step sound, as returned by {@link #stepSound()}
* @return the created instance
*/
@Contract(value = "_, _, _, _ -> new", pure = true)
static SoundSet of(
final RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> deathSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> stepSound
) {
record Impl(
RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound,
RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound,
RegistryHolder<Sound, SoundEventRegistryEntry> deathSound,
RegistryHolder<Sound, SoundEventRegistryEntry> stepSound
) implements SoundSet {
}
return new Impl(ambientSound, hurtSound, deathSound, stepSound);
}
/**
* {@return the sound played randomly while the chicken is idle}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound();
/**
* {@return the sound played when the chicken is hurt}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound();
/**
* {@return the sound played when the chicken dies}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> deathSound();
/**
* {@return the sound played when the chicken walks}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> stepSound();
}
/**
* A mutable builder for the {@link ChickenSoundVariantRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #adultSounds(SoundSet)}</li>
* <li>{@link #babySounds(SoundSet)}</li>
* </ul>
*/
@ApiStatus.NonExtendable
interface Builder extends ChickenSoundVariantRegistryEntry, RegistryBuilder<Chicken.SoundVariant> {
/**
* Sets the sounds played by adult chickens of this variant.
*
* @param adultSounds the sound set
* @return this builder instance
* @see ChickenSoundVariantRegistryEntry#adultSounds()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder adultSounds(SoundSet adultSounds);
/**
* Sets the sounds played by baby chickens of this variant.
*
* @param babySounds the sound set
* @return this builder instance
* @see ChickenSoundVariantRegistryEntry#babySounds()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder babySounds(SoundSet babySounds);
}
}
@@ -1,139 +0,0 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.holder.RegistryHolder;
import org.bukkit.Sound;
import org.bukkit.entity.Cow;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
/**
* A data-centric version-specific registry entry for the {@link Cow.SoundVariant} type.
*/
@ApiStatus.NonExtendable
public interface CowSoundVariantRegistryEntry {
/**
* {@return the sound played randomly while the cow is idle}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound();
/**
* {@return the sound played when the cow is hurt}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound();
/**
* {@return the sound played when the cow dies}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> deathSound();
/**
* {@return the sound played when the cow walks}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> stepSound();
/**
* A mutable builder for the {@link CowSoundVariantRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #ambientSound(TypedKey)} or {@link #ambientSound(RegistryHolder)}</li>
* <li>{@link #hurtSound(TypedKey)} or {@link #hurtSound(RegistryHolder)}</li>
* <li>{@link #deathSound(TypedKey)} or {@link #deathSound(RegistryHolder)}</li>
* <li>{@link #stepSound(TypedKey)} or {@link #stepSound(RegistryHolder)}</li>
* </ul>
*/
@ApiStatus.NonExtendable
interface Builder extends CowSoundVariantRegistryEntry, RegistryBuilder<Cow.SoundVariant> {
/**
* Sets the ambient sound.
*
* @param ambientSound the key of the ambient sound
* @return this builder instance
* @see CowSoundVariantRegistryEntry#ambientSound()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder ambientSound(TypedKey<Sound> ambientSound);
/**
* Sets the ambient sound.
* <p>
* {@link RegistryHolder} instances can be created with {@link io.papermc.paper.registry.event.RegistryFactory}.
*
* @param ambientSound the ambient sound
* @return this builder instance
* @see CowSoundVariantRegistryEntry#ambientSound()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder ambientSound(RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound);
/**
* Sets the hurt sound.
*
* @param hurtSound the key of the hurt sound
* @return this builder instance
* @see CowSoundVariantRegistryEntry#hurtSound()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder hurtSound(TypedKey<Sound> hurtSound);
/**
* Sets the hurt sound.
* <p>
* {@link RegistryHolder} instances can be created with {@link io.papermc.paper.registry.event.RegistryFactory}.
*
* @param hurtSound the hurt sound
* @return this builder instance
* @see CowSoundVariantRegistryEntry#hurtSound()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder hurtSound(RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound);
/**
* Sets the death sound.
*
* @param deathSound the key of the death sound
* @return this builder instance
* @see CowSoundVariantRegistryEntry#deathSound()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder deathSound(TypedKey<Sound> deathSound);
/**
* Sets the death sound.
* <p>
* {@link RegistryHolder} instances can be created with {@link io.papermc.paper.registry.event.RegistryFactory}.
*
* @param deathSound the death sound
* @return this builder instance
* @see CowSoundVariantRegistryEntry#deathSound()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder deathSound(RegistryHolder<Sound, SoundEventRegistryEntry> deathSound);
/**
* Sets the step sound.
*
* @param stepSound the key of the step sound
* @return this builder instance
* @see CowSoundVariantRegistryEntry#stepSound()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder stepSound(TypedKey<Sound> stepSound);
/**
* Sets the step sound.
* <p>
* {@link RegistryHolder} instances can be created with {@link io.papermc.paper.registry.event.RegistryFactory}.
*
* @param stepSound the step sound
* @return this builder instance
* @see CowSoundVariantRegistryEntry#stepSound()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder stepSound(RegistryHolder<Sound, SoundEventRegistryEntry> stepSound);
}
}
@@ -161,7 +161,6 @@ public interface EnchantmentRegistryEntry {
* @param supportedItems the registry key set representing the supported items
* @return this builder instance
* @see RegistrySet#keySet(RegistryKey, TypedKey[])
* @see RegistrySet#keySet(TypedKey, TypedKey[])
* @see RegistryComposeEvent#getOrCreateTag(TagKey)
*/
@Contract(value = "_ -> this", mutates = "this")
@@ -183,7 +182,6 @@ public interface EnchantmentRegistryEntry {
* @param primaryItems the registry key set representing the primary items.
* @return this builder instance.
* @see RegistrySet#keySet(RegistryKey, TypedKey[])
* @see RegistrySet#keySet(TypedKey, TypedKey[])
* @see RegistryComposeEvent#getOrCreateTag(TagKey)
*/
@Contract(value = "_ -> this", mutates = "this")
@@ -287,7 +285,6 @@ public interface EnchantmentRegistryEntry {
* @param exclusiveWith a registry set of enchantments exclusive to this one
* @return this builder instance
* @see RegistrySet#keySet(RegistryKey, TypedKey[])
* @see RegistrySet#keySet(TypedKey, TypedKey[])
* @see RegistryComposeEvent#getOrCreateTag(TagKey)
*/
@Contract(value = "_ -> this", mutates = "this")
@@ -0,0 +1,35 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.dialog.Dialog;
import io.papermc.paper.registry.RegistryBuilderFactory;
import io.papermc.paper.registry.data.dialog.DialogRegistryEntry;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.function.Consumer;
import org.bukkit.MusicInstrument;
import org.bukkit.inventory.meta.trim.TrimMaterial;
import org.bukkit.inventory.meta.trim.TrimPattern;
import org.jetbrains.annotations.ApiStatus;
/**
* @hidden
*/
@ApiStatus.Internal
@ApiStatus.NonExtendable
public interface InlinedRegistryBuilderProvider {
static InlinedRegistryBuilderProvider instance() {
final class Holder {
static final Optional<InlinedRegistryBuilderProvider> INSTANCE = ServiceLoader.load(InlinedRegistryBuilderProvider.class, InlinedRegistryBuilderProvider.class.getClassLoader()).findFirst();
}
return Holder.INSTANCE.orElseThrow();
}
MusicInstrument createInstrument(Consumer<RegistryBuilderFactory<MusicInstrument, ? extends InstrumentRegistryEntry.Builder>> value);
Dialog createDialog(Consumer<RegistryBuilderFactory<Dialog, ? extends DialogRegistryEntry.Builder>> value);
TrimMaterial createTrimMaterial(Consumer<RegistryBuilderFactory<TrimMaterial, ? extends TrimMaterialRegistryEntry.Builder>> value);
TrimPattern createTrimPattern(Consumer<RegistryBuilderFactory<TrimPattern, ? extends TrimPatternRegistryEntry.Builder>> value);
}
@@ -1,152 +0,0 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.holder.RegistryHolder;
import org.bukkit.Sound;
import org.bukkit.entity.Pig;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import static io.papermc.paper.registry.data.RegistryBuilderProvider.transientHolder;
/**
* A data-centric version-specific registry entry for the {@link Pig.SoundVariant} type.
*/
@ApiStatus.NonExtendable
public interface PigSoundVariantRegistryEntry {
/**
* {@return the sounds played by adult pigs of this variant}
*/
SoundSet adultSounds();
/**
* {@return the sounds played by baby pigs of this variant}
*/
SoundSet babySounds();
/**
* The set of sounds played by a pig of a specific age.
*/
@ApiStatus.NonExtendable
interface SoundSet {
/**
* Creates a new sound set based on the passed values.
*
* @param ambientSound the ambient sound, as returned by {@link #ambientSound()}
* @param hurtSound the hurt sound, as returned by {@link #hurtSound()}
* @param deathSound the death sound, as returned by {@link #deathSound()}
* @param stepSound the step sound, as returned by {@link #stepSound()}
* @param eatSound the eat sound, as returned by {@link #eatSound()}
* @return the created instance
*/
@Contract(value = "_, _, _, _, _ -> new", pure = true)
static SoundSet of(
final TypedKey<Sound> ambientSound,
final TypedKey<Sound> hurtSound,
final TypedKey<Sound> deathSound,
final TypedKey<Sound> stepSound,
final TypedKey<Sound> eatSound
) {
return of(
transientHolder(ambientSound),
transientHolder(hurtSound),
transientHolder(deathSound),
transientHolder(stepSound),
transientHolder(eatSound)
);
}
/**
* Creates a new sound set based on the passed values.
* <p>
* {@link RegistryHolder} instances can be created with {@link io.papermc.paper.registry.event.RegistryFactory}.
*
* @param ambientSound the ambient sound, as returned by {@link #ambientSound()}
* @param hurtSound the hurt sound, as returned by {@link #hurtSound()}
* @param deathSound the death sound, as returned by {@link #deathSound()}
* @param stepSound the step sound, as returned by {@link #stepSound()}
* @param eatSound the eat sound, as returned by {@link #eatSound()}
* @return the created instance
*/
@Contract(value = "_, _, _, _, _ -> new", pure = true)
static SoundSet of(
final RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> deathSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> stepSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> eatSound
) {
record Impl(
RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound,
RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound,
RegistryHolder<Sound, SoundEventRegistryEntry> deathSound,
RegistryHolder<Sound, SoundEventRegistryEntry> stepSound,
RegistryHolder<Sound, SoundEventRegistryEntry> eatSound
) implements SoundSet {
}
return new Impl(ambientSound, hurtSound, deathSound, stepSound, eatSound);
}
/**
* {@return the sound played randomly while the pig is idle}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound();
/**
* {@return the sound played when the pig is hurt}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound();
/**
* {@return the sound played when the pig dies}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> deathSound();
/**
* {@return the sound played when the pig walks}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> stepSound();
/**
* {@return the sound played when the pig eats}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> eatSound();
}
/**
* A mutable builder for the {@link PigSoundVariantRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #adultSounds(SoundSet)}</li>
* <li>{@link #babySounds(SoundSet)}</li>
* </ul>
*/
@ApiStatus.NonExtendable
interface Builder extends PigSoundVariantRegistryEntry, RegistryBuilder<Pig.SoundVariant> {
/**
* Sets the sounds played by adult pigs of this variant.
*
* @param adultSounds the sound set
* @return this builder instance
* @see PigSoundVariantRegistryEntry#adultSounds()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder adultSounds(SoundSet adultSounds);
/**
* Sets the sounds played by baby pigs of this variant.
*
* @param babySounds the sound set
* @return this builder instance
* @see PigSoundVariantRegistryEntry#babySounds()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder babySounds(SoundSet babySounds);
}
}
@@ -1,36 +0,0 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.RegistryBuilderFactory;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.holder.RegistryHolder;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.function.Consumer;
import org.bukkit.Keyed;
import org.jetbrains.annotations.ApiStatus;
/**
* @hidden
*/
@ApiStatus.Internal
@ApiStatus.NonExtendable
public interface RegistryBuilderProvider {
static RegistryBuilderProvider instance() {
final class Holder {
static final Optional<RegistryBuilderProvider> INSTANCE = ServiceLoader.load(RegistryBuilderProvider.class, RegistryBuilderProvider.class.getClassLoader()).findFirst();
}
return Holder.INSTANCE.orElseThrow();
}
static <T extends RegistryElement.Buildable<T, E, ?>, E> RegistryHolder<T, E> transientHolder(final TypedKey<T> key) {
return instance().createTransientReferenceHolder(key);
}
<T extends RegistryElement.Inlineable<T, ?, B> & Keyed, B extends RegistryBuilder<T>> T create(RegistryKey<T> key, Consumer<RegistryBuilderFactory<T, ? extends B>> value);
<T extends RegistryElement.Buildable<T, E, ?>, E> RegistryHolder.Reference<T, E> createTransientReferenceHolder(TypedKey<T> key);
}
@@ -2,7 +2,6 @@ package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.holder.RegistryHolder;
import io.papermc.paper.registry.set.RegistryKeySet;
import java.util.List;
import org.bukkit.Sound;
@@ -17,7 +16,6 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.Nullable;
import static io.papermc.paper.registry.data.RegistryBuilderProvider.transientHolder;
import static io.papermc.paper.util.BoundChecker.requireNonNegative;
import static io.papermc.paper.util.BoundChecker.requirePositive;
@@ -182,15 +180,18 @@ public interface SulfurCubeArchetypeRegistryEntry {
@ApiStatus.NonExtendable
interface SoundSettings {
// todo The sounds should take a RegistryHolder but need more thoughts on the create method
/**
* {@return the sound played once the sulfur cube is knocked}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> hitSound();
@ApiStatus.Experimental
TypedKey<Sound> hitSound();
/**
* {@return the sound played once the sulfur cube is pushed}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> pushSound();
@ApiStatus.Experimental
TypedKey<Sound> pushSound();
/**
* {@return the smallest impulse required to play the push sound}
@@ -198,7 +199,7 @@ public interface SulfurCubeArchetypeRegistryEntry {
float pushSoundImpulseThreshold();
/**
* {@return the number of seconds before the push sound can be played again}
* {@return the amount of seconds before the push sound can be played again}
*/
float pushSoundCooldown();
@@ -208,28 +209,13 @@ public interface SulfurCubeArchetypeRegistryEntry {
* @param hitSound the sound played once the sulfur cube is knocked, as returned by {@link #hitSound()}
* @param pushSound the sound played once the sulfur cube is pushed, as returned by {@link #pushSound()}
* @param pushSoundImpulseThreshold the smallest impulse required to play the push sound, as returned by {@link #pushSoundImpulseThreshold()}
* @param pushSoundCooldown the number of seconds before the push sound can be played again, as returned by {@link #pushSoundCooldown()}
* @param pushSoundCooldown the amount of seconds before the push sound can be played again, as returned by {@link #pushSoundCooldown()}
* @return the created instance
*/
@Contract(value = "_, _, _, _ -> new", pure = true)
@ApiStatus.Experimental
static SoundSettings of(final TypedKey<Sound> hitSound, final TypedKey<Sound> pushSound, final float pushSoundImpulseThreshold, final float pushSoundCooldown) {
return of(transientHolder(hitSound), transientHolder(pushSound), pushSoundImpulseThreshold, pushSoundCooldown);
}
/**
* Creates a new sound settings instance based on the passed values.
* <p>
* {@link RegistryHolder} instances can be created with {@link io.papermc.paper.registry.event.RegistryFactory}.
*
* @param hitSound the sound played once the sulfur cube is knocked, as returned by {@link #hitSound()}
* @param pushSound the sound played once the sulfur cube is pushed, as returned by {@link #pushSound()}
* @param pushSoundImpulseThreshold the smallest impulse required to play the push sound, as returned by {@link #pushSoundImpulseThreshold()}
* @param pushSoundCooldown the number of seconds before the push sound can be played again, as returned by {@link #pushSoundCooldown()}
* @return the created instance
*/
@Contract(value = "_, _, _, _ -> new", pure = true)
static SoundSettings of(final RegistryHolder<Sound, SoundEventRegistryEntry> hitSound, final RegistryHolder<Sound, SoundEventRegistryEntry> pushSound, final float pushSoundImpulseThreshold, final float pushSoundCooldown) {
record Impl(RegistryHolder<Sound, SoundEventRegistryEntry> hitSound, RegistryHolder<Sound, SoundEventRegistryEntry> pushSound, float pushSoundImpulseThreshold, float pushSoundCooldown) implements SoundSettings {
record Impl(TypedKey<Sound> hitSound, TypedKey<Sound> pushSound, float pushSoundImpulseThreshold, float pushSoundCooldown) implements SoundSettings {
}
return new Impl(hitSound, pushSound, pushSoundImpulseThreshold, pushSoundCooldown);
@@ -1,174 +0,0 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.holder.RegistryHolder;
import org.bukkit.Sound;
import org.bukkit.entity.Wolf;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import static io.papermc.paper.registry.data.RegistryBuilderProvider.transientHolder;
/**
* A data-centric version-specific registry entry for the {@link Wolf.SoundVariant} type.
*/
@ApiStatus.NonExtendable
public interface WolfSoundVariantRegistryEntry {
/**
* {@return the sounds played by adult wolves of this variant}
*/
SoundSet adultSounds();
/**
* {@return the sounds played by baby wolves of this variant}
*/
SoundSet babySounds();
/**
* The set of sounds played by a wolf of a specific age.
*/
@ApiStatus.NonExtendable
interface SoundSet {
/**
* Creates a new sound set based on the passed values.
*
* @param ambientSound the ambient sound, as returned by {@link #ambientSound()}
* @param deathSound the death sound, as returned by {@link #deathSound()}
* @param growlSound the growl sound, as returned by {@link #growlSound()}
* @param hurtSound the hurt sound, as returned by {@link #hurtSound()}
* @param pantSound the pant sound, as returned by {@link #pantSound()}
* @param whineSound the whine sound, as returned by {@link #whineSound()}
* @param stepSound the step sound, as returned by {@link #stepSound()}
* @return the created instance
*/
@Contract(value = "_, _, _, _, _, _, _ -> new", pure = true)
static SoundSet of(
final TypedKey<Sound> ambientSound,
final TypedKey<Sound> deathSound,
final TypedKey<Sound> growlSound,
final TypedKey<Sound> hurtSound,
final TypedKey<Sound> pantSound,
final TypedKey<Sound> whineSound,
final TypedKey<Sound> stepSound
) {
return of(
transientHolder(ambientSound),
transientHolder(deathSound),
transientHolder(growlSound),
transientHolder(hurtSound),
transientHolder(pantSound),
transientHolder(whineSound),
transientHolder(stepSound)
);
}
/**
* Creates a new sound set based on the passed values.
* <p>
* {@link RegistryHolder} instances can be created with {@link io.papermc.paper.registry.event.RegistryFactory}.
*
* @param ambientSound the ambient sound, as returned by {@link #ambientSound()}
* @param deathSound the death sound, as returned by {@link #deathSound()}
* @param growlSound the growl sound, as returned by {@link #growlSound()}
* @param hurtSound the hurt sound, as returned by {@link #hurtSound()}
* @param pantSound the pant sound, as returned by {@link #pantSound()}
* @param whineSound the whine sound, as returned by {@link #whineSound()}
* @param stepSound the step sound, as returned by {@link #stepSound()}
* @return the created instance
*/
@Contract(value = "_, _, _, _, _, _, _ -> new", pure = true)
static SoundSet of(
final RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> deathSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> growlSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> pantSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> whineSound,
final RegistryHolder<Sound, SoundEventRegistryEntry> stepSound
) {
record Impl(
RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound,
RegistryHolder<Sound, SoundEventRegistryEntry> deathSound,
RegistryHolder<Sound, SoundEventRegistryEntry> growlSound,
RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound,
RegistryHolder<Sound, SoundEventRegistryEntry> pantSound,
RegistryHolder<Sound, SoundEventRegistryEntry> whineSound,
RegistryHolder<Sound, SoundEventRegistryEntry> stepSound
) implements SoundSet {
}
return new Impl(ambientSound, deathSound, growlSound, hurtSound, pantSound, whineSound, stepSound);
}
/**
* {@return the sound played randomly while the wolf is idle}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> ambientSound();
/**
* {@return the sound played when the wolf dies}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> deathSound();
/**
* {@return the sound played instead of the ambient sound while the wolf is angry}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> growlSound();
/**
* {@return the sound played when the wolf is hurt}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> hurtSound();
/**
* {@return the sound played randomly while the wolf is idle, unless the whine sound is played instead}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> pantSound();
/**
* {@return the sound played randomly while the wolf is idle, tamed and not at full health}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> whineSound();
/**
* {@return the sound played when the wolf walks}
*/
RegistryHolder<Sound, SoundEventRegistryEntry> stepSound();
}
/**
* A mutable builder for the {@link WolfSoundVariantRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #adultSounds(SoundSet)}</li>
* <li>{@link #babySounds(SoundSet)}</li>
* </ul>
*/
@ApiStatus.NonExtendable
interface Builder extends WolfSoundVariantRegistryEntry, RegistryBuilder<Wolf.SoundVariant> {
/**
* Sets the sounds played by adult wolves of this variant.
*
* @param adultSounds the sound set
* @return this builder instance
* @see WolfSoundVariantRegistryEntry#adultSounds()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder adultSounds(SoundSet adultSounds);
/**
* Sets the sounds played by baby wolves of this variant.
*
* @param babySounds the sound set
* @return this builder instance
* @see WolfSoundVariantRegistryEntry#babySounds()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder babySounds(SoundSet babySounds);
}
}
@@ -48,10 +48,8 @@ public interface DialogRegistryEntry {
* <p>Not a part of the registry entry.</p>
*
* @return a new registry value set builder
* @deprecated use {@link io.papermc.paper.registry.event.RegistryFactory} on the registry event and {@link io.papermc.paper.registry.set.RegistryHolderSetBuilder}
*/
@Contract(value = "-> new", pure = true)
@Deprecated(since = "26.4", forRemoval = true)
RegistryValueSetBuilder<Dialog, DialogRegistryEntry.Builder> registryValueSet();
/**
@@ -114,7 +114,7 @@ public non-sealed interface TextDialogInput extends DialogInput {
* @return this builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder width(@Range(from = 1, to = 1024) int width);
Builder width(final @Range(from = 1, to = 1024) int width);
/**
* Sets whether the label should be visible.
@@ -123,7 +123,7 @@ public non-sealed interface TextDialogInput extends DialogInput {
* @return this builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder labelVisible(boolean labelVisible);
Builder labelVisible(final boolean labelVisible);
/**
* Sets the initial value of the input.
@@ -132,7 +132,7 @@ public non-sealed interface TextDialogInput extends DialogInput {
* @return this builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder initial(String initial);
Builder initial(final String initial);
/**
* Sets the maximum length of the input.
@@ -141,7 +141,7 @@ public non-sealed interface TextDialogInput extends DialogInput {
* @return this builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder maxLength(@Positive int maxLength);
Builder maxLength(final @Positive int maxLength);
/**
* Sets the multiline options for the input.
@@ -150,7 +150,7 @@ public non-sealed interface TextDialogInput extends DialogInput {
* @return this builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder multiline(@Nullable MultilineOptions multiline);
Builder multiline(final @Nullable MultilineOptions multiline);
/**
* Builds the text dialog input.
@@ -61,7 +61,7 @@ public non-sealed interface DialogListType extends DialogType {
* @return the builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder exitAction(@Nullable ActionButton exitAction);
Builder exitAction(final @Nullable ActionButton exitAction);
/**
* Sets the number of columns to display in the dialog list.
@@ -70,7 +70,7 @@ public non-sealed interface DialogListType extends DialogType {
* @return the builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder columns(@Positive int columns);
Builder columns(final @Positive int columns);
/**
* Sets the width of each button in the dialog list.
@@ -79,7 +79,7 @@ public non-sealed interface DialogListType extends DialogType {
* @return the builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder buttonWidth(@Range(from = 1, to = 1024) int buttonWidth);
Builder buttonWidth(final @Range(from = 1, to = 1024) int buttonWidth);
/**
* Builds the dialog list type.
@@ -53,7 +53,7 @@ public non-sealed interface MultiActionType extends DialogType {
* @return the builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder exitAction(@Nullable ActionButton exitAction);
Builder exitAction(final @Nullable ActionButton exitAction);
/**
* Sets the number of columns to display in the dialog.
@@ -62,7 +62,7 @@ public non-sealed interface MultiActionType extends DialogType {
* @return the builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder columns(@Positive int columns);
Builder columns(final @Positive int columns);
/**
* Builds the multi-action dialog.
@@ -7,7 +7,7 @@ import org.bukkit.Keyed;
import org.jetbrains.annotations.ApiStatus;
/**
* Event object for {@link RegistryEvents#compose(io.papermc.paper.registry.RegistryKey)}. This
* Event object for {@link RegistryEventProvider#compose()}. This
* event is fired after a registry is loaded with its normal values.
* It provides a way for plugins to add new objects to the registry.
*
@@ -34,11 +34,4 @@ public interface RegistryComposeEvent<T, B extends RegistryBuilder<T>> extends R
* @param <V> the tag value type
*/
<V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey); // TODO remove Keyed
/**
* Gets the factory for creating tags, holders, and holder sets.
*
* @return the registry factory
*/
RegistryFactory factory();
}
@@ -8,8 +8,8 @@ import org.bukkit.Keyed;
import org.jetbrains.annotations.ApiStatus;
/**
* Event object for {@link RegistryEvents#entryAdd(io.papermc.paper.registry.RegistryKey)}. This
* event is fired right before a specific entry is registered in/added to the registry.
* Event object for {@link RegistryEventProvider#entryAdd()}. This
* event is fired right before a specific entry is registered in/added to registry.
* It provides a way for plugins to modify parts of this entry.
*
* @param <T> registry entry type
@@ -42,11 +42,4 @@ public interface RegistryEntryAddEvent<T, B extends RegistryBuilder<T>> extends
* @param <V> the tag value type
*/
<V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey);
/**
* Gets the factory for creating tags, holders, and holder sets.
*
* @return the registry factory
*/
RegistryFactory factory();
}
@@ -4,7 +4,6 @@ import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.event.type.RegistryEntryAddEventType;
import org.jetbrains.annotations.ApiStatus;
@@ -20,11 +19,9 @@ import org.jetbrains.annotations.ApiStatus;
*
* @param <T> registry entry type
* @param <B> registry entry builder type
* @deprecated use {@link RegistryEvents#compose(RegistryKey)} and {@link RegistryEvents#entryAdd(RegistryKey)}
*/
@ApiStatus.NonExtendable
@Deprecated(forRemoval = true, since = "26.4")
public interface RegistryEventProvider<T extends RegistryElement.Buildable<T, ?, B>, B extends RegistryBuilder<T>> {
public interface RegistryEventProvider<T, B extends RegistryBuilder<T>> {
/**
* Gets the event type for {@link RegistryEntryAddEvent} which is fired just before
@@ -3,25 +3,24 @@ package io.papermc.paper.registry.event;
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.event.type.RegistryEntryAddEventType;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
record RegistryEventProviderImpl<T extends RegistryElement.Buildable<T, E, B>, E, B extends RegistryBuilder<T>>(RegistryKey<T> registryKey) implements RegistryEventProvider<T, B> {
record RegistryEventProviderImpl<T, B extends RegistryBuilder<T>>(RegistryKey<T> registryKey) implements RegistryEventProvider<T, B> {
static <T extends RegistryElement.Buildable<T, E, B>, E, B extends RegistryBuilder<T>> RegistryEventProvider<T, B> create(final RegistryKey<T> registryKey) {
static <T, B extends RegistryBuilder<T>> RegistryEventProvider<T, B> create(final RegistryKey<T> registryKey) {
return new RegistryEventProviderImpl<>(registryKey);
}
@Override
public RegistryEntryAddEventType<T, B> entryAdd() {
return RegistryEvents.entryAdd(this.registryKey);
return RegistryEventTypeProvider.provider().registryEntryAdd(this);
}
@Override
public LifecycleEventType.Prioritizable<BootstrapContext, RegistryComposeEvent<T, B>> compose() {
return RegistryEvents.compose(this.registryKey);
return RegistryEventTypeProvider.provider().registryCompose(this);
}
}
@@ -3,8 +3,6 @@ package io.papermc.paper.registry.event;
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.event.type.RegistryEntryAddEventType;
import java.util.Optional;
import java.util.ServiceLoader;
@@ -19,7 +17,7 @@ interface RegistryEventTypeProvider {
return PROVIDER.orElseThrow(() -> new IllegalStateException("Could not find a %s service implementation".formatted(RegistryEventTypeProvider.class.getSimpleName())));
}
<API extends RegistryElement.Buildable<API, E, B>, E, B extends RegistryBuilder<API>> RegistryEntryAddEventType<API, B> registryEntryAdd(RegistryKey<API> key);
<T, B extends RegistryBuilder<T>> RegistryEntryAddEventType<T, B> registryEntryAdd(RegistryEventProvider<T, B> type);
<API extends RegistryElement.Buildable<API, E, B>, E, B extends RegistryBuilder<API>> LifecycleEventType.Prioritizable<BootstrapContext, RegistryComposeEvent<API, B>> registryCompose(RegistryKey<API> key);
<T, B extends RegistryBuilder<T>> LifecycleEventType.Prioritizable<BootstrapContext, RegistryComposeEvent<T, B>> registryCompose(RegistryEventProvider<T, B> type);
}
@@ -2,10 +2,6 @@ package io.papermc.paper.registry.event;
import io.papermc.paper.block.pot.PotPatternType;
import io.papermc.paper.dialog.Dialog;
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.BannerPatternRegistryEntry;
import io.papermc.paper.registry.data.CatTypeRegistryEntry;
@@ -26,7 +22,6 @@ import io.papermc.paper.registry.data.TrimPatternRegistryEntry;
import io.papermc.paper.registry.data.WolfVariantRegistryEntry;
import io.papermc.paper.registry.data.ZombieNautilusVariantRegistryEntry;
import io.papermc.paper.registry.data.dialog.DialogRegistryEntry;
import io.papermc.paper.registry.event.type.RegistryEntryAddEventType;
import org.bukkit.Art;
import org.bukkit.GameEvent;
import org.bukkit.JukeboxSong;
@@ -48,141 +43,32 @@ import org.bukkit.inventory.meta.trim.TrimPattern;
import static io.papermc.paper.registry.event.RegistryEventProviderImpl.create;
/**
* Holds methods to create registry event types for various registry-related events.
* Holds providers for {@link RegistryEntryAddEvent} and {@link RegistryComposeEvent}
* handlers for each applicable registry.
*/
public final class RegistryEvents {
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
// Start generate - RegistryEvents
public static final RegistryEventProvider<GameEvent, GameEventRegistryEntry.Builder> GAME_EVENT = create(RegistryKey.GAME_EVENT);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<TrimMaterial, TrimMaterialRegistryEntry.Builder> TRIM_MATERIAL = create(RegistryKey.TRIM_MATERIAL);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<TrimPattern, TrimPatternRegistryEntry.Builder> TRIM_PATTERN = create(RegistryKey.TRIM_PATTERN);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<DamageType, DamageTypeRegistryEntry.Builder> DAMAGE_TYPE = create(RegistryKey.DAMAGE_TYPE);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<Wolf.Variant, WolfVariantRegistryEntry.Builder> WOLF_VARIANT = create(RegistryKey.WOLF_VARIANT);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<Enchantment, EnchantmentRegistryEntry.Builder> ENCHANTMENT = create(RegistryKey.ENCHANTMENT);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<JukeboxSong, JukeboxSongRegistryEntry.Builder> JUKEBOX_SONG = create(RegistryKey.JUKEBOX_SONG);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<PatternType, BannerPatternRegistryEntry.Builder> BANNER_PATTERN = create(RegistryKey.BANNER_PATTERN);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<PotPatternType, DecoratedPotPatternRegistryEntry.Builder> DECORATED_POT_PATTERN = create(RegistryKey.DECORATED_POT_PATTERN);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<Art, PaintingVariantRegistryEntry.Builder> PAINTING_VARIANT = create(RegistryKey.PAINTING_VARIANT);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<MusicInstrument, InstrumentRegistryEntry.Builder> INSTRUMENT = create(RegistryKey.INSTRUMENT);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<Cat.Type, CatTypeRegistryEntry.Builder> CAT_VARIANT = create(RegistryKey.CAT_VARIANT);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<Frog.Variant, FrogVariantRegistryEntry.Builder> FROG_VARIANT = create(RegistryKey.FROG_VARIANT);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<Chicken.Variant, ChickenVariantRegistryEntry.Builder> CHICKEN_VARIANT = create(RegistryKey.CHICKEN_VARIANT);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<Cow.Variant, CowVariantRegistryEntry.Builder> COW_VARIANT = create(RegistryKey.COW_VARIANT);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<Pig.Variant, PigVariantRegistryEntry.Builder> PIG_VARIANT = create(RegistryKey.PIG_VARIANT);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<ZombieNautilus.Variant, ZombieNautilusVariantRegistryEntry.Builder> ZOMBIE_NAUTILUS_VARIANT = create(RegistryKey.ZOMBIE_NAUTILUS_VARIANT);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<SulfurCube.Archetype, SulfurCubeArchetypeRegistryEntry.Builder> SULFUR_CUBE_ARCHETYPE = create(RegistryKey.SULFUR_CUBE_ARCHETYPE);
/**
* @deprecated use {@link #entryAdd(RegistryKey)} and {@link #compose(RegistryKey)}
*/
@Deprecated(forRemoval = true, since = "26.4")
public static final RegistryEventProvider<Dialog, DialogRegistryEntry.Builder> DIALOG = create(RegistryKey.DIALOG);
/**
* Gets the event type for {@link RegistryEntryAddEvent} which is fired just before
* an object is added to a registry.
* <p>
* Can be used in {@link io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager#registerEventHandler(LifecycleEventType, io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler)}
* to register a handler for {@link RegistryEntryAddEvent}.
*
* @param registryKey the registry key
* @param <API> the api type
* @param <E> the registry entry type
* @param <B> the registry entry builder type
*
* @return the registry entry add event type
*/
public static <API extends RegistryElement.Buildable<API, E, B>, E, B extends RegistryBuilder<API>> RegistryEntryAddEventType<API, B> entryAdd(final RegistryKey<API> registryKey) {
return RegistryEventTypeProvider.provider().registryEntryAdd(registryKey);
}
/**
* Gets the event type for {@link RegistryComposeEvent} which is fired after
* a registry is loaded of expected elements. It allows for the registration of new objects.
* <p>
* Can be used in {@link io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager#registerEventHandler(LifecycleEventType, io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler)}
* to register a handler for {@link RegistryComposeEvent}.
*
* @param registryKey the registry key
* @param <API> the api type
* @param <E> the registry entry type
* @param <B> the registry entry builder type
*
* @return the registry compose event type
*/
public static <API extends RegistryElement.Buildable<API, E, B>, E, B extends RegistryBuilder<API>> LifecycleEventType.Prioritizable<BootstrapContext, RegistryComposeEvent<API, B>> compose(final RegistryKey<API> registryKey) {
return RegistryEventTypeProvider.provider().registryCompose(registryKey);
}
// End generate - RegistryEvents
private RegistryEvents() {
}
@@ -1,76 +0,0 @@
package io.papermc.paper.registry.event;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.RegistryBuilderFactory;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.holder.RegistryHolder;
import io.papermc.paper.registry.set.RegistryHolderSetBuilder;
import io.papermc.paper.registry.tag.Tag;
import io.papermc.paper.registry.tag.TagKey;
import java.util.function.Consumer;
import org.bukkit.Keyed;
import org.jetbrains.annotations.ApiStatus;
/**
* A factory for creating tags, holders, and holder sets while
* reacting to registry events.
*/
@ApiStatus.Experimental
public interface RegistryFactory {
/**
* Gets or creates a tag for the given tag key. This tag
* is then required to be filled either from the built-in or
* custom datapack.
*
* @param tagKey the tag key
* @return the tag
* @param <V> the tag value type
*/
<V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey); // TODO remove Keyed
/**
* Gets or creates a reference holder for the given key. The referenced
* value does not need to be present in the registry yet.
* <p>
* You can only create new reference holders for registries in the same registry layer. For example,
* since {@link RegistryKey#SOUND_EVENT} is a built-in registry, you cannot create new
* reference holders while in an event for {@link RegistryKey#SULFUR_CUBE_ARCHETYPE} as that
* is in a later layer. Try a {@link #createInlinedHolder(RegistryKey, Consumer)}.
*
* @param key the key of the referenced value
* @return the reference holder
* @param <V> the API type
* @param <E> the registry entry type
* @param <B> the builder type
* @see #createInlinedHolder(RegistryKey, Consumer)
*/
<V extends Keyed & RegistryElement.Buildable<V, E, B>, E, B extends RegistryBuilder<V>> RegistryHolder.Reference<V, E> getOrCreateReferenceHolder(TypedKey<V> key); // TODO remove Keyed
/**
* Creates an inlined holder wrapping an anonymous value built from the
* given builder consumer.
*
* @param registryKey the registry key for the value's type
* @param value a consumer configuring the inlined value's builder
* @return the inlined holder
* @param <V> the API type
* @param <E> the registry entry type
* @param <B> the builder type
* @see #getOrCreateReferenceHolder(TypedKey)
*/
<V extends Keyed & RegistryElement.Inlineable<V, E, B>, E, B extends RegistryBuilder<V>> RegistryHolder.Inlined<V, E> createInlinedHolder(RegistryKey<V> registryKey, Consumer<RegistryBuilderFactory<V, ? extends B>> value); // TODO remove Keyed
/**
* Creates a new builder for a {@link RegistryHolderSetBuilder holder set} of the given registry.
*
* @param registryKey the registry key for the value's type
* @return a new holder set builder
* @param <V> the API type
* @param <E> the registry entry type
* @param <B> the builder type
*/
<V extends Keyed & RegistryElement.Inlineable<V, E, B>, E, B extends RegistryBuilder<V>> RegistryHolderSetBuilder<V, E, B> createSetBuilder(RegistryKey<V> registryKey); // TODO remove Keyed
}
@@ -1,7 +1,5 @@
package io.papermc.paper.registry.holder;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import org.jetbrains.annotations.ApiStatus;
@@ -14,28 +12,7 @@ import org.jetbrains.annotations.ApiStatus;
* @param <E> the type of the registry entry (for inlined values)
*/
@ApiStatus.Experimental
public sealed interface RegistryHolder<T extends RegistryElement.Buildable<T, E, ?>, E> permits RegistryHolder.Reference, RegistryHolder.Inlined {
/**
* Gets the registry key of the registry this holder's value belongs to.
*
* @return the registry key
*/
RegistryKey<T> registryKey();
/**
* Gets the value held by this holder.
*
* @return the value
*/
T value();
/**
* Gets the registry entry held by this holder.
*
* @return the entry
*/
E entry();
public sealed interface RegistryHolder<T, E> permits RegistryHolder.Reference, RegistryHolder.Inlined {
/**
* A holder that references a registry value by key, but does not have the entry itself.
@@ -45,7 +22,7 @@ public sealed interface RegistryHolder<T extends RegistryElement.Buildable<T, E,
* @param <E> the type of the registry entry
*/
@ApiStatus.NonExtendable
non-sealed interface Reference<T extends RegistryElement.Buildable<T, E, ?>, E> extends RegistryHolder<T, E> {
non-sealed interface Reference<T, E> extends RegistryHolder<T, E> {
/**
* The key of the referenced value.
@@ -62,14 +39,13 @@ public sealed interface RegistryHolder<T extends RegistryElement.Buildable<T, E,
* @param <E> the type of the registry entry
*/
@ApiStatus.NonExtendable
non-sealed interface Inlined<T extends RegistryElement.Buildable<T, E, ?>, E> extends RegistryHolder<T, E> {
non-sealed interface Inlined<T, E> extends RegistryHolder<T, E> {
/**
* The inlined entry.
*
* @return the inlined entry
*/
@Override
E entry();
}
}
@@ -1,28 +0,0 @@
package io.papermc.paper.registry.set;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.holder.RegistryHolder;
import java.util.Collection;
import org.jetbrains.annotations.Unmodifiable;
/**
* A {@link RegistrySet} backed by {@link RegistryHolder holders}, each of which is
* either a reference to a registry value or an inlined, anonymous value.
* <p>
* Create with {@link RegistrySet#holderSetBuilder(RegistryKey)}, or if in a registry event context,
* {@link io.papermc.paper.registry.event.RegistryFactory#createSetBuilder(RegistryKey)}.
* </p>
*
* @param <T> the API type
* @param <E> the registry entry type
*/
public non-sealed interface RegistryHolderSet<T extends RegistryElement.Buildable<T, E, ?>, E> extends RegistrySet<T> {
/**
* Gets the holders in this set.
*
* @return an unmodifiable collection of holders
*/
@Unmodifiable Collection<RegistryHolder<T, E>> holders();
}
@@ -1,49 +0,0 @@
package io.papermc.paper.registry.set;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.RegistryBuilderFactory;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.TypedKey;
import java.util.function.Consumer;
/**
* A builder for a {@link RegistryHolderSet}.
*
* @param <T> the API type
* @param <E> the registry entry type
* @param <B> the builder type
*/
public interface RegistryHolderSetBuilder<T extends RegistryElement.Inlineable<T, E, B>, E, B extends RegistryBuilder<T>> {
/**
* Adds a value to the set.
*
* @param value the value to add
* @return this builder
*/
RegistryHolderSetBuilder<T, E, B> add(T value);
/**
* Adds a value by its key to the set. The referenced value does not need
* to be present in the registry yet.
*
* @param key the key of the value to add
* @return this builder
*/
RegistryHolderSetBuilder<T, E, B> add(TypedKey<T> key);
/**
* Adds an inlined, anonymous value built from the given builder consumer to the set.
*
* @param value a consumer configuring the inlined value's builder
* @return this builder
*/
RegistryHolderSetBuilder<T, E, B> add(Consumer<RegistryBuilderFactory<T, ? extends B>> value);
/**
* Builds the holder set.
*
* @return a new holder set
*/
RegistryHolderSet<T, E> build();
}
@@ -3,6 +3,7 @@ package io.papermc.paper.registry.set;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.tag.Tag;
import io.papermc.paper.registry.tag.TagKey;
import java.util.Collection;
import java.util.Iterator;
import org.bukkit.Keyed;
@@ -42,24 +43,12 @@ public non-sealed interface RegistryKeySet<T extends Keyed> extends Iterable<Typ
* Resolve this set into a collection of values. Prefer using
* {@link #values()}.
*
* @param ignored the registry to resolve the values from (must match {@link #registryKey()})
* @param registry the registry to resolve the values from (must match {@link #registryKey()})
* @return the resolved values
* @see RegistryKeySet#values()
* @deprecated use {@link #resolve()}, the registry is not needed
* @see Registry#getTagValues(TagKey)
*/
@Deprecated(since = "26.4", forRemoval = true)
default @Unmodifiable Collection<T> resolve(final Registry<T> ignored) {
return this.resolve();
}
/**
* Resolve this set into a collection of values. Prefer using
* {@link #values()}.
*
* @return the resolved values
* @see RegistryKeySet#values()
*/
@Unmodifiable Collection<T> resolve();
@Unmodifiable Collection<T> resolve(final Registry<T> registry);
/**
* Checks if this set contains the value with the given key.
@@ -37,8 +37,7 @@ record RegistryKeySetImpl<T extends Keyed>(RegistryKey<T> registryKey, List<Type
}
@Override
public Collection<T> resolve() {
final Registry<T> registry = RegistryAccess.registryAccess().getRegistry(this.registryKey);
public Collection<T> resolve(final Registry<T> registry) {
final List<T> values = new ArrayList<>(this.values.size());
for (final TypedKey<T> key : this.values) {
final T value = registry.get(key.key());
@@ -1,12 +1,9 @@
package io.papermc.paper.registry.set;
import com.google.common.collect.Lists;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.tag.Tag;
import java.util.List;
import org.bukkit.Keyed;
import org.jetbrains.annotations.Contract;
@@ -19,30 +16,13 @@ import org.jetbrains.annotations.Contract;
* These are obtained via {@link org.bukkit.Registry#getTag(io.papermc.paper.registry.tag.TagKey)}.</li>
* <li>{@link RegistryKeySet} which is a set of keys linked to values that are present in the registry. These are
* created via {@link #keySet(RegistryKey, Iterable)} or {@link #keySetFromValues(RegistryKey, Iterable)}.</li>
* <li>{@link RegistryHolderSet} which is a mixed set of values, some of which are anonymous (don't have keys in the registry). These are
* created via {@link #holderSetBuilder(RegistryKey)}.</li>
* <li>{@link RegistryValueSet} which is a set of values which are anonymous (don't have keys in the registry). These are
* created via {@link #valueSet(RegistryKey, Iterable)}.</li>
* </ul>
*
* @param <T> registry value type
*/
public sealed interface RegistrySet<T> permits RegistryHolderSet, RegistryKeySet, RegistryValueSet {
/**
* Creates a new builder for a {@link RegistryHolderSet}, a mixed set of registry-backed
* references and inlined, anonymous values.
* <p>
* In a registry event context, use {@link io.papermc.paper.registry.event.RegistryFactory#createSetBuilder(RegistryKey)} instead.
*
* @param registryKey the registry key for the type of these values
* @return a new holder set builder
* @param <T> the API type
* @param <E> the registry entry type
* @param <B> the builder type
*/
@Contract(value = "_ -> new", pure = true)
static <T extends Keyed & RegistryElement.Inlineable<T, E, B>, E, B extends RegistryBuilder<T>> RegistryHolderSetBuilder<T, E, B> holderSetBuilder(final RegistryKey<T> registryKey) { // TODO remove Keyed
return RegistrySetProvider.instance().registryHolderSetBuilder(registryKey);
}
public sealed interface RegistrySet<T> permits RegistryKeySet, RegistryValueSet {
/**
* Creates a {@link RegistryValueSet} from anonymous values.
@@ -52,10 +32,8 @@ public sealed interface RegistrySet<T> permits RegistryHolderSet, RegistryKeySet
* @param values the values
* @return a new registry set
* @param <T> the type of the values
* @deprecated Use {@link #holderSetBuilder(RegistryKey)}
*/
@Contract(value = "_, _ -> new", pure = true)
@Deprecated(since = "26.3", forRemoval = true)
static <T> RegistryValueSet<T> valueSet(final RegistryKey<T> registryKey, final Iterable<? extends T> values) {
return RegistryValueSetImpl.create(registryKey, values);
}
@@ -63,7 +41,7 @@ public sealed interface RegistrySet<T> permits RegistryHolderSet, RegistryKeySet
/**
* Creates a {@link RegistryKeySet} from registry-backed values.
* <p>All values provided <b>must</b> have keys in the given registry.
* For anonymous values, use {@link #valueSet(RegistryKey, Iterable)}.</p>
* <!--For anonymous values, use {@link #valueSet(RegistryKey, Iterable)}--></p>
* <p>If references to actual objects are not available yet, use {@link #keySet(RegistryKey, Iterable)} to
* create an equivalent {@link RegistryKeySet} using just {@link TypedKey TypedKeys}.</p>
*
@@ -79,7 +57,7 @@ public sealed interface RegistrySet<T> permits RegistryHolderSet, RegistryKeySet
}
/**
* Creates a direct {@code RegistrySet} from {@link TypedKey TypedKeys}.
* Creates a direct {@link RegistrySet} from {@link TypedKey TypedKeys}.
*
* @param registryKey the registry key for the owner of these keys
* @param keys the keys for the values
@@ -92,22 +70,7 @@ public sealed interface RegistrySet<T> permits RegistryHolderSet, RegistryKeySet
}
/**
* Creates a non empty direct {@code RegistrySet} from {@link TypedKey TypedKeys}.
*
* @param firstKey the first key for the values
* @param otherKeys the other keys for the values
* @return a new registry set
* @param <T> the type of the values
*/
@SafeVarargs
static <T extends Keyed> RegistryKeySet<T> keySet(final TypedKey<T> firstKey, final TypedKey<T>... otherKeys) { // TODO remove Keyed
final List<TypedKey<T>> keys = Lists.newArrayList(otherKeys);
keys.addFirst(firstKey);
return keySet(firstKey.registryKey(), keys);
}
/**
* Creates a direct {@code RegistrySet} from {@link TypedKey TypedKeys}.
* Creates a direct {@link RegistrySet} from {@link TypedKey TypedKeys}.
*
* @param registryKey the registry key for the owner of these keys
* @param keys the keys for the values
@@ -1,26 +0,0 @@
package io.papermc.paper.registry.set;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import java.util.Optional;
import java.util.ServiceLoader;
import org.bukkit.Keyed;
import org.jetbrains.annotations.ApiStatus;
/**
* @hidden
*/
@ApiStatus.Internal
@ApiStatus.NonExtendable
public interface RegistrySetProvider {
static RegistrySetProvider instance() {
final class Holder {
static final Optional<RegistrySetProvider> INSTANCE = ServiceLoader.load(RegistrySetProvider.class, RegistrySetProvider.class.getClassLoader()).findFirst();
}
return Holder.INSTANCE.orElseThrow();
}
<T extends Keyed & RegistryElement.Inlineable<T, E, B>, E, B extends RegistryBuilder<T>> RegistryHolderSetBuilder<T, E, B> registryHolderSetBuilder(RegistryKey<T> registryKey); // TODO remove Keyed
}
@@ -12,9 +12,7 @@ import org.jetbrains.annotations.Unmodifiable;
* in the context of a {@link io.papermc.paper.registry.RegistryBuilder},
* there are methods to create them like {@link DialogRegistryEntry.Builder#registryValueSet()}.
* @param <T> registry value type
* @deprecated use {@link RegistryHolderSet} and {@link RegistryHolderSetBuilder}
*/
@Deprecated(since = "26.4", forRemoval = true)
public sealed interface RegistryValueSet<T> extends Iterable<T>, RegistrySet<T> permits RegistryValueSetImpl {
@Override
@@ -10,10 +10,8 @@ import org.jetbrains.annotations.ApiStatus;
*
* @param <API> the API type
* @param <ENTRY_BUILDER> the type of the entry builder,
* @deprecated use {@link RegistryHolderSetBuilder}
*/
@ApiStatus.NonExtendable
@Deprecated(since = "26.4", forRemoval = true)
public interface RegistryValueSetBuilder<API, ENTRY_BUILDER extends RegistryBuilder<API>> {
/**
+1 -3
View File
@@ -2,9 +2,7 @@ package org.bukkit;
import com.google.common.base.Preconditions;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.PaintingVariantRegistryEntry;
import java.util.Locale;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
@@ -20,7 +18,7 @@ import org.jetbrains.annotations.Nullable;
* There may be additional arts present in the server, for example from a {@link io.papermc.paper.datapack.Datapack}
* which can be accessed via {@link RegistryAccess#registryAccess()} and {@link RegistryKey#PAINTING_VARIANT}.
*/
public interface Art extends RegistryElement.Buildable<Art, PaintingVariantRegistryEntry, PaintingVariantRegistryEntry.Builder>, OldEnum<Art>, Keyed {
public interface Art extends OldEnum<Art>, Keyed {
// Start generate - Art
Art ALBAN = getArt("alban");
@@ -1,7 +1,6 @@
package org.bukkit;
import com.google.common.base.Preconditions;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import java.util.Locale;
import net.kyori.adventure.key.Key;
@@ -12,7 +11,7 @@ import org.jetbrains.annotations.NotNull;
/**
* Represents a fluid type.
*/
public interface Fluid extends RegistryElement<Fluid>, OldEnum<Fluid>, Keyed {
public interface Fluid extends OldEnum<Fluid>, Keyed {
// Start generate - Fluid
Fluid EMPTY = getFluid("empty");
@@ -1,7 +1,5 @@
package org.bukkit;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.data.GameEventRegistryEntry;
import java.util.Collection;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
@@ -11,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Represents a generic Mojang game event.
*/
public abstract class GameEvent implements RegistryElement.Buildable<GameEvent, GameEventRegistryEntry, GameEventRegistryEntry.Builder>, Keyed {
public abstract class GameEvent implements Keyed {
// Start generate - GameEvent
public static final GameEvent BLOCK_ACTIVATE = getEvent("block_activate");
@@ -2,7 +2,6 @@ package org.bukkit;
import com.google.common.base.Preconditions;
import io.papermc.paper.InternalAPIBridge;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.world.flag.FeatureDependant;
import java.util.function.UnaryOperator;
import org.jetbrains.annotations.ApiStatus;
@@ -20,7 +19,7 @@ import org.jetbrains.annotations.Nullable;
* @see GameRules
*/
@ApiStatus.NonExtendable
public abstract class GameRule<T> implements RegistryElement<GameRule<T>>, net.kyori.adventure.translation.Translatable, FeatureDependant, Keyed {
public abstract class GameRule<T> implements net.kyori.adventure.translation.Translatable, FeatureDependant, Keyed {
// Boolean rules
/**
@@ -1,9 +1,7 @@
package org.bukkit;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.JukeboxSongRegistryEntry;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import net.kyori.adventure.text.Component;
@@ -13,7 +11,7 @@ import org.jspecify.annotations.NullMarked;
* Represents a song which may play in a Jukebox.
*/
@NullMarked
public interface JukeboxSong extends RegistryElement.Buildable<JukeboxSong, JukeboxSongRegistryEntry, JukeboxSongRegistryEntry.Builder>, Keyed, Translatable {
public interface JukeboxSong extends Keyed, Translatable {
// Start generate - JukeboxSong
JukeboxSong ELEVEN = get("11");
@@ -2,10 +2,9 @@ package org.bukkit;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryBuilderFactory;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.InlinedRegistryBuilderProvider;
import io.papermc.paper.registry.data.InstrumentRegistryEntry;
import io.papermc.paper.registry.data.RegistryBuilderProvider;
import java.util.Collection;
import java.util.function.Consumer;
import net.kyori.adventure.key.Key;
@@ -15,7 +14,7 @@ import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
@NullMarked
public abstract class MusicInstrument implements RegistryElement.Inlineable<MusicInstrument, InstrumentRegistryEntry, InstrumentRegistryEntry.Builder>, Keyed, net.kyori.adventure.translation.Translatable {
public abstract class MusicInstrument implements Keyed, net.kyori.adventure.translation.Translatable {
/**
* Creates an inlined music instrument.
@@ -24,7 +23,7 @@ public abstract class MusicInstrument implements RegistryElement.Inlineable<Musi
* @return the created music instrument
*/
public static MusicInstrument create(final Consumer<RegistryBuilderFactory<MusicInstrument, ? extends InstrumentRegistryEntry.Builder>> value) {
return RegistryBuilderProvider.instance().create(RegistryKey.INSTRUMENT, value);
return InlinedRegistryBuilderProvider.instance().createInstrument(value);
}
// Start generate - MusicInstrument
@@ -500,6 +500,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
* @throws NoSuchElementException if no tag with the given key is found
* @throws UnsupportedOperationException if this registry doesn't have or support tags
* @see #hasTag(TagKey)
* @see #getTagValues(TagKey)
*/
Tag<T> getTag(TagKey<T> key);
@@ -511,13 +512,11 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
* @throws NoSuchElementException if no tag with the given key is found
* @throws UnsupportedOperationException if this registry doesn't have or support tags
* @see #getTag(TagKey)
* @see Tag#resolve()
* @deprecated use {@link Tag#resolve()} on the fetched tag
* @see Tag#resolve(Registry)
*/
@Deprecated(since = "26.4", forRemoval = true)
default Collection<T> getTagValues(final TagKey<T> key) {
final Tag<T> tag = this.getTag(key);
return tag.resolve();
Tag<T> tag = this.getTag(key);
return tag.resolve(this);
}
/**
+9 -42
View File
@@ -1,18 +1,12 @@
package org.bukkit;
import com.google.common.base.Preconditions;
import io.papermc.paper.registry.RegistryBuilderFactory;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.RegistryBuilderProvider;
import io.papermc.paper.registry.data.SoundEventRegistryEntry;
import java.util.Locale;
import java.util.function.Consumer;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import org.bukkit.util.OldEnum;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
/**
* An interface of Sounds the server is able to send to players.
@@ -27,29 +21,7 @@ import org.jspecify.annotations.Nullable;
* guarantee values will not be removed from this interface. As such, you should not
* depend on the ordinal values of this class.
*/
@NullMarked
public interface Sound extends RegistryElement.Inlineable<Sound, SoundEventRegistryEntry, SoundEventRegistryEntry.Builder>, OldEnum<Sound>, Keyed, net.kyori.adventure.sound.Sound.Type { // Paper - implement Sound.Type
/**
* Creates an inlined sound event.
*
* @param key the sound location
* @param range an optional fixed range
* @return the created sound
*/
static Sound create(final Key key, final @Nullable Float range) {
return create(builder -> builder.empty().location(key).fixedRange(range));
}
/**
* Creates an inlined sound event.
*
* @param value a consumer for the builder factory
* @return the created sound
*/
static Sound create(final Consumer<RegistryBuilderFactory<Sound, ? extends SoundEventRegistryEntry.Builder>> value) {
return RegistryBuilderProvider.instance().create(RegistryKey.SOUND_EVENT, value);
}
public interface Sound extends OldEnum<Sound>, Keyed, net.kyori.adventure.sound.Sound.Type { // Paper - implement Sound.Type
// Start generate - Sound
Sound AMBIENT_BASALT_DELTAS_ADDITIONS = getSound("ambient.basalt_deltas.additions");
@@ -4035,7 +4007,8 @@ public interface Sound extends RegistryElement.Inlineable<Sound, SoundEventRegis
Sound WEATHER_RAIN_ABOVE = getSound("weather.rain.above");
// End generate - Sound
private static Sound getSound(@KeyPattern.Value String key) {
@NotNull
private static Sound getSound(@NotNull @KeyPattern.Value String key) {
return Registry.SOUNDS.getOrThrow(Key.key(Key.MINECRAFT_NAMESPACE, key));
}
@@ -4044,8 +4017,9 @@ public interface Sound extends RegistryElement.Inlineable<Sound, SoundEventRegis
* @return the sound with the given name.
* @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead.
*/
@NotNull
@Deprecated(since = "1.21.3", forRemoval = true) @org.jetbrains.annotations.ApiStatus.ScheduledForRemoval(inVersion = "1.22") // Paper - will be removed via asm-utils
static Sound valueOf(String name) {
static Sound valueOf(@NotNull String name) {
final NamespacedKey key = NamespacedKey.fromString(name.toLowerCase(Locale.ROOT));
Sound sound;
@@ -4075,21 +4049,14 @@ public interface Sound extends RegistryElement.Inlineable<Sound, SoundEventRegis
*/
@Deprecated(since = "1.20.5", forRemoval = true)
@Override
NamespacedKey getKey();
@NotNull NamespacedKey getKey();
// Paper end - deprecate getKey
/**
* Gets the fixed range, a radius in block which this sound is audible.
* The computed range will depends on the volume when this value is not defined.
*
* @return the fixed range
*/
@Nullable Float getFixedRange();
/**
* @return an array of all known sounds.
* @deprecated use {@link Registry#stream()}.
*/
@NotNull
@Deprecated(since = "1.21.3", forRemoval = true) @org.jetbrains.annotations.ApiStatus.ScheduledForRemoval(inVersion = "1.22") // Paper - will be removed via asm-utils
static Sound[] values() {
return Registry.SOUNDS.stream().toArray(Sound[]::new);
@@ -4102,7 +4069,7 @@ public interface Sound extends RegistryElement.Inlineable<Sound, SoundEventRegis
*/
@Deprecated(since = "1.20.5", forRemoval = true)
@Override
default net.kyori.adventure.key.Key key() {
default net.kyori.adventure.key.@NotNull Key key() {
return this.getKey();
}
// Paper end
@@ -1,7 +1,6 @@
package org.bukkit.attribute;
import com.google.common.base.Preconditions;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import java.util.Locale;
import net.kyori.adventure.key.Key;
@@ -18,7 +17,7 @@ import org.jetbrains.annotations.NotNull;
/**
* Types of attributes which may be present on an {@link Attributable}.
*/
public interface Attribute extends RegistryElement<Attribute>, OldEnum<Attribute>, Keyed, Translatable, net.kyori.adventure.translation.Translatable { // Paper - Adventure translations
public interface Attribute extends OldEnum<Attribute>, Keyed, Translatable, net.kyori.adventure.translation.Translatable { // Paper - Adventure translations
/**
* Maximum health of an Entity.
@@ -3,7 +3,6 @@ package org.bukkit.block;
import com.google.common.base.Preconditions;
import io.papermc.paper.InternalAPIBridge;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import java.util.Locale;
import net.kyori.adventure.key.Key;
@@ -24,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
* There may be additional biomes present in the server, for example from a {@link io.papermc.paper.datapack.Datapack}
* which can be accessed via {@link io.papermc.paper.registry.RegistryAccess#getRegistry(RegistryKey)} and {@link RegistryKey#BIOME}.
*/
public interface Biome extends RegistryElement<Biome>, OldEnum<Biome>, Keyed, net.kyori.adventure.translation.Translatable { // Paper - Adventure translations
public interface Biome extends OldEnum<Biome>, Keyed, net.kyori.adventure.translation.Translatable { // Paper - Adventure translations
// Start generate - Biome
Biome BADLANDS = getBiome("badlands");
@@ -1,6 +1,5 @@
package org.bukkit.block;
import io.papermc.paper.registry.RegistryElement;
import java.util.Collection;
import java.util.function.Consumer;
import net.kyori.adventure.key.Key;
@@ -136,7 +135,7 @@ import org.jspecify.annotations.Nullable;
* Represents a block type.
*/
@NullMarked
public interface BlockType extends RegistryElement<BlockType>, Keyed, Translatable, net.kyori.adventure.translation.Translatable, io.papermc.paper.world.flag.FeatureDependant { // Paper - add translatable & feature flag API
public interface BlockType extends Keyed, Translatable, net.kyori.adventure.translation.Translatable, io.papermc.paper.world.flag.FeatureDependant { // Paper - add translatable & feature flag API
/**
* Typed represents a subtype of {@link BlockType}s that have a known block
@@ -2,9 +2,7 @@ package org.bukkit.block.banner;
import com.google.common.base.Preconditions;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.BannerPatternRegistryEntry;
import java.util.Locale;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
@@ -19,7 +17,7 @@ import org.jspecify.annotations.Nullable;
/**
* A type of pattern that can be applied to a banner.
*/
public interface PatternType extends RegistryElement.Buildable<PatternType, BannerPatternRegistryEntry, BannerPatternRegistryEntry.Builder>, OldEnum<PatternType>, Keyed {
public interface PatternType extends OldEnum<PatternType>, Keyed {
// Start generate - PatternType
PatternType BASE = getType("base");
@@ -1,9 +1,7 @@
package org.bukkit.damage;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.DamageTypeRegistryEntry;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import org.bukkit.Keyed;
@@ -19,7 +17,7 @@ import org.jetbrains.annotations.NotNull;
*
* @see <a href="https://minecraft.wiki/w/Damage_type">Minecraft Wiki</a>
*/
public interface DamageType extends RegistryElement.Buildable<DamageType, DamageTypeRegistryEntry, DamageTypeRegistryEntry.Builder>, Keyed, Translatable {
public interface DamageType extends Keyed, Translatable {
// Start generate - DamageType
DamageType ARROW = getDamageType("arrow");
@@ -1,9 +1,7 @@
package org.bukkit.enchantments;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.EnchantmentRegistryEntry;
import java.util.Locale;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
@@ -20,7 +18,7 @@ import org.jetbrains.annotations.Nullable;
/**
* The various type of enchantments that may be added to armour or weapons
*/
public abstract class Enchantment implements RegistryElement.Buildable<Enchantment, EnchantmentRegistryEntry, EnchantmentRegistryEntry.Builder>, Keyed, Translatable, net.kyori.adventure.translation.Translatable { // Paper - Adventure translations
public abstract class Enchantment implements Keyed, Translatable, net.kyori.adventure.translation.Translatable { // Paper - Adventure translations
/**
* Provides protection against environmental damage
*/
@@ -2,10 +2,7 @@ package org.bukkit.entity;
import com.google.common.base.Preconditions;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.CatSoundVariantRegistryEntry;
import io.papermc.paper.registry.data.CatTypeRegistryEntry;
import java.util.Locale;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
@@ -71,7 +68,7 @@ public interface Cat extends Tameable, Sittable, io.papermc.paper.entity.CollarC
/**
* Represents the various different cat types there are.
*/
interface Type extends RegistryElement.Buildable<Type, CatTypeRegistryEntry, CatTypeRegistryEntry.Builder>, OldEnum<Type>, Keyed {
interface Type extends OldEnum<Type>, Keyed {
// Start generate - CatType
Type ALL_BLACK = getType("all_black");
@@ -130,7 +127,7 @@ public interface Cat extends Tameable, Sittable, io.papermc.paper.entity.CollarC
/**
* Represents the sound variant of a cat.
*/
interface SoundVariant extends RegistryElement.Buildable<SoundVariant, CatSoundVariantRegistryEntry, CatSoundVariantRegistryEntry.Builder>, Keyed {
interface SoundVariant extends Keyed {
// Start generate - CatSoundVariant
SoundVariant CLASSIC = getSoundVariant("classic");
@@ -1,10 +1,7 @@
package org.bukkit.entity;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.ChickenSoundVariantRegistryEntry;
import io.papermc.paper.registry.data.ChickenVariantRegistryEntry;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import org.bukkit.Keyed;
@@ -75,7 +72,7 @@ public interface Chicken extends Animals {
/**
* Represents the variant of a chicken.
*/
interface Variant extends RegistryElement.Buildable<Variant, ChickenVariantRegistryEntry, ChickenVariantRegistryEntry.Builder>, Keyed {
interface Variant extends Keyed {
// Start generate - ChickenVariant
Variant COLD = getVariant("cold");
@@ -93,7 +90,7 @@ public interface Chicken extends Animals {
/**
* Represents the sound variant of a chicken.
*/
interface SoundVariant extends RegistryElement.Buildable<SoundVariant, ChickenSoundVariantRegistryEntry, ChickenSoundVariantRegistryEntry.Builder>, Keyed {
interface SoundVariant extends Keyed {
// Start generate - ChickenSoundVariant
SoundVariant CLASSIC = getSoundVariant("classic");
@@ -1,10 +1,7 @@
package org.bukkit.entity;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.CowSoundVariantRegistryEntry;
import io.papermc.paper.registry.data.CowVariantRegistryEntry;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import org.bukkit.Keyed;
@@ -47,7 +44,7 @@ public interface Cow extends AbstractCow {
/**
* Represents the variant of a cow.
*/
interface Variant extends RegistryElement.Buildable<Variant, CowVariantRegistryEntry, CowVariantRegistryEntry.Builder>, Keyed {
interface Variant extends Keyed {
// Start generate - CowVariant
Variant COLD = getVariant("cold");
@@ -65,7 +62,7 @@ public interface Cow extends AbstractCow {
/**
* Represents the sound variant of a cow.
*/
interface SoundVariant extends RegistryElement.Buildable<SoundVariant, CowSoundVariantRegistryEntry, CowSoundVariantRegistryEntry.Builder>, Keyed {
interface SoundVariant extends Keyed {
// Start generate - CowSoundVariant
SoundVariant CLASSIC = getSoundVariant("classic");
@@ -2,9 +2,7 @@ package org.bukkit.entity;
import com.google.common.base.Preconditions;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.FrogVariantRegistryEntry;
import java.util.Locale;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
@@ -53,7 +51,7 @@ public interface Frog extends Animals {
/**
* Represents the variant of a frog - ie its color.
*/
interface Variant extends RegistryElement.Buildable<Variant, FrogVariantRegistryEntry, FrogVariantRegistryEntry.Builder>, OldEnum<Variant>, Keyed {
interface Variant extends OldEnum<Variant>, Keyed {
// Start generate - FrogVariant
Variant COLD = getVariant("cold");
@@ -1,10 +1,7 @@
package org.bukkit.entity;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.PigSoundVariantRegistryEntry;
import io.papermc.paper.registry.data.PigVariantRegistryEntry;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import org.bukkit.Keyed;
@@ -47,7 +44,7 @@ public interface Pig extends Steerable, Vehicle {
/**
* Represents the variant of a pig.
*/
interface Variant extends RegistryElement.Buildable<Variant, PigVariantRegistryEntry, PigVariantRegistryEntry.Builder>, Keyed {
interface Variant extends Keyed {
// Start generate - PigVariant
Variant COLD = getVariant("cold");
@@ -65,7 +62,7 @@ public interface Pig extends Steerable, Vehicle {
/**
* Represents the sound variant of a pig.
*/
interface SoundVariant extends RegistryElement.Buildable<SoundVariant, PigSoundVariantRegistryEntry, PigSoundVariantRegistryEntry.Builder>, Keyed {
interface SoundVariant extends Keyed {
// Start generate - PigSoundVariant
SoundVariant BIG = getSoundVariant("big");
@@ -5,9 +5,7 @@ import io.papermc.paper.entity.Bucketable;
import io.papermc.paper.entity.Shearable;
import io.papermc.paper.event.entity.EntityEquipmentChangedEvent;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.SulfurCubeArchetypeRegistryEntry;
import io.papermc.paper.registry.keys.tags.ItemTypeTagKeys;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
@@ -137,7 +135,7 @@ public interface SulfurCube extends AbstractCubeMob, Shearable, Bucketable, Agea
* which define a lot of possible behavior and interaction
* throughout its lifetime.
*/
interface Archetype extends RegistryElement.Buildable<Archetype, SulfurCubeArchetypeRegistryEntry, SulfurCubeArchetypeRegistryEntry.Builder>, Keyed {
interface Archetype extends Keyed {
// Start generate - SulfurCubeArchetype
Archetype BOUNCY = getArchetype("bouncy");
@@ -1,10 +1,9 @@
package org.bukkit.entity;
import com.google.common.base.Preconditions;
import io.papermc.paper.registry.RegistryElement;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.Map; // Paper
import java.util.UUID; // Paper
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import org.bukkit.Keyed;
@@ -167,7 +166,7 @@ public interface Villager extends AbstractVillager {
* Represents Villager type, usually corresponding to what biome they spawn
* in.
*/
interface Type extends RegistryElement<Type>, OldEnum<Type>, Keyed {
interface Type extends OldEnum<Type>, Keyed {
// Start generate - VillagerType
Type DESERT = getType("desert");
@@ -219,7 +218,7 @@ public interface Villager extends AbstractVillager {
* Represents the various different Villager professions there may be.
* Villagers have different trading options depending on their profession,
*/
interface Profession extends RegistryElement<Profession>, OldEnum<Profession>, Keyed, net.kyori.adventure.translation.Translatable {
interface Profession extends OldEnum<Profession>, Keyed, net.kyori.adventure.translation.Translatable {
// Start generate - VillagerProfession
/**
@@ -1,10 +1,7 @@
package org.bukkit.entity;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.WolfSoundVariantRegistryEntry;
import io.papermc.paper.registry.data.WolfVariantRegistryEntry;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import org.bukkit.DyeColor;
@@ -111,7 +108,7 @@ public interface Wolf extends Tameable, Sittable, io.papermc.paper.entity.Collar
/**
* Represents the variant of a wolf.
*/
interface Variant extends RegistryElement.Buildable<Variant, WolfVariantRegistryEntry, WolfVariantRegistryEntry.Builder>, Keyed {
interface Variant extends Keyed {
// Start generate - WolfVariant
// @GeneratedFrom 1.21.5
@@ -143,7 +140,7 @@ public interface Wolf extends Tameable, Sittable, io.papermc.paper.entity.Collar
/**
* Represents the sound variant of a wolf.
*/
interface SoundVariant extends RegistryElement.Buildable<SoundVariant, WolfSoundVariantRegistryEntry, WolfSoundVariantRegistryEntry.Builder>, Keyed {
interface SoundVariant extends Keyed {
// Start generate - WolfSoundVariant
SoundVariant ANGRY = getSoundVariant("angry");
@@ -1,9 +1,7 @@
package org.bukkit.entity;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.ZombieNautilusVariantRegistryEntry;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import org.bukkit.Keyed;
@@ -29,7 +27,7 @@ public interface ZombieNautilus extends AbstractNautilus {
/**
* Represents the variant of a Zombie Nautilus.
*/
interface Variant extends RegistryElement.Buildable<Variant, ZombieNautilusVariantRegistryEntry, ZombieNautilusVariantRegistryEntry.Builder>, Keyed {
interface Variant extends Keyed {
// Start generate - ZombieNautilusVariant
Variant TEMPERATE = getVariant("temperate");
@@ -1,7 +1,6 @@
package org.bukkit.generator.structure;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
@@ -17,7 +16,7 @@ import org.jetbrains.annotations.NotNull;
* there might be additional structures present (for example structures added by
* data packs), which can be received via {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} and {@link io.papermc.paper.registry.RegistryKey#STRUCTURE}.
*/
public abstract class Structure implements RegistryElement<Structure>, Keyed {
public abstract class Structure implements Keyed {
// Start generate - Structure
public static final Structure ABANDONED_CAMP_BAMBOO_JUNGLE = getStructure("abandoned_camp_bamboo_jungle");
@@ -1,6 +1,5 @@
package org.bukkit.generator.structure;
import io.papermc.paper.registry.RegistryElement;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import org.bukkit.Keyed;
@@ -15,7 +14,7 @@ import org.jetbrains.annotations.NotNull;
* structure types added by data packs), which can be received via
* {@link Registry#STRUCTURE_TYPE}.
*/
public abstract class StructureType implements RegistryElement<StructureType>, Keyed {
public abstract class StructureType implements Keyed {
// Start generate - StructureType
public static final StructureType BURIED_TREASURE = getStructureType("buried_treasure");
@@ -1169,6 +1169,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
}
// Paper end - expose itemstack tooltip lines
// Paper start - data component API
/**
* Gets the value for the data component type on this stack.
*
@@ -1357,31 +1358,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
* @return {@code true} if the provided item is equal, ignoring the provided components
*/
public boolean matchesWithoutData(final @NotNull ItemStack item, final @NotNull java.util.Set<io.papermc.paper.datacomponent.@NotNull DataComponentType> excludeTypes, final boolean ignoreCount) {
return this.matchesWithoutData(item, excludeTypes::contains, ignoreCount);
}
/**
* Checks if this itemstack matches another given itemstack excluding the provided components.
* This is useful if you are wanting to ignore certain properties of itemstacks, such as durability.
*
* @param item the item to compare
* @param excludeTypes the data component types to ignore
* @return {@code true} if the provided item is equal, ignoring the provided components
*/
public boolean matchesWithoutData(final @NotNull ItemStack item, final @NotNull Predicate<io.papermc.paper.datacomponent.@NotNull DataComponentType> excludeTypes) {
return this.matchesWithoutData(item, excludeTypes, false);
}
/**
* Checks if this itemstack matches another given itemstack excluding the provided components.
* This is useful if you are wanting to ignore certain properties of itemstacks, such as durability.
*
* @param item the item to compare
* @param excludeTypes the data component types to ignore
* @param ignoreCount ignore the count of the item
* @return {@code true} if the provided item is equal, ignoring the provided components
*/
public boolean matchesWithoutData(final @NotNull ItemStack item, final @NotNull Predicate<io.papermc.paper.datacomponent.@NotNull DataComponentType> excludeTypes, final boolean ignoreCount) {
return this.craftDelegate.matchesWithoutData(item, excludeTypes, ignoreCount);
}
// Paper end - data component API
}
@@ -2,7 +2,6 @@ package org.bukkit.inventory;
import com.google.common.collect.Multimap;
import io.papermc.paper.datacomponent.DataComponentType;
import io.papermc.paper.registry.RegistryElement;
import java.util.Set;
import java.util.function.Consumer;
import net.kyori.adventure.key.Key;
@@ -48,7 +47,7 @@ import org.jspecify.annotations.Nullable;
* Represents an item type.
*/
@NullMarked
public interface ItemType extends RegistryElement<ItemType>, Keyed, Translatable, net.kyori.adventure.translation.Translatable, io.papermc.paper.world.flag.FeatureDependant { // Paper - add Translatable & feature flag API
public interface ItemType extends Keyed, Translatable, net.kyori.adventure.translation.Translatable, io.papermc.paper.world.flag.FeatureDependant { // Paper - add Translatable & feature flag API
/**
* Typed represents a subtype of {@link ItemType}s that have a known item meta type
@@ -70,7 +70,7 @@ final class ItemTypeRecipeChoiceImpl extends RecipeChoice.MaterialChoice impleme
if (this.legacyChoices == null) {
final List<Material> choices = new ArrayList<>();
for (final TypedKey<ItemType> itemTypeKey : this.itemTypes) {
choices.add(Registry.MATERIAL.getOrThrow(itemTypeKey.key()));
choices.add(Registry.MATERIAL.getOrThrow(itemTypeKey));
}
this.legacyChoices = Collections.unmodifiableList(choices);
}
@@ -1,6 +1,5 @@
package org.bukkit.inventory;
import io.papermc.paper.registry.RegistryElement;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import net.kyori.adventure.text.Component;
@@ -28,7 +27,7 @@ import org.jspecify.annotations.Nullable;
* created and viewed by the player.
*/
@NullMarked
public interface MenuType extends RegistryElement<MenuType>, Keyed, io.papermc.paper.world.flag.FeatureDependant { // Paper - make FeatureDependant
public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDependant { // Paper - make FeatureDependant
/**
* A MenuType which represents a chest with 1 row.
@@ -59,7 +59,7 @@ public interface RecipeChoice extends Predicate<ItemStack>, Cloneable {
/**
* Creates a new recipe choice based on a {@link RegistryKeySet} of item types.
* Can either be created via {@link RegistryKeySet#keySet(RegistryKey, TypedKey[])}/{@link RegistryKeySet#keySet(TypedKey, TypedKey[])}
* Can either be created via {@link RegistryKeySet#keySet(RegistryKey, TypedKey[])}
* or obtained from {@link org.bukkit.Registry#getTag(TagKey)}.
*
* @param itemTypes the item types to match
@@ -2,9 +2,8 @@ package org.bukkit.inventory.meta.trim;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryBuilderFactory;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.RegistryBuilderProvider;
import io.papermc.paper.registry.data.InlinedRegistryBuilderProvider;
import io.papermc.paper.registry.data.TrimMaterialRegistryEntry;
import java.util.function.Consumer;
import net.kyori.adventure.key.Key;
@@ -20,7 +19,7 @@ import org.jspecify.annotations.NullMarked;
* Represents a material that may be used in an {@link ArmorTrim}.
*/
@NullMarked
public interface TrimMaterial extends RegistryElement.Inlineable<TrimMaterial, TrimMaterialRegistryEntry, TrimMaterialRegistryEntry.Builder>, Keyed, Translatable {
public interface TrimMaterial extends Keyed, Translatable {
/**
* Creates an inlined trim material.
@@ -29,7 +28,7 @@ public interface TrimMaterial extends RegistryElement.Inlineable<TrimMaterial, T
* @return the created trim material
*/
static TrimMaterial create(final Consumer<RegistryBuilderFactory<TrimMaterial, ? extends TrimMaterialRegistryEntry.Builder>> value) {
return RegistryBuilderProvider.instance().create(RegistryKey.TRIM_MATERIAL, value);
return InlinedRegistryBuilderProvider.instance().createTrimMaterial(value);
}
// Start generate - TrimMaterial
@@ -2,9 +2,8 @@ package org.bukkit.inventory.meta.trim;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryBuilderFactory;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.RegistryBuilderProvider;
import io.papermc.paper.registry.data.InlinedRegistryBuilderProvider;
import io.papermc.paper.registry.data.TrimPatternRegistryEntry;
import java.util.function.Consumer;
import net.kyori.adventure.key.Key;
@@ -20,7 +19,7 @@ import org.jspecify.annotations.NullMarked;
* Represents a pattern that may be used in an {@link ArmorTrim}.
*/
@NullMarked
public interface TrimPattern extends RegistryElement.Inlineable<TrimPattern, TrimPatternRegistryEntry, TrimPatternRegistryEntry.Builder>, Keyed, Translatable {
public interface TrimPattern extends Keyed, Translatable {
/**
* Creates an inlined trim pattern.
@@ -29,7 +28,7 @@ public interface TrimPattern extends RegistryElement.Inlineable<TrimPattern, Tri
* @return the created trim pattern
*/
static TrimPattern create(final Consumer<RegistryBuilderFactory<TrimPattern, ? extends TrimPatternRegistryEntry.Builder>> value) {
return RegistryBuilderProvider.instance().create(RegistryKey.TRIM_PATTERN, value);
return InlinedRegistryBuilderProvider.instance().createTrimPattern(value);
}
// Start generate - TrimPattern
@@ -1,7 +1,6 @@
package org.bukkit.map;
import com.google.common.base.Preconditions;
import io.papermc.paper.registry.RegistryElement;
import java.util.Locale;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
@@ -288,7 +287,7 @@ public final class MapCursor {
* index in the file './assets/minecraft/textures/map/map_icons.png' from minecraft.jar or from a
* resource pack.
*/
public interface Type extends RegistryElement<Type>, OldEnum<Type>, Keyed {
public interface Type extends OldEnum<Type>, Keyed {
// Start generate - MapCursorType
Type ABANDONED_CAMP = getType("abandoned_camp");
@@ -3,7 +3,6 @@ package org.bukkit.potion;
import com.google.common.base.Preconditions;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import io.papermc.paper.registry.RegistryElement;
import java.util.Locale;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
@@ -21,7 +20,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Represents a type of potion and its effect on an entity.
*/
public abstract class PotionEffectType implements RegistryElement<PotionEffectType>, Keyed, Translatable, net.kyori.adventure.translation.Translatable, io.papermc.paper.world.flag.FeatureDependant { // Paper - implement Translatable & feature flag API
public abstract class PotionEffectType implements Keyed, Translatable, net.kyori.adventure.translation.Translatable, io.papermc.paper.world.flag.FeatureDependant { // Paper - implement Translatable & feature flag API
private static final BiMap<Integer, PotionEffectType> ID_MAP = HashBiMap.create();
/**
@@ -198,12 +198,12 @@ public final class Rewriters {
.register("JukeboxSong", JukeboxSong.class, new RegistryFieldRewriter<>(Registries.JUKEBOX_SONG, "get") {
@Override
protected String rewriteFieldName(Holder.Reference<net.minecraft.world.item.JukeboxSong> reference) {
String constantName = super.rewriteFieldName(reference);
if (!SourceVersion.isIdentifier(constantName)) {
String keyedName = super.rewriteFieldName(reference);
if (!SourceVersion.isIdentifier(keyedName)) {
// fallback to field names for invalid identifier (happens for 5, 11, 13 etc.)
return RegistryEntries.byRegistryKey(Registries.JUKEBOX_SONG).getFieldNames().get(reference.key());
}
return constantName;
return keyedName;
}
})
.register("GameRules", GameRules.class, new RegistryFieldRewriter<>(Registries.GAME_RULE, "getRule") {
@@ -251,6 +251,7 @@ public final class Rewriters {
.register("FeatureFlag", FeatureFlag.class, new FeatureFlagRewriter())
.register("Tag", Tag.class, new TagRewriter())
.register("MapPalette#colors", MapPalette.class, new MapPaletteRewriter());
RegistryBootstrapper.bootstrapApi(sourceSet);
}
private static void bootstrapServer(PatternSourceSetRewriter sourceSet) {
@@ -3,9 +3,11 @@ package io.papermc.generator.registry;
import io.papermc.generator.rewriter.registration.PatternSourceSetRewriter;
import io.papermc.generator.rewriter.types.Types;
import io.papermc.generator.rewriter.types.registry.PaperRegistriesRewriter;
import io.papermc.generator.rewriter.types.registry.RegistryEventsRewriter;
import io.papermc.generator.types.SourceGenerator;
import io.papermc.generator.types.registry.GeneratedKeyType;
import io.papermc.generator.types.registry.GeneratedTagKeyType;
import io.papermc.paper.registry.event.RegistryEvents;
import java.util.List;
import net.minecraft.core.registries.Registries;
@@ -18,19 +20,24 @@ public final class RegistryBootstrapper {
RegistryEntries.forEach(entry -> {
generators.add(new GeneratedKeyType<>(PAPER_REGISTRY_PACKAGE + ".keys", entry));
if (entry.registry().listTags().findAny().isPresent()) {
generators.add(new GeneratedTagKeyType<>(entry, PAPER_REGISTRY_PACKAGE + ".keys.tags"));
generators.add(new GeneratedTagKeyType(entry, PAPER_REGISTRY_PACKAGE + ".keys.tags"));
}
});
// todo remove once entity type and potion are both a registry
generators.add(new GeneratedTagKeyType<>(RegistryEntries.byRegistryKey(Registries.ENTITY_TYPE), PAPER_REGISTRY_PACKAGE + ".keys.tags"));
generators.add(new GeneratedTagKeyType<>(RegistryEntries.byRegistryKey(Registries.POTION), PAPER_REGISTRY_PACKAGE + ".keys.tags"));
generators.add(new GeneratedTagKeyType(RegistryEntries.byRegistryKey(Registries.ENTITY_TYPE), PAPER_REGISTRY_PACKAGE + ".keys.tags"));
generators.add(new GeneratedTagKeyType(RegistryEntries.byRegistryKey(Registries.POTION), PAPER_REGISTRY_PACKAGE + ".keys.tags"));
}
public static void bootstrap(PatternSourceSetRewriter apiSourceSet, PatternSourceSetRewriter serverSourceSet) {
bootstrapApi(apiSourceSet);
bootstrapServer(serverSourceSet);
}
public static void bootstrapApi(PatternSourceSetRewriter sourceSet) {
sourceSet.register("RegistryEvents", RegistryEvents.class, new RegistryEventsRewriter());
}
public static void bootstrapServer(PatternSourceSetRewriter sourceSet) {
sourceSet.register("RegistryDefinitions", Types.PAPER_REGISTRIES, new PaperRegistriesRewriter());
}
@@ -8,11 +8,8 @@ import io.papermc.paper.dialog.Dialog;
import io.papermc.paper.entity.poi.PoiType;
import io.papermc.paper.entity.poi.PoiTypes;
import io.papermc.paper.registry.data.BannerPatternRegistryEntry;
import io.papermc.paper.registry.data.CatSoundVariantRegistryEntry;
import io.papermc.paper.registry.data.CatTypeRegistryEntry;
import io.papermc.paper.registry.data.ChickenSoundVariantRegistryEntry;
import io.papermc.paper.registry.data.ChickenVariantRegistryEntry;
import io.papermc.paper.registry.data.CowSoundVariantRegistryEntry;
import io.papermc.paper.registry.data.CowVariantRegistryEntry;
import io.papermc.paper.registry.data.DamageTypeRegistryEntry;
import io.papermc.paper.registry.data.DecoratedPotPatternRegistryEntry;
@@ -22,13 +19,11 @@ import io.papermc.paper.registry.data.GameEventRegistryEntry;
import io.papermc.paper.registry.data.InstrumentRegistryEntry;
import io.papermc.paper.registry.data.JukeboxSongRegistryEntry;
import io.papermc.paper.registry.data.PaintingVariantRegistryEntry;
import io.papermc.paper.registry.data.PigSoundVariantRegistryEntry;
import io.papermc.paper.registry.data.PigVariantRegistryEntry;
import io.papermc.paper.registry.data.SoundEventRegistryEntry;
import io.papermc.paper.registry.data.SulfurCubeArchetypeRegistryEntry;
import io.papermc.paper.registry.data.TrimMaterialRegistryEntry;
import io.papermc.paper.registry.data.TrimPatternRegistryEntry;
import io.papermc.paper.registry.data.WolfSoundVariantRegistryEntry;
import io.papermc.paper.registry.data.WolfVariantRegistryEntry;
import io.papermc.paper.registry.data.ZombieNautilusVariantRegistryEntry;
import io.papermc.paper.registry.data.dialog.DialogRegistryEntry;
@@ -180,7 +175,7 @@ public final class RegistryEntries {
entry(Registries.TRIM_PATTERN, TrimPatterns.class, TrimPattern.class).writableApiRegistryBuilder(TrimPatternRegistryEntry.Builder.class, "PaperTrimPatternRegistryEntry.PaperBuilder").allowDirect().delayed(),
entry(Registries.DAMAGE_TYPE, DamageTypes.class, DamageType.class).writableApiRegistryBuilder(DamageTypeRegistryEntry.Builder.class, "PaperDamageTypeRegistryEntry.PaperBuilder").delayed(),
entry(Registries.WOLF_VARIANT, WolfVariants.class, Wolf.Variant.class).writableApiRegistryBuilder(WolfVariantRegistryEntry.Builder.class, "PaperWolfVariantRegistryEntry.PaperBuilder").delayed(),
entry(Registries.WOLF_SOUND_VARIANT, WolfSoundVariants.class, Wolf.SoundVariant.class).writableApiRegistryBuilder(WolfSoundVariantRegistryEntry.Builder.class, "PaperWolfSoundVariantRegistryEntry.PaperBuilder"),
entry(Registries.WOLF_SOUND_VARIANT, WolfSoundVariants.class, Wolf.SoundVariant.class),
entry(Registries.ENCHANTMENT, Enchantments.class, Enchantment.class).writableApiRegistryBuilder(EnchantmentRegistryEntry.Builder.class, "PaperEnchantmentRegistryEntry.PaperBuilder").serializationUpdater("ENCHANTMENT_RENAME").delayed(),
entry(Registries.JUKEBOX_SONG, JukeboxSongs.class, JukeboxSong.class).writableApiRegistryBuilder(JukeboxSongRegistryEntry.Builder.class, "PaperJukeboxSongRegistryEntry.PaperBuilder").delayed(),
entry(Registries.BANNER_PATTERN, BannerPatterns.class, PatternType.class).allowDirect().writableApiRegistryBuilder(BannerPatternRegistryEntry.Builder.class, "PaperBannerPatternRegistryEntry.PaperBuilder").delayed(),
@@ -188,14 +183,14 @@ public final class RegistryEntries {
entry(Registries.PAINTING_VARIANT, PaintingVariants.class, Art.class).writableApiRegistryBuilder(PaintingVariantRegistryEntry.Builder.class, "PaperPaintingVariantRegistryEntry.PaperBuilder").apiRegistryField("ART").delayed(),
entry(Registries.INSTRUMENT, Instruments.class, MusicInstrument.class).allowDirect().writableApiRegistryBuilder(InstrumentRegistryEntry.Builder.class, "PaperInstrumentRegistryEntry.PaperBuilder").delayed(),
entry(Registries.CAT_VARIANT, CatVariants.class, Cat.Type.class).writableApiRegistryBuilder(CatTypeRegistryEntry.Builder.class, "PaperCatTypeRegistryEntry.PaperBuilder").delayed(),
entry(Registries.CAT_SOUND_VARIANT, CatSoundVariants.class, Cat.SoundVariant.class).writableApiRegistryBuilder(CatSoundVariantRegistryEntry.Builder.class, "PaperCatSoundVariantRegistryEntry.PaperBuilder"),
entry(Registries.CAT_SOUND_VARIANT, CatSoundVariants.class, Cat.SoundVariant.class),
entry(Registries.FROG_VARIANT, FrogVariants.class, Frog.Variant.class).writableApiRegistryBuilder(FrogVariantRegistryEntry.Builder.class, "PaperFrogVariantRegistryEntry.PaperBuilder").delayed(),
entry(Registries.CHICKEN_VARIANT, ChickenVariants.class, Chicken.Variant.class).writableApiRegistryBuilder(ChickenVariantRegistryEntry.Builder.class, "PaperChickenVariantRegistryEntry.PaperBuilder"),
entry(Registries.CHICKEN_SOUND_VARIANT, ChickenSoundVariants.class, Chicken.SoundVariant.class).writableApiRegistryBuilder(ChickenSoundVariantRegistryEntry.Builder.class, "PaperChickenSoundVariantRegistryEntry.PaperBuilder"),
entry(Registries.CHICKEN_SOUND_VARIANT, ChickenSoundVariants.class, Chicken.SoundVariant.class),
entry(Registries.COW_VARIANT, CowVariants.class, Cow.Variant.class).writableApiRegistryBuilder(CowVariantRegistryEntry.Builder.class, "PaperCowVariantRegistryEntry.PaperBuilder"),
entry(Registries.COW_SOUND_VARIANT, CowSoundVariants.class, Cow.SoundVariant.class).writableApiRegistryBuilder(CowSoundVariantRegistryEntry.Builder.class, "PaperCowSoundVariantRegistryEntry.PaperBuilder"),
entry(Registries.COW_SOUND_VARIANT, CowSoundVariants.class, Cow.SoundVariant.class),
entry(Registries.PIG_VARIANT, PigVariants.class, Pig.Variant.class).writableApiRegistryBuilder(PigVariantRegistryEntry.Builder.class, "PaperPigVariantRegistryEntry.PaperBuilder"),
entry(Registries.PIG_SOUND_VARIANT, PigSoundVariants.class, Pig.SoundVariant.class).writableApiRegistryBuilder(PigSoundVariantRegistryEntry.Builder.class, "PaperPigSoundVariantRegistryEntry.PaperBuilder"),
entry(Registries.PIG_SOUND_VARIANT, PigSoundVariants.class, Pig.SoundVariant.class),
entry(Registries.ZOMBIE_NAUTILUS_VARIANT, ZombieNautilusVariants.class, ZombieNautilus.Variant.class).writableApiRegistryBuilder(ZombieNautilusVariantRegistryEntry.Builder.class, "PaperZombieNautilusVariantRegistryEntry.PaperBuilder"),
entry(Registries.SULFUR_CUBE_ARCHETYPE, SulfurCubeArchetypes.class, SulfurCube.Archetype.class).writableApiRegistryBuilder(SulfurCubeArchetypeRegistryEntry.Builder.class, "PaperSulfurCubeArchetypeRegistryEntry.PaperBuilder"),
entry(Registries.DIALOG, Dialogs.class, Dialog.class, "Paper").allowDirect().writableApiRegistryBuilder(DialogRegistryEntry.Builder.class, "PaperDialogRegistryEntry.PaperBuilder")
@@ -16,9 +16,9 @@ public class PaperFeatureFlagMapping extends SearchReplaceRewriter {
while (flagIterator.hasNext()) {
Identifier name = flagIterator.next();
String fieldName = Formatting.formatKeyAsField(name.getPath());
String keyedName = Formatting.formatKeyAsField(name.getPath());
builder.append(metadata.indent());
builder.append("%s.%s, %s.%s".formatted(FeatureFlag.class.getSimpleName(), fieldName, FeatureFlags.class.getSimpleName(), fieldName));
builder.append("%s.%s, %s.%s".formatted(FeatureFlag.class.getSimpleName(), keyedName, FeatureFlags.class.getSimpleName(), keyedName));
if (flagIterator.hasNext()) {
builder.append(',');
}
@@ -4,7 +4,6 @@ import com.google.common.base.CaseFormat;
import io.papermc.generator.registry.RegistryEntries;
import io.papermc.generator.registry.RegistryEntry;
import io.papermc.generator.rewriter.types.Types;
import io.papermc.paper.registry.RegistryElement;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.typewriter.ClassNamed;
import io.papermc.typewriter.replace.SearchMetadata;
@@ -12,6 +11,7 @@ import io.papermc.typewriter.replace.SearchReplaceRewriter;
import java.lang.constant.ConstantDescs;
import java.util.stream.Stream;
import net.minecraft.core.registries.Registries;
import org.bukkit.Keyed;
import org.bukkit.Registry;
public class PaperRegistriesRewriter extends SearchReplaceRewriter {
@@ -57,11 +57,7 @@ public class PaperRegistriesRewriter extends SearchReplaceRewriter {
case MODIFIABLE -> builder.append(".modifiable(");
case NONE -> builder.append(".create(");
}
// the builder impl is always nested in the base entry class; reference the base entry constructor first, then the builder constructor
ClassNamed builderImpl = this.classNamedView.findFirst(entry.apiRegistryBuilderImpl()).resolve(this.classResolver);
builder.append(this.importCollector.getShortName(builderImpl.topLevel())).append("::new");
builder.append(", ");
builder.append(builderImpl.dottedNestedName()).append("::new");
builder.append(this.importCollector.getShortName(this.classNamedView.findFirst(entry.apiRegistryBuilderImpl()).resolve(this.classResolver))).append("::new");
if (entry.modificationApiSupport() == RegistryEntry.RegistryModificationApiSupport.NONE) {
builder.append(", ");
builder.append(Types.REGISTRY_MODIFICATION_API_SUPPORT.dottedNestedName()).append(".NONE");
@@ -109,7 +105,7 @@ public class PaperRegistriesRewriter extends SearchReplaceRewriter {
private ClassNamed getImplClassName(RegistryEntry<?> entry) {
try (Stream<ClassNamed> stream = this.classNamedView.find(entry.implClass())) {
return stream.map(klass -> klass.resolve(this.classResolver))
.filter(klass -> RegistryElement.class.isAssignableFrom(klass.knownClass()))
.filter(klass -> Keyed.class.isAssignableFrom(klass.knownClass())) // todo check handleable/holderable once keyed is gone
.findFirst().orElseThrow();
}
}
@@ -0,0 +1,32 @@
package io.papermc.generator.rewriter.types.registry;
import io.papermc.generator.registry.RegistryEntries;
import io.papermc.generator.registry.RegistryEntry;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.event.RegistryEventProvider;
import io.papermc.typewriter.replace.SearchMetadata;
import io.papermc.typewriter.replace.SearchReplaceRewriter;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
public class RegistryEventsRewriter extends SearchReplaceRewriter {
@Override
public void insert(SearchMetadata metadata, StringBuilder builder) {
RegistryEntries.forEach(entry -> {
if (entry.apiRegistryBuilder() != null && entry.modificationApiSupport() != RegistryEntry.RegistryModificationApiSupport.NONE) {
builder.append(metadata.indent());
builder.append("%s %s %s ".formatted(PUBLIC, STATIC, FINAL));
builder.append(RegistryEventProvider.class.getSimpleName());
builder.append("<").append(this.importCollector.getShortName(entry.apiClass())).append(", ").append(this.importCollector.getShortName(entry.apiRegistryBuilder())).append('>');
builder.append(' ');
builder.append(entry.registryKeyField());
builder.append(" = ");
builder.append("create(").append(RegistryKey.class.getSimpleName()).append('.').append(entry.registryKeyField()).append(");");
builder.append('\n');
}
});
}
}
@@ -23,9 +23,9 @@ public class CraftPotionUtilRewriter extends SearchReplaceRewriter {
BuiltInRegistries.POTION.keySet().stream()
.filter(key -> BuiltInRegistries.POTION.containsKey(key.withPath(path -> this.statePrefix + "_" + path)))
.sorted(Formatting.alphabeticKeyOrder(Identifier::getPath)).forEach(key -> {
String fieldName = Formatting.formatKeyAsField(key.getPath());
String keyedName = Formatting.formatKeyAsField(key.getPath());
builder.append(metadata.indent());
builder.append(".put(%s.%s, %s.%s_%s)".formatted(PotionType.class.getSimpleName(), fieldName, PotionType.class.getSimpleName(), upperStatePrefix, fieldName));
builder.append(".put(%s.%s, %s.%s_%s)".formatted(PotionType.class.getSimpleName(), keyedName, PotionType.class.getSimpleName(), upperStatePrefix, keyedName));
builder.append('\n');
});
}
@@ -18,7 +18,7 @@ public class MapPaletteRewriter extends SearchReplaceRewriter {
int count = 0;
for (@Nullable MapColor mapColor : MapColor.MATERIAL_COLORS) {
if (mapColor == null) {
break;
continue;
}
for (MapColor.Brightness brightness : MapColor.Brightness.values()) {
@@ -102,8 +102,8 @@ public class MemoryKeyRewriter extends RegistryFieldRewriter<MemoryModuleType<?>
@Override
protected String rewriteFieldName(Holder.Reference<MemoryModuleType<?>> reference) {
String constantName = super.rewriteFieldName(reference);
return FIELD_RENAMES.getOrDefault(constantName, constantName);
String keyedName = super.rewriteFieldName(reference);
return FIELD_RENAMES.getOrDefault(keyedName, keyedName);
}
@Override
@@ -81,11 +81,11 @@ public class StatisticRewriter {
@Override
protected EnumValue.Builder rewriteEnumValue(Holder.Reference<Identifier> reference) {
String fieldName = Formatting.formatKeyAsField(reference.key().identifier().getPath());
String keyedName = Formatting.formatKeyAsField(reference.key().identifier().getPath());
return super.rewriteEnumValue(reference)
.rename(name -> FIELD_RENAMES.getOrDefault(name, name))
.argument("%s.%s".formatted(Stats.class.getSimpleName(), INTERNAL_FIELD_RENAMES.getOrDefault(fieldName, fieldName)));
.argument("%s.%s".formatted(Stats.class.getSimpleName(), INTERNAL_FIELD_RENAMES.getOrDefault(keyedName, keyedName)));
}
}
@@ -29,11 +29,11 @@ import static javax.lang.model.element.Modifier.PRIVATE;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
public class GeneratedTagKeyType<T> extends SimpleGenerator {
public class GeneratedTagKeyType extends SimpleGenerator {
private final RegistryEntry<T> entry;
private final RegistryEntry<?> entry;
public GeneratedTagKeyType(RegistryEntry<T> entry, String packageName) {
public GeneratedTagKeyType(RegistryEntry<?> entry, String packageName) {
super(entry.keyClassName().concat("TagKeys"), packageName);
this.entry = entry;
}
@@ -161,6 +161,17 @@ public final class PaperAdventure {
return asVanilla(key);
}
public static Holder<SoundEvent> resolveSound(final Key key) {
Identifier id = asVanilla(key);
Optional<Holder.Reference<SoundEvent>> vanilla = BuiltInRegistries.SOUND_EVENT.get(id);
if (vanilla.isPresent()) {
return vanilla.get();
}
// sound is not known so not in the registry but might be used by the client with a resource pack
return Holder.direct(SoundEvent.createVariableRangeEvent(id));
}
// Component
public static @NotNull Component asAdventure(final net.minecraft.network.chat.@Nullable Component component) {
@@ -6,7 +6,7 @@ import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.block.entity.DecoratedPotPattern;
import org.bukkit.craftbukkit.CraftRegistry;
public class PaperPotPatternType extends HolderableBase<net.minecraft.world.level.block.entity.DecoratedPotPattern, PotPatternType> implements PotPatternType {
public class PaperPotPatternType extends HolderableBase<net.minecraft.world.level.block.entity.DecoratedPotPattern> implements PotPatternType {
public PaperPotPatternType(final Holder<DecoratedPotPattern> holder) {
super(holder);
@@ -1,43 +0,0 @@
package io.papermc.paper.datacomponent;
import java.util.function.Function;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.util.NullOps;
import net.minecraft.util.Unit;
import org.bukkit.craftbukkit.CraftRegistry;
public record DataComponentAdapter<NMS, API>(
Function<API, NMS> apiToVanilla,
Function<NMS, API> vanillaToApi,
boolean codecValidation
) {
static final Function<Void, Unit> API_TO_UNIT_CONVERTER = _ -> Unit.INSTANCE;
static final Function API_TO_UNIMPLEMENTED_CONVERTER = _ -> {
throw new UnsupportedOperationException("Cannot convert an API value to an unimplemented type");
};
public boolean isValued() {
return this.apiToVanilla != API_TO_UNIT_CONVERTER;
}
public boolean isUnimplemented() {
return this.apiToVanilla == API_TO_UNIMPLEMENTED_CONVERTER;
}
public NMS toVanilla(final API value, final Holder<? extends DataComponentType<NMS>> type) {
final NMS nms = this.apiToVanilla.apply(value);
if (this.codecValidation && !type.value().isTransient()) {
type.value().codecOrThrow().encodeStart(CraftRegistry.getMinecraftRegistry().createSerializationContext(NullOps.INSTANCE), nms).ifError(error -> {
throw new IllegalArgumentException("Failed to encode data component %s (%s)".formatted(type.unwrapKey().orElseThrow(), error.message()));
});
}
return nms;
}
public API fromVanilla(final NMS value) {
return this.vanillaToApi.apply(value);
}
}
@@ -1,269 +0,0 @@
package io.papermc.paper.datacomponent;
import io.papermc.paper.adventure.PaperAdventure;
import io.papermc.paper.block.pot.PaperPotPatternType;
import io.papermc.paper.datacomponent.item.PaperAttackRange;
import io.papermc.paper.datacomponent.item.PaperBannerPatternLayers;
import io.papermc.paper.datacomponent.item.PaperBlockItemDataProperties;
import io.papermc.paper.datacomponent.item.PaperBlocksAttacks;
import io.papermc.paper.datacomponent.item.PaperBundleContents;
import io.papermc.paper.datacomponent.item.PaperChargedProjectiles;
import io.papermc.paper.datacomponent.item.PaperConsumable;
import io.papermc.paper.datacomponent.item.PaperCustomModelData;
import io.papermc.paper.datacomponent.item.PaperDamageResistant;
import io.papermc.paper.datacomponent.item.PaperDeathProtection;
import io.papermc.paper.datacomponent.item.PaperDyedItemColor;
import io.papermc.paper.datacomponent.item.PaperEnchantable;
import io.papermc.paper.datacomponent.item.PaperEquippable;
import io.papermc.paper.datacomponent.item.PaperFireworks;
import io.papermc.paper.datacomponent.item.PaperFoodProperties;
import io.papermc.paper.datacomponent.item.PaperItemAdventurePredicate;
import io.papermc.paper.datacomponent.item.PaperItemArmorTrim;
import io.papermc.paper.datacomponent.item.PaperItemAttributeModifiers;
import io.papermc.paper.datacomponent.item.PaperItemContainerContents;
import io.papermc.paper.datacomponent.item.PaperItemEnchantments;
import io.papermc.paper.datacomponent.item.PaperItemLore;
import io.papermc.paper.datacomponent.item.PaperItemTool;
import io.papermc.paper.datacomponent.item.PaperJukeboxPlayable;
import io.papermc.paper.datacomponent.item.PaperKineticWeapon;
import io.papermc.paper.datacomponent.item.PaperLodestoneTracker;
import io.papermc.paper.datacomponent.item.PaperMapDecorations;
import io.papermc.paper.datacomponent.item.PaperMapId;
import io.papermc.paper.datacomponent.item.PaperMobVisibility;
import io.papermc.paper.datacomponent.item.PaperOminousBottleAmplifier;
import io.papermc.paper.datacomponent.item.PaperPiercingWeapon;
import io.papermc.paper.datacomponent.item.PaperPotDecorations;
import io.papermc.paper.datacomponent.item.PaperPotionContents;
import io.papermc.paper.datacomponent.item.PaperRepairable;
import io.papermc.paper.datacomponent.item.PaperResolvableProfile;
import io.papermc.paper.datacomponent.item.PaperSeededContainerLoot;
import io.papermc.paper.datacomponent.item.PaperSignText;
import io.papermc.paper.datacomponent.item.PaperSulfurCubeContent;
import io.papermc.paper.datacomponent.item.PaperSuspiciousStewEffects;
import io.papermc.paper.datacomponent.item.PaperSwingAnimation;
import io.papermc.paper.datacomponent.item.PaperTooltipDisplay;
import io.papermc.paper.datacomponent.item.PaperUseCooldown;
import io.papermc.paper.datacomponent.item.PaperUseEffects;
import io.papermc.paper.datacomponent.item.PaperUseRemainder;
import io.papermc.paper.datacomponent.item.PaperVillagerFood;
import io.papermc.paper.datacomponent.item.PaperWeapon;
import io.papermc.paper.datacomponent.item.PaperWritableBookContent;
import io.papermc.paper.datacomponent.item.PaperWrittenBookContent;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.util.Conversions;
import io.papermc.paper.registry.set.PaperRegistrySets;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.util.Unit;
import net.minecraft.world.item.Rarity;
import net.minecraft.world.item.component.InstrumentComponent;
import net.minecraft.world.item.component.MapPostProcessing;
import org.bukkit.DyeColor;
import org.bukkit.craftbukkit.CraftArt;
import org.bukkit.craftbukkit.CraftMusicInstrument;
import org.bukkit.craftbukkit.CraftSound;
import org.bukkit.craftbukkit.damage.CraftDamageType;
import org.bukkit.craftbukkit.entity.CraftCat;
import org.bukkit.craftbukkit.entity.CraftChicken;
import org.bukkit.craftbukkit.entity.CraftCow;
import org.bukkit.craftbukkit.entity.CraftFrog;
import org.bukkit.craftbukkit.entity.CraftPig;
import org.bukkit.craftbukkit.entity.CraftVillager;
import org.bukkit.craftbukkit.entity.CraftWolf;
import org.bukkit.craftbukkit.entity.CraftZombieNautilus;
import org.bukkit.craftbukkit.inventory.CraftMetaFirework;
import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial;
import org.bukkit.craftbukkit.util.Handleable;
import org.bukkit.entity.Axolotl;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Llama;
import org.bukkit.entity.MushroomCow;
import org.bukkit.entity.Parrot;
import org.bukkit.entity.Rabbit;
import org.bukkit.entity.Salmon;
import org.bukkit.entity.TropicalFish;
import org.bukkit.inventory.ItemRarity;
import static io.papermc.paper.util.MCUtil.transformUnmodifiable;
public final class DataComponentAdapters {
static final Function<Unit, Void> UNIT_TO_API_CONVERTER = _ -> {
throw new UnsupportedOperationException("Cannot convert the Unit type to an API value");
};
static final Function UNIMPLEMENTED_TO_API_CONVERTER = _ -> {
throw new UnsupportedOperationException("Cannot convert the an unimplemented type to an API value");
};
static final Map<ResourceKey<DataComponentType<?>>, DataComponentAdapter<?, ?>> ADAPTERS = new HashMap<>();
public static void bootstrap() {
registerIdentity(DataComponents.MAX_STACK_SIZE);
registerIdentity(DataComponents.MAX_DAMAGE);
registerIdentity(DataComponents.DAMAGE);
registerUntyped(DataComponents.UNBREAKABLE);
register(DataComponents.USE_EFFECTS, PaperUseEffects::new);
register(DataComponents.CUSTOM_NAME, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
registerIdentity(DataComponents.MINIMUM_ATTACK_CHARGE);
register(DataComponents.DAMAGE_TYPE, CraftDamageType::minecraftHolderToBukkit, CraftDamageType::bukkitToMinecraftHolder);
register(DataComponents.ITEM_NAME, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
register(DataComponents.ITEM_MODEL, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
register(DataComponents.LORE, PaperItemLore::new);
register(DataComponents.RARITY, nms -> ItemRarity.valueOf(nms.name()), api -> Rarity.valueOf(api.name()));
register(DataComponents.ENCHANTMENTS, PaperItemEnchantments::new);
register(DataComponents.CAN_PLACE_ON, PaperItemAdventurePredicate::new);
register(DataComponents.CAN_BREAK, PaperItemAdventurePredicate::new);
register(DataComponents.ATTRIBUTE_MODIFIERS, PaperItemAttributeModifiers::new);
register(DataComponents.CUSTOM_MODEL_DATA, PaperCustomModelData::new);
register(DataComponents.TOOLTIP_DISPLAY, PaperTooltipDisplay::new);
registerIdentity(DataComponents.REPAIR_COST);
// registerUntyped(DataComponents.CREATIVE_SLOT_LOCK);
registerIdentity(DataComponents.ENCHANTMENT_GLINT_OVERRIDE);
registerUntyped(DataComponents.INTANGIBLE_PROJECTILE);
register(DataComponents.FOOD, PaperFoodProperties::new);
register(DataComponents.CONSUMABLE, PaperConsumable::new);
register(DataComponents.USE_REMAINDER, PaperUseRemainder::new);
register(DataComponents.USE_COOLDOWN, PaperUseCooldown::new);
register(DataComponents.DAMAGE_RESISTANT, PaperDamageResistant::new);
register(DataComponents.TOOL, PaperItemTool::new);
register(DataComponents.WEAPON, PaperWeapon::new);
register(DataComponents.ATTACK_RANGE, PaperAttackRange::new);
register(DataComponents.ENCHANTABLE, PaperEnchantable::new);
register(DataComponents.EQUIPPABLE, PaperEquippable::new);
register(DataComponents.REPAIRABLE, PaperRepairable::new);
registerUntyped(DataComponents.GLIDER);
register(DataComponents.TOOLTIP_STYLE, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
register(DataComponents.DEATH_PROTECTION, PaperDeathProtection::new);
register(DataComponents.STORED_ENCHANTMENTS, PaperItemEnchantments::new);
register(DataComponents.DYE, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
register(DataComponents.DYED_COLOR, PaperDyedItemColor::new);
register(DataComponents.MAP_ID, PaperMapId::new);
register(DataComponents.MAP_DECORATIONS, PaperMapDecorations::new);
register(DataComponents.MAP_POST_PROCESSING, nms -> io.papermc.paper.item.MapPostProcessing.valueOf(nms.name()), api -> MapPostProcessing.valueOf(api.name()));
register(DataComponents.CHARGED_PROJECTILES, PaperChargedProjectiles::new);
register(DataComponents.BUNDLE_CONTENTS, PaperBundleContents::new);
register(DataComponents.POTION_CONTENTS, PaperPotionContents::new);
registerIdentity(DataComponents.POTION_DURATION_SCALE);
register(DataComponents.SUSPICIOUS_STEW_EFFECTS, PaperSuspiciousStewEffects::new);
register(DataComponents.WRITTEN_BOOK_CONTENT, PaperWrittenBookContent::new);
register(DataComponents.WRITABLE_BOOK_CONTENT, PaperWritableBookContent::new);
register(DataComponents.TRIM, PaperItemArmorTrim::new);
// debug stick state
// entity data
// bucket entity data
// block entity data
register(DataComponents.INSTRUMENT, nms -> CraftMusicInstrument.minecraftHolderToBukkit(nms.instrument()), api -> new InstrumentComponent(CraftMusicInstrument.bukkitToMinecraftHolder(api)));
register(DataComponents.PROVIDES_TRIM_MATERIAL, CraftTrimMaterial::minecraftHolderToBukkit, CraftTrimMaterial::bukkitToMinecraftHolder);
register(DataComponents.OMINOUS_BOTTLE_AMPLIFIER, PaperOminousBottleAmplifier::new);
register(DataComponents.JUKEBOX_PLAYABLE, PaperJukeboxPlayable::new);
register(DataComponents.PROVIDES_BANNER_PATTERNS, set -> PaperRegistrySets.convertToApi(RegistryKey.BANNER_PATTERN, set), set -> PaperRegistrySets.convertToNms(Registries.BANNER_PATTERN, Conversions.global().lookup(), set));
register(
DataComponents.RECIPES,
nms -> transformUnmodifiable(nms, PaperAdventure::asAdventureKey),
api -> transformUnmodifiable(api, key -> PaperAdventure.asVanilla(Registries.RECIPE, key))
);
register(DataComponents.LODESTONE_TRACKER, PaperLodestoneTracker::new);
register(DataComponents.FIREWORK_EXPLOSION, CraftMetaFirework::getEffect, CraftMetaFirework::getExplosion);
register(DataComponents.FIREWORKS, PaperFireworks::new);
register(DataComponents.PROFILE, PaperResolvableProfile::new);
register(DataComponents.NOTE_BLOCK_SOUND, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
register(DataComponents.BANNER_PATTERNS, PaperBannerPatternLayers::new);
register(DataComponents.BASE_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
register(DataComponents.POT_DECORATIONS, PaperPotDecorations::new);
register(DataComponents.CONTAINER, PaperItemContainerContents::new);
register(DataComponents.BLOCK_STATE, PaperBlockItemDataProperties::new);
// bees
register(DataComponents.SULFUR_CUBE_CONTENT, PaperSulfurCubeContent::new);
// register(DataComponents.LOCK, PaperLockCode::new);
register(DataComponents.CONTAINER_LOOT, PaperSeededContainerLoot::new);
register(DataComponents.BREAK_SOUND, CraftSound::minecraftHolderToBukkit, CraftSound::bukkitToMinecraftHolder);
register(DataComponents.BLOCKS_ATTACKS, PaperBlocksAttacks::new);
register(DataComponents.PIERCING_WEAPON, PaperPiercingWeapon::new);
register(DataComponents.KINETIC_WEAPON, PaperKineticWeapon::new);
register(DataComponents.ATTACK_ANIMATION, PaperSwingAnimation::new);
register(DataComponents.INTERACT_ANIMATION, PaperSwingAnimation::new);
// registerIdentity(DataComponents.ADDITIONAL_TRADE_COST);
// block transformer
register(DataComponents.VILLAGER_FOOD, PaperVillagerFood::new);
register(DataComponents.MOB_VISIBILITY, PaperMobVisibility::new);
register(DataComponents.VILLAGER_VARIANT, CraftVillager.CraftType::minecraftHolderToBukkit, CraftVillager.CraftType::bukkitToMinecraftHolder);
register(DataComponents.WOLF_VARIANT, CraftWolf.CraftVariant::minecraftHolderToBukkit, CraftWolf.CraftVariant::bukkitToMinecraftHolder);
register(DataComponents.WOLF_COLLAR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
register(DataComponents.WOLF_SOUND_VARIANT, CraftWolf.CraftSoundVariant::minecraftHolderToBukkit, CraftWolf.CraftSoundVariant::bukkitToMinecraftHolder);
register(DataComponents.FOX_VARIANT, nms -> org.bukkit.entity.Fox.Type.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.fox.Fox.Variant.byId(api.ordinal()));
register(DataComponents.SALMON_SIZE, nms -> Salmon.Variant.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.fish.Salmon.Variant.values()[api.ordinal()]);
register(DataComponents.PARROT_VARIANT, nms -> Parrot.Variant.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.parrot.Parrot.Variant.byId(api.ordinal()));
register(DataComponents.TROPICAL_FISH_PATTERN, nms -> TropicalFish.Pattern.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.fish.TropicalFish.Pattern.values()[api.ordinal()]);
register(DataComponents.TROPICAL_FISH_BASE_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
register(DataComponents.TROPICAL_FISH_PATTERN_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
register(DataComponents.MOOSHROOM_VARIANT, nms -> MushroomCow.Variant.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.cow.MushroomCow.Variant.values()[api.ordinal()]);
register(DataComponents.RABBIT_VARIANT, nms -> Rabbit.Type.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.rabbit.Rabbit.Variant.values()[api.ordinal()]);
register(DataComponents.PIG_VARIANT, CraftPig.CraftVariant::minecraftHolderToBukkit, CraftPig.CraftVariant::bukkitToMinecraftHolder);
register(DataComponents.PIG_SOUND_VARIANT, CraftPig.CraftSoundVariant::minecraftHolderToBukkit, CraftPig.CraftSoundVariant::bukkitToMinecraftHolder);
register(DataComponents.COW_VARIANT, CraftCow.CraftVariant::minecraftHolderToBukkit, CraftCow.CraftVariant::bukkitToMinecraftHolder);
register(DataComponents.COW_SOUND_VARIANT, CraftCow.CraftSoundVariant::minecraftHolderToBukkit, CraftCow.CraftSoundVariant::bukkitToMinecraftHolder);
register(DataComponents.CHICKEN_VARIANT, CraftChicken.CraftVariant::minecraftHolderToBukkit, CraftChicken.CraftVariant::bukkitToMinecraftHolder);
register(DataComponents.CHICKEN_SOUND_VARIANT, CraftChicken.CraftSoundVariant::minecraftHolderToBukkit, CraftChicken.CraftSoundVariant::bukkitToMinecraftHolder);
register(DataComponents.FROG_VARIANT, CraftFrog.CraftVariant::minecraftHolderToBukkit, CraftFrog.CraftVariant::bukkitToMinecraftHolder);
register(DataComponents.ZOMBIE_NAUTILUS_VARIANT, CraftZombieNautilus.CraftVariant::minecraftHolderToBukkit, CraftZombieNautilus.CraftVariant::bukkitToMinecraftHolder);
register(DataComponents.HORSE_VARIANT, nms -> Horse.Color.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.equine.Variant.byId(api.ordinal()));
register(DataComponents.PAINTING_VARIANT, CraftArt::minecraftHolderToBukkit, CraftArt::bukkitToMinecraftHolder);
register(DataComponents.LLAMA_VARIANT, nms -> Llama.Color.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.equine.Llama.Variant.byId(api.ordinal()));
register(DataComponents.AXOLOTL_VARIANT, nms -> Axolotl.Variant.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.axolotl.Axolotl.Variant.byId(api.ordinal()));
register(DataComponents.CAT_VARIANT, CraftCat.CraftType::minecraftHolderToBukkit, CraftCat.CraftType::bukkitToMinecraftHolder);
register(DataComponents.CAT_SOUND_VARIANT, CraftCat.CraftSoundVariant::minecraftHolderToBukkit, CraftCat.CraftSoundVariant::bukkitToMinecraftHolder);
register(DataComponents.CAT_COLLAR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
register(DataComponents.SHEEP_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
register(DataComponents.SHULKER_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
register(DataComponents.PROVIDES_POTTERY_PATTERN, PaperPotPatternType::minecraftHolderToBukkit, PaperPotPatternType::bukkitToMinecraftHolder);
register(DataComponents.SIGN_TEXT_FRONT, PaperSignText::new);
register(DataComponents.SIGN_TEXT_BACK, PaperSignText::new);
registerUntyped(DataComponents.WAXED);
register(DataComponents.CUSHION_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
for (final ResourceKey<DataComponentType<?>> key : BuiltInRegistries.DATA_COMPONENT_TYPE.registryKeySet()) {
if (!ADAPTERS.containsKey(key)) {
registerUnimplemented(key);
}
}
}
private static <NMS> ResourceKey<DataComponentType<?>> getKey(final DataComponentType<NMS> type) {
return BuiltInRegistries.DATA_COMPONENT_TYPE.getResourceKey(type).orElseThrow();
}
public static void registerUntyped(final DataComponentType<Unit> type) {
registerInternal(getKey(type), UNIT_TO_API_CONVERTER, DataComponentAdapter.API_TO_UNIT_CONVERTER, false);
}
private static <COMMON> void registerIdentity(final DataComponentType<COMMON> type) {
registerInternal(getKey(type), Function.identity(), Function.identity(), true);
}
@SuppressWarnings("unchecked")
public static void registerUnimplemented(final ResourceKey<DataComponentType<?>> key) {
registerInternal(key, UNIMPLEMENTED_TO_API_CONVERTER, DataComponentAdapter.API_TO_UNIMPLEMENTED_CONVERTER, false);
}
private static <NMS, API extends Handleable<NMS>> void register(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi) {
registerInternal(getKey(type), vanillaToApi, Handleable::getHandle, false);
}
private static <NMS, API> void register(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla) {
registerInternal(getKey(type), vanillaToApi, apiToVanilla, false);
}
private static <NMS, API> void registerInternal(final ResourceKey<DataComponentType<?>> key, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla, final boolean codecValidation) {
if (ADAPTERS.containsKey(key)) {
throw new IllegalStateException("Duplicate adapter registration for " + key);
}
ADAPTERS.put(key, new DataComponentAdapter<>(apiToVanilla, vanillaToApi, codecValidation));
}
}
@@ -1,21 +1,237 @@
package io.papermc.paper.datacomponent;
import io.papermc.paper.adventure.PaperAdventure;
import io.papermc.paper.datacomponent.item.PaperAttackRange;
import io.papermc.paper.datacomponent.item.PaperBannerPatternLayers;
import io.papermc.paper.datacomponent.item.PaperBlockItemDataProperties;
import io.papermc.paper.datacomponent.item.PaperBlocksAttacks;
import io.papermc.paper.datacomponent.item.PaperBundleContents;
import io.papermc.paper.datacomponent.item.PaperChargedProjectiles;
import io.papermc.paper.datacomponent.item.PaperConsumable;
import io.papermc.paper.datacomponent.item.PaperCustomModelData;
import io.papermc.paper.datacomponent.item.PaperDamageResistant;
import io.papermc.paper.datacomponent.item.PaperDeathProtection;
import io.papermc.paper.datacomponent.item.PaperDyedItemColor;
import io.papermc.paper.datacomponent.item.PaperEnchantable;
import io.papermc.paper.datacomponent.item.PaperEquippable;
import io.papermc.paper.datacomponent.item.PaperFireworks;
import io.papermc.paper.datacomponent.item.PaperFoodProperties;
import io.papermc.paper.datacomponent.item.PaperItemAdventurePredicate;
import io.papermc.paper.datacomponent.item.PaperItemArmorTrim;
import io.papermc.paper.datacomponent.item.PaperItemAttributeModifiers;
import io.papermc.paper.datacomponent.item.PaperItemContainerContents;
import io.papermc.paper.datacomponent.item.PaperItemEnchantments;
import io.papermc.paper.datacomponent.item.PaperItemLore;
import io.papermc.paper.datacomponent.item.PaperItemTool;
import io.papermc.paper.datacomponent.item.PaperJukeboxPlayable;
import io.papermc.paper.datacomponent.item.PaperKineticWeapon;
import io.papermc.paper.datacomponent.item.PaperLodestoneTracker;
import io.papermc.paper.datacomponent.item.PaperMapDecorations;
import io.papermc.paper.datacomponent.item.PaperMapId;
import io.papermc.paper.datacomponent.item.PaperMobVisibility;
import io.papermc.paper.datacomponent.item.PaperOminousBottleAmplifier;
import io.papermc.paper.datacomponent.item.PaperPiercingWeapon;
import io.papermc.paper.datacomponent.item.PaperPotDecorations;
import io.papermc.paper.datacomponent.item.PaperPotionContents;
import io.papermc.paper.datacomponent.item.PaperRepairable;
import io.papermc.paper.datacomponent.item.PaperResolvableProfile;
import io.papermc.paper.datacomponent.item.PaperSeededContainerLoot;
import io.papermc.paper.datacomponent.item.PaperSignText;
import io.papermc.paper.datacomponent.item.PaperSulfurCubeContent;
import io.papermc.paper.datacomponent.item.PaperSuspiciousStewEffects;
import io.papermc.paper.datacomponent.item.PaperSwingAnimation;
import io.papermc.paper.datacomponent.item.PaperTooltipDisplay;
import io.papermc.paper.datacomponent.item.PaperUseCooldown;
import io.papermc.paper.datacomponent.item.PaperUseEffects;
import io.papermc.paper.datacomponent.item.PaperUseRemainder;
import io.papermc.paper.datacomponent.item.PaperVillagerFood;
import io.papermc.paper.datacomponent.item.PaperWeapon;
import io.papermc.paper.datacomponent.item.PaperWritableBookContent;
import io.papermc.paper.datacomponent.item.PaperWrittenBookContent;
import io.papermc.paper.item.MapPostProcessing;
import io.papermc.paper.registry.HolderableBase;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.util.Conversions;
import io.papermc.paper.registry.set.PaperRegistrySets;
import io.papermc.paper.registry.typed.PaperTypedDataAdapters;
import io.papermc.paper.registry.typed.PaperTypedDataCollector;
import io.papermc.paper.util.converter.Converter;
import io.papermc.paper.util.converter.Converters;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Function;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentGetter;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.item.Rarity;
import net.minecraft.world.item.component.InstrumentComponent;
import org.bukkit.DyeColor;
import org.bukkit.craftbukkit.CraftMusicInstrument;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.inventory.CraftMetaFirework;
import org.bukkit.entity.Axolotl;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Llama;
import org.bukkit.entity.MushroomCow;
import org.bukkit.entity.Parrot;
import org.bukkit.entity.Rabbit;
import org.bukkit.entity.Salmon;
import org.bukkit.entity.TropicalFish;
import org.bukkit.inventory.ItemRarity;
import org.jspecify.annotations.Nullable;
public abstract class PaperDataComponentType<T, NMS> extends HolderableBase<net.minecraft.core.component.DataComponentType<NMS>, DataComponentType> implements DataComponentType {
import static io.papermc.paper.util.converter.Converter.direct;
import static io.papermc.paper.util.converter.Converters.listOf;
import static io.papermc.paper.util.converter.Converters.registryElement;
import static io.papermc.paper.util.converter.Converters.sameName;
import static io.papermc.paper.util.converter.Converters.sameOrder;
import static io.papermc.paper.util.converter.Converters.wrapper;
static {
DataComponentAdapters.bootstrap();
public abstract class PaperDataComponentType<A, M> extends HolderableBase<net.minecraft.core.component.DataComponentType<M>> implements DataComponentType {
// this is a hack around generics limitations to prevent
// having to define generics on each register call as seen below, making collectors easier to read:
// collector.<T, A>register(...)
private static <M, A> void register(final PaperTypedDataCollector<net.minecraft.core.component.DataComponentType<?>> collector, final net.minecraft.core.component.DataComponentType<M> dataComponentType, final Function<M, A> vanillaToApi, final Function<A, M> apiToVanilla) {
collector.register(dataComponentType, vanillaToApi, apiToVanilla);
}
@SuppressWarnings("RedundantTypeArguments")
private static final PaperTypedDataAdapters<net.minecraft.core.component.DataComponentType<?>> ADAPTERS = PaperTypedDataAdapters.<net.minecraft.core.component.DataComponentType<?>, PaperTypedDataCollector<net.minecraft.core.component.DataComponentType<?>>>create(
BuiltInRegistries.DATA_COMPONENT_TYPE,
PaperTypedDataCollector::new,
collector -> {
final Converter<net.minecraft.world.item.DyeColor, DyeColor> dyeColor = direct(
color -> DyeColor.getByWoolData((byte) color.getId()), color -> net.minecraft.world.item.DyeColor.byId(color.getWoolData())
);
collector.dispatch(_ -> Converters.unvalued()).add(
DataComponents.UNBREAKABLE,
DataComponents.INTANGIBLE_PROJECTILE,
DataComponents.GLIDER,
DataComponents.WAXED
// DataComponents.CREATIVE_SLOT_LOCK
);
collector.dispatch(type -> Converter.identity(type.codec())).add(
DataComponents.MAX_STACK_SIZE,
DataComponents.MAX_DAMAGE,
DataComponents.DAMAGE,
DataComponents.POTION_DURATION_SCALE,
DataComponents.MINIMUM_ATTACK_CHARGE,
DataComponents.REPAIR_COST,
DataComponents.ENCHANTMENT_GLINT_OVERRIDE
// DataComponents.ADDITIONAL_TRADE_COST
);
collector.register(DataComponents.USE_EFFECTS, wrapper(PaperUseEffects::new));
register(collector, DataComponents.CUSTOM_NAME, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
collector.register(DataComponents.DAMAGE_TYPE, registryElement(Registries.DAMAGE_TYPE));
register(collector, DataComponents.ITEM_NAME, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
register(collector, DataComponents.ITEM_MODEL, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
collector.register(DataComponents.LORE, wrapper(PaperItemLore::new));
collector.register(DataComponents.RARITY, sameName(ItemRarity.class, Rarity.class));
collector.register(DataComponents.ENCHANTMENTS, wrapper(PaperItemEnchantments::of));
collector.register(DataComponents.CAN_PLACE_ON, wrapper(PaperItemAdventurePredicate::new));
collector.register(DataComponents.CAN_BREAK, wrapper(PaperItemAdventurePredicate::new));
collector.register(DataComponents.ATTRIBUTE_MODIFIERS, wrapper(PaperItemAttributeModifiers::new));
collector.register(DataComponents.CUSTOM_MODEL_DATA, wrapper(PaperCustomModelData::new));
collector.register(DataComponents.TOOLTIP_DISPLAY, wrapper(PaperTooltipDisplay::new));
collector.register(DataComponents.FOOD, wrapper(PaperFoodProperties::new));
collector.register(DataComponents.CONSUMABLE, wrapper(PaperConsumable::new));
collector.register(DataComponents.USE_REMAINDER, wrapper(PaperUseRemainder::new));
collector.register(DataComponents.USE_COOLDOWN, wrapper(PaperUseCooldown::new));
collector.register(DataComponents.DAMAGE_RESISTANT, wrapper(PaperDamageResistant::new));
collector.register(DataComponents.TOOL, wrapper(PaperItemTool::new));
collector.register(DataComponents.WEAPON, wrapper(PaperWeapon::new));
collector.register(DataComponents.ATTACK_RANGE, wrapper(PaperAttackRange::new));
collector.register(DataComponents.ENCHANTABLE, wrapper(PaperEnchantable::new));
collector.register(DataComponents.EQUIPPABLE, wrapper(PaperEquippable::new));
collector.register(DataComponents.REPAIRABLE, wrapper(PaperRepairable::new));
register(collector, DataComponents.TOOLTIP_STYLE, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
collector.register(DataComponents.DEATH_PROTECTION, wrapper(PaperDeathProtection::new));
collector.register(DataComponents.STORED_ENCHANTMENTS, wrapper(PaperItemEnchantments::of));
collector.register(DataComponents.DYE, dyeColor);
collector.register(DataComponents.DYED_COLOR, wrapper(PaperDyedItemColor::new));
collector.register(DataComponents.MAP_ID, wrapper(PaperMapId::new));
collector.register(DataComponents.MAP_DECORATIONS, wrapper(PaperMapDecorations::new));
collector.register(DataComponents.MAP_POST_PROCESSING, sameName(MapPostProcessing.class, net.minecraft.world.item.component.MapPostProcessing.class));
collector.register(DataComponents.CHARGED_PROJECTILES, wrapper(PaperChargedProjectiles::new));
collector.register(DataComponents.BUNDLE_CONTENTS, wrapper(PaperBundleContents::new));
collector.register(DataComponents.POTION_CONTENTS, wrapper(PaperPotionContents::new));
collector.register(DataComponents.SUSPICIOUS_STEW_EFFECTS, wrapper(PaperSuspiciousStewEffects::new));
collector.register(DataComponents.WRITTEN_BOOK_CONTENT, wrapper(PaperWrittenBookContent::new));
collector.register(DataComponents.WRITABLE_BOOK_CONTENT, wrapper(PaperWritableBookContent::new));
collector.register(DataComponents.TRIM, wrapper(PaperItemArmorTrim::new));
// debug stick state
// entity data
// bucket entity data
// block entity data
register(collector, DataComponents.INSTRUMENT, component -> CraftMusicInstrument.minecraftHolderToBukkit(component.instrument()), api -> new InstrumentComponent(CraftMusicInstrument.bukkitToMinecraftHolder(api)));
collector.register(DataComponents.PROVIDES_TRIM_MATERIAL, registryElement(Registries.TRIM_MATERIAL));
collector.register(DataComponents.OMINOUS_BOTTLE_AMPLIFIER, wrapper(PaperOminousBottleAmplifier::new));
collector.register(DataComponents.JUKEBOX_PLAYABLE, wrapper(PaperJukeboxPlayable::new));
register(collector, DataComponents.PROVIDES_BANNER_PATTERNS, set -> PaperRegistrySets.convertToApi(RegistryKey.BANNER_PATTERN, set), set -> PaperRegistrySets.convertToNms(Registries.BANNER_PATTERN, Conversions.global().lookup(), set));
collector.register(DataComponents.RECIPES, listOf(PaperAdventure::asAdventureKey, key -> PaperAdventure.asVanilla(Registries.RECIPE, key)));
collector.register(DataComponents.LODESTONE_TRACKER, wrapper(PaperLodestoneTracker::new));
collector.register(DataComponents.FIREWORK_EXPLOSION, CraftMetaFirework::getEffect, CraftMetaFirework::getExplosion);
collector.register(DataComponents.FIREWORKS, wrapper(PaperFireworks::new));
collector.register(DataComponents.PROFILE, wrapper(PaperResolvableProfile::new));
register(collector, DataComponents.NOTE_BLOCK_SOUND, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
collector.register(DataComponents.BANNER_PATTERNS, wrapper(PaperBannerPatternLayers::new));
collector.register(DataComponents.BASE_COLOR, dyeColor);
collector.register(DataComponents.POT_DECORATIONS, wrapper(PaperPotDecorations::new));
collector.register(DataComponents.CONTAINER, wrapper(PaperItemContainerContents::new));
collector.register(DataComponents.BLOCK_STATE, wrapper(PaperBlockItemDataProperties::new));
// bees
collector.register(DataComponents.SULFUR_CUBE_CONTENT, wrapper(PaperSulfurCubeContent::new));
// register(DataComponents.LOCK, wrapper(PaperLockCode::new));
collector.register(DataComponents.CONTAINER_LOOT, wrapper(PaperSeededContainerLoot::new));
collector.register(DataComponents.BREAK_SOUND, sound -> PaperAdventure.asAdventure(sound.value().location()), PaperAdventure::resolveSound);
collector.register(DataComponents.BLOCKS_ATTACKS, wrapper(PaperBlocksAttacks::new));
collector.register(DataComponents.PIERCING_WEAPON, wrapper(PaperPiercingWeapon::new));
collector.register(DataComponents.KINETIC_WEAPON, wrapper(PaperKineticWeapon::new));
collector.register(DataComponents.ATTACK_ANIMATION, wrapper(PaperSwingAnimation::new));
collector.register(DataComponents.INTERACT_ANIMATION, wrapper(PaperSwingAnimation::new));
// block transformer
collector.register(DataComponents.VILLAGER_FOOD, wrapper(PaperVillagerFood::new));
collector.register(DataComponents.MOB_VISIBILITY, wrapper(PaperMobVisibility::new));
collector.register(DataComponents.VILLAGER_VARIANT, registryElement(Registries.VILLAGER_TYPE));
collector.register(DataComponents.WOLF_VARIANT, registryElement(Registries.WOLF_VARIANT));
collector.register(DataComponents.WOLF_COLLAR, dyeColor);
collector.register(DataComponents.WOLF_SOUND_VARIANT, registryElement(Registries.WOLF_SOUND_VARIANT));
collector.register(DataComponents.FOX_VARIANT, sameOrder(org.bukkit.entity.Fox.Type.class, net.minecraft.world.entity.animal.fox.Fox.Variant.class));
collector.register(DataComponents.SALMON_SIZE, sameOrder(Salmon.Variant.class, net.minecraft.world.entity.animal.fish.Salmon.Variant.class));
collector.register(DataComponents.PARROT_VARIANT, sameOrder(Parrot.Variant.class, net.minecraft.world.entity.animal.parrot.Parrot.Variant.class));
collector.register(DataComponents.TROPICAL_FISH_PATTERN, sameOrder(TropicalFish.Pattern.class, net.minecraft.world.entity.animal.fish.TropicalFish.Pattern.class));
collector.register(DataComponents.TROPICAL_FISH_BASE_COLOR, dyeColor);
collector.register(DataComponents.TROPICAL_FISH_PATTERN_COLOR, dyeColor);
collector.register(DataComponents.MOOSHROOM_VARIANT, sameOrder(MushroomCow.Variant.class, net.minecraft.world.entity.animal.cow.MushroomCow.Variant.class));
collector.register(DataComponents.RABBIT_VARIANT, sameOrder(Rabbit.Type.class, net.minecraft.world.entity.animal.rabbit.Rabbit.Variant.class));
collector.register(DataComponents.PIG_VARIANT, registryElement(Registries.PIG_VARIANT));
collector.register(DataComponents.PIG_SOUND_VARIANT, registryElement(Registries.PIG_SOUND_VARIANT));
collector.register(DataComponents.COW_VARIANT, registryElement(Registries.COW_VARIANT));
collector.register(DataComponents.COW_SOUND_VARIANT, registryElement(Registries.COW_SOUND_VARIANT));
collector.register(DataComponents.CHICKEN_VARIANT, registryElement(Registries.CHICKEN_VARIANT));
collector.register(DataComponents.CHICKEN_SOUND_VARIANT, registryElement(Registries.CHICKEN_SOUND_VARIANT));
collector.register(DataComponents.FROG_VARIANT, registryElement(Registries.FROG_VARIANT));
collector.register(DataComponents.ZOMBIE_NAUTILUS_VARIANT, registryElement(Registries.ZOMBIE_NAUTILUS_VARIANT));
collector.register(DataComponents.HORSE_VARIANT, sameOrder(Horse.Color.class, net.minecraft.world.entity.animal.equine.Variant.class));
collector.register(DataComponents.PAINTING_VARIANT, registryElement(Registries.PAINTING_VARIANT));
collector.register(DataComponents.LLAMA_VARIANT, sameOrder(Llama.Color.class, net.minecraft.world.entity.animal.equine.Llama.Variant.class));
collector.register(DataComponents.AXOLOTL_VARIANT, sameOrder(Axolotl.Variant.class, net.minecraft.world.entity.animal.axolotl.Axolotl.Variant.class));
collector.register(DataComponents.CAT_VARIANT, registryElement(Registries.CAT_VARIANT));
collector.register(DataComponents.CAT_SOUND_VARIANT, registryElement(Registries.CAT_SOUND_VARIANT));
collector.register(DataComponents.CAT_COLLAR, dyeColor);
collector.register(DataComponents.SHEEP_COLOR, dyeColor);
collector.register(DataComponents.SHULKER_COLOR, dyeColor);
collector.register(DataComponents.PROVIDES_POTTERY_PATTERN, registryElement(Registries.DECORATED_POT_PATTERN));
collector.register(DataComponents.SIGN_TEXT_FRONT, wrapper(PaperSignText::new));
collector.register(DataComponents.SIGN_TEXT_BACK, wrapper(PaperSignText::new));
collector.register(DataComponents.CUSHION_COLOR, dyeColor);
}
);
public static <T> net.minecraft.core.component.DataComponentType<T> bukkitToMinecraft(final DataComponentType type) {
return CraftRegistry.bukkitToMinecraft(type);
}
@@ -24,28 +240,27 @@ public abstract class PaperDataComponentType<T, NMS> extends HolderableBase<net.
return CraftRegistry.minecraftToBukkit(type, Registries.DATA_COMPONENT_TYPE);
}
public static Set<DataComponentType> minecraftToBukkit(final Set<net.minecraft.core.component.DataComponentType<?>> nmsTypes) {
final Set<DataComponentType> types = new HashSet<>(nmsTypes.size());
for (final net.minecraft.core.component.DataComponentType<?> nmsType : nmsTypes) {
types.add(PaperDataComponentType.minecraftToBukkit(nmsType));
public static Set<DataComponentType> minecraftToBukkit(final Set<net.minecraft.core.component.DataComponentType<?>> types) {
final Set<DataComponentType> result = new HashSet<>(types.size());
for (final net.minecraft.core.component.DataComponentType<?> type : types) {
result.add(PaperDataComponentType.minecraftToBukkit(type));
}
return Collections.unmodifiableSet(types);
return Collections.unmodifiableSet(result);
}
public static <B, M> @Nullable B convertDataComponentValue(final DataComponentGetter getter, final PaperDataComponentType.ValuedImpl<B, M> type) {
final net.minecraft.core.component.DataComponentType<M> nms = bukkitToMinecraft(type);
final M nmsValue = getter.get(nms);
if (nmsValue == null) {
final M value = getter.get(bukkitToMinecraft(type));
if (value == null) {
return null;
}
return type.getAdapter().fromVanilla(nmsValue);
return type.getConverter().fromVanilla(value);
}
private final DataComponentAdapter<NMS, T> adapter;
private final Converter<M, A> converter;
private PaperDataComponentType(final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder, final DataComponentAdapter<NMS, T> adapter) {
private PaperDataComponentType(final Holder<net.minecraft.core.component.DataComponentType<M>> holder, final Converter<M, A> converter) {
super(holder);
this.adapter = adapter;
this.converter = converter;
}
@Override
@@ -53,52 +268,50 @@ public abstract class PaperDataComponentType<T, NMS> extends HolderableBase<net.
return !this.getHandle().isTransient();
}
public DataComponentAdapter<NMS, T> getAdapter() {
return this.adapter;
public Converter<M, A> getConverter() {
return this.converter;
}
@SuppressWarnings({"unchecked"})
public static <NMS> DataComponentType of(final Holder<?> holder) {
final DataComponentAdapter<NMS, ?> adapter = (DataComponentAdapter<NMS, ?>) DataComponentAdapters.ADAPTERS.get(holder.unwrapKey().orElseThrow());
if (adapter == null) {
throw new IllegalArgumentException("No adapter found for " + holder);
}
if (adapter.isUnimplemented()) {
return new Unimplemented<>((Holder<net.minecraft.core.component.DataComponentType<NMS>>) holder, adapter);
} else if (adapter.isValued()) {
return new ValuedImpl<>((Holder<net.minecraft.core.component.DataComponentType<NMS>>) holder, adapter);
@SuppressWarnings("unchecked")
public static <M> DataComponentType of(final Holder<?> holder) {
final Holder.Reference<net.minecraft.core.component.DataComponentType<M>> reference = (Holder.Reference<net.minecraft.core.component.DataComponentType<M>>) holder;
final Converter<M, ?> converter = PaperDataComponentType.ADAPTERS.get(reference.key());
if (converter == Converters.unimplemented()) {
return new Unimplemented<>(reference, converter);
} else if (converter == Converters.unvalued()) {
return new NonValuedImpl<>(reference, converter);
} else {
return new NonValuedImpl<>((Holder<net.minecraft.core.component.DataComponentType<NMS>>) holder, adapter);
return new ValuedImpl<>(reference, converter);
}
}
public static final class NonValuedImpl<T, NMS> extends PaperDataComponentType<T, NMS> implements NonValued {
public static final class NonValuedImpl<A, M> extends PaperDataComponentType<A, M> implements NonValued {
NonValuedImpl(
final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder,
final DataComponentAdapter<NMS, T> adapter
final Holder<net.minecraft.core.component.DataComponentType<M>> holder,
final Converter<M, A> adapter
) {
super(holder, adapter);
}
}
public static final class ValuedImpl<T, NMS> extends PaperDataComponentType<T, NMS> implements Valued<T> {
public static final class ValuedImpl<A, M> extends PaperDataComponentType<A, M> implements Valued<A> {
ValuedImpl(
final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder,
final DataComponentAdapter<NMS, T> adapter
final Holder<net.minecraft.core.component.DataComponentType<M>> holder,
final Converter<M, A> converter
) {
super(holder, adapter);
super(holder, converter);
}
}
public static final class Unimplemented<T, NMS> extends PaperDataComponentType<T, NMS> {
public static final class Unimplemented<A, M> extends PaperDataComponentType<A, M> {
public Unimplemented(
final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder,
final DataComponentAdapter<NMS, T> adapter
final Holder<net.minecraft.core.component.DataComponentType<M>> holder,
final Converter<M, A> converter
) {
super(holder, adapter);
super(holder, converter);
}
}
}
@@ -1,5 +1,6 @@
package io.papermc.paper.datacomponent.item;
import io.papermc.paper.adventure.PaperAdventure;
import io.papermc.paper.datacomponent.item.blocksattacks.DamageReduction;
import io.papermc.paper.datacomponent.item.blocksattacks.ItemDamageFunction;
import io.papermc.paper.datacomponent.item.blocksattacks.PaperDamageReduction;
@@ -11,9 +12,8 @@ import io.papermc.paper.registry.set.RegistryKeySet;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import java.util.Optional;
import net.kyori.adventure.key.Key;
import net.minecraft.core.registries.Registries;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.CraftSound;
import org.bukkit.craftbukkit.util.Handleable;
import org.bukkit.damage.DamageType;
import org.checkerframework.checker.index.qual.NonNegative;
@@ -56,13 +56,13 @@ public record PaperBlocksAttacks(
}
@Override
public @Nullable Sound blockSound() {
return this.impl.blockSound().map(CraftSound::minecraftHolderToBukkit).orElse(null);
public @Nullable Key blockSound() {
return this.impl.blockSound().map(holder -> PaperAdventure.asAdventure(holder.value().location())).orElse(null);
}
@Override
public @Nullable Sound disableSound() {
return this.impl.disableSound().map(CraftSound::minecraftHolderToBukkit).orElse(null);
public @Nullable Key disableSound() {
return this.impl.disableSound().map(holder -> PaperAdventure.asAdventure(holder.value().location())).orElse(null);
}
static final class BuilderImpl implements Builder {
@@ -72,8 +72,8 @@ public record PaperBlocksAttacks(
private List<DamageReduction> damageReductions = new ObjectArrayList<>();
private ItemDamageFunction itemDamage = new PaperItemDamageFunction(net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction.DEFAULT);
private @Nullable RegistryKeySet<DamageType> bypassedBy;
private @Nullable Sound blockSound;
private @Nullable Sound disableSound;
private @Nullable Key blockSound;
private @Nullable Key disableSound;
@Override
public Builder blockDelaySeconds(final @NonNegative float delay) {
@@ -112,13 +112,13 @@ public record PaperBlocksAttacks(
}
@Override
public Builder blockSound(final @Nullable Sound sound) {
public Builder blockSound(final @Nullable Key sound) {
this.blockSound = sound;
return this;
}
@Override
public Builder disableSound(final @Nullable Sound sound) {
public Builder disableSound(final @Nullable Key sound) {
this.disableSound = sound;
return this;
}
@@ -131,8 +131,8 @@ public record PaperBlocksAttacks(
this.damageReductions.stream().map(damageReduction -> ((PaperDamageReduction) damageReduction).internal()).toList(),
((PaperItemDamageFunction) this.itemDamage).internal(),
Optional.ofNullable(this.bypassedBy).map(holders -> PaperRegistrySets.convertToNms(Registries.DAMAGE_TYPE, Conversions.global().lookup(), holders)),
Optional.ofNullable(this.blockSound).map(CraftSound::bukkitToMinecraftHolder),
Optional.ofNullable(this.disableSound).map(CraftSound::bukkitToMinecraftHolder)
Optional.ofNullable(this.blockSound).map(PaperAdventure::resolveSound),
Optional.ofNullable(this.disableSound).map(PaperAdventure::resolveSound)
));
}
}
@@ -1,16 +1,16 @@
package io.papermc.paper.datacomponent.item;
import io.papermc.paper.adventure.PaperAdventure;
import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect;
import io.papermc.paper.datacomponent.item.consumable.ItemUseAnimation;
import io.papermc.paper.datacomponent.item.consumable.PaperConsumableEffect;
import io.papermc.paper.util.MCUtil;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import net.kyori.adventure.key.Key;
import net.minecraft.core.Holder;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.CraftSound;
import org.bukkit.craftbukkit.util.Handleable;
import org.checkerframework.checker.index.qual.NonNegative;
import org.jetbrains.annotations.Unmodifiable;
@@ -39,8 +39,8 @@ public record PaperConsumable(
}
@Override
public Sound sound() {
return CraftSound.minecraftHolderToBukkit(this.impl.sound());
public Key sound() {
return PaperAdventure.asAdventure(this.impl.sound().value().location());
}
@Override
@@ -86,8 +86,8 @@ public record PaperConsumable(
}
@Override
public Builder sound(final Sound sound) {
this.eatSound = CraftSound.bukkitToMinecraftHolder(sound);
public Builder sound(final Key sound) {
this.eatSound = PaperAdventure.resolveSound(sound);
return this;
}
@@ -17,9 +17,7 @@ import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.item.equipment.EquipmentAsset;
import net.minecraft.world.item.equipment.EquipmentAssets;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.CraftEquipmentSlot;
import org.bukkit.craftbukkit.CraftSound;
import org.bukkit.craftbukkit.util.Handleable;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.EquipmentSlot;
@@ -40,8 +38,8 @@ public record PaperEquippable(
}
@Override
public Sound equipSound() {
return CraftSound.minecraftHolderToBukkit(this.impl.equipSound());
public Key equipSound() {
return PaperAdventure.asAdventure(this.impl.equipSound().value().location());
}
@Override
@@ -91,8 +89,8 @@ public record PaperEquippable(
}
@Override
public Sound shearSound() {
return CraftSound.minecraftHolderToBukkit(this.impl.shearingSound());
public Key shearSound() {
return PaperAdventure.asAdventure(this.impl.shearingSound().value().location());
}
@Override
@@ -130,8 +128,8 @@ public record PaperEquippable(
}
@Override
public Builder equipSound(final Sound sound) {
this.equipSound = CraftSound.bukkitToMinecraftHolder(sound);
public Builder equipSound(final Key sound) {
this.equipSound = PaperAdventure.resolveSound(sound);
return this;
}
@@ -144,7 +142,7 @@ public record PaperEquippable(
}
@Override
public Builder cameraOverlay(final @Nullable Key cameraOverlay) {
public Builder cameraOverlay(@Nullable final Key cameraOverlay) {
this.cameraOverlay = Optional.ofNullable(cameraOverlay)
.map(PaperAdventure::asVanilla);
@@ -189,8 +187,8 @@ public record PaperEquippable(
}
@Override
public Builder shearSound(final Sound shearSound) {
this.shearSound = CraftSound.bukkitToMinecraftHolder(shearSound);
public Builder shearSound(final Key shearSound) {
this.shearSound = PaperAdventure.resolveSound(shearSound);
return this;
}
@@ -17,8 +17,8 @@ public record PaperItemEnchantments(
Map<Enchantment, Integer> enchantments // API values are stored externally as the concept of a lazy key transformer map does not make much sense
) implements ItemEnchantments, Handleable<net.minecraft.world.item.enchantment.ItemEnchantments> {
public PaperItemEnchantments(final net.minecraft.world.item.enchantment.ItemEnchantments itemEnchantments) {
this(itemEnchantments, convert(itemEnchantments));
public static PaperItemEnchantments of(final net.minecraft.world.item.enchantment.ItemEnchantments itemEnchantments) {
return new PaperItemEnchantments(itemEnchantments, convert(itemEnchantments));
}
private static Map<Enchantment, Integer> convert(final net.minecraft.world.item.enchantment.ItemEnchantments itemEnchantments) {
@@ -57,14 +57,14 @@ public record PaperItemEnchantments(
public ItemEnchantments build() {
final net.minecraft.world.item.enchantment.ItemEnchantments initialEnchantments = net.minecraft.world.item.enchantment.ItemEnchantments.EMPTY;
if (this.enchantments.isEmpty()) {
return new PaperItemEnchantments(initialEnchantments);
return PaperItemEnchantments.of(initialEnchantments);
}
final net.minecraft.world.item.enchantment.ItemEnchantments.Mutable mutable = new net.minecraft.world.item.enchantment.ItemEnchantments.Mutable(initialEnchantments);
this.enchantments.forEach((enchantment, level) ->
mutable.set(CraftEnchantment.bukkitToMinecraftHolder(enchantment), level)
);
return new PaperItemEnchantments(mutable.toImmutable());
return PaperItemEnchantments.of(mutable.toImmutable());
}
}
}
@@ -1,8 +1,10 @@
package io.papermc.paper.datacomponent.item;
import io.papermc.paper.adventure.PaperAdventure;
import java.util.Optional;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.CraftSound;
import net.kyori.adventure.key.Key;
import net.minecraft.core.Holder;
import net.minecraft.sounds.SoundEvent;
import org.bukkit.craftbukkit.util.Handleable;
import org.checkerframework.checker.index.qual.NonNegative;
import org.jspecify.annotations.Nullable;
@@ -67,13 +69,21 @@ public record PaperKineticWeapon(
}
@Override
public @Nullable Sound sound() {
return this.impl.sound().map(CraftSound::minecraftHolderToBukkit).orElse(null);
public @Nullable Key sound() {
return this.impl.sound()
.map(Holder::value)
.map(SoundEvent::location)
.map(PaperAdventure::asAdventure)
.orElse(null);
}
@Override
public @Nullable Sound hitSound() {
return this.impl.hitSound().map(CraftSound::minecraftHolderToBukkit).orElse(null);
public @Nullable Key hitSound() {
return this.impl.hitSound()
.map(Holder::value)
.map(SoundEvent::location)
.map(PaperAdventure::asAdventure)
.orElse(null);
}
public record PaperKineticWeaponCondition(
@@ -110,8 +120,8 @@ public record PaperKineticWeapon(
private net.minecraft.world.item.component.KineticWeapon.@Nullable Condition knockbackConditions;
private net.minecraft.world.item.component.KineticWeapon.@Nullable Condition damageConditions;
private @Nullable Sound sound = null;
private @Nullable Sound hitSound = null;
private @Nullable Key sound = null;
private @Nullable Key hitSound = null;
private float damageMultiplier = 1;
private float forwardMovement = 0.0F;
@@ -159,13 +169,13 @@ public record PaperKineticWeapon(
}
@Override
public KineticWeapon.Builder sound(final @Nullable Sound sound) {
public KineticWeapon.Builder sound(final @Nullable Key sound) {
this.sound = sound;
return this;
}
@Override
public KineticWeapon.Builder hitSound(final @Nullable Sound sound) {
public KineticWeapon.Builder hitSound(final @Nullable Key sound) {
this.hitSound = sound;
return this;
}
@@ -181,8 +191,8 @@ public record PaperKineticWeapon(
Optional.ofNullable(this.damageConditions),
this.forwardMovement,
this.damageMultiplier,
Optional.ofNullable(this.sound).map(CraftSound::bukkitToMinecraftHolder),
Optional.ofNullable(this.hitSound).map(CraftSound::bukkitToMinecraftHolder)
Optional.ofNullable(this.sound).map(PaperAdventure::resolveSound),
Optional.ofNullable(this.hitSound).map(PaperAdventure::resolveSound)
)
);
}
Loaded 100 of 183 files, more files were not shown because too many files have changed in this diff. Show more