SPIGOT-6026: Pull PotionEffectType and Enchantment from registry

By: DerFrZocker <derrieple@gmail.com>
This commit is contained in:
Bukkit/Spigot
2023-12-06 03:40:00 +11:00
parent d569990c3b
commit 9ac8229b9b
5 changed files with 261 additions and 350 deletions

View File

@@ -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<Integer, PotionEffectType> 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.<br>
* 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.<br>
* 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.<br>
* \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<String, PotionEffectType> byName = new HashMap<String, PotionEffectType>();
private static final Map<NamespacedKey, PotionEffectType> byKey = new HashMap<NamespacedKey, PotionEffectType>();
// 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.
* <p>
* 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;
}
}

View File

@@ -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;
}
}