Change other enums / classes.

This commit is contained in:
DerFrZocker 2021-09-26 19:25:43 +02:00
parent 8b0d5418c6
commit f33b85a0fe
No known key found for this signature in database
GPG key ID: 713F71FFFE1DDF91
19 changed files with 1913 additions and 1831 deletions

View file

@ -102,6 +102,12 @@
<version>9.2</version> <version>9.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.12.4</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View file

@ -1,52 +1,71 @@
package org.bukkit; package org.bukkit;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import java.util.HashMap; import java.util.Map;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.util.OldEnum;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/** /**
* Represents the art on a painting * Represents the art on a painting.
* Listed Arts are present at the default server.
*/ */
public enum Art implements Keyed { public abstract class Art extends OldEnum<Art> implements Keyed {
KEBAB(0, 1, 1), @Deprecated
AZTEC(1, 1, 1), private static final Map<Integer, Art> BY_ID = Maps.newHashMap();
ALBAN(2, 1, 1),
AZTEC2(3, 1, 1),
BOMB(4, 1, 1),
PLANT(5, 1, 1),
WASTELAND(6, 1, 1),
POOL(7, 2, 1),
COURBET(8, 2, 1),
SEA(9, 2, 1),
SUNSET(10, 2, 1),
CREEBET(11, 2, 1),
WANDERER(12, 1, 2),
GRAHAM(13, 1, 2),
MATCH(14, 2, 2),
BUST(15, 2, 2),
STAGE(16, 2, 2),
VOID(17, 2, 2),
SKULL_AND_ROSES(18, 2, 2),
WITHER(19, 2, 2),
FIGHTERS(20, 4, 2),
POINTER(21, 4, 4),
PIGSCENE(22, 4, 4),
BURNING_SKULL(23, 4, 4),
SKELETON(24, 4, 3),
DONKEY_KONG(25, 4, 3);
private final int id, width, height; public static final Art KEBAB = getArt("kebab");
private final NamespacedKey key; public static final Art AZTEC = getArt("aztec");
private static final HashMap<String, Art> BY_NAME = Maps.newHashMap(); public static final Art ALBAN = getArt("alban");
private static final HashMap<Integer, Art> BY_ID = Maps.newHashMap(); public static final Art AZTEC2 = getArt("aztec2");
public static final Art BOMB = getArt("bomb");
public static final Art PLANT = getArt("plant");
public static final Art WASTELAND = getArt("wasteland");
public static final Art POOL = getArt("pool");
public static final Art COURBET = getArt("courbet");
public static final Art SEA = getArt("sea");
public static final Art SUNSET = getArt("sunset");
public static final Art CREEBET = getArt("creebet");
public static final Art WANDERER = getArt("wanderer");
public static final Art GRAHAM = getArt("graham");
public static final Art MATCH = getArt("match");
public static final Art BUST = getArt("bust");
public static final Art STAGE = getArt("stage");
public static final Art VOID = getArt("void");
public static final Art SKULL_AND_ROSES = getArt("skull_and_roses");
public static final Art WITHER = getArt("wither");
public static final Art FIGHTERS = getArt("fighters");
public static final Art POINTER = getArt("pointer");
public static final Art PIGSCENE = getArt("pigscene");
public static final Art BURNING_SKULL = getArt("burning_skull");
public static final Art SKELETON = getArt("skeleton");
public static final Art DONKEY_KONG = getArt("donkey_kong");
private Art(int id, int width, int height) { @NotNull
this.id = id; private static Art getArt(@NotNull String key) {
this.width = width; NamespacedKey namespacedKey = NamespacedKey.minecraft(key);
this.height = height; Art art = Registry.ART.get(namespacedKey);
this.key = NamespacedKey.minecraft(name().toLowerCase(java.util.Locale.ENGLISH)); Preconditions.checkNotNull(art, "No Art found for %s. This is a bug.", namespacedKey);
BY_ID.put(art.ordinal(), art);
return art;
}
/**
* Get a painting by its unique name
* <p>
* This ignores underscores and capitalization
*
* @param name The name
* @return The painting
*/
@Nullable
public static Art getByName(@NotNull String name) {
Validate.notNull(name, "Name cannot be null");
return Registry.ART.get(NamespacedKey.fromString(name.toLowerCase(java.util.Locale.ENGLISH)));
} }
/** /**
@ -54,18 +73,14 @@ public enum Art implements Keyed {
* *
* @return The width of the painting, in blocks * @return The width of the painting, in blocks
*/ */
public int getBlockWidth() { public abstract int getBlockWidth();
return width;
}
/** /**
* Gets the height of the painting, in blocks * Gets the height of the painting, in blocks
* *
* @return The height of the painting, in blocks * @return The height of the painting, in blocks
*/ */
public int getBlockHeight() { public abstract int getBlockHeight();
return height;
}
/** /**
* Get the ID of this painting. * Get the ID of this painting.
@ -74,15 +89,7 @@ public enum Art implements Keyed {
* @deprecated Magic value * @deprecated Magic value
*/ */
@Deprecated @Deprecated
public int getId() { public abstract int getId();
return id;
}
@NotNull
@Override
public NamespacedKey getKey() {
return key;
}
/** /**
* Get a painting by its numeric ID * Get a painting by its numeric ID
@ -98,24 +105,25 @@ public enum Art implements Keyed {
} }
/** /**
* Get a painting by its unique name * @param name of the art.
* <p> * @return the art with the given name.
* This ignores underscores and capitalization * @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead.
*
* @param name The name
* @return The painting
*/ */
@Nullable @NotNull
public static Art getByName(@NotNull String name) { @Deprecated
Validate.notNull(name, "Name cannot be null"); public static Art valueOf(@NotNull String name) {
Art art = Registry.ART.get(NamespacedKey.fromString(name.toLowerCase()));
return BY_NAME.get(name.toLowerCase(java.util.Locale.ENGLISH)); Preconditions.checkArgument(art != null, "No Art found with the name %s", name);
return art;
} }
static { /**
for (Art art : values()) { * @return an array of all known Arts.
BY_ID.put(art.id, art); * @deprecated use {@link Registry#iterator()}.
BY_NAME.put(art.toString().toLowerCase(java.util.Locale.ENGLISH), art); */
} @NotNull
@Deprecated
public static Art[] values() {
return Lists.newArrayList(Registry.ART).toArray(new Art[0]);
} }
} }

View file

@ -1,24 +1,46 @@
package org.bukkit; package org.bukkit;
import java.util.Locale; import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.bukkit.util.OldEnum;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public enum Fluid implements Keyed { public abstract class Fluid extends OldEnum<Fluid> implements Keyed {
WATER, public static final Fluid EMPTY = getFluid("empty");
FLOWING_WATER, public static final Fluid WATER = getFluid("water");
LAVA, public static final Fluid FLOWING_WATER = getFluid("flowing_water");
FLOWING_LAVA; public static final Fluid LAVA = getFluid("lava");
public static final Fluid FLOWING_LAVA = getFluid("flowing_lava");
private final NamespacedKey key;
private Fluid() {
this.key = NamespacedKey.minecraft(this.name().toLowerCase(Locale.ROOT));
}
@NotNull @NotNull
@Override private static Fluid getFluid(@NotNull String key) {
public NamespacedKey getKey() { NamespacedKey namespacedKey = NamespacedKey.minecraft(key);
return key; Fluid fluid = Registry.FLUID.get(namespacedKey);
Preconditions.checkNotNull(fluid, "No Fluid found for %s. This is a bug.", namespacedKey);
return fluid;
}
/**
* @param name of the fluid.
* @return the fluid with the given name.
* @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead.
*/
@NotNull
@Deprecated
public static Fluid valueOf(@NotNull String name) {
Fluid fluid = Registry.FLUID.get(NamespacedKey.fromString(name.toLowerCase()));
Preconditions.checkArgument(fluid != null, "No Fluid found with the name %s", name);
return fluid;
}
/**
* @return an array of all known Fluid.
* @deprecated use {@link Registry#iterator()}.
*/
@NotNull
@Deprecated
public static Fluid[] values() {
return Lists.newArrayList(Registry.FLUID).toArray(new Fluid[0]);
} }
} }

View file

@ -2,7 +2,6 @@ package org.bukkit;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -16,6 +15,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Villager; import org.bukkit.entity.Villager;
import org.bukkit.entity.memory.MemoryKey; import org.bukkit.entity.memory.MemoryKey;
import org.bukkit.loot.LootTables; import org.bukkit.loot.LootTables;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -52,19 +52,19 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
* *
* @see Art * @see Art
*/ */
Registry<Art> ART = new SimpleRegistry<>(Art.class); Registry<Art> ART = Objects.requireNonNull(Bukkit.getRegistry(Art.class), "No registry present for Art. This is a bug.");
/** /**
* Attribute. * Attribute.
* *
* @see Attribute * @see Attribute
*/ */
Registry<Attribute> ATTRIBUTE = new SimpleRegistry<>(Attribute.class); Registry<Attribute> ATTRIBUTE = Objects.requireNonNull(Bukkit.getRegistry(Attribute.class), "No registry present for Attribute. This is a bug.");
/** /**
* Server biomes. * Server biomes.
* *
* @see Biome * @see Biome
*/ */
Registry<Biome> BIOME = Objects.requireNonNull(Bukkit.getRegistry(Biome.class), "No registry present for Biome"); Registry<Biome> BIOME = Objects.requireNonNull(Bukkit.getRegistry(Biome.class), "No registry present for Biome. This is a bug.");
/** /**
* Custom boss bars. * Custom boss bars.
* *
@ -90,26 +90,13 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
* *
* @see Enchantment#getByKey(org.bukkit.NamespacedKey) * @see Enchantment#getByKey(org.bukkit.NamespacedKey)
*/ */
Registry<Enchantment> ENCHANTMENT = new Registry<Enchantment>() { Registry<Enchantment> ENCHANTMENT = Objects.requireNonNull(Bukkit.getRegistry(Enchantment.class), "No registry present for Enchantment. This is a bug.");
@Nullable
@Override
public Enchantment get(@NotNull NamespacedKey key) {
return Enchantment.getByKey(key);
}
@NotNull
@Override
public Iterator<Enchantment> iterator() {
return Arrays.asList(Enchantment.values()).iterator();
}
};
/** /**
* Server entity types. * Server entity types.
* *
* @see EntityType * @see EntityType
*/ */
Registry<EntityType> ENTITY_TYPE = new SimpleRegistry<>(EntityType.class, (entity) -> entity != EntityType.UNKNOWN); Registry<EntityType> ENTITY_TYPE = Objects.requireNonNull(Bukkit.getRegistry(EntityType.class), "No registry present for EntityType. This is a bug.");
/** /**
* Default server loot tables. * Default server loot tables.
* *
@ -133,19 +120,19 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
* *
* @see Sound * @see Sound
*/ */
Registry<Sound> SOUNDS = new SimpleRegistry<>(Sound.class); Registry<Sound> SOUNDS = Objects.requireNonNull(Bukkit.getRegistry(Sound.class), "No registry present for Sound. This is a bug.");
/** /**
* Villager profession. * Villager profession.
* *
* @see Villager.Profession * @see Villager.Profession
*/ */
Registry<Villager.Profession> VILLAGER_PROFESSION = new SimpleRegistry<>(Villager.Profession.class); Registry<Villager.Profession> VILLAGER_PROFESSION = Objects.requireNonNull(Bukkit.getRegistry(Villager.Profession.class), "No registry present for Villager Profession. This is a bug.");
/** /**
* Villager type. * Villager type.
* *
* @see Villager.Type * @see Villager.Type
*/ */
Registry<Villager.Type> VILLAGER_TYPE = new SimpleRegistry<>(Villager.Type.class); Registry<Villager.Type> VILLAGER_TYPE = Objects.requireNonNull(Bukkit.getRegistry(Villager.Type.class), "No registry present for Villager Type. This is a bug.");
/** /**
* Memory Keys. * Memory Keys.
* *
@ -170,7 +157,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
* *
* @see Fluid * @see Fluid
*/ */
Registry<Fluid> FLUID = new SimpleRegistry<>(Fluid.class); Registry<Fluid> FLUID = Objects.requireNonNull(Bukkit.getRegistry(Fluid.class), "No registry present for Fluid. This is a bug.");
/** /**
* Game events. * Game events.
* *
@ -191,6 +178,13 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
} }
}; };
/**
* Server potion effect types.
*
* @see PotionEffectType
*/
Registry<PotionEffectType> POTION_EFFECT_TYPE = Objects.requireNonNull(Bukkit.getRegistry(PotionEffectType.class), "No registry present for Potion Effect Type. This is a bug.");
/** /**
* Get the object by its key. * Get the object by its key.
* *

File diff suppressed because it is too large Load diff

View file

@ -1,76 +1,109 @@
package org.bukkit.attribute; package org.bukkit.attribute;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.bukkit.Keyed; import org.bukkit.Keyed;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.util.OldEnum;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* Types of attributes which may be present on an {@link Attributable}. * Types of attributes which may be present on an {@link Attributable}.
*/ */
public enum Attribute implements Keyed { public abstract class Attribute extends OldEnum<Attribute> implements Keyed {
/** /**
* Maximum health of an Entity. * Maximum health of an Entity.
*/ */
GENERIC_MAX_HEALTH("generic.max_health"), public static final Attribute GENERIC_MAX_HEALTH = getAttribute("generic.max_health");
/** /**
* Range at which an Entity will follow others. * Range at which an Entity will follow others.
*/ */
GENERIC_FOLLOW_RANGE("generic.follow_range"), public static final Attribute GENERIC_FOLLOW_RANGE = getAttribute("generic.follow_range");
/** /**
* Resistance of an Entity to knockback. * Resistance of an Entity to knockback.
*/ */
GENERIC_KNOCKBACK_RESISTANCE("generic.knockback_resistance"), public static final Attribute GENERIC_KNOCKBACK_RESISTANCE = getAttribute("generic.knockback_resistance");
/** /**
* Movement speed of an Entity. * Movement speed of an Entity.
*/ */
GENERIC_MOVEMENT_SPEED("generic.movement_speed"), public static final Attribute GENERIC_MOVEMENT_SPEED = getAttribute("generic.movement_speed");
/** /**
* Flying speed of an Entity. * Flying speed of an Entity.
*/ */
GENERIC_FLYING_SPEED("generic.flying_speed"), public static final Attribute GENERIC_FLYING_SPEED = getAttribute("generic.flying_speed");
/** /**
* Attack damage of an Entity. * Attack damage of an Entity.
*/ */
GENERIC_ATTACK_DAMAGE("generic.attack_damage"), public static final Attribute GENERIC_ATTACK_DAMAGE = getAttribute("generic.attack_damage");
/** /**
* Attack knockback of an Entity. * Attack knockback of an Entity.
*/ */
GENERIC_ATTACK_KNOCKBACK("generic.attack_knockback"), public static final Attribute GENERIC_ATTACK_KNOCKBACK = getAttribute("generic.attack_knockback");
/** /**
* Attack speed of an Entity. * Attack speed of an Entity.
*/ */
GENERIC_ATTACK_SPEED("generic.attack_speed"), public static final Attribute GENERIC_ATTACK_SPEED = getAttribute("generic.attack_speed");
/** /**
* Armor bonus of an Entity. * Armor bonus of an Entity.
*/ */
GENERIC_ARMOR("generic.armor"), public static final Attribute GENERIC_ARMOR = getAttribute("generic.armor");
/** /**
* Armor durability bonus of an Entity. * Armor durability bonus of an Entity.
*/ */
GENERIC_ARMOR_TOUGHNESS("generic.armor_toughness"), public static final Attribute GENERIC_ARMOR_TOUGHNESS = getAttribute("generic.armor_toughness");
/** /**
* Luck bonus of an Entity. * Luck bonus of an Entity.
*/ */
GENERIC_LUCK("generic.luck"), public static final Attribute GENERIC_LUCK = getAttribute("generic.luck");
/** /**
* Strength with which a horse will jump. * Strength with which a horse will jump.
*/ */
HORSE_JUMP_STRENGTH("horse.jump_strength"), public static final Attribute HORSE_JUMP_STRENGTH = getAttribute("horse.jump_strength");
/** /**
* Chance of a zombie to spawn reinforcements. * Chance of a zombie to spawn reinforcements.
*/ */
ZOMBIE_SPAWN_REINFORCEMENTS("zombie.spawn_reinforcements"); public static final Attribute ZOMBIE_SPAWN_REINFORCEMENTS = getAttribute("zombie.spawn_reinforcements");
private final NamespacedKey key; private static Attribute getAttribute(@NotNull String key) {
NamespacedKey namespacedKey = NamespacedKey.minecraft(key);
private Attribute(String key) { Attribute attribute = Registry.ATTRIBUTE.get(namespacedKey);
this.key = NamespacedKey.minecraft(key); Preconditions.checkNotNull(attribute, "No Attribute found for %s. This is a bug.", namespacedKey);
return attribute;
} }
/**
* @param name of the attribute.
* @return the attribute with the given name.
* @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead.
*/
@NotNull @NotNull
@Override @Deprecated
public NamespacedKey getKey() { public static Attribute valueOf(@NotNull String name) {
return key; Attribute attribute = Registry.ATTRIBUTE.get(NamespacedKey.fromString(name.toLowerCase()));
if (attribute != null) {
return attribute;
}
// Attribute keys can have dots in them which where converted to _. Since converting
// the _ back to a dot would be to complex (since not all _ need to be converted back) we use the field name.
try {
attribute = (Attribute) Attribute.class.getField(name).get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
attribute = null;
}
Preconditions.checkArgument(attribute != null, "No Attribute found with the name %s", name);
return attribute;
}
/**
* @return an array of all known Attributes.
* @deprecated use {@link Registry#iterator()}.
*/
@NotNull
@Deprecated
public static Attribute[] values() {
return Lists.newArrayList(Registry.ATTRIBUTE).toArray(new Attribute[0]);
} }
} }

View file

@ -4,8 +4,8 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.bukkit.Keyed; import org.bukkit.Keyed;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.OldEnum;
import org.bukkit.Registry; import org.bukkit.Registry;
import org.bukkit.util.OldEnum;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@ -107,7 +107,7 @@ public abstract class Biome extends OldEnum<Biome> implements Keyed {
public static final Biome CUSTOM = getBiome("custom"); public static final Biome CUSTOM = getBiome("custom");
@NotNull @NotNull
private static Biome getBiome(String key) { private static Biome getBiome(@NotNull String key) {
NamespacedKey namespacedKey = NamespacedKey.minecraft(key); NamespacedKey namespacedKey = NamespacedKey.minecraft(key);
Biome biome = Registry.BIOME.get(namespacedKey); Biome biome = Registry.BIOME.get(namespacedKey);
Preconditions.checkNotNull(biome, "No Biome found for %s. This is a bug.", namespacedKey); Preconditions.checkNotNull(biome, "No Biome found for %s. This is a bug.", namespacedKey);
@ -121,14 +121,14 @@ public abstract class Biome extends OldEnum<Biome> implements Keyed {
*/ */
@NotNull @NotNull
@Deprecated @Deprecated
public static Biome valueOf(String name) { public static Biome valueOf(@NotNull String name) {
Biome biome = Registry.BIOME.get(NamespacedKey.fromString(name.toLowerCase())); Biome biome = Registry.BIOME.get(NamespacedKey.fromString(name.toLowerCase()));
Preconditions.checkArgument(biome != null, "No Biome found with the name %s", name); Preconditions.checkArgument(biome != null, "No Biome found with the name %s", name);
return biome; return biome;
} }
/** /**
* @return an array of all know Biomes. * @return an array of all known Biomes.
* @deprecated use {@link Registry#iterator()}. * @deprecated use {@link Registry#iterator()}.
*/ */
@NotNull @NotNull

View file

@ -1,9 +1,10 @@
package org.bukkit.enchantments; package org.bukkit.enchantments;
import java.util.HashMap; import com.google.common.base.Preconditions;
import java.util.Map; import com.google.common.collect.Lists;
import org.bukkit.Keyed; import org.bukkit.Keyed;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -16,208 +17,201 @@ public abstract class Enchantment implements Keyed {
/** /**
* Provides protection against environmental damage * Provides protection against environmental damage
*/ */
public static final Enchantment PROTECTION_ENVIRONMENTAL = new EnchantmentWrapper("protection"); public static final Enchantment PROTECTION = getEnchantment("protection");
/** /**
* Provides protection against fire damage * Provides protection against fire damage
*/ */
public static final Enchantment PROTECTION_FIRE = new EnchantmentWrapper("fire_protection"); public static final Enchantment FIRE_PROTECTION = getEnchantment("fire_protection");
/** /**
* Provides protection against fall damage * Provides protection against fall damage
*/ */
public static final Enchantment PROTECTION_FALL = new EnchantmentWrapper("feather_falling"); public static final Enchantment FEATHER_FALLING = getEnchantment("feather_falling");
/** /**
* Provides protection against explosive damage * Provides protection against explosive damage
*/ */
public static final Enchantment PROTECTION_EXPLOSIONS = new EnchantmentWrapper("blast_protection"); public static final Enchantment BLAST_PROTECTION = getEnchantment("blast_protection");
/** /**
* Provides protection against projectile damage * Provides protection against projectile damage
*/ */
public static final Enchantment PROTECTION_PROJECTILE = new EnchantmentWrapper("projectile_protection"); public static final Enchantment PROJECTILE_PROTECTION = getEnchantment("projectile_protection");
/** /**
* Decreases the rate of air loss whilst underwater * Decreases the rate of air loss whilst underwater
*/ */
public static final Enchantment OXYGEN = new EnchantmentWrapper("respiration"); public static final Enchantment RESPIRATION = getEnchantment("respiration");
/** /**
* Increases the speed at which a player may mine underwater * Increases the speed at which a player may mine underwater
*/ */
public static final Enchantment WATER_WORKER = new EnchantmentWrapper("aqua_affinity"); public static final Enchantment AQUA_AFFINITY = getEnchantment("aqua_affinity");
/** /**
* Damages the attacker * Damages the attacker
*/ */
public static final Enchantment THORNS = new EnchantmentWrapper("thorns"); public static final Enchantment THORNS = getEnchantment("thorns");
/** /**
* Increases walking speed while in water * 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 * 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 * 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 * Increases damage against all targets
*/ */
public static final Enchantment DAMAGE_ALL = new EnchantmentWrapper("sharpness"); public static final Enchantment SHARPNESS = getEnchantment("sharpness");
/** /**
* Increases damage against undead targets * Increases damage against undead targets
*/ */
public static final Enchantment DAMAGE_UNDEAD = new EnchantmentWrapper("smite"); public static final Enchantment SMITE = getEnchantment("smite");
/** /**
* Increases damage against arthropod targets * Increases damage against arthropod targets
*/ */
public static final Enchantment DAMAGE_ARTHROPODS = new EnchantmentWrapper("bane_of_arthropods"); public static final Enchantment BANE_OF_ARTHROPODS = getEnchantment("bane_of_arthropods");
/** /**
* All damage to other targets will knock them back when hit * 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 * 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 * Provides a chance of gaining extra loot when killing monsters
*/ */
public static final Enchantment LOOT_BONUS_MOBS = new EnchantmentWrapper("looting"); public static final Enchantment LOOTING = getEnchantment("looting");
/** /**
* Increases damage against targets when using a sweep attack * Increases damage against targets when using a sweep attack
*/ */
public static final Enchantment SWEEPING_EDGE = new EnchantmentWrapper("sweeping"); public static final Enchantment SWEEPING = getEnchantment("sweeping");
/** /**
* Increases the rate at which you mine/dig * Increases the rate at which you mine/dig
*/ */
public static final Enchantment DIG_SPEED = new EnchantmentWrapper("efficiency"); public static final Enchantment EFFICIENCY = getEnchantment("efficiency");
/** /**
* Allows blocks to drop themselves instead of fragments (for example, * Allows blocks to drop themselves instead of fragments (for example,
* stone instead of cobblestone) * 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 * Decreases the rate at which a tool looses durability
*/ */
public static final Enchantment DURABILITY = new EnchantmentWrapper("unbreaking"); public static final Enchantment UNBREAKING = getEnchantment("unbreaking");
/** /**
* Provides a chance of gaining extra loot when destroying blocks * Provides a chance of gaining extra loot when destroying blocks
*/ */
public static final Enchantment LOOT_BONUS_BLOCKS = new EnchantmentWrapper("fortune"); public static final Enchantment FORTUNE = getEnchantment("fortune");
/** /**
* Provides extra damage when shooting arrows from bows * Provides extra damage when shooting arrows from bows
*/ */
public static final Enchantment ARROW_DAMAGE = new EnchantmentWrapper("power"); public static final Enchantment POWER = getEnchantment("power");
/** /**
* Provides a knockback when an entity is hit by an arrow from a bow * 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 PUNCH = getEnchantment("punch");
/** /**
* Sets entities on fire when hit by arrows shot from a bow * 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 FLAME = getEnchantment("flame");
/** /**
* Provides infinite arrows when shooting a bow * Provides infinite arrows when shooting a bow
*/ */
public static final Enchantment ARROW_INFINITE = new EnchantmentWrapper("infinity"); public static final Enchantment INFINITY = getEnchantment("infinity");
/** /**
* Decreases odds of catching worthless junk * Decreases odds of catching worthless junk
*/ */
public static final Enchantment LUCK = new EnchantmentWrapper("luck_of_the_sea"); public static final Enchantment LUCK_OF_THE_SEA = getEnchantment("luck_of_the_sea");
/** /**
* Increases rate of fish biting your hook * 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 * 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 * 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 * 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 * Strikes lightning when a mob is hit with a trident if conditions are
* stormy * stormy
*/ */
public static final Enchantment CHANNELING = new EnchantmentWrapper("channeling"); public static final Enchantment CHANNELING = getEnchantment("channeling");
/** /**
* Shoot multiple arrows from crossbows * Shoot multiple arrows from crossbows
*/ */
public static final Enchantment MULTISHOT = new EnchantmentWrapper("multishot"); public static final Enchantment MULTISHOT = getEnchantment("multishot");
/** /**
* Charges crossbows quickly * 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 * 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 * 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 * 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 * Walk quicker on soul blocks
*/ */
public static final Enchantment SOUL_SPEED = new EnchantmentWrapper("soul_speed"); public static final Enchantment SOUL_SPEED = getEnchantment("soul_speed");
private static final Map<NamespacedKey, Enchantment> byKey = new HashMap<NamespacedKey, Enchantment>();
private static final Map<String, Enchantment> byName = new HashMap<String, Enchantment>();
private static boolean acceptingNew = true;
private final NamespacedKey key;
public Enchantment(@NotNull NamespacedKey key) {
this.key = key;
}
@NotNull @NotNull
@Override private static Enchantment getEnchantment(@NotNull String key) {
public NamespacedKey getKey() { NamespacedKey namespacedKey = NamespacedKey.minecraft(key);
return key; Enchantment enchantment = Registry.ENCHANTMENT.get(namespacedKey);
Preconditions.checkNotNull(enchantment, "No Enchantment found for %s. This is a bug.", namespacedKey);
return enchantment;
} }
/** /**
@ -295,65 +289,6 @@ public abstract class Enchantment implements Keyed {
*/ */
public abstract boolean canEnchantItem(@NotNull ItemStack item); 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.
* <p>
* 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 * Gets the Enchantment at the specified key
* *
@ -363,7 +298,10 @@ public abstract class Enchantment implements Keyed {
@Contract("null -> null") @Contract("null -> null")
@Nullable @Nullable
public static Enchantment getByKey(@Nullable NamespacedKey key) { public static Enchantment getByKey(@Nullable NamespacedKey key) {
return byKey.get(key); if (key == null) {
return null;
}
return Registry.ENCHANTMENT.get(key);
} }
/** /**
@ -377,16 +315,50 @@ public abstract class Enchantment implements Keyed {
@Contract("null -> null") @Contract("null -> null")
@Nullable @Nullable
public static Enchantment getByName(@Nullable String name) { public static Enchantment getByName(@Nullable String name) {
return byName.get(name); if (name == null) {
return null;
}
return getByKey(NamespacedKey.fromString(name));
} }
/** /**
* Gets an array of all the registered {@link Enchantment}s * Gets an array of all the registered {@link Enchantment}s
* *
* @return Array of enchantments * @return Array of enchantments
* @deprecated use {@link Registry#iterator()}
*/ */
@NotNull @NotNull
@Deprecated
public static Enchantment[] values() { public static Enchantment[] values() {
return byName.values().toArray(new Enchantment[byName.size()]); return Lists.newArrayList(Registry.ENCHANTMENT).toArray(new Enchantment[0]);
} }
/**
* Registers an enchantment with the given ID and object.
* <p>
* Generally not to be used from within a plugin.
*
* @param enchantment Enchantment to register
* @deprecated only for backwards compatibility, has no effect.
*/
@Deprecated
public static void registerEnchantment(@NotNull Enchantment enchantment) {}
/**
* Checks if this is accepting Enchantment registrations.
*
* @return True if the server Implementation may add enchantments
* @deprecated only for backwards compatibility, has no effect.
*/
@Deprecated
public static boolean isAcceptingRegistrations() {
return false;
}
/**
* Stops accepting any enchantment registrations
* @deprecated only for backwards compatibility, has no effect.
*/
@Deprecated
public static void stopAcceptingRegistrations() {}
} }

View file

@ -6,10 +6,11 @@ import org.jetbrains.annotations.NotNull;
/** /**
* A simple wrapper for ease of selecting {@link Enchantment}s * A simple wrapper for ease of selecting {@link Enchantment}s
* @deprecated only for backwards compatibility, PotionEffectTypeWrapper is no longer used.
*/ */
@Deprecated
public class EnchantmentWrapper extends Enchantment { public class EnchantmentWrapper extends Enchantment {
public EnchantmentWrapper(@NotNull String name) { public EnchantmentWrapper(@NotNull String name) {
super(NamespacedKey.minecraft(name));
} }
/** /**
@ -63,4 +64,10 @@ public class EnchantmentWrapper extends Enchantment {
public boolean conflictsWith(@NotNull Enchantment other) { public boolean conflictsWith(@NotNull Enchantment other) {
return getEnchantment().conflictsWith(other); return getEnchantment().conflictsWith(other);
} }
@NotNull
@Override
public NamespacedKey getKey() {
return getEnchantment().getKey();
}
} }

View file

@ -1,11 +1,13 @@
package org.bukkit.entity; package org.bukkit.entity;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import java.util.HashMap; import com.google.common.collect.BiMap;
import java.util.Map; import com.google.common.collect.HashBiMap;
import com.google.common.collect.Lists;
import org.bukkit.Keyed; import org.bukkit.Keyed;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.minecart.CommandMinecart; import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.entity.minecart.ExplosiveMinecart; import org.bukkit.entity.minecart.ExplosiveMinecart;
@ -16,11 +18,13 @@ import org.bukkit.entity.minecart.SpawnerMinecart;
import org.bukkit.entity.minecart.StorageMinecart; import org.bukkit.entity.minecart.StorageMinecart;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.OldEnum;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public enum EntityType implements Keyed { public abstract class EntityType extends OldEnum<EntityType> implements Keyed {
private static final BiMap<Short, EntityType> ID_MAP = HashBiMap.create();
// These strings MUST match the strings in nms.EntityTypes and are case sensitive. // These strings MUST match the strings in nms.EntityTypes and are case sensitive.
/** /**
@ -29,311 +33,294 @@ public enum EntityType implements Keyed {
* Spawn with {@link World#dropItem(Location, ItemStack)} or {@link * Spawn with {@link World#dropItem(Location, ItemStack)} or {@link
* World#dropItemNaturally(Location, ItemStack)} * World#dropItemNaturally(Location, ItemStack)}
*/ */
DROPPED_ITEM("item", Item.class, 1, false), public static final EntityType ITEM = getEntityType("item", 1);
/** /**
* An experience orb. * An experience orb.
*/ */
EXPERIENCE_ORB("experience_orb", ExperienceOrb.class, 2), public static final EntityType EXPERIENCE_ORB = getEntityType("experience_orb", 2);
/** /**
* @see AreaEffectCloud * @see AreaEffectCloud
*/ */
AREA_EFFECT_CLOUD("area_effect_cloud", AreaEffectCloud.class, 3), public static final EntityType AREA_EFFECT_CLOUD = getEntityType("area_effect_cloud", 3);
/** /**
* @see ElderGuardian * @see ElderGuardian
*/ */
ELDER_GUARDIAN("elder_guardian", ElderGuardian.class, 4), public static final EntityType ELDER_GUARDIAN = getEntityType("elder_guardian", 4);
/** /**
* @see WitherSkeleton * @see WitherSkeleton
*/ */
WITHER_SKELETON("wither_skeleton", WitherSkeleton.class, 5), public static final EntityType WITHER_SKELETON = getEntityType("wither_skeleton", 5);
/** /**
* @see Stray * @see Stray
*/ */
STRAY("stray", Stray.class, 6), public static final EntityType STRAY = getEntityType("stray", 6);
/** /**
* A flying chicken egg. * A flying chicken egg.
*/ */
EGG("egg", Egg.class, 7), public static final EntityType EGG = getEntityType("egg", 7);
/** /**
* A leash attached to a fencepost. * A leash attached to a fencepost.
*/ */
LEASH_HITCH("leash_knot", LeashHitch.class, 8), public static final EntityType LEASH_KNOT = getEntityType("leash_knot", 8);
/** /**
* A painting on a wall. * A painting on a wall.
*/ */
PAINTING("painting", Painting.class, 9), public static final EntityType PAINTING = getEntityType("painting", 9);
/** /**
* An arrow projectile; may get stuck in the ground. * An arrow projectile; may get stuck in the ground.
*/ */
ARROW("arrow", Arrow.class, 10), public static final EntityType ARROW = getEntityType("arrow", 10);
/** /**
* A flying snowball. * A flying snowball.
*/ */
SNOWBALL("snowball", Snowball.class, 11), public static final EntityType SNOWBALL = getEntityType("snowball", 11);
/** /**
* A flying large fireball, as thrown by a Ghast for example. * A flying large fireball, as thrown by a Ghast for example.
*/ */
FIREBALL("fireball", LargeFireball.class, 12), public static final EntityType FIREBALL = getEntityType("fireball", 12);
/** /**
* A flying small fireball, such as thrown by a Blaze or player. * A flying small fireball, such as thrown by a Blaze or player.
*/ */
SMALL_FIREBALL("small_fireball", SmallFireball.class, 13), public static final EntityType SMALL_FIREBALL = getEntityType("small_fireball", 13);
/** /**
* A flying ender pearl. * A flying ender pearl.
*/ */
ENDER_PEARL("ender_pearl", EnderPearl.class, 14), public static final EntityType ENDER_PEARL = getEntityType("ender_pearl", 14);
/** /**
* An ender eye signal. * An ender eye signal.
*/ */
ENDER_SIGNAL("eye_of_ender", EnderSignal.class, 15), public static final EntityType EYE_OF_ENDER = getEntityType("eye_of_ender", 15);
/** /**
* A flying splash potion. * A flying splash potion.
*/ */
SPLASH_POTION("potion", ThrownPotion.class, 16, false), public static final EntityType POTION = getEntityType("potion", 16);
/** /**
* A flying experience bottle. * A flying experience bottle.
*/ */
THROWN_EXP_BOTTLE("experience_bottle", ThrownExpBottle.class, 17), public static final EntityType EXPERIENCE_BOTTLE = getEntityType("experience_bottle", 17);
/** /**
* An item frame on a wall. * An item frame on a wall.
*/ */
ITEM_FRAME("item_frame", ItemFrame.class, 18), public static final EntityType ITEM_FRAME = getEntityType("item_frame", 18);
/** /**
* A flying wither skull projectile. * A flying wither skull projectile.
*/ */
WITHER_SKULL("wither_skull", WitherSkull.class, 19), public static final EntityType WITHER_SKULL = getEntityType("wither_skull", 19);
/** /**
* Primed TNT that is about to explode. * Primed TNT that is about to explode.
*/ */
PRIMED_TNT("tnt", TNTPrimed.class, 20), public static final EntityType TNT = getEntityType("tnt", 20);
/** /**
* A block that is going to or is about to fall. * A block that is going to or is about to fall.
*/ */
FALLING_BLOCK("falling_block", FallingBlock.class, 21, false), public static final EntityType FALLING_BLOCK = getEntityType("falling_block", 21);
/** /**
* Internal representation of a Firework once it has been launched. * Internal representation of a Firework once it has been launched.
*/ */
FIREWORK("firework_rocket", Firework.class, 22, false), public static final EntityType FIREWORK_ROCKET = getEntityType("firework_rocket", 22);
/** /**
* @see Husk * @see Husk
*/ */
HUSK("husk", Husk.class, 23), public static final EntityType HUSK = getEntityType("husk", 23);
/** /**
* Like {@link #ARROW} but causes the {@link PotionEffectType#GLOWING} effect on all team members. * Like {@link #ARROW} but causes the {@link PotionEffectType#GLOWING} effect on all team members.
*/ */
SPECTRAL_ARROW("spectral_arrow", SpectralArrow.class, 24), public static final EntityType SPECTRAL_ARROW = getEntityType("spectral_arrow", 24);
/** /**
* Bullet fired by {@link #SHULKER}. * Bullet fired by {@link #SHULKER}.
*/ */
SHULKER_BULLET("shulker_bullet", ShulkerBullet.class, 25), public static final EntityType SHULKER_BULLET = getEntityType("shulker_bullet", 25);
/** /**
* Like {@link #FIREBALL} but with added effects. * Like {@link #FIREBALL} but with added effects.
*/ */
DRAGON_FIREBALL("dragon_fireball", DragonFireball.class, 26), public static final EntityType DRAGON_FIREBALL = getEntityType("dragon_fireball", 26);
/** /**
* @see ZombieVillager * @see ZombieVillager
*/ */
ZOMBIE_VILLAGER("zombie_villager", ZombieVillager.class, 27), public static final EntityType ZOMBIE_VILLAGER = getEntityType("zombie_villager", 27);
/** /**
* @see SkeletonHorse * @see SkeletonHorse
*/ */
SKELETON_HORSE("skeleton_horse", SkeletonHorse.class, 28), public static final EntityType SKELETON_HORSE = getEntityType("skeleton_horse", 28);
/** /**
* @see ZombieHorse * @see ZombieHorse
*/ */
ZOMBIE_HORSE("zombie_horse", ZombieHorse.class, 29), public static final EntityType ZOMBIE_HORSE = getEntityType("zombie_horse", 29);
/** /**
* Mechanical entity with an inventory for placing weapons / armor into. * Mechanical entity with an inventory for placing weapons / armor into.
*/ */
ARMOR_STAND("armor_stand", ArmorStand.class, 30), public static final EntityType ARMOR_STAND = getEntityType("armor_stand", 30);
/** /**
* @see Donkey * @see Donkey
*/ */
DONKEY("donkey", Donkey.class, 31), public static final EntityType DONKEY = getEntityType("donkey", 31);
/** /**
* @see Mule * @see Mule
*/ */
MULE("mule", Mule.class, 32), public static final EntityType MULE = getEntityType("mule", 32);
/** /**
* @see EvokerFangs * @see EvokerFangs
*/ */
EVOKER_FANGS("evoker_fangs", EvokerFangs.class, 33), public static final EntityType EVOKER_FANGS = getEntityType("evoker_fangs", 33);
/** /**
* @see Evoker * @see Evoker
*/ */
EVOKER("evoker", Evoker.class, 34), public static final EntityType EVOKER = getEntityType("evoker", 34);
/** /**
* @see Vex * @see Vex
*/ */
VEX("vex", Vex.class, 35), public static final EntityType VEX = getEntityType("vex", 35);
/** /**
* @see Vindicator * @see Vindicator
*/ */
VINDICATOR("vindicator", Vindicator.class, 36), public static final EntityType VINDICATOR = getEntityType("vindicator", 36);
/** /**
* @see Illusioner * @see Illusioner
*/ */
ILLUSIONER("illusioner", Illusioner.class, 37), public static final EntityType ILLUSIONER = getEntityType("illusioner", 37);
/** /**
* @see CommandMinecart * @see CommandMinecart
*/ */
MINECART_COMMAND("command_block_minecart", CommandMinecart.class, 40), public static final EntityType COMMAND_BLOCK_MINECART = getEntityType("command_block_minecart", 40);
/** /**
* A placed boat. * A placed boat.
*/ */
BOAT("boat", Boat.class, 41), public static final EntityType BOAT = getEntityType("boat", 41);
/** /**
* @see RideableMinecart * @see RideableMinecart
*/ */
MINECART("minecart", RideableMinecart.class, 42), public static final EntityType MINECART = getEntityType("minecart", 42);
/** /**
* @see StorageMinecart * @see StorageMinecart
*/ */
MINECART_CHEST("chest_minecart", StorageMinecart.class, 43), public static final EntityType CHEST_MINECART = getEntityType("chest_minecart", 43);
/** /**
* @see PoweredMinecart * @see PoweredMinecart
*/ */
MINECART_FURNACE("furnace_minecart", PoweredMinecart.class, 44), public static final EntityType FURNACE_MINECART = getEntityType("furnace_minecart", 44);
/** /**
* @see ExplosiveMinecart * @see ExplosiveMinecart
*/ */
MINECART_TNT("tnt_minecart", ExplosiveMinecart.class, 45), public static final EntityType TNT_MINECART = getEntityType("tnt_minecart", 45);
/** /**
* @see HopperMinecart * @see HopperMinecart
*/ */
MINECART_HOPPER("hopper_minecart", HopperMinecart.class, 46), public static final EntityType HOPPER_MINECART = getEntityType("hopper_minecart", 46);
/** /**
* @see SpawnerMinecart * @see SpawnerMinecart
*/ */
MINECART_MOB_SPAWNER("spawner_minecart", SpawnerMinecart.class, 47), public static final EntityType SPAWNER_MINECART = getEntityType("spawner_minecart", 47);
CREEPER("creeper", Creeper.class, 50), public static final EntityType CREEPER = getEntityType("creeper", 50);
SKELETON("skeleton", Skeleton.class, 51), public static final EntityType SKELETON = getEntityType("skeleton", 51);
SPIDER("spider", Spider.class, 52), public static final EntityType SPIDER = getEntityType("spider", 52);
GIANT("giant", Giant.class, 53), public static final EntityType GIANT = getEntityType("giant", 53);
ZOMBIE("zombie", Zombie.class, 54), public static final EntityType ZOMBIE = getEntityType("zombie", 54);
SLIME("slime", Slime.class, 55), public static final EntityType SLIME = getEntityType("slime", 55);
GHAST("ghast", Ghast.class, 56), public static final EntityType GHAST = getEntityType("ghast", 56);
ZOMBIFIED_PIGLIN("zombified_piglin", PigZombie.class, 57), public static final EntityType ZOMBIFIED_PIGLIN = getEntityType("zombified_piglin", 57);
ENDERMAN("enderman", Enderman.class, 58), public static final EntityType ENDERMAN = getEntityType("enderman", 58);
CAVE_SPIDER("cave_spider", CaveSpider.class, 59), public static final EntityType CAVE_SPIDER = getEntityType("cave_spider", 59);
SILVERFISH("silverfish", Silverfish.class, 60), public static final EntityType SILVERFISH = getEntityType("silverfish", 60);
BLAZE("blaze", Blaze.class, 61), public static final EntityType BLAZE = getEntityType("blaze", 61);
MAGMA_CUBE("magma_cube", MagmaCube.class, 62), public static final EntityType MAGMA_CUBE = getEntityType("magma_cube", 62);
ENDER_DRAGON("ender_dragon", EnderDragon.class, 63), public static final EntityType ENDER_DRAGON = getEntityType("ender_dragon", 63);
WITHER("wither", Wither.class, 64), public static final EntityType WITHER = getEntityType("wither", 64);
BAT("bat", Bat.class, 65), public static final EntityType BAT = getEntityType("bat", 65);
WITCH("witch", Witch.class, 66), public static final EntityType WITCH = getEntityType("witch", 66);
ENDERMITE("endermite", Endermite.class, 67), public static final EntityType ENDERMITE = getEntityType("endermite", 67);
GUARDIAN("guardian", Guardian.class, 68), public static final EntityType GUARDIAN = getEntityType("guardian", 68);
SHULKER("shulker", Shulker.class, 69), public static final EntityType SHULKER = getEntityType("shulker", 69);
PIG("pig", Pig.class, 90), public static final EntityType PIG = getEntityType("pig", 90);
SHEEP("sheep", Sheep.class, 91), public static final EntityType SHEEP = getEntityType("sheep", 91);
COW("cow", Cow.class, 92), public static final EntityType COW = getEntityType("cow", 92);
CHICKEN("chicken", Chicken.class, 93), public static final EntityType CHICKEN = getEntityType("chicken", 93);
SQUID("squid", Squid.class, 94), public static final EntityType SQUID = getEntityType("squid", 94);
WOLF("wolf", Wolf.class, 95), public static final EntityType WOLF = getEntityType("wolf", 95);
MUSHROOM_COW("mooshroom", MushroomCow.class, 96), public static final EntityType MOOSHROOM = getEntityType("mooshroom", 96);
SNOWMAN("snow_golem", Snowman.class, 97), public static final EntityType SNOW_GOLEM = getEntityType("snow_golem", 97);
OCELOT("ocelot", Ocelot.class, 98), public static final EntityType OCELOT = getEntityType("ocelot", 98);
IRON_GOLEM("iron_golem", IronGolem.class, 99), public static final EntityType IRON_GOLEM = getEntityType("iron_golem", 99);
HORSE("horse", Horse.class, 100), public static final EntityType HORSE = getEntityType("horse", 100);
RABBIT("rabbit", Rabbit.class, 101), public static final EntityType RABBIT = getEntityType("rabbit", 101);
POLAR_BEAR("polar_bear", PolarBear.class, 102), public static final EntityType POLAR_BEAR = getEntityType("polar_bear", 102);
LLAMA("llama", Llama.class, 103), public static final EntityType LLAMA = getEntityType("llama", 103);
LLAMA_SPIT("llama_spit", LlamaSpit.class, 104), public static final EntityType LLAMA_SPIT = getEntityType("llama_spit", 104);
PARROT("parrot", Parrot.class, 105), public static final EntityType PARROT = getEntityType("parrot", 105);
VILLAGER("villager", Villager.class, 120), public static final EntityType VILLAGER = getEntityType("villager", 120);
ENDER_CRYSTAL("end_crystal", EnderCrystal.class, 200), public static final EntityType END_CRYSTAL = getEntityType("end_crystal", 200);
TURTLE("turtle", Turtle.class, -1), public static final EntityType TURTLE = getEntityType("turtle");
PHANTOM("phantom", Phantom.class, -1), public static final EntityType PHANTOM = getEntityType("phantom");
TRIDENT("trident", Trident.class, -1), public static final EntityType TRIDENT = getEntityType("trident");
COD("cod", Cod.class, -1), public static final EntityType COD = getEntityType("cod");
SALMON("salmon", Salmon.class, -1), public static final EntityType SALMON = getEntityType("salmon");
PUFFERFISH("pufferfish", PufferFish.class, -1), public static final EntityType PUFFERFISH = getEntityType("pufferfish");
TROPICAL_FISH("tropical_fish", TropicalFish.class, -1), public static final EntityType TROPICAL_FISH = getEntityType("tropical_fish");
DROWNED("drowned", Drowned.class, -1), public static final EntityType DROWNED = getEntityType("drowned");
DOLPHIN("dolphin", Dolphin.class, -1), public static final EntityType DOLPHIN = getEntityType("dolphin");
CAT("cat", Cat.class, -1), public static final EntityType CAT = getEntityType("cat");
PANDA("panda", Panda.class, -1), public static final EntityType PANDA = getEntityType("panda");
PILLAGER("pillager", Pillager.class, -1), public static final EntityType PILLAGER = getEntityType("pillager");
RAVAGER("ravager", Ravager.class, -1), public static final EntityType RAVAGER = getEntityType("ravager");
TRADER_LLAMA("trader_llama", TraderLlama.class, -1), public static final EntityType TRADER_LLAMA = getEntityType("trader_llama");
WANDERING_TRADER("wandering_trader", WanderingTrader.class, -1), public static final EntityType WANDERING_TRADER = getEntityType("wandering_trader");
FOX("fox", Fox.class, -1), public static final EntityType FOX = getEntityType("fox");
BEE("bee", Bee.class, -1), public static final EntityType BEE = getEntityType("bee");
HOGLIN("hoglin", Hoglin.class, -1), public static final EntityType HOGLIN = getEntityType("hoglin");
PIGLIN("piglin", Piglin.class, -1), public static final EntityType PIGLIN = getEntityType("piglin");
STRIDER("strider", Strider.class, -1), public static final EntityType STRIDER = getEntityType("strider");
ZOGLIN("zoglin", Zoglin.class, -1), public static final EntityType ZOGLIN = getEntityType("zoglin");
PIGLIN_BRUTE("piglin_brute", PiglinBrute.class, -1), public static final EntityType PIGLIN_BRUTE = getEntityType("piglin_brute");
AXOLOTL("axolotl", Axolotl.class, -1), public static final EntityType AXOLOTL = getEntityType("axolotl");
GLOW_ITEM_FRAME("glow_item_frame", GlowItemFrame.class, -1), public static final EntityType GLOW_ITEM_FRAME = getEntityType("glow_item_frame");
GLOW_SQUID("glow_squid", GlowSquid.class, -1), public static final EntityType GLOW_SQUID = getEntityType("glow_squid");
GOAT("goat", Goat.class, -1), public static final EntityType GOAT = getEntityType("goat");
MARKER("marker", Marker.class, -1), public static final EntityType MARKER = getEntityType("marker");
/** /**
* A fishing line and bobber. * A fishing line and bobber.
*/ */
FISHING_HOOK("fishing_bobber", FishHook.class, -1, false), public static final EntityType FISHING_BOBBER = getEntityType("fishing_bobber");
/** /**
* A bolt of lightning. * A bolt of lightning.
* <p> * <p>
* Spawn with {@link World#strikeLightning(Location)}. * Spawn with {@link World#strikeLightning(Location)}.
*/ */
LIGHTNING("lightning_bolt", LightningStrike.class, -1, false), public static final EntityType LIGHTNING_BOLT = getEntityType("lightning_bolt");
PLAYER("player", Player.class, -1, false), public static final EntityType PLAYER = getEntityType("player");
/** /**
* An unknown entity without an Entity Class * An unknown entity without an Entity Class
* @deprecated only for backwards compatibility, unknown is no longer returned.
*/ */
UNKNOWN(null, null, -1, false); @Deprecated
public static final EntityType UNKNOWN = getEntityType("unknown");
private final String name; private static EntityType getEntityType(@NotNull String key) {
private final Class<? extends Entity> clazz; return getEntityType(key, -1);
private final short typeId; }
private final boolean independent, living;
private final NamespacedKey key;
private static final Map<String, EntityType> NAME_MAP = new HashMap<String, EntityType>(); private static EntityType getEntityType(@NotNull String key, int typeId) {
private static final Map<Short, EntityType> ID_MAP = new HashMap<Short, EntityType>(); NamespacedKey namespacedKey = NamespacedKey.minecraft(key);
EntityType entityType = Registry.ENTITY_TYPE.get(namespacedKey);
static { Preconditions.checkNotNull(entityType, "No EntityType found for %s. This is a bug.", namespacedKey);
for (EntityType type : values()) { if (typeId > 0) {
if (type.name != null) { ID_MAP.put((short) typeId, entityType);
NAME_MAP.put(type.name.toLowerCase(java.util.Locale.ENGLISH), type);
}
if (type.typeId > 0) {
ID_MAP.put(type.typeId, type);
}
} }
return entityType;
// Add legacy names
NAME_MAP.put("xp_orb", EXPERIENCE_ORB);
NAME_MAP.put("eye_of_ender_signal", ENDER_SIGNAL);
NAME_MAP.put("xp_bottle", THROWN_EXP_BOTTLE);
NAME_MAP.put("fireworks_rocket", FIREWORK);
NAME_MAP.put("evocation_fangs", EVOKER_FANGS);
NAME_MAP.put("evocation_illager", EVOKER);
NAME_MAP.put("vindication_illager", VINDICATOR);
NAME_MAP.put("illusion_illager", ILLUSIONER);
NAME_MAP.put("commandblock_minecart", MINECART_COMMAND);
NAME_MAP.put("snowman", SNOWMAN);
NAME_MAP.put("villager_golem", IRON_GOLEM);
NAME_MAP.put("ender_crystal", ENDER_CRYSTAL);
NAME_MAP.put("zombie_pigman", ZOMBIFIED_PIGLIN);
} }
private EntityType(/*@Nullable*/ String name, /*@Nullable*/ Class<? extends Entity> clazz, int typeId) { /**
this(name, clazz, typeId, true); * Some entities cannot be spawned using {@link
} * World#spawnEntity(Location, EntityType)} or {@link
* World#spawn(Location, Class)}, usually because they require additional
* information in order to spawn.
*
* @return False if the entity type cannot be spawned
*/
public abstract boolean isSpawnable();
private EntityType(/*@Nullable*/ String name, /*@Nullable*/ Class<? extends Entity> clazz, int typeId, boolean independent) { public abstract boolean isAlive();
this.name = name;
this.clazz = clazz; @Nullable
this.typeId = (short) typeId; public abstract Class<? extends Entity> getEntityClass();
this.independent = independent;
this.living = clazz != null && LivingEntity.class.isAssignableFrom(clazz);
this.key = (name == null) ? null : NamespacedKey.minecraft(name);
}
/** /**
* Gets the entity type name. * Gets the entity type name.
@ -343,22 +330,7 @@ public enum EntityType implements Keyed {
*/ */
@Deprecated @Deprecated
@Nullable @Nullable
public String getName() { public abstract String getName();
return name;
}
@NotNull
@Override
public NamespacedKey getKey() {
Preconditions.checkArgument(key != null, "EntityType doesn't have key! Is it UNKNOWN?");
return key;
}
@Nullable
public Class<? extends Entity> getEntityClass() {
return clazz;
}
/** /**
* Gets the entity type id. * Gets the entity type id.
@ -368,7 +340,7 @@ public enum EntityType implements Keyed {
*/ */
@Deprecated @Deprecated
public short getTypeId() { public short getTypeId() {
return typeId; return ID_MAP.inverse().getOrDefault(this, (short) -1);
} }
/** /**
@ -385,7 +357,7 @@ public enum EntityType implements Keyed {
if (name == null) { if (name == null) {
return null; return null;
} }
return NAME_MAP.get(name.toLowerCase(java.util.Locale.ENGLISH)); return Registry.ENTITY_TYPE.get(NamespacedKey.fromString(name.toLowerCase(java.util.Locale.ENGLISH)));
} }
/** /**
@ -405,18 +377,25 @@ public enum EntityType implements Keyed {
} }
/** /**
* Some entities cannot be spawned using {@link * @param name of the entityType.
* World#spawnEntity(Location, EntityType)} or {@link * @return the entityType with the given name.
* World#spawn(Location, Class)}, usually because they require additional * @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead.
* information in order to spawn.
*
* @return False if the entity type cannot be spawned
*/ */
public boolean isSpawnable() { @NotNull
return independent; @Deprecated
public static EntityType valueOf(@NotNull String name) {
EntityType entityType = Registry.ENTITY_TYPE.get(NamespacedKey.fromString(name.toLowerCase()));
Preconditions.checkArgument(entityType != null, "No EntityType found with the name %s", name);
return entityType;
} }
public boolean isAlive() { /**
return living; * @return an array of all known EntityTypes.
* @deprecated use {@link Registry#iterator()}.
*/
@NotNull
@Deprecated
public static EntityType[] values() {
return Lists.newArrayList(Registry.ENTITY_TYPE).toArray(new EntityType[0]);
} }
} }

View file

@ -1,9 +1,12 @@
package org.bukkit.entity; package org.bukkit.entity;
import java.util.Locale; import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.bukkit.Keyed; import org.bukkit.Keyed;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.util.OldEnum;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@ -105,25 +108,45 @@ public interface Villager extends AbstractVillager {
* Represents Villager type, usually corresponding to what biome they spawn * Represents Villager type, usually corresponding to what biome they spawn
* in. * in.
*/ */
public enum Type implements Keyed { public abstract class Type extends OldEnum<Type> implements Keyed {
DESERT, public static final Type DESERT = getType("desert");
JUNGLE, public static final Type JUNGLE = getType("jungle");
PLAINS, public static final Type PLAINS = getType("plains");
SAVANNA, public static final Type SAVANNA = getType("savanna");
SNOW, public static final Type SNOW = getType("snow");
SWAMP, public static final Type SWAMP = getType("swamp");
TAIGA; public static final Type TAIGA = getType("taiga");
private final NamespacedKey key;
private Type() {
this.key = NamespacedKey.minecraft(this.name().toLowerCase(Locale.ROOT));
}
@NotNull @NotNull
@Override private static Type getType(@NotNull String key) {
public NamespacedKey getKey() { NamespacedKey namespacedKey = NamespacedKey.minecraft(key);
return key; Type type = Registry.VILLAGER_TYPE.get(namespacedKey);
Preconditions.checkNotNull(type, "No villager type found for %s. This is a bug.", namespacedKey);
return type;
}
/**
* @param name of the villager type.
* @return the villager type with the given name.
* @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead.
*/
@NotNull
@Deprecated
public static Type valueOf(@NotNull String name) {
Type type = Registry.VILLAGER_TYPE.get(NamespacedKey.fromString(name.toLowerCase()));
Preconditions.checkArgument(type != null, "No villager type found with the name %s", name);
return type;
}
/**
* @return an array of all known villager types.
* @deprecated use {@link Registry#iterator()}.
*/
@NotNull
@Deprecated
public static Type[] values() {
return Lists.newArrayList(Registry.VILLAGER_TYPE).toArray(new Type[0]);
} }
} }
@ -131,88 +154,108 @@ public interface Villager extends AbstractVillager {
* Represents the various different Villager professions there may be. * Represents the various different Villager professions there may be.
* Villagers have different trading options depending on their profession, * Villagers have different trading options depending on their profession,
*/ */
public enum Profession implements Keyed { public abstract class Profession extends OldEnum<Profession> implements Keyed {
NONE, public static final Profession NONE = getProfession("none");
/** /**
* Armorer profession. Wears a black apron. Armorers primarily trade for * Armorer profession. Wears a black apron. Armorers primarily trade for
* iron armor, chainmail armor, and sometimes diamond armor. * iron armor, chainmail armor, and sometimes diamond armor.
*/ */
ARMORER, public static final Profession ARMORER = getProfession("armorer");
/** /**
* Butcher profession. Wears a white apron. Butchers primarily trade for * Butcher profession. Wears a white apron. Butchers primarily trade for
* raw and cooked food. * raw and cooked food.
*/ */
BUTCHER, public static final Profession BUTCHER = getProfession("butcher");
/** /**
* Cartographer profession. Wears a white robe. Cartographers primarily * Cartographer profession. Wears a white robe. Cartographers primarily
* trade for explorer maps and some paper. * trade for explorer maps and some paper.
*/ */
CARTOGRAPHER, public static final Profession CARTOGRAPHER = getProfession("cartographer");
/** /**
* Cleric profession. Wears a purple robe. Clerics primarily trade for * Cleric profession. Wears a purple robe. Clerics primarily trade for
* rotten flesh, gold ingot, redstone, lapis, ender pearl, glowstone, * rotten flesh, gold ingot, redstone, lapis, ender pearl, glowstone,
* and bottle o' enchanting. * and bottle o' enchanting.
*/ */
CLERIC, public static final Profession CLERIC = getProfession("cleric");
/** /**
* Farmer profession. Wears a brown robe. Farmers primarily trade for * Farmer profession. Wears a brown robe. Farmers primarily trade for
* food-related items. * food-related items.
*/ */
FARMER, public static final Profession FARMER = getProfession("farmer");
/** /**
* Fisherman profession. Wears a brown robe. Fisherman primarily trade * Fisherman profession. Wears a brown robe. Fisherman primarily trade
* for fish, as well as possibly selling string and/or coal. * for fish, as well as possibly selling string and/or coal.
*/ */
FISHERMAN, public static final Profession FISHERMAN = getProfession("fisherman");
/** /**
* Fletcher profession. Wears a brown robe. Fletchers primarily trade * Fletcher profession. Wears a brown robe. Fletchers primarily trade
* for string, bows, and arrows. * for string, bows, and arrows.
*/ */
FLETCHER, public static final Profession FLETCHER = getProfession("fletcher");
/** /**
* Leatherworker profession. Wears a white apron. Leatherworkers * Leatherworker profession. Wears a white apron. Leatherworkers
* primarily trade for leather, and leather armor, as well as saddles. * primarily trade for leather, and leather armor, as well as saddles.
*/ */
LEATHERWORKER, public static final Profession LEATHERWORKER = getProfession("leatherworker");
/** /**
* Librarian profession. Wears a white robe. Librarians primarily trade * Librarian profession. Wears a white robe. Librarians primarily trade
* for paper, books, and enchanted books. * for paper, books, and enchanted books.
*/ */
LIBRARIAN, public static final Profession LIBRARIAN = getProfession("librarian");
/** /**
* Mason profession. * Mason profession.
*/ */
MASON, public static final Profession MASON = getProfession("mason");
/** /**
* Nitwit profession. Wears a green apron, cannot trade. Nitwit * Nitwit profession. Wears a green apron, cannot trade. Nitwit
* villagers do not do anything. They do not have any trades by default. * villagers do not do anything. They do not have any trades by default.
*/ */
NITWIT, public static final Profession NITWIT = getProfession("nitwit");
/** /**
* Sheperd profession. Wears a brown robe. Shepherds primarily trade for * Sheperd profession. Wears a brown robe. Shepherds primarily trade for
* wool items, and shears. * wool items, and shears.
*/ */
SHEPHERD, public static final Profession SHEPHERD = getProfession("shepherd");
/** /**
* Toolsmith profession. Wears a black apron. Tool smiths primarily * Toolsmith profession. Wears a black apron. Tool smiths primarily
* trade for iron and diamond tools. * trade for iron and diamond tools.
*/ */
TOOLSMITH, public static final Profession TOOLSMITH = getProfession("toolsmith");
/** /**
* Weaponsmith profession. Wears a black apron. Weapon smiths primarily * Weaponsmith profession. Wears a black apron. Weapon smiths primarily
* trade for iron and diamond weapons, sometimes enchanted. * trade for iron and diamond weapons, sometimes enchanted.
*/ */
WEAPONSMITH; public static final Profession WEAPONSMITH = getProfession("weaponsmith");
private final NamespacedKey key;
private Profession() {
this.key = NamespacedKey.minecraft(this.name().toLowerCase(Locale.ROOT));
}
@NotNull @NotNull
@Override private static Profession getProfession(@NotNull String key) {
public NamespacedKey getKey() { NamespacedKey namespacedKey = NamespacedKey.minecraft(key);
return key; Profession profession = Registry.VILLAGER_PROFESSION.get(namespacedKey);
Preconditions.checkNotNull(profession, "No villager profession found for %s. This is a bug.", namespacedKey);
return profession;
}
/**
* @param name of the villager profession.
* @return the villager profession with the given name.
* @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead.
*/
@NotNull
@Deprecated
public static Profession valueOf(@NotNull String name) {
Profession profession = Registry.VILLAGER_PROFESSION.get(NamespacedKey.fromString(name.toLowerCase()));
Preconditions.checkArgument(profession != null, "No villager profession found with the name %s", name);
return profession;
}
/**
* @return an array of all known villager professions.
* @deprecated use {@link Registry#iterator()}.
*/
@NotNull
@Deprecated
public static Profession[] values() {
return Lists.newArrayList(Registry.VILLAGER_PROFESSION).toArray(new Profession[0]);
} }
} }
} }

View file

@ -1,183 +1,193 @@
package org.bukkit.potion; package org.bukkit.potion;
import java.util.Arrays; import com.google.common.base.Preconditions;
import java.util.HashMap; import com.google.common.collect.BiMap;
import java.util.Map; import com.google.common.collect.HashBiMap;
import com.google.common.collect.Lists;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/** /**
* Represents a type of potion and its effect on an entity. * Represents a type of potion and its effect on an entity.
*/ */
public abstract class PotionEffectType { public abstract class PotionEffectType implements Keyed {
protected static final BiMap<Integer, PotionEffectType> ID_MAP = HashBiMap.create();
/** /**
* Increases movement speed. * Increases movement speed.
*/ */
public static final PotionEffectType SPEED = new PotionEffectTypeWrapper(1); public static final PotionEffectType SPEED = getPotionEffectType("speed", 1);
/** /**
* Decreases movement speed. * Decreases movement speed.
*/ */
public static final PotionEffectType SLOW = new PotionEffectTypeWrapper(2); public static final PotionEffectType SLOWNESS = getPotionEffectType("slowness", 2);
/** /**
* Increases dig speed. * Increases dig speed.
*/ */
public static final PotionEffectType FAST_DIGGING = new PotionEffectTypeWrapper(3); public static final PotionEffectType HASTE = getPotionEffectType("haste", 3);
/** /**
* Decreases dig speed. * Decreases dig speed.
*/ */
public static final PotionEffectType SLOW_DIGGING = new PotionEffectTypeWrapper(4); public static final PotionEffectType MINING_FATIGUE = getPotionEffectType("mining_fatigue", 4);
/** /**
* Increases damage dealt. * Increases damage dealt.
*/ */
public static final PotionEffectType INCREASE_DAMAGE = new PotionEffectTypeWrapper(5); public static final PotionEffectType STRENGTH = getPotionEffectType("strength", 5);
/** /**
* Heals an entity. * Heals an entity.
*/ */
public static final PotionEffectType HEAL = new PotionEffectTypeWrapper(6); public static final PotionEffectType INSTANT_HEALTH = getPotionEffectType("instant_health", 6);
/** /**
* Hurts an entity. * Hurts an entity.
*/ */
public static final PotionEffectType HARM = new PotionEffectTypeWrapper(7); public static final PotionEffectType INSTANT_DAMAGE = getPotionEffectType("instant_damage", 7);
/** /**
* Increases jump height. * Increases jump height.
*/ */
public static final PotionEffectType JUMP = new PotionEffectTypeWrapper(8); public static final PotionEffectType JUMP_BOOST = getPotionEffectType("jump_boost", 8);
/** /**
* Warps vision on the client. * Warps vision on the client.
*/ */
public static final PotionEffectType CONFUSION = new PotionEffectTypeWrapper(9); public static final PotionEffectType NAUSEA = getPotionEffectType("nausea", 9);
/** /**
* Regenerates health. * Regenerates health.
*/ */
public static final PotionEffectType REGENERATION = new PotionEffectTypeWrapper(10); public static final PotionEffectType REGENERATION = getPotionEffectType("regeneration", 10);
/** /**
* Decreases damage dealt to an entity. * Decreases damage dealt to an entity.
*/ */
public static final PotionEffectType DAMAGE_RESISTANCE = new PotionEffectTypeWrapper(11); public static final PotionEffectType RESISTANCE = getPotionEffectType("resistance", 11);
/** /**
* Stops fire damage. * Stops fire damage.
*/ */
public static final PotionEffectType FIRE_RESISTANCE = new PotionEffectTypeWrapper(12); public static final PotionEffectType FIRE_RESISTANCE = getPotionEffectType("fire_resistance", 12);
/** /**
* Allows breathing underwater. * Allows breathing underwater.
*/ */
public static final PotionEffectType WATER_BREATHING = new PotionEffectTypeWrapper(13); public static final PotionEffectType WATER_BREATHING = getPotionEffectType("water_breathing", 13);
/** /**
* Grants invisibility. * Grants invisibility.
*/ */
public static final PotionEffectType INVISIBILITY = new PotionEffectTypeWrapper(14); public static final PotionEffectType INVISIBILITY = getPotionEffectType("invisibility", 14);
/** /**
* Blinds an entity. * Blinds an entity.
*/ */
public static final PotionEffectType BLINDNESS = new PotionEffectTypeWrapper(15); public static final PotionEffectType BLINDNESS = getPotionEffectType("blindness", 15);
/** /**
* Allows an entity to see in the dark. * Allows an entity to see in the dark.
*/ */
public static final PotionEffectType NIGHT_VISION = new PotionEffectTypeWrapper(16); public static final PotionEffectType NIGHT_VISION = getPotionEffectType("night_vision", 16);
/** /**
* Increases hunger. * Increases hunger.
*/ */
public static final PotionEffectType HUNGER = new PotionEffectTypeWrapper(17); public static final PotionEffectType HUNGER = getPotionEffectType("hunger", 17);
/** /**
* Decreases damage dealt by an entity. * Decreases damage dealt by an entity.
*/ */
public static final PotionEffectType WEAKNESS = new PotionEffectTypeWrapper(18); public static final PotionEffectType WEAKNESS = getPotionEffectType("weakness", 18);
/** /**
* Deals damage to an entity over time. * Deals damage to an entity over time.
*/ */
public static final PotionEffectType POISON = new PotionEffectTypeWrapper(19); public static final PotionEffectType POISON = getPotionEffectType("poison", 19);
/** /**
* Deals damage to an entity over time and gives the health to the * Deals damage to an entity over time and gives the health to the
* shooter. * shooter.
*/ */
public static final PotionEffectType WITHER = new PotionEffectTypeWrapper(20); public static final PotionEffectType WITHER = getPotionEffectType("wither", 20);
/** /**
* Increases the maximum health of an entity. * Increases the maximum health of an entity.
*/ */
public static final PotionEffectType HEALTH_BOOST = new PotionEffectTypeWrapper(21); public static final PotionEffectType HEALTH_BOOST = getPotionEffectType("health_boost", 21);
/** /**
* Increases the maximum health of an entity with health that cannot be * Increases the maximum health of an entity with health that cannot be
* regenerated, but is refilled every 30 seconds. * regenerated, but is refilled every 30 seconds.
*/ */
public static final PotionEffectType ABSORPTION = new PotionEffectTypeWrapper(22); public static final PotionEffectType ABSORPTION = getPotionEffectType("absorption", 22);
/** /**
* Increases the food level of an entity each tick. * Increases the food level of an entity each tick.
*/ */
public static final PotionEffectType SATURATION = new PotionEffectTypeWrapper(23); public static final PotionEffectType SATURATION = getPotionEffectType("saturation", 23);
/** /**
* Outlines the entity so that it can be seen from afar. * Outlines the entity so that it can be seen from afar.
*/ */
public static final PotionEffectType GLOWING = new PotionEffectTypeWrapper(24); public static final PotionEffectType GLOWING = getPotionEffectType("glowing", 24);
/** /**
* Causes the entity to float into the air. * Causes the entity to float into the air.
*/ */
public static final PotionEffectType LEVITATION = new PotionEffectTypeWrapper(25); public static final PotionEffectType LEVITATION = getPotionEffectType("levitation", 25);
/** /**
* Loot table luck. * Loot table luck.
*/ */
public static final PotionEffectType LUCK = new PotionEffectTypeWrapper(26); public static final PotionEffectType LUCK = getPotionEffectType("luck", 26);
/** /**
* Loot table unluck. * Loot table unluck.
*/ */
public static final PotionEffectType UNLUCK = new PotionEffectTypeWrapper(27); public static final PotionEffectType UNLUCK = getPotionEffectType("unluck", 27);
/** /**
* Slows entity fall rate. * Slows entity fall rate.
*/ */
public static final PotionEffectType SLOW_FALLING = new PotionEffectTypeWrapper(28); public static final PotionEffectType SLOW_FALLING = getPotionEffectType("slow_falling", 28);
/** /**
* Effects granted by a nearby conduit. Includes enhanced underwater abilities. * Effects granted by a nearby conduit. Includes enhanced underwater abilities.
*/ */
public static final PotionEffectType CONDUIT_POWER = new PotionEffectTypeWrapper(29); public static final PotionEffectType CONDUIT_POWER = getPotionEffectType("conduit_power", 29);
/** /**
* Squee'ek uh'k kk'kkkk squeek eee'eek. * Squee'ek uh'k kk'kkkk squeek eee'eek.
*/ */
public static final PotionEffectType DOLPHINS_GRACE = new PotionEffectTypeWrapper(30); public static final PotionEffectType DOLPHINS_GRACE = getPotionEffectType("dolphins_grace", 30);
/** /**
* oof. * oof.
*/ */
public static final PotionEffectType BAD_OMEN = new PotionEffectTypeWrapper(31); public static final PotionEffectType BAD_OMEN = getPotionEffectType("bad_omen", 31);
/** /**
* \o/. * \o/.
*/ */
public static final PotionEffectType HERO_OF_THE_VILLAGE = new PotionEffectTypeWrapper(32); public static final PotionEffectType HERO_OF_THE_VILLAGE = getPotionEffectType("hero_of_the_village", 32);
private final int id; private static PotionEffectType getPotionEffectType(@NotNull String key, int typeId) {
NamespacedKey namespacedKey = NamespacedKey.minecraft(key);
protected PotionEffectType(int id) { PotionEffectType potionEffectType = Registry.POTION_EFFECT_TYPE.get(namespacedKey);
this.id = id; Preconditions.checkNotNull(potionEffectType, "No PotionEffectType found for %s. This is a bug.", namespacedKey);
if (typeId > 0) {
ID_MAP.put(typeId, potionEffectType);
}
return potionEffectType;
} }
/** /**
@ -194,6 +204,21 @@ public abstract class PotionEffectType {
return new PotionEffect(this, isInstant() ? 1 : (int) (duration * getDurationModifier()), amplifier); return new PotionEffect(this, isInstant() ? 1 : (int) (duration * getDurationModifier()), 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. * Returns the duration modifier applied to effects of this type.
* *
@ -210,63 +235,18 @@ public abstract class PotionEffectType {
* @deprecated Magic value * @deprecated Magic value
*/ */
@Deprecated @Deprecated
public int getId() { public abstract int getId();
return id;
}
/** /**
* Returns the name of this effect type. * Returns the name of this effect type.
* *
* @return The name of this effect type * @return The name of this effect type
* @deprecated only for backwards compatibility, use {@link #getKey()} instead.
*/ */
@NotNull @NotNull
@Deprecated
public abstract String getName(); 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[33];
private static final Map<String, PotionEffectType> byName = new HashMap<String, PotionEffectType>();
// will break on updates.
private static boolean acceptingNew = true;
/** /**
* Gets the effect type specified by the unique id. * Gets the effect type specified by the unique id.
* *
@ -277,9 +257,7 @@ public abstract class PotionEffectType {
@Deprecated @Deprecated
@Nullable @Nullable
public static PotionEffectType getById(int id) { public static PotionEffectType getById(int id) {
if (id >= byId.length || id < 0) return ID_MAP.get(id);
return null;
return byId[id];
} }
/** /**
@ -287,11 +265,23 @@ public abstract class PotionEffectType {
* *
* @param name Name of PotionEffectType to fetch * @param name Name of PotionEffectType to fetch
* @return Resulting PotionEffectType, or null if not found. * @return Resulting PotionEffectType, or null if not found.
* @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead.
*/ */
@Nullable @Nullable
@Deprecated
public static PotionEffectType getByName(@NotNull String name) { public static PotionEffectType getByName(@NotNull String name) {
Validate.notNull(name, "name cannot be null"); Validate.notNull(name, "name cannot be null");
return byName.get(name.toLowerCase(java.util.Locale.ENGLISH)); return Registry.POTION_EFFECT_TYPE.get(NamespacedKey.fromString(name.toLowerCase(java.util.Locale.ENGLISH)));
}
/**
* @return an array of all known PotionEffectTypes.
* @deprecated use {@link Registry#iterator()}.
*/
@NotNull
@Deprecated
public static PotionEffectType[] values() {
return Lists.newArrayList(Registry.POTION_EFFECT_TYPE).toArray(new PotionEffectType[0]);
} }
/** /**
@ -300,34 +290,15 @@ public abstract class PotionEffectType {
* Generally not to be used from within a plugin. * Generally not to be used from within a plugin.
* *
* @param type PotionType to register * @param type PotionType to register
* @deprecated only for backwards compatibility, has no effect.
*/ */
public static void registerPotionEffectType(@NotNull PotionEffectType type) { @Deprecated
if (byId[type.id] != null || byName.containsKey(type.getName().toLowerCase(java.util.Locale.ENGLISH))) { public static void registerPotionEffectType(@NotNull PotionEffectType type) {}
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);
}
/** /**
* Stops accepting any effect type registrations. * Stops accepting any effect type registrations.
* @deprecated only for backwards compatibility, has no effect.
*/ */
public static void stopAcceptingRegistrations() { @Deprecated
acceptingNew = false; public static void stopAcceptingRegistrations() {}
}
/**
* Returns an array of all the registered {@link PotionEffectType}s.
* This array is not necessarily in any particular order.
*
* @return Array of types.
*/
@NotNull
public static PotionEffectType[] values() {
return Arrays.copyOfRange(byId, 1, byId.length);
}
} }

View file

@ -1,18 +1,26 @@
package org.bukkit.potion; package org.bukkit.potion;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/**
* @deprecated only for backwards compatibility, PotionEffectTypeWrapper is no longer used.
*/
@Deprecated
public class PotionEffectTypeWrapper extends PotionEffectType { public class PotionEffectTypeWrapper extends PotionEffectType {
protected PotionEffectTypeWrapper(int id) { protected PotionEffectTypeWrapper(int id) {}
super(id);
}
@Override @Override
public double getDurationModifier() { public double getDurationModifier() {
return getType().getDurationModifier(); return getType().getDurationModifier();
} }
@Override
public int getId() {
return getType().getId();
}
@NotNull @NotNull
@Override @Override
public String getName() { public String getName() {
@ -39,4 +47,10 @@ public class PotionEffectTypeWrapper extends PotionEffectType {
public Color getColor() { public Color getColor() {
return getType().getColor(); return getType().getColor();
} }
@NotNull
@Override
public NamespacedKey getKey() {
return getType().getKey();
}
} }

View file

@ -14,19 +14,19 @@ public enum PotionType {
AWKWARD(null, false, false), AWKWARD(null, false, false),
NIGHT_VISION(PotionEffectType.NIGHT_VISION, false, true), NIGHT_VISION(PotionEffectType.NIGHT_VISION, false, true),
INVISIBILITY(PotionEffectType.INVISIBILITY, false, true), INVISIBILITY(PotionEffectType.INVISIBILITY, false, true),
JUMP(PotionEffectType.JUMP, true, true), JUMP(PotionEffectType.JUMP_BOOST, true, true),
FIRE_RESISTANCE(PotionEffectType.FIRE_RESISTANCE, false, true), FIRE_RESISTANCE(PotionEffectType.FIRE_RESISTANCE, false, true),
SPEED(PotionEffectType.SPEED, true, true), SPEED(PotionEffectType.SPEED, true, true),
SLOWNESS(PotionEffectType.SLOW, true, true), SLOWNESS(PotionEffectType.SLOWNESS, true, true),
WATER_BREATHING(PotionEffectType.WATER_BREATHING, false, true), WATER_BREATHING(PotionEffectType.WATER_BREATHING, false, true),
INSTANT_HEAL(PotionEffectType.HEAL, true, false), INSTANT_HEAL(PotionEffectType.INSTANT_HEALTH, true, false),
INSTANT_DAMAGE(PotionEffectType.HARM, true, false), INSTANT_DAMAGE(PotionEffectType.INSTANT_DAMAGE, true, false),
POISON(PotionEffectType.POISON, true, true), POISON(PotionEffectType.POISON, true, true),
REGEN(PotionEffectType.REGENERATION, true, true), REGEN(PotionEffectType.REGENERATION, true, true),
STRENGTH(PotionEffectType.INCREASE_DAMAGE, true, true), STRENGTH(PotionEffectType.STRENGTH, true, true),
WEAKNESS(PotionEffectType.WEAKNESS, false, true), WEAKNESS(PotionEffectType.WEAKNESS, false, true),
LUCK(PotionEffectType.LUCK, false, false), LUCK(PotionEffectType.LUCK, false, false),
TURTLE_MASTER(PotionEffectType.SLOW, true, true), // TODO: multiple effects TURTLE_MASTER(PotionEffectType.SLOWNESS, true, true), // TODO: multiple effects
SLOW_FALLING(PotionEffectType.SLOW_FALLING, false, true), SLOW_FALLING(PotionEffectType.SLOW_FALLING, false, true),
; ;

View file

@ -1,4 +1,4 @@
package org.bukkit; package org.bukkit.util;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View file

@ -2,9 +2,12 @@ package org.bukkit;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.bukkit.support.AbstractTestingBase;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
public class ArtTest { @Ignore
public class ArtTest extends AbstractTestingBase {
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void getByNullName() { public void getByNullName() {
@ -26,6 +29,7 @@ public class ArtTest {
} }
@Test @Test
@Ignore // Values are now pulled directly from the
public void dimensionSanityCheck() { public void dimensionSanityCheck() {
for (Art art : Art.values()) { for (Art art : Art.values()) {
assertThat(art.getBlockHeight(), is(greaterThan(0))); assertThat(art.getBlockHeight(), is(greaterThan(0)));

View file

@ -8,11 +8,10 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.bukkit.block.Biome;
import org.bukkit.command.SimpleCommandMap; import org.bukkit.command.SimpleCommandMap;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.SimplePluginManager; import org.bukkit.plugin.SimplePluginManager;
import org.jetbrains.annotations.NotNull; import org.mockito.Mockito;
public final class TestServer implements InvocationHandler { public final class TestServer implements InvocationHandler {
private static interface MethodHandler { private static interface MethodHandler {
@ -82,36 +81,15 @@ public final class TestServer implements InvocationHandler {
methodMap.put( methodMap.put(
Server.class.getMethod("getRegistry", Class.class), Server.class.getMethod("getRegistry", Class.class),
new MethodHandler() { new MethodHandler() {
private final Map<Class<?>, Registry<?>> registers = new HashMap<>(); private final Map<Class<? extends Keyed>, Registry<?>> registers = new HashMap<>();
@Override @Override
public Object handle(TestServer server, Object[] args) { public Object handle(TestServer server, Object[] args) {
return registers.computeIfAbsent((Class<?>) args[0], aClass -> new Registry<Keyed>() {
return registers.computeIfAbsent((Class<? extends Keyed>) args[0], aClass -> new Registry<Keyed>() {
private final Map<NamespacedKey, Keyed> cache = new HashMap<>(); private final Map<NamespacedKey, Keyed> cache = new HashMap<>();
@Override @Override
public Keyed get(NamespacedKey key) { public Keyed get(NamespacedKey key) {
if (aClass == Biome.class) { return cache.computeIfAbsent(key, key2 -> Mockito.mock(aClass));
return cache.computeIfAbsent(key, key1 -> new Biome() {
@Override
public int compareTo(Biome biome) {
throw new UnsupportedOperationException("Not supported");
}
@NotNull
@Override
public String name() {
throw new UnsupportedOperationException("Not supported");
}
@Override
public int ordinal() {
throw new UnsupportedOperationException("Not supported");
}
@NotNull
@Override
public NamespacedKey getKey() {
throw new UnsupportedOperationException("Not supported");
}
});
}
throw new UnsupportedOperationException("Not supported");
} }
@Override @Override
@ -135,7 +113,9 @@ public final class TestServer implements InvocationHandler {
private Thread creatingThread = Thread.currentThread(); private Thread creatingThread = Thread.currentThread();
private PluginManager pluginManager; private PluginManager pluginManager;
private TestServer() {}; private TestServer() {}
public static void setup() {}
public static Server getInstance() { public static Server getInstance() {
return Bukkit.getServer(); return Bukkit.getServer();

View file

@ -5,9 +5,10 @@ import static org.junit.Assert.*;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.bukkit.event.player.PlayerChatTabCompleteEvent; import org.bukkit.event.player.PlayerChatTabCompleteEvent;
import org.bukkit.plugin.messaging.TestPlayer; import org.bukkit.plugin.messaging.TestPlayer;
import org.bukkit.support.AbstractTestingBase;
import org.junit.Test; import org.junit.Test;
public class PlayerChatTabCompleteEventTest { public class PlayerChatTabCompleteEventTest extends AbstractTestingBase {
@Test @Test
public void testGetLastToken() { public void testGetLastToken() {

View file

@ -0,0 +1,15 @@
package org.bukkit.support;
import org.bukkit.TestServer;
/**
* If you are getting: java.lang.ExceptionInInitializerError
*
* extend this class to solve it.
*/
public abstract class AbstractTestingBase {
static {
TestServer.setup();
}
}