From 9ac8229b9b63984b6bf8e4c36c06ef3ce6c81f14 Mon Sep 17 00:00:00 2001 From: Bukkit/Spigot Date: Wed, 6 Dec 2023 03:40:00 +1100 Subject: [PATCH] SPIGOT-6026: Pull PotionEffectType and Enchantment from registry By: DerFrZocker --- .../src/main/java/org/bukkit/Registry.java | 31 +-- .../org/bukkit/enchantments/Enchantment.java | 230 +++++++-------- .../enchantments/EnchantmentWrapper.java | 53 +--- .../org/bukkit/potion/PotionEffectType.java | 262 +++++++++--------- .../potion/PotionEffectTypeWrapper.java | 35 +-- 5 files changed, 261 insertions(+), 350 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/Registry.java b/paper-api/src/main/java/org/bukkit/Registry.java index c373614a86..3be4214348 100644 --- a/paper-api/src/main/java/org/bukkit/Registry.java +++ b/paper-api/src/main/java/org/bukkit/Registry.java @@ -3,7 +3,6 @@ package org.bukkit; import com.google.common.base.Preconditions; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableMap; -import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.Objects; @@ -24,6 +23,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.PotionEffectType; import org.bukkit.potion.PotionType; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -110,28 +110,9 @@ public interface Registry extends Iterable { /** * Server enchantments. * - * @see Enchantment#getByKey(org.bukkit.NamespacedKey) + * @see Enchantment */ - Registry ENCHANTMENT = new Registry() { - - @Nullable - @Override - public Enchantment get(@NotNull NamespacedKey key) { - return Enchantment.getByKey(key); - } - - @NotNull - @Override - public Stream stream() { - return StreamSupport.stream(spliterator(), false); - } - - @NotNull - @Override - public Iterator iterator() { - return Arrays.asList(Enchantment.values()).iterator(); - } - }; + Registry ENCHANTMENT = Objects.requireNonNull(Bukkit.getRegistry(Enchantment.class), "No registry present for Enchantment. This is a bug."); /** * Server entity types. * @@ -156,6 +137,12 @@ public interface Registry extends Iterable { * @see Material */ Registry MATERIAL = new SimpleRegistry<>(Material.class, (mat) -> !mat.isLegacy()); + /** + * Server mob effects. + * + * @see PotionEffectType + */ + Registry EFFECT = Objects.requireNonNull(Bukkit.getRegistry(PotionEffectType.class), "No registry present for PotionEffectType. This is a bug."); /** * Server particles. * diff --git a/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java b/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java index e2800dc97a..c349cd16de 100644 --- a/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java +++ b/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java @@ -1,9 +1,10 @@ package org.bukkit.enchantments; -import java.util.HashMap; -import java.util.Map; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; +import org.bukkit.Registry; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -16,213 +17,208 @@ public abstract class Enchantment implements Keyed { /** * Provides protection against environmental damage */ - public static final Enchantment PROTECTION_ENVIRONMENTAL = new EnchantmentWrapper("protection"); + public static final Enchantment PROTECTION_ENVIRONMENTAL = getEnchantment("protection"); /** * Provides protection against fire damage */ - public static final Enchantment PROTECTION_FIRE = new EnchantmentWrapper("fire_protection"); + public static final Enchantment PROTECTION_FIRE = getEnchantment("fire_protection"); /** * Provides protection against fall damage */ - public static final Enchantment PROTECTION_FALL = new EnchantmentWrapper("feather_falling"); + public static final Enchantment PROTECTION_FALL = getEnchantment("feather_falling"); /** * Provides protection against explosive damage */ - public static final Enchantment PROTECTION_EXPLOSIONS = new EnchantmentWrapper("blast_protection"); + public static final Enchantment PROTECTION_EXPLOSIONS = getEnchantment("blast_protection"); /** * Provides protection against projectile damage */ - public static final Enchantment PROTECTION_PROJECTILE = new EnchantmentWrapper("projectile_protection"); + public static final Enchantment PROTECTION_PROJECTILE = getEnchantment("projectile_protection"); /** * Decreases the rate of air loss whilst underwater */ - public static final Enchantment OXYGEN = new EnchantmentWrapper("respiration"); + public static final Enchantment OXYGEN = getEnchantment("respiration"); /** * Increases the speed at which a player may mine underwater */ - public static final Enchantment WATER_WORKER = new EnchantmentWrapper("aqua_affinity"); + public static final Enchantment WATER_WORKER = getEnchantment("aqua_affinity"); /** * Damages the attacker */ - public static final Enchantment THORNS = new EnchantmentWrapper("thorns"); + public static final Enchantment THORNS = getEnchantment("thorns"); /** * Increases walking speed while in water */ - public static final Enchantment DEPTH_STRIDER = new EnchantmentWrapper("depth_strider"); + public static final Enchantment DEPTH_STRIDER = getEnchantment("depth_strider"); /** * Freezes any still water adjacent to ice / frost which player is walking on */ - public static final Enchantment FROST_WALKER = new EnchantmentWrapper("frost_walker"); + public static final Enchantment FROST_WALKER = getEnchantment("frost_walker"); /** * Item cannot be removed */ - public static final Enchantment BINDING_CURSE = new EnchantmentWrapper("binding_curse"); + public static final Enchantment BINDING_CURSE = getEnchantment("binding_curse"); /** * Increases damage against all targets */ - public static final Enchantment DAMAGE_ALL = new EnchantmentWrapper("sharpness"); + public static final Enchantment DAMAGE_ALL = getEnchantment("sharpness"); /** * Increases damage against undead targets */ - public static final Enchantment DAMAGE_UNDEAD = new EnchantmentWrapper("smite"); + public static final Enchantment DAMAGE_UNDEAD = getEnchantment("smite"); /** * Increases damage against arthropod targets */ - public static final Enchantment DAMAGE_ARTHROPODS = new EnchantmentWrapper("bane_of_arthropods"); + public static final Enchantment DAMAGE_ARTHROPODS = getEnchantment("bane_of_arthropods"); /** * All damage to other targets will knock them back when hit */ - public static final Enchantment KNOCKBACK = new EnchantmentWrapper("knockback"); + public static final Enchantment KNOCKBACK = getEnchantment("knockback"); /** * When attacking a target, has a chance to set them on fire */ - public static final Enchantment FIRE_ASPECT = new EnchantmentWrapper("fire_aspect"); + public static final Enchantment FIRE_ASPECT = getEnchantment("fire_aspect"); /** * Provides a chance of gaining extra loot when killing monsters */ - public static final Enchantment LOOT_BONUS_MOBS = new EnchantmentWrapper("looting"); + public static final Enchantment LOOT_BONUS_MOBS = getEnchantment("looting"); /** * Increases damage against targets when using a sweep attack */ - public static final Enchantment SWEEPING_EDGE = new EnchantmentWrapper("sweeping"); + public static final Enchantment SWEEPING_EDGE = getEnchantment("sweeping"); /** * Increases the rate at which you mine/dig */ - public static final Enchantment DIG_SPEED = new EnchantmentWrapper("efficiency"); + public static final Enchantment DIG_SPEED = getEnchantment("efficiency"); /** * Allows blocks to drop themselves instead of fragments (for example, * stone instead of cobblestone) */ - public static final Enchantment SILK_TOUCH = new EnchantmentWrapper("silk_touch"); + public static final Enchantment SILK_TOUCH = getEnchantment("silk_touch"); /** * Decreases the rate at which a tool looses durability */ - public static final Enchantment DURABILITY = new EnchantmentWrapper("unbreaking"); + public static final Enchantment DURABILITY = getEnchantment("unbreaking"); /** * Provides a chance of gaining extra loot when destroying blocks */ - public static final Enchantment LOOT_BONUS_BLOCKS = new EnchantmentWrapper("fortune"); + public static final Enchantment LOOT_BONUS_BLOCKS = getEnchantment("fortune"); /** * Provides extra damage when shooting arrows from bows */ - public static final Enchantment ARROW_DAMAGE = new EnchantmentWrapper("power"); + public static final Enchantment ARROW_DAMAGE = getEnchantment("power"); /** * Provides a knockback when an entity is hit by an arrow from a bow */ - public static final Enchantment ARROW_KNOCKBACK = new EnchantmentWrapper("punch"); + public static final Enchantment ARROW_KNOCKBACK = getEnchantment("punch"); /** * Sets entities on fire when hit by arrows shot from a bow */ - public static final Enchantment ARROW_FIRE = new EnchantmentWrapper("flame"); + public static final Enchantment ARROW_FIRE = getEnchantment("flame"); /** * Provides infinite arrows when shooting a bow */ - public static final Enchantment ARROW_INFINITE = new EnchantmentWrapper("infinity"); + public static final Enchantment ARROW_INFINITE = getEnchantment("infinity"); /** * Decreases odds of catching worthless junk */ - public static final Enchantment LUCK = new EnchantmentWrapper("luck_of_the_sea"); + public static final Enchantment LUCK = getEnchantment("luck_of_the_sea"); /** * Increases rate of fish biting your hook */ - public static final Enchantment LURE = new EnchantmentWrapper("lure"); + public static final Enchantment LURE = getEnchantment("lure"); /** * Causes a thrown trident to return to the player who threw it */ - public static final Enchantment LOYALTY = new EnchantmentWrapper("loyalty"); + public static final Enchantment LOYALTY = getEnchantment("loyalty"); /** * Deals more damage to mobs that live in the ocean */ - public static final Enchantment IMPALING = new EnchantmentWrapper("impaling"); + public static final Enchantment IMPALING = getEnchantment("impaling"); /** * When it is rainy, launches the player in the direction their trident is thrown */ - public static final Enchantment RIPTIDE = new EnchantmentWrapper("riptide"); + public static final Enchantment RIPTIDE = getEnchantment("riptide"); /** * Strikes lightning when a mob is hit with a trident if conditions are * stormy */ - public static final Enchantment CHANNELING = new EnchantmentWrapper("channeling"); + public static final Enchantment CHANNELING = getEnchantment("channeling"); /** * Shoot multiple arrows from crossbows */ - public static final Enchantment MULTISHOT = new EnchantmentWrapper("multishot"); + public static final Enchantment MULTISHOT = getEnchantment("multishot"); /** * Charges crossbows quickly */ - public static final Enchantment QUICK_CHARGE = new EnchantmentWrapper("quick_charge"); + public static final Enchantment QUICK_CHARGE = getEnchantment("quick_charge"); /** * Crossbow projectiles pierce entities */ - public static final Enchantment PIERCING = new EnchantmentWrapper("piercing"); + public static final Enchantment PIERCING = getEnchantment("piercing"); /** * Allows mending the item using experience orbs */ - public static final Enchantment MENDING = new EnchantmentWrapper("mending"); + public static final Enchantment MENDING = getEnchantment("mending"); /** * Item disappears instead of dropping */ - public static final Enchantment VANISHING_CURSE = new EnchantmentWrapper("vanishing_curse"); + public static final Enchantment VANISHING_CURSE = getEnchantment("vanishing_curse"); /** * Walk quicker on soul blocks */ - public static final Enchantment SOUL_SPEED = new EnchantmentWrapper("soul_speed"); + public static final Enchantment SOUL_SPEED = getEnchantment("soul_speed"); /** * Walk quicker while sneaking */ - public static final Enchantment SWIFT_SNEAK = new EnchantmentWrapper("swift_sneak"); - - private static final Map byKey = new HashMap(); - private static final Map byName = new HashMap(); - private static boolean acceptingNew = true; - private final NamespacedKey key; - - public Enchantment(@NotNull NamespacedKey key) { - this.key = key; - } + public static final Enchantment SWIFT_SNEAK = getEnchantment("swift_sneak"); @NotNull - @Override - public NamespacedKey getKey() { - return key; + private static Enchantment getEnchantment(@NotNull String key) { + NamespacedKey namespacedKey = NamespacedKey.minecraft(key); + Enchantment enchantment = Registry.ENCHANTMENT.get(namespacedKey); + + Preconditions.checkNotNull(enchantment, "No Enchantment found for %s. This is a bug.", namespacedKey); + + return enchantment; } /** @@ -300,75 +296,21 @@ public abstract class Enchantment implements Keyed { */ public abstract boolean canEnchantItem(@NotNull ItemStack item); - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (!(obj instanceof Enchantment)) { - return false; - } - final Enchantment other = (Enchantment) obj; - if (!this.key.equals(other.key)) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return key.hashCode(); - } - - @Override - public String toString() { - return "Enchantment[" + key + ", " + getName() + "]"; - } - - /** - * Registers an enchantment with the given ID and object. - *

- * Generally not to be used from within a plugin. - * - * @param enchantment Enchantment to register - */ - public static void registerEnchantment(@NotNull Enchantment enchantment) { - if (byKey.containsKey(enchantment.key) || byName.containsKey(enchantment.getName())) { - throw new IllegalArgumentException("Cannot set already-set enchantment"); - } else if (!isAcceptingRegistrations()) { - throw new IllegalStateException("No longer accepting new enchantments (can only be done by the server implementation)"); - } - - byKey.put(enchantment.key, enchantment); - byName.put(enchantment.getName(), enchantment); - } - - /** - * Checks if this is accepting Enchantment registrations. - * - * @return True if the server Implementation may add enchantments - */ - public static boolean isAcceptingRegistrations() { - return acceptingNew; - } - - /** - * Stops accepting any enchantment registrations - */ - public static void stopAcceptingRegistrations() { - acceptingNew = false; - } - /** * Gets the Enchantment at the specified key * * @param key key to fetch * @return Resulting Enchantment, or null if not found + * @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead */ @Contract("null -> null") @Nullable + @Deprecated public static Enchantment getByKey(@Nullable NamespacedKey key) { - return byKey.get(key); + if (key == null) { + return null; + } + return Registry.ENCHANTMENT.get(key); } /** @@ -382,16 +324,74 @@ public abstract class Enchantment implements Keyed { @Contract("null -> null") @Nullable public static Enchantment getByName(@Nullable String name) { - return byName.get(name); + if (name == null) { + return null; + } + + name = convertLegacy(name); + return getByKey(NamespacedKey.fromString(name.toLowerCase())); } /** * Gets an array of all the registered {@link Enchantment}s * * @return Array of enchantments + * @deprecated use {@link Registry#iterator()} */ @NotNull + @Deprecated public static Enchantment[] values() { - return byName.values().toArray(new Enchantment[byName.size()]); + return Lists.newArrayList(Registry.ENCHANTMENT).toArray(new Enchantment[0]); + } + + private static String convertLegacy(String from) { + if (from == null) { + return null; + } + + switch (from.toLowerCase()) { + case "protection_environmental": + return "protection"; + case "protection_fire": + return "fire_protection"; + case "protection_fall": + return "feather_falling"; + case "protection_explosions": + return "blast_protection"; + case "protection_projectile": + return "projectile_protection"; + case "oxygen": + return "respiration"; + case "water_worker": + return "aqua_affinity"; + case "damage_all": + return "sharpness"; + case "damage_undead": + return "smite"; + case "damage_arthropods": + return "bane_of_arthropods"; + case "loot_bonus_mobs": + return "looting"; + case "sweeping_edge": + return "sweeping"; + case "dig_speed": + return "efficiency"; + case "durability": + return "unbreaking"; + case "loot_bonus_blocks": + return "fortune"; + case "arrow_damage": + return "power"; + case "arrow_knockback": + return "punch"; + case "arrow_fire": + return "flame"; + case "arrow_infinite": + return "infinity"; + case "luck": + return "luck_of_the_sea"; + } + + return from; } } diff --git a/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java b/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java index 9566e4306a..7ad7bcf9a9 100644 --- a/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java +++ b/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java @@ -1,15 +1,14 @@ package org.bukkit.enchantments; -import org.bukkit.NamespacedKey; -import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; /** * A simple wrapper for ease of selecting {@link Enchantment}s + * @deprecated only for backwards compatibility, EnchantmentWrapper is no longer used. */ -public class EnchantmentWrapper extends Enchantment { - public EnchantmentWrapper(@NotNull String name) { - super(NamespacedKey.minecraft(name)); +@Deprecated +public abstract class EnchantmentWrapper extends Enchantment { + protected EnchantmentWrapper() { } /** @@ -19,48 +18,6 @@ public class EnchantmentWrapper extends Enchantment { */ @NotNull public Enchantment getEnchantment() { - return Enchantment.getByKey(getKey()); - } - - @Override - public int getMaxLevel() { - return getEnchantment().getMaxLevel(); - } - - @Override - public int getStartLevel() { - return getEnchantment().getStartLevel(); - } - - @NotNull - @Override - public EnchantmentTarget getItemTarget() { - return getEnchantment().getItemTarget(); - } - - @Override - public boolean canEnchantItem(@NotNull ItemStack item) { - return getEnchantment().canEnchantItem(item); - } - - @NotNull - @Override - public String getName() { - return getEnchantment().getName(); - } - - @Override - public boolean isTreasure() { - return getEnchantment().isTreasure(); - } - - @Override - public boolean isCursed() { - return getEnchantment().isCursed(); - } - - @Override - public boolean conflictsWith(@NotNull Enchantment other) { - return getEnchantment().conflictsWith(other); + return this; } } diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionEffectType.java b/paper-api/src/main/java/org/bukkit/potion/PotionEffectType.java index 5f3aa6fd18..b7c394fb70 100644 --- a/paper-api/src/main/java/org/bukkit/potion/PotionEffectType.java +++ b/paper-api/src/main/java/org/bukkit/potion/PotionEffectType.java @@ -1,12 +1,13 @@ package org.bukkit.potion; import com.google.common.base.Preconditions; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.Lists; import org.bukkit.Color; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; +import org.bukkit.Registry; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -15,182 +16,187 @@ import org.jetbrains.annotations.Nullable; * Represents a type of potion and its effect on an entity. */ public abstract class PotionEffectType implements Keyed { + private static final BiMap ID_MAP = HashBiMap.create(); + /** * Increases movement speed. */ - public static final PotionEffectType SPEED = new PotionEffectTypeWrapper(1, "speed"); + public static final PotionEffectType SPEED = getPotionEffectType(1, "speed"); /** * Decreases movement speed. */ - public static final PotionEffectType SLOW = new PotionEffectTypeWrapper(2, "slowness"); + public static final PotionEffectType SLOW = getPotionEffectType(2, "slowness"); /** * Increases dig speed. */ - public static final PotionEffectType FAST_DIGGING = new PotionEffectTypeWrapper(3, "haste"); + public static final PotionEffectType FAST_DIGGING = getPotionEffectType(3, "haste"); /** * Decreases dig speed. */ - public static final PotionEffectType SLOW_DIGGING = new PotionEffectTypeWrapper(4, "mining_fatigue"); + public static final PotionEffectType SLOW_DIGGING = getPotionEffectType(4, "mining_fatigue"); /** * Increases damage dealt. */ - public static final PotionEffectType INCREASE_DAMAGE = new PotionEffectTypeWrapper(5, "strength"); + public static final PotionEffectType INCREASE_DAMAGE = getPotionEffectType(5, "strength"); /** * Heals an entity. */ - public static final PotionEffectType HEAL = new PotionEffectTypeWrapper(6, "instant_health"); + public static final PotionEffectType HEAL = getPotionEffectType(6, "instant_health"); /** * Hurts an entity. */ - public static final PotionEffectType HARM = new PotionEffectTypeWrapper(7, "instant_damage"); + public static final PotionEffectType HARM = getPotionEffectType(7, "instant_damage"); /** * Increases jump height. */ - public static final PotionEffectType JUMP = new PotionEffectTypeWrapper(8, "jump_boost"); + public static final PotionEffectType JUMP = getPotionEffectType(8, "jump_boost"); /** * Warps vision on the client. */ - public static final PotionEffectType CONFUSION = new PotionEffectTypeWrapper(9, "nausea"); + public static final PotionEffectType CONFUSION = getPotionEffectType(9, "nausea"); /** * Regenerates health. */ - public static final PotionEffectType REGENERATION = new PotionEffectTypeWrapper(10, "regeneration"); + public static final PotionEffectType REGENERATION = getPotionEffectType(10, "regeneration"); /** * Decreases damage dealt to an entity. */ - public static final PotionEffectType DAMAGE_RESISTANCE = new PotionEffectTypeWrapper(11, "resistance"); + public static final PotionEffectType DAMAGE_RESISTANCE = getPotionEffectType(11, "resistance"); /** * Stops fire damage. */ - public static final PotionEffectType FIRE_RESISTANCE = new PotionEffectTypeWrapper(12, "fire_resistance"); + public static final PotionEffectType FIRE_RESISTANCE = getPotionEffectType(12, "fire_resistance"); /** * Allows breathing underwater. */ - public static final PotionEffectType WATER_BREATHING = new PotionEffectTypeWrapper(13, "water_breathing"); + public static final PotionEffectType WATER_BREATHING = getPotionEffectType(13, "water_breathing"); /** * Grants invisibility. */ - public static final PotionEffectType INVISIBILITY = new PotionEffectTypeWrapper(14, "invisibility"); + public static final PotionEffectType INVISIBILITY = getPotionEffectType(14, "invisibility"); /** * Blinds an entity. */ - public static final PotionEffectType BLINDNESS = new PotionEffectTypeWrapper(15, "blindness"); + public static final PotionEffectType BLINDNESS = getPotionEffectType(15, "blindness"); /** * Allows an entity to see in the dark. */ - public static final PotionEffectType NIGHT_VISION = new PotionEffectTypeWrapper(16, "night_vision"); + public static final PotionEffectType NIGHT_VISION = getPotionEffectType(16, "night_vision"); /** * Increases hunger. */ - public static final PotionEffectType HUNGER = new PotionEffectTypeWrapper(17, "hunger"); + public static final PotionEffectType HUNGER = getPotionEffectType(17, "hunger"); /** * Decreases damage dealt by an entity. */ - public static final PotionEffectType WEAKNESS = new PotionEffectTypeWrapper(18, "weakness"); + public static final PotionEffectType WEAKNESS = getPotionEffectType(18, "weakness"); /** * Deals damage to an entity over time. */ - public static final PotionEffectType POISON = new PotionEffectTypeWrapper(19, "poison"); + public static final PotionEffectType POISON = getPotionEffectType(19, "poison"); /** * Deals damage to an entity over time and gives the health to the * shooter. */ - public static final PotionEffectType WITHER = new PotionEffectTypeWrapper(20, "wither"); + public static final PotionEffectType WITHER = getPotionEffectType(20, "wither"); /** * Increases the maximum health of an entity. */ - public static final PotionEffectType HEALTH_BOOST = new PotionEffectTypeWrapper(21, "health_boost"); + public static final PotionEffectType HEALTH_BOOST = getPotionEffectType(21, "health_boost"); /** * Increases the maximum health of an entity with health that cannot be * regenerated, but is refilled every 30 seconds. */ - public static final PotionEffectType ABSORPTION = new PotionEffectTypeWrapper(22, "absorption"); + public static final PotionEffectType ABSORPTION = getPotionEffectType(22, "absorption"); /** * Increases the food level of an entity each tick. */ - public static final PotionEffectType SATURATION = new PotionEffectTypeWrapper(23, "saturation"); + public static final PotionEffectType SATURATION = getPotionEffectType(23, "saturation"); /** * Outlines the entity so that it can be seen from afar. */ - public static final PotionEffectType GLOWING = new PotionEffectTypeWrapper(24, "glowing"); + public static final PotionEffectType GLOWING = getPotionEffectType(24, "glowing"); /** * Causes the entity to float into the air. */ - public static final PotionEffectType LEVITATION = new PotionEffectTypeWrapper(25, "levitation"); + public static final PotionEffectType LEVITATION = getPotionEffectType(25, "levitation"); /** * Loot table luck. */ - public static final PotionEffectType LUCK = new PotionEffectTypeWrapper(26, "luck"); + public static final PotionEffectType LUCK = getPotionEffectType(26, "luck"); /** * Loot table unluck. */ - public static final PotionEffectType UNLUCK = new PotionEffectTypeWrapper(27, "unluck"); + public static final PotionEffectType UNLUCK = getPotionEffectType(27, "unluck"); /** * Slows entity fall rate. */ - public static final PotionEffectType SLOW_FALLING = new PotionEffectTypeWrapper(28, "slow_falling"); + public static final PotionEffectType SLOW_FALLING = getPotionEffectType(28, "slow_falling"); /** * Effects granted by a nearby conduit. Includes enhanced underwater abilities. */ - public static final PotionEffectType CONDUIT_POWER = new PotionEffectTypeWrapper(29, "conduit_power"); + public static final PotionEffectType CONDUIT_POWER = getPotionEffectType(29, "conduit_power"); /** * Increses underwater movement speed.
* Squee'ek uh'k kk'kkkk squeek eee'eek. */ - public static final PotionEffectType DOLPHINS_GRACE = new PotionEffectTypeWrapper(30, "dolphins_grace"); + public static final PotionEffectType DOLPHINS_GRACE = getPotionEffectType(30, "dolphins_grace"); /** * Triggers a raid when the player enters a village.
* oof. */ - public static final PotionEffectType BAD_OMEN = new PotionEffectTypeWrapper(31, "bad_omen"); + public static final PotionEffectType BAD_OMEN = getPotionEffectType(31, "bad_omen"); /** * Reduces the cost of villager trades.
* \o/. */ - public static final PotionEffectType HERO_OF_THE_VILLAGE = new PotionEffectTypeWrapper(32, "hero_of_the_village"); + public static final PotionEffectType HERO_OF_THE_VILLAGE = getPotionEffectType(32, "hero_of_the_village"); /** * Causes the player's vision to dim occasionally. */ - public static final PotionEffectType DARKNESS = new PotionEffectTypeWrapper(33, "darkness"); + public static final PotionEffectType DARKNESS = getPotionEffectType(33, "darkness"); - private final int id; - private final NamespacedKey key; - - protected PotionEffectType(int id, @NotNull NamespacedKey key) { - this.id = id; - this.key = key; + @NotNull + private static PotionEffectType getPotionEffectType(int typeId, @NotNull String key) { + NamespacedKey namespacedKey = NamespacedKey.minecraft(key); + PotionEffectType potionEffectType = Registry.EFFECT.get(namespacedKey); + Preconditions.checkNotNull(potionEffectType, "No PotionEffectType found for %s. This is a bug.", namespacedKey); + if (typeId > 0) { + ID_MAP.put(typeId, potionEffectType); + } + return potionEffectType; } /** @@ -203,9 +209,22 @@ public abstract class PotionEffectType implements Keyed { * @see PotionBrewer#createEffect(PotionEffectType, int, int) */ @NotNull - public PotionEffect createEffect(int duration, int amplifier) { - return new PotionEffect(this, isInstant() ? 1 : (int) (duration * getDurationModifier()), amplifier); - } + public abstract PotionEffect createEffect(int duration, int amplifier); + + /** + * Returns whether the effect of this type happens once, immediately. + * + * @return whether this type is normally instant + */ + public abstract boolean isInstant(); + + /** + * Returns the color of this effect type. + * + * @return the color + */ + @NotNull + public abstract Color getColor(); /** * Returns the duration modifier applied to effects of this type. @@ -223,80 +242,34 @@ public abstract class PotionEffectType implements Keyed { * @deprecated Magic value */ @Deprecated - public int getId() { - return id; - } - - @NotNull - @Override - public NamespacedKey getKey() { - return key; - } + public abstract int getId(); /** * Returns the name of this effect type. * * @return The name of this effect type + * @deprecated only for backwards compatibility, use {@link #getKey()} instead. */ @NotNull + @Deprecated public abstract String getName(); - /** - * Returns whether the effect of this type happens once, immediately. - * - * @return whether this type is normally instant - */ - public abstract boolean isInstant(); - - /** - * Returns the color of this effect type. - * - * @return the color - */ - @NotNull - public abstract Color getColor(); - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (!(obj instanceof PotionEffectType)) { - return false; - } - final PotionEffectType other = (PotionEffectType) obj; - if (this.id != other.id) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return id; - } - - @Override - public String toString() { - return "PotionEffectType[" + id + ", " + getName() + "]"; - } - - private static final PotionEffectType[] byId = new PotionEffectType[34]; - private static final Map byName = new HashMap(); - private static final Map byKey = new HashMap(); - // will break on updates. - private static boolean acceptingNew = true; - /** * Gets the PotionEffectType at the specified key * * @param key key to fetch * @return Resulting PotionEffectType, or null if not found + * @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead. */ @Contract("null -> null") @Nullable + @Deprecated public static PotionEffectType getByKey(@Nullable NamespacedKey key) { - return byKey.get(key); + if (key == null) { + return null; + } + + return Registry.EFFECT.get(key); } /** @@ -309,9 +282,20 @@ public abstract class PotionEffectType implements Keyed { @Deprecated @Nullable public static PotionEffectType getById(int id) { - if (id >= byId.length || id < 0) - return null; - return byId[id]; + PotionEffectType type = ID_MAP.get(id); + + if (type != null) { + return type; + } + + for (PotionEffectType other : Registry.EFFECT) { + if (other.getId() == id) { + ID_MAP.put(id, other); + return other; + } + } + + return null; } /** @@ -319,48 +303,52 @@ public abstract class PotionEffectType implements Keyed { * * @param name Name of PotionEffectType to fetch * @return Resulting PotionEffectType, or null if not found. + * @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead. */ @Nullable + @Deprecated public static PotionEffectType getByName(@NotNull String name) { Preconditions.checkArgument(name != null, "name cannot be null"); - return byName.get(name.toLowerCase(java.util.Locale.ENGLISH)); + name = convertLegacy(name); + return Registry.EFFECT.get(NamespacedKey.fromString(name.toLowerCase(java.util.Locale.ENGLISH))); } /** - * Registers an effect type with the given object. - *

- * Generally not to be used from within a plugin. - * - * @param type PotionType to register - */ - public static void registerPotionEffectType(@NotNull PotionEffectType type) { - if (byId[type.id] != null || byName.containsKey(type.getName().toLowerCase(java.util.Locale.ENGLISH)) || byKey.containsKey(type.key)) { - throw new IllegalArgumentException("Cannot set already-set type"); - } else if (!acceptingNew) { - throw new IllegalStateException( - "No longer accepting new potion effect types (can only be done by the server implementation)"); - } - - byId[type.id] = type; - byName.put(type.getName().toLowerCase(java.util.Locale.ENGLISH), type); - byKey.put(type.key, type); - } - - /** - * Stops accepting any effect type registrations. - */ - public static void stopAcceptingRegistrations() { - acceptingNew = false; - } - - /** - * Returns an array of all the registered {@link PotionEffectType}s. - * This array is not necessarily in any particular order. - * - * @return Array of types. + * @return an array of all known PotionEffectTypes. + * @deprecated use {@link Registry#iterator()}. */ @NotNull + @Deprecated public static PotionEffectType[] values() { - return Arrays.copyOfRange(byId, 1, byId.length); + return Lists.newArrayList(Registry.EFFECT).toArray(new PotionEffectType[0]); + } + + private static String convertLegacy(String from) { + if (from == null) { + return null; + } + + switch (from.toLowerCase()) { + case "slow": + return "slowness"; + case "fast_digging": + return "haste"; + case "slow_digging": + return "mining_fatigue"; + case "increase_damage": + return "strength"; + case "heal": + return "instant_health"; + case "harm": + return "instant_damage"; + case "jump": + return "jump_boost"; + case "confusion": + return "nausea"; + case "damage_resistance": + return "resistance"; + } + + return from; } } diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java b/paper-api/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java index 6994981bde..a613debb03 100644 --- a/paper-api/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java +++ b/paper-api/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java @@ -1,23 +1,13 @@ package org.bukkit.potion; -import org.bukkit.Color; -import org.bukkit.NamespacedKey; import org.jetbrains.annotations.NotNull; -public class PotionEffectTypeWrapper extends PotionEffectType { - protected PotionEffectTypeWrapper(int id, @NotNull String name) { - super(id, NamespacedKey.minecraft(name)); - } - - @Override - public double getDurationModifier() { - return getType().getDurationModifier(); - } - - @NotNull - @Override - public String getName() { - return getType().getName(); +/** + * @deprecated only for backwards compatibility, PotionEffectTypeWrapper is no longer used. + */ +@Deprecated +public abstract class PotionEffectTypeWrapper extends PotionEffectType { + protected PotionEffectTypeWrapper() { } /** @@ -27,17 +17,6 @@ public class PotionEffectTypeWrapper extends PotionEffectType { */ @NotNull public PotionEffectType getType() { - return PotionEffectType.getByKey(getKey()); - } - - @Override - public boolean isInstant() { - return getType().isInstant(); - } - - @NotNull - @Override - public Color getColor() { - return getType().getColor(); + return this; } }