diff --git a/paper-api/src/main/java/org/bukkit/Registry.java b/paper-api/src/main/java/org/bukkit/Registry.java index 44b8c9111d..f79f4f20ee 100644 --- a/paper-api/src/main/java/org/bukkit/Registry.java +++ b/paper-api/src/main/java/org/bukkit/Registry.java @@ -24,6 +24,7 @@ import org.bukkit.generator.structure.StructureType; import org.bukkit.inventory.meta.trim.TrimMaterial; import org.bukkit.inventory.meta.trim.TrimPattern; import org.bukkit.loot.LootTables; +import org.bukkit.potion.PotionType; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -155,6 +156,12 @@ public interface Registry<T extends Keyed> extends Iterable<T> { * @see Material */ Registry<Material> MATERIAL = new SimpleRegistry<>(Material.class, (mat) -> !mat.isLegacy()); + /** + * Server potions. + * + * @see PotionType + */ + Registry<PotionType> POTION = new SimpleRegistry<>(PotionType.class); /** * Server statistics. * diff --git a/paper-api/src/main/java/org/bukkit/UnsafeValues.java b/paper-api/src/main/java/org/bukkit/UnsafeValues.java index 68194147e9..4a9a82540e 100644 --- a/paper-api/src/main/java/org/bukkit/UnsafeValues.java +++ b/paper-api/src/main/java/org/bukkit/UnsafeValues.java @@ -12,6 +12,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.material.MaterialData; import org.bukkit.plugin.InvalidPluginException; import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.potion.PotionType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -91,4 +92,12 @@ public interface UnsafeValues { @Nullable FeatureFlag getFeatureFlag(@NotNull NamespacedKey key); + + /** + * Do not use, method will get removed, and the plugin won't run + * + * @param key of the potion type + * @return an internal potion data + */ + PotionType.InternalPotionData getInternalPotionData(NamespacedKey key); } diff --git a/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java b/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java index c2096b5344..8d6caae8ba 100644 --- a/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java +++ b/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java @@ -6,6 +6,7 @@ import org.bukkit.Particle; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionType; import org.bukkit.projectiles.ProjectileSource; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -149,17 +150,36 @@ public interface AreaEffectCloud extends Entity { * Sets the underlying potion data * * @param data PotionData to set the base potion state to + * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #setBasePotionType} instead. */ + @Deprecated void setBasePotionData(@NotNull PotionData data); /** * Returns the potion data about the base potion * * @return a PotionData object + * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #getBasePotionType()} instead. */ @NotNull + @Deprecated PotionData getBasePotionData(); + /** + * Sets the underlying potion type + * + * @param type PotionType to set the base potion state to + */ + void setBasePotionType(@NotNull PotionType type); + + /** + * Returns the potion type about the base potion + * + * @return a PotionType object + */ + @NotNull + PotionType getBasePotionType(); + /** * Checks for the presence of custom potion effects. * diff --git a/paper-api/src/main/java/org/bukkit/entity/Arrow.java b/paper-api/src/main/java/org/bukkit/entity/Arrow.java index 8814519df1..8eb0cf31b1 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Arrow.java +++ b/paper-api/src/main/java/org/bukkit/entity/Arrow.java @@ -5,6 +5,7 @@ import org.bukkit.Color; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -14,17 +15,36 @@ public interface Arrow extends AbstractArrow { * Sets the underlying potion data * * @param data PotionData to set the base potion state to + * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #setBasePotionType} instead. */ + @Deprecated void setBasePotionData(@NotNull PotionData data); /** * Returns the potion data about the base potion * * @return a PotionData object + * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #getBasePotionType()} instead. */ @NotNull + @Deprecated PotionData getBasePotionData(); + /** + * Sets the underlying potion type + * + * @param type PotionType to set the base potion state to + */ + void setBasePotionType(@NotNull PotionType type); + + /** + * Returns the potion type about the base potion + * + * @return a PotionType object + */ + @NotNull + PotionType getBasePotionType(); + /** * Gets the color of this arrow. * diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java b/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java index 8e2f474a44..1113c40fb3 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java @@ -5,6 +5,7 @@ import org.bukkit.Color; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -17,17 +18,36 @@ public interface PotionMeta extends ItemMeta { * Sets the underlying potion data * * @param data PotionData to set the base potion state to + * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #setBasePotionType} instead. */ + @Deprecated void setBasePotionData(@NotNull PotionData data); /** * Returns the potion data about the base potion * * @return a PotionData object + * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #getBasePotionType()} instead. */ @NotNull + @Deprecated PotionData getBasePotionData(); + /** + * Sets the underlying potion type + * + * @param type PotionType to set the base potion state to + */ + void setBasePotionType(@NotNull PotionType type); + + /** + * Returns the potion type about the base potion + * + * @return a PotionType object + */ + @NotNull + PotionType getBasePotionType(); + /** * Checks for the presence of custom potion effects. * diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionBrewer.java b/paper-api/src/main/java/org/bukkit/potion/PotionBrewer.java index d21f407cc1..2072f048e1 100644 --- a/paper-api/src/main/java/org/bukkit/potion/PotionBrewer.java +++ b/paper-api/src/main/java/org/bukkit/potion/PotionBrewer.java @@ -40,7 +40,9 @@ public interface PotionBrewer { * @param upgraded Whether the potion is upgraded * @param extended Whether the potion is extended * @return The list of effects + * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link PotionType#getPotionEffects()} instead */ @NotNull + @Deprecated public Collection<PotionEffect> getEffects(@NotNull PotionType type, boolean upgraded, boolean extended); } diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionData.java b/paper-api/src/main/java/org/bukkit/potion/PotionData.java index ef5fe586a7..3852a092fa 100644 --- a/paper-api/src/main/java/org/bukkit/potion/PotionData.java +++ b/paper-api/src/main/java/org/bukkit/potion/PotionData.java @@ -3,6 +3,10 @@ package org.bukkit.potion; import com.google.common.base.Preconditions; import org.jetbrains.annotations.NotNull; +/** + * @deprecated Upgraded / extended potions are now their own {@link PotionType} use them instead. + */ +@Deprecated public final class PotionData { private final PotionType type; @@ -24,6 +28,8 @@ public final class PotionData { Preconditions.checkArgument(!upgraded || type.isUpgradeable(), "Potion Type is not upgradable"); Preconditions.checkArgument(!extended || type.isExtendable(), "Potion Type is not extendable"); Preconditions.checkArgument(!upgraded || !extended, "Potion cannot be both extended and upgraded"); + Preconditions.checkArgument(!type.getKey().getKey().startsWith("strong_"), "Strong potion type cannot be used directly, got %s", type.getKey()); + Preconditions.checkArgument(!type.getKey().getKey().startsWith("long_"), "Extended potion type cannot be used directly, got %s", type.getKey()); this.type = type; this.extended = extended; this.upgraded = upgraded; diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionType.java b/paper-api/src/main/java/org/bukkit/potion/PotionType.java index af7dea669c..70456f0866 100644 --- a/paper-api/src/main/java/org/bukkit/potion/PotionType.java +++ b/paper-api/src/main/java/org/bukkit/potion/PotionType.java @@ -1,52 +1,99 @@ package org.bukkit.potion; +import com.google.common.base.Suppliers; +import java.util.List; +import java.util.function.Supplier; +import org.bukkit.Bukkit; +import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * This enum reflects and matches each potion state that can be obtained from * the Creative mode inventory */ -public enum PotionType { - UNCRAFTABLE(null, false, false), - WATER(null, false, false), - MUNDANE(null, false, false), - THICK(null, false, false), - AWKWARD(null, false, false), - NIGHT_VISION(PotionEffectType.NIGHT_VISION, false, true), - INVISIBILITY(PotionEffectType.INVISIBILITY, false, true), - JUMP(PotionEffectType.JUMP, true, true), - FIRE_RESISTANCE(PotionEffectType.FIRE_RESISTANCE, false, true), - SPEED(PotionEffectType.SPEED, true, true), - SLOWNESS(PotionEffectType.SLOW, true, true), - WATER_BREATHING(PotionEffectType.WATER_BREATHING, false, true), - INSTANT_HEAL(PotionEffectType.HEAL, true, false), - INSTANT_DAMAGE(PotionEffectType.HARM, true, false), - POISON(PotionEffectType.POISON, true, true), - REGEN(PotionEffectType.REGENERATION, true, true), - STRENGTH(PotionEffectType.INCREASE_DAMAGE, true, true), - WEAKNESS(PotionEffectType.WEAKNESS, false, true), - LUCK(PotionEffectType.LUCK, false, false), - TURTLE_MASTER(PotionEffectType.SLOW, true, true), // TODO: multiple effects - SLOW_FALLING(PotionEffectType.SLOW_FALLING, false, true), +public enum PotionType implements Keyed { + UNCRAFTABLE("empty"), + WATER("water"), + MUNDANE("mundane"), + THICK("thick"), + AWKWARD("awkward"), + NIGHT_VISION("night_vision"), + LONG_NIGHT_VISION("long_night_vision"), + INVISIBILITY("invisibility"), + LONG_INVISIBILITY("long_invisibility"), + JUMP("leaping"), + LONG_LEAPING("long_leaping"), + STRONG_LEAPING("strong_leaping"), + FIRE_RESISTANCE("fire_resistance"), + LONG_FIRE_RESISTANCE("long_fire_resistance"), + SPEED("swiftness"), + LONG_SWIFTNESS("long_swiftness"), + STRONG_SWIFTNESS("strong_swiftness"), + SLOWNESS("slowness"), + LONG_SLOWNESS("long_slowness"), + STRONG_SLOWNESS("strong_slowness"), + WATER_BREATHING("water_breathing"), + LONG_WATER_BREATHING("long_water_breathing"), + INSTANT_HEAL("healing"), + STRONG_HEALING("strong_healing"), + INSTANT_DAMAGE("harming"), + STRONG_HARMING("strong_harming"), + POISON("poison"), + LONG_POISON("long_poison"), + STRONG_POISON("strong_poison"), + REGEN("regeneration"), + LONG_REGENERATION("long_regeneration"), + STRONG_REGENERATION("strong_regeneration"), + STRENGTH("strength"), + LONG_STRENGTH("long_strength"), + STRONG_STRENGTH("strong_strength"), + WEAKNESS("weakness"), + LONG_WEAKNESS("long_weakness"), + LUCK("luck"), + TURTLE_MASTER("turtle_master"), + LONG_TURTLE_MASTER("long_turtle_master"), + STRONG_TURTLE_MASTER("strong_turtle_master"), + SLOW_FALLING("slow_falling"), + LONG_SLOW_FALLING("long_slow_falling"), ; - private final PotionEffectType effect; - private final boolean upgradeable; - private final boolean extendable; + private final NamespacedKey key; + private final Supplier<InternalPotionData> internalPotionDataSupplier; - PotionType(/*@Nullable*/ PotionEffectType effect, boolean upgradeable, boolean extendable) { - this.effect = effect; - this.upgradeable = upgradeable; - this.extendable = extendable; + PotionType(String key) { + this.key = NamespacedKey.minecraft(key); + this.internalPotionDataSupplier = Suppliers.memoize(() -> Bukkit.getUnsafe().getInternalPotionData(this.key)); } + /** + * @return the potion effect type of this potion type + * @deprecated Potions can have multiple effects use {@link #getPotionEffects()} + */ @Nullable + @Deprecated public PotionEffectType getEffectType() { - return effect; + return internalPotionDataSupplier.get().getEffectType(); } + /** + * @return a list of all effects this potion type has + */ + @NotNull + public List<PotionEffect> getPotionEffects() { + return internalPotionDataSupplier.get().getPotionEffects(); + } + + /** + * @return if this potion type is instant + * @deprecated PotionType can have multiple effects, some of which can be instant and others not. + * Use {@link PotionEffectType#isInstant()} in combination with {@link #getPotionEffects()} and {@link PotionEffect#getType()} + */ + @Deprecated public boolean isInstant() { - return effect != null && effect.isInstant(); + return internalPotionDataSupplier.get().isInstant(); } /** @@ -57,7 +104,7 @@ public enum PotionType { * @return true if the potion type can be upgraded; */ public boolean isUpgradeable() { - return upgradeable; + return internalPotionDataSupplier.get().isUpgradeable(); } /** @@ -67,11 +114,11 @@ public enum PotionType { * @return true if the potion type can be extended */ public boolean isExtendable() { - return extendable; + return internalPotionDataSupplier.get().isExtendable(); } public int getMaxLevel() { - return upgradeable ? 2 : 1; + return internalPotionDataSupplier.get().getMaxLevel(); } /** @@ -85,9 +132,35 @@ public enum PotionType { if (effectType == null) return WATER; for (PotionType type : PotionType.values()) { - if (effectType.equals(type.effect)) + if (effectType.equals(type.getEffectType())) return type; } return null; } + + @NotNull + @Override + public NamespacedKey getKey() { + return key; + } + + /** + * @deprecated Do not use, interface will get removed, and the plugin won't run + */ + @Deprecated + @ApiStatus.Internal + public interface InternalPotionData { + + PotionEffectType getEffectType(); + + List<PotionEffect> getPotionEffects(); + + boolean isInstant(); + + boolean isUpgradeable(); + + boolean isExtendable(); + + int getMaxLevel(); + } }