Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Instrument Component fields into MusicInstrument #11925

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.ServiceLoader;
import java.util.function.Consumer;
import org.bukkit.Art;
import org.bukkit.MusicInstrument;
import org.jetbrains.annotations.ApiStatus;

@ApiStatus.Internal
Expand All @@ -19,4 +20,6 @@ class Holder {
}

Art createPaintingVariant(Consumer<RegistryBuilderFactory<Art, ? extends PaintingVariantRegistryEntry.Builder>> value);

MusicInstrument createInstrument(Consumer<RegistryBuilderFactory<MusicInstrument, ? extends InstrumentRegistryEntry.Builder>> value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package io.papermc.paper.registry.data;

import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.RegistryBuilderFactory;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.Component;
import org.bukkit.MusicInstrument;
import org.checkerframework.checker.index.qual.Positive;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import java.util.function.Consumer;

/**
* A data-centric version-specific registry entry for the {@link org.bukkit.MusicInstrument} type.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface InstrumentRegistryEntry {

/**
* Provides the duration of the instrument, which is time to use.
*
* @return the duration.
*/
@Contract(pure = true)
@Positive float duration();

/**
* Provides the range of the instrument, which is range of the sound.
*
* @return the range.
*/
@Contract(pure = true)
@Positive float range();

/**
* Provides the description of the instrument, which is used in the item tooltip.
*
* @return the description.
*/
Component description();

/**
* Provides the sound event of the instrument.
*
* @return the sound event.
*/
@Contract(pure = true)
Either<TypedKey<Sound>, SoundEventRegistryEntry> soundEvent();

/**
* A mutable builder for the {@link InstrumentRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #duration(float)}</li>
* <li>{@link #range(float)}</li>
* <li>{@link #description(Component)}</li>
* <li>
* {@link #soundEvent(TypedKey)} or {@link #soundEvent(Consumer)}
* </li>
* </ul>
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends InstrumentRegistryEntry, RegistryBuilder<MusicInstrument> {

/**
* Sets the duration of use for this instrument.
*
* @param duration the duration (positive)
* @return this builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder duration(@Positive float duration);

/**
* Sets the range for this instrument.
*
* @param range the range (positive)
* @return this builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder range(@Positive float range);

/**
* Sets the description for this instrument.
*
* @param description the description
* @return this builder
*/
@Contract(value = "_ -> this", mutates = "this")
Builder description(Component description);

/**
* Sets the sound event for this instrument to a sound event present
* in the {@link io.papermc.paper.registry.RegistryKey#SOUND_EVENT} registry.
* <p>This will override {@link #soundEvent(Consumer)}</p>
*
* @param soundEvent the sound event
* @return this builder
* @see #soundEvent(Consumer)
*/
@Contract(value = "_ -> this", mutates = "this")
Builder soundEvent(TypedKey<Sound> soundEvent);

/**
* Sets the sound event for this instrument to a new sound event.
* <p>This will override {@link #soundEvent(TypedKey)}</p>
*
* @param soundEvent the sound event
* @return this builder
* @see #soundEvent(TypedKey)
*/
@Contract(value = "_ -> this", mutates = "this")
Builder soundEvent(Consumer<RegistryBuilderFactory<Sound, ? extends SoundEventRegistryEntry.Builder>> soundEvent);
}

}
53 changes: 47 additions & 6 deletions paper-api/src/main/java/org/bukkit/MusicInstrument.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@
import io.papermc.paper.registry.RegistryKey;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Consumer;
import io.papermc.paper.registry.RegistryBuilderFactory;
import io.papermc.paper.registry.data.InlinedRegistryBuilderProvider;
import io.papermc.paper.registry.data.InstrumentRegistryEntry;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import net.kyori.adventure.translation.Translatable;

public abstract class MusicInstrument implements Keyed, net.kyori.adventure.translation.Translatable { // Paper - translation keys
public abstract class MusicInstrument implements Keyed, Translatable {

public static final MusicInstrument PONDER_GOAT_HORN = getInstrument("ponder_goat_horn");
public static final MusicInstrument SING_GOAT_HORN = getInstrument("sing_goat_horn");
Expand All @@ -19,6 +26,17 @@ public abstract class MusicInstrument implements Keyed, net.kyori.adventure.tran
public static final MusicInstrument YEARN_GOAT_HORN = getInstrument("yearn_goat_horn");
public static final MusicInstrument DREAM_GOAT_HORN = getInstrument("dream_goat_horn");

/**
* Create an inlined music instrument.
*
* @param value a consumer for the builder factory
* @return the created instrument
*/
@ApiStatus.Experimental
static @NotNull MusicInstrument create(final @NotNull Consumer<RegistryBuilderFactory<MusicInstrument, ? extends InstrumentRegistryEntry.Builder>> value) {
return InlinedRegistryBuilderProvider.instance().createInstrument(value);
}

/**
* Returns a {@link MusicInstrument} by a {@link NamespacedKey}.
*
Expand Down Expand Up @@ -49,7 +67,34 @@ private static MusicInstrument getInstrument(@NotNull String key) {
return RegistryAccess.registryAccess().getRegistry(RegistryKey.INSTRUMENT).getOrThrow(NamespacedKey.minecraft(key));
}

// Paper start - deprecate getKey
/**
* Gets for how long the use duration is for the instrument.
*
* @return the duration.
*/
public abstract float getDuration();

/**
* Gets the range of the sound.
*
* @return the range of the sound.
*/
public abstract float getRange();

/**
* Provides the description of this instrument as displayed to the client.
*
* @return the description component.
*/
public abstract @NotNull Component description();

/**
* Gets the sound/sound-event for this instrument.
*
* @return a sound
*/
public abstract @NotNull Sound getSoundEvent();

/**
* @deprecated use {@link Registry#getKey(Keyed)}, {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)},
* and {@link io.papermc.paper.registry.RegistryKey#INSTRUMENT}. MusicInstruments can exist without a key.
Expand All @@ -68,15 +113,11 @@ private static MusicInstrument getInstrument(@NotNull String key) {
return Keyed.super.key();
}

// Paper end - deprecate getKey

// Paper start - mark translation key as deprecated
/**
* @deprecated this method assumes that the instrument description
* always be a translatable component which is not guaranteed.
*/
@Override
@Deprecated(forRemoval = true)
public abstract @NotNull String translationKey();
// Paper end - mark translation key as deprecated
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package org.bukkit.craftbukkit;

import com.google.common.base.Preconditions;
import io.papermc.paper.adventure.PaperAdventure;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.util.Holderable;
import net.kyori.adventure.text.Component;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.item.Instrument;
import org.bukkit.MusicInstrument;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.Sound;
import org.jetbrains.annotations.NotNull;

public class CraftMusicInstrument extends MusicInstrument implements io.papermc.paper.util.Holderable<Instrument> {
Expand Down Expand Up @@ -41,31 +43,35 @@ public static MusicInstrument stringToBukkit(Object string) { // Paper - switch
return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(string, Instrument.CODEC, RegistryKey.INSTRUMENT); // Paper - switch to Holder
}

// Paper start - switch to Holder
private final Holder<Instrument> holder;

public CraftMusicInstrument(Holder<Instrument> holder) {
this.holder = holder;
}

@Override
public boolean equals(final Object o) {
return this.implEquals(o);
public Holder<Instrument> getHolder() {
return this.holder;
}

@Override
public int hashCode() {
return this.implHashCode();
public Component description() {
return PaperAdventure.asAdventure(this.getHandle().description());
}

@Override
public String toString() {
return this.implToString();
public float getDuration() {
return this.getHandle().useDuration();
}

private final Holder<Instrument> holder;
public CraftMusicInstrument(Holder<Instrument> holder) {
this.holder = holder;
// Paper end - switch to Holder
@Override
public float getRange() {
return this.getHandle().range();
}

@Override
public Holder<Instrument> getHolder() { // Paper - switch to Holder
return this.holder; // Paper - switch to Holder
public Sound getSoundEvent() {
return CraftSound.minecraftHolderToBukkit(this.getHandle().soundEvent());
}

@NotNull
Expand All @@ -74,15 +80,26 @@ public NamespacedKey getKey() {
return Holderable.super.getKey();
}

// Paper start - add translationKey methods
@Override
public @NotNull String translationKey() {
if (!(this.getHandle().description().getContents() instanceof final net.minecraft.network.chat.contents.TranslatableContents translatableContents)) {
throw new UnsupportedOperationException("Description isn't translatable!"); // Paper
}
return translatableContents.getKey();
}
// Paper end - add translationKey methods

// Paper - switch to Holder
@Override
public boolean equals(final Object o) {
return this.implEquals(o);
}

@Override
public int hashCode() {
return this.implHashCode();
}

@Override
public String toString() {
return this.implToString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ public static Sound minecraftToBukkit(SoundEvent minecraft) {
return CraftRegistry.minecraftToBukkit(minecraft, Registries.SOUND_EVENT);
}

public static Sound minecraftHolderToBukkit(Holder<SoundEvent> minecraft) {
return minecraftToBukkit(minecraft.value());
}

public static SoundEvent bukkitToMinecraft(Sound bukkit) {
return CraftRegistry.bukkitToMinecraft(bukkit);
}
Expand All @@ -26,9 +30,7 @@ public CraftSound(Holder<SoundEvent> soundEffect) {
super(soundEffect, count++);
}

// Paper start
public static String getSound(Sound sound) {
return sound.getKey().getKey();
}
// Paper end
}
Loading
Loading