From 19830133bd8e6eab082ebbc24ec58a23f16a6d1f Mon Sep 17 00:00:00 2001 From: Jishuna Date: Wed, 25 Oct 2023 18:54:03 +1100 Subject: [PATCH 01/22] #925: Add hit entity/block to events extending ProjectileHitEvent --- .../java/org/bukkit/event/entity/ExpBottleEvent.java | 11 ++++++++++- .../event/entity/LingeringPotionSplashEvent.java | 11 ++++++++++- .../org/bukkit/event/entity/PotionSplashEvent.java | 10 +++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/bukkit/event/entity/ExpBottleEvent.java b/src/main/java/org/bukkit/event/entity/ExpBottleEvent.java index 6417c2fd..997c86b0 100644 --- a/src/main/java/org/bukkit/event/entity/ExpBottleEvent.java +++ b/src/main/java/org/bukkit/event/entity/ExpBottleEvent.java @@ -1,8 +1,12 @@ package org.bukkit.event.entity; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; import org.bukkit.entity.ThrownExpBottle; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Called when a ThrownExpBottle hits and releases experience. @@ -12,8 +16,13 @@ public class ExpBottleEvent extends ProjectileHitEvent { private int exp; private boolean showEffect = true; + @Deprecated public ExpBottleEvent(@NotNull final ThrownExpBottle bottle, final int exp) { - super(bottle); + this(bottle, null, null, null, exp); + } + + public ExpBottleEvent(@NotNull final ThrownExpBottle bottle, @Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace, final int exp) { + super(bottle, hitEntity, hitBlock, hitFace); this.exp = exp; } diff --git a/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java b/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java index a10dab16..1584c6c4 100644 --- a/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java +++ b/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java @@ -1,10 +1,14 @@ package org.bukkit.event.entity; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.entity.AreaEffectCloud; +import org.bukkit.entity.Entity; import org.bukkit.entity.ThrownPotion; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Called when a splash potion hits an area @@ -14,8 +18,13 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca private boolean cancelled; private final AreaEffectCloud entity; + @Deprecated public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @NotNull final AreaEffectCloud entity) { - super(potion); + this(potion, null, null, null, entity); + } + + public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace, @NotNull final AreaEffectCloud entity) { + super(potion, hitEntity, hitBlock, hitFace); this.entity = entity; } diff --git a/src/main/java/org/bukkit/event/entity/PotionSplashEvent.java b/src/main/java/org/bukkit/event/entity/PotionSplashEvent.java index 80f31a26..bc6ba6c4 100644 --- a/src/main/java/org/bukkit/event/entity/PotionSplashEvent.java +++ b/src/main/java/org/bukkit/event/entity/PotionSplashEvent.java @@ -4,11 +4,15 @@ import com.google.common.base.Preconditions; import java.util.ArrayList; import java.util.Collection; import java.util.Map; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.ThrownPotion; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Called when a splash potion hits an area @@ -18,9 +22,13 @@ public class PotionSplashEvent extends ProjectileHitEvent implements Cancellable private boolean cancelled; private final Map affectedEntities; + @Deprecated public PotionSplashEvent(@NotNull final ThrownPotion potion, @NotNull final Map affectedEntities) { - super(potion); + this(potion, null, null, null, affectedEntities); + } + public PotionSplashEvent(@NotNull final ThrownPotion potion, @Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace, @NotNull final Map affectedEntities) { + super(potion, hitEntity, hitBlock, hitFace); this.affectedEntities = affectedEntities; } From d40e22dad28cfc913721c759a01fa8df8bd48020 Mon Sep 17 00:00:00 2001 From: James Peters Date: Mon, 6 Nov 2023 20:37:32 +1100 Subject: [PATCH 02/22] #712: Add API to get full result of crafting items --- src/main/java/org/bukkit/Bukkit.java | 76 +++++++++++++++++++ src/main/java/org/bukkit/Server.java | 69 +++++++++++++++++ .../org/bukkit/inventory/ItemCraftResult.java | 38 ++++++++++ 3 files changed, 183 insertions(+) create mode 100644 src/main/java/org/bukkit/inventory/ItemCraftResult.java diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java index d0532011..b9c18154 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -35,6 +35,7 @@ import org.bukkit.generator.ChunkGenerator; import org.bukkit.help.HelpMap; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemCraftResult; import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Merchant; @@ -943,6 +944,58 @@ public final class Bukkit { return server.getCraftingRecipe(craftingMatrix, world); } + /** + * Get the crafted item using the list of {@link ItemStack} provided. + * + *

The list is formatted as a crafting matrix where the index follow + * the pattern below:

+ * + *
+     * [ 0 1 2 ]
+     * [ 3 4 5 ]
+     * [ 6 7 8 ]
+     * 
+ * + *

The {@link World} and {@link Player} arguments are required to fulfill the Bukkit Crafting + * events.

+ * + *

Calls {@link org.bukkit.event.inventory.PrepareItemCraftEvent} to imitate the {@link Player} + * initiating the crafting event.

+ * + * @param craftingMatrix list of items to be crafted from. + * Must not contain more than 9 items. + * @param world The world the crafting takes place in. + * @param player The player to imitate the crafting event on. + * @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items. + */ + @NotNull + public static ItemCraftResult craftItemResult(@NotNull ItemStack[] craftingMatrix, @NotNull World world, @NotNull Player player) { + return server.craftItemResult(craftingMatrix, world, player); + } + + /** + * Get the crafted item using the list of {@link ItemStack} provided. + * + *

The list is formatted as a crafting matrix where the index follow + * the pattern below:

+ * + *
+     * [ 0 1 2 ]
+     * [ 3 4 5 ]
+     * [ 6 7 8 ]
+     * 
+ * + * @param craftingMatrix list of items to be crafted from. + * Must not contain more than 9 items. + * @param world The world the crafting takes place in. + * @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items. + */ + @NotNull + public static ItemCraftResult craftItemResult(@NotNull ItemStack[] craftingMatrix, @NotNull World world) { + return server.craftItemResult(craftingMatrix, world); + } + + /** * Get the crafted item using the list of {@link ItemStack} provided. * @@ -973,6 +1026,29 @@ public final class Bukkit { return server.craftItem(craftingMatrix, world, player); } + /** + * Get the crafted item using the list of {@link ItemStack} provided. + * + *

The list is formatted as a crafting matrix where the index follow + * the pattern below:

+ * + *
+     * [ 0 1 2 ]
+     * [ 3 4 5 ]
+     * [ 6 7 8 ]
+     * 
+ * + * @param craftingMatrix list of items to be crafted from. + * Must not contain more than 9 items. + * @param world The world the crafting takes place in. + * @return the {@link ItemStack} resulting from the given crafting matrix, if no recipe is found + * an ItemStack of {@link Material#AIR} is returned. + */ + @NotNull + public static ItemStack craftItem(@NotNull ItemStack[] craftingMatrix, @NotNull World world) { + return server.craftItem(craftingMatrix, world); + } + /** * Get an iterator through the list of crafting recipes. * diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java index e0df9253..e033b575 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -35,6 +35,7 @@ import org.bukkit.generator.ChunkGenerator; import org.bukkit.help.HelpMap; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemCraftResult; import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Merchant; @@ -835,6 +836,74 @@ public interface Server extends PluginMessageRecipient { @NotNull public ItemStack craftItem(@NotNull ItemStack[] craftingMatrix, @NotNull World world, @NotNull Player player); + /** + * Get the crafted item using the list of {@link ItemStack} provided. + * + *

The list is formatted as a crafting matrix where the index follow + * the pattern below:

+ * + *
+     * [ 0 1 2 ]
+     * [ 3 4 5 ]
+     * [ 6 7 8 ]
+     * 
+ * + * @param craftingMatrix list of items to be crafted from. + * Must not contain more than 9 items. + * @param world The world the crafting takes place in. + * @return the {@link ItemStack} resulting from the given crafting matrix, if no recipe is found + * an ItemStack of {@link Material#AIR} is returned. + */ + @NotNull + public ItemStack craftItem(@NotNull ItemStack[] craftingMatrix, @NotNull World world); + + /** + * Get the crafted item using the list of {@link ItemStack} provided. + * + *

The list is formatted as a crafting matrix where the index follow + * the pattern below:

+ * + *
+     * [ 0 1 2 ]
+     * [ 3 4 5 ]
+     * [ 6 7 8 ]
+     * 
+ * + *

The {@link World} and {@link Player} arguments are required to fulfill the Bukkit Crafting + * events.

+ * + *

Calls {@link org.bukkit.event.inventory.PrepareItemCraftEvent} to imitate the {@link Player} + * initiating the crafting event.

+ * + * @param craftingMatrix list of items to be crafted from. + * Must not contain more than 9 items. + * @param world The world the crafting takes place in. + * @param player The player to imitate the crafting event on. + * @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items. + */ + @NotNull + public ItemCraftResult craftItemResult(@NotNull ItemStack[] craftingMatrix, @NotNull World world, @NotNull Player player); + + /** + * Get the crafted item using the list of {@link ItemStack} provided. + * + *

The list is formatted as a crafting matrix where the index follow + * the pattern below:

+ * + *
+     * [ 0 1 2 ]
+     * [ 3 4 5 ]
+     * [ 6 7 8 ]
+     * 
+ * + * @param craftingMatrix list of items to be crafted from. + * Must not contain more than 9 items. + * @param world The world the crafting takes place in. + * @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items. + */ + @NotNull + public ItemCraftResult craftItemResult(@NotNull ItemStack[] craftingMatrix, @NotNull World world); + /** * Get an iterator through the list of crafting recipes. * diff --git a/src/main/java/org/bukkit/inventory/ItemCraftResult.java b/src/main/java/org/bukkit/inventory/ItemCraftResult.java new file mode 100644 index 00000000..ebb4d19e --- /dev/null +++ b/src/main/java/org/bukkit/inventory/ItemCraftResult.java @@ -0,0 +1,38 @@ +package org.bukkit.inventory; + +import java.util.List; +import org.jetbrains.annotations.NotNull; + +/** + * Container class containing the results of a Crafting event. + *
+ * This class makes no guarantees about the nature or mutability of the returned + * values. + */ +public interface ItemCraftResult { + + /** + * The resulting {@link ItemStack} that was crafted. + * + * @return {@link ItemStack} that was crafted. + */ + @NotNull + public ItemStack getResult(); + + /** + * Gets the resulting matrix from the crafting operation. + * + * @return resulting matrix + */ + @NotNull + public ItemStack[] getResultingMatrix(); + + /** + * Gets the overflowed items for items that don't fit back into the crafting + * matrix. + * + * @return overflow items + */ + @NotNull + public List getOverflowItems(); +} From f6f7c79d83d380b417d3275f4e2a9d985ca3f3e8 Mon Sep 17 00:00:00 2001 From: Miles Holder Date: Thu, 9 Nov 2023 06:30:10 +1100 Subject: [PATCH 03/22] SPIGOT-7514, #929: Add "Enchantment Roll" API to enchant items according to Minecraft mechanics --- .../org/bukkit/inventory/ItemFactory.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java index 502a1fd3..e606f63a 100644 --- a/src/main/java/org/bukkit/inventory/ItemFactory.java +++ b/src/main/java/org/bukkit/inventory/ItemFactory.java @@ -3,7 +3,9 @@ package org.bukkit.inventory; import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.Server; +import org.bukkit.World; import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.ItemMeta; @@ -172,4 +174,47 @@ public interface ItemFactory { */ @Nullable Material getSpawnEgg(@NotNull EntityType type); + + /** + * Enchants the given item at the provided level. + *
+ * If an item that is air is passed through an error is thrown. + * + * @param entity the entity to use as a source of randomness + * @param item the item to enchant + * @param level the level to use, which is the level in the enchantment table + * @param allowTreasures allows treasure enchants, e.g. mending, if true. + * @return the modified ItemStack, or a copy if the ItemStack cannot be enchanted directly + */ + @NotNull + ItemStack enchantItem(@NotNull final Entity entity, @NotNull final ItemStack item, final int level, final boolean allowTreasures); + + /** + * Enchants the given item at the provided level. + *
+ * If an item that is air is passed through an error is thrown. + * + * @param world the world to use as a source of randomness + * @param item the item to enchant + * @param level the level to use, which is the level in the enchantment table + * @param allowTreasures allow the treasure enchants, e.g. mending, if true. + * @return the modified ItemStack, or a copy if the ItemStack cannot be + * enchanted directly + */ + @NotNull + ItemStack enchantItem(@NotNull final World world, @NotNull final ItemStack item, final int level, final boolean allowTreasures); + + /** + * Enchants the given item at the provided level. + *
+ * If an item that is air is passed through an error is thrown. + * + * @param item the item to enchant + * @param level the level to use, which is the level in the enchantment table + * @param allowTreasures allow treasure enchantments, e.g. mending, if true. + * @return the modified ItemStack, or a copy if the ItemStack cannot be + * enchanted directly + */ + @NotNull + ItemStack enchantItem(@NotNull final ItemStack item, final int level, final boolean allowTreasures); } From 949ff21720fc8f6a586ec6e0e719e9f190436cfe Mon Sep 17 00:00:00 2001 From: Jishuna Date: Thu, 9 Nov 2023 06:36:02 +1100 Subject: [PATCH 04/22] #930: Add methods to get/set evoker fang attack delay --- src/main/java/org/bukkit/entity/EvokerFangs.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/org/bukkit/entity/EvokerFangs.java b/src/main/java/org/bukkit/entity/EvokerFangs.java index 7cc1dcda..7d5f9ccb 100644 --- a/src/main/java/org/bukkit/entity/EvokerFangs.java +++ b/src/main/java/org/bukkit/entity/EvokerFangs.java @@ -21,4 +21,18 @@ public interface EvokerFangs extends Entity { * @param owner the {@link LivingEntity} which summoned the fangs */ void setOwner(@Nullable LivingEntity owner); + + /** + * Get the delay in ticks until the fang attacks. + * + * @return the delay + */ + int getAttackDelay(); + + /** + * Set the delay in ticks until the fang attacks. + * + * @param delay the delay, must be positive + */ + void setAttackDelay(int delay); } From fde5602a24e30d563009378e8c9b08f693b148e2 Mon Sep 17 00:00:00 2001 From: Jishuna Date: Thu, 9 Nov 2023 06:43:30 +1100 Subject: [PATCH 05/22] #927: Add PlayerRecipeBookSettingsChangeEvent --- .../PlayerRecipeBookSettingsChangeEvent.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/main/java/org/bukkit/event/player/PlayerRecipeBookSettingsChangeEvent.java diff --git a/src/main/java/org/bukkit/event/player/PlayerRecipeBookSettingsChangeEvent.java b/src/main/java/org/bukkit/event/player/PlayerRecipeBookSettingsChangeEvent.java new file mode 100644 index 00000000..249f670f --- /dev/null +++ b/src/main/java/org/bukkit/event/player/PlayerRecipeBookSettingsChangeEvent.java @@ -0,0 +1,87 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +/** + * Called when a player changes recipe book settings. + */ +public class PlayerRecipeBookSettingsChangeEvent extends PlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + private final RecipeBookType recipeBookType; + private final boolean open; + private final boolean filtering; + + public PlayerRecipeBookSettingsChangeEvent(@NotNull final Player player, @NotNull final RecipeBookType recipeBookType, final boolean open, final boolean filtering) { + super(player); + this.recipeBookType = recipeBookType; + this.open = open; + this.filtering = filtering; + } + + /** + * Gets the type of recipe book the player is changing the settings for. + * + * @return the type of recipe book + */ + @NotNull + public RecipeBookType getRecipeBookType() { + return recipeBookType; + } + + /** + * Checks if the recipe book is being opened or closed. + * + * @return true if opening + */ + public boolean isOpen() { + return open; + } + + /** + * Checks if the recipe book filter is being enabled or disabled. + * + * @return true if enabling + */ + public boolean isFiltering() { + return filtering; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return handlers; + } + + @NotNull + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * Enum representing the various types of recipe book. + *
+ * Different types of recipe book are shown in different GUIs. + */ + public enum RecipeBookType { + + /** + * Recipe book seen in crafting table and player inventory. + */ + CRAFTING, + /** + * Recipe book seen in furnace. + */ + FURNACE, + /** + * Recipe book seen in blast furnace. + */ + BLAST_FURNACE, + /** + * Recipe book seen in smoker. + */ + SMOKER; + } +} From 0616ec8b24e1f596b1e92c88676a9ea91e5fbe8a Mon Sep 17 00:00:00 2001 From: DerFrZocker Date: Thu, 9 Nov 2023 10:20:23 +0100 Subject: [PATCH 06/22] Add eclipse .factorypath file to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 11038da2..5dd700a9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /.project /.settings /.checkstyle +/.factorypath # netbeans /nbproject From 27ae46dcd29c7a8e576f3e21f38a542f9b719ada Mon Sep 17 00:00:00 2001 From: Jishuna Date: Fri, 10 Nov 2023 06:58:15 +1100 Subject: [PATCH 07/22] SPIGOT-3641, SPIGOT-7479, #931: Add missing values to EntityEffect --- src/main/java/org/bukkit/EntityEffect.java | 164 +++++++++++++++++++-- 1 file changed, 153 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/bukkit/EntityEffect.java b/src/main/java/org/bukkit/EntityEffect.java index 1747b912..9db85b2f 100644 --- a/src/main/java/org/bukkit/EntityEffect.java +++ b/src/main/java/org/bukkit/EntityEffect.java @@ -1,25 +1,37 @@ package org.bukkit; +import com.google.common.base.Preconditions; import org.bukkit.entity.Ageable; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Cat; import org.bukkit.entity.Dolphin; +import org.bukkit.entity.Egg; import org.bukkit.entity.Entity; +import org.bukkit.entity.EvokerFangs; import org.bukkit.entity.Firework; import org.bukkit.entity.Fox; +import org.bukkit.entity.Goat; import org.bukkit.entity.Guardian; +import org.bukkit.entity.Hoglin; import org.bukkit.entity.IronGolem; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Rabbit; import org.bukkit.entity.Ravager; +import org.bukkit.entity.Sheep; +import org.bukkit.entity.Sniffer; +import org.bukkit.entity.Snowball; import org.bukkit.entity.Squid; import org.bukkit.entity.Tameable; import org.bukkit.entity.TippedArrow; import org.bukkit.entity.Villager; +import org.bukkit.entity.Warden; import org.bukkit.entity.Witch; import org.bukkit.entity.Wolf; +import org.bukkit.entity.Zoglin; import org.bukkit.entity.ZombieVillager; +import org.bukkit.entity.minecart.ExplosiveMinecart; +import org.bukkit.entity.minecart.SpawnerMinecart; import org.jetbrains.annotations.NotNull; /** @@ -35,6 +47,11 @@ public enum EntityEffect { * Rabbit jumping. */ RABBIT_JUMP(1, Rabbit.class), + /** + * Resets a spawner minecart's delay to 200. Does not effect actual spawning + * delay, only the speed at which the entity in the spawner spins + */ + RESET_SPAWNER_MINECART_DELAY(1, SpawnerMinecart.class), /** * When mobs get hurt. * @@ -47,35 +64,86 @@ public enum EntityEffect { *

* This will cause client-glitches! * - * @deprecated although this effect may trigger other events on non-living - * entities, it's only supported usage is on living ones. + * @deprecated split into individual effects + * @see #EGG_BREAK + * @see #SNOWBALL_BREAK + * @see #ENTITY_DEATH */ @Deprecated DEATH(3, Entity.class), - // PAIL - SPIGOT-3641 duplicate - // GOLEM_ATTACK(4, IronGolem.class), + /** + * Spawns the egg breaking particles + */ + EGG_BREAK(3, Egg.class), + /** + * Spawns the snowball breaking particles + */ + SNOWBALL_BREAK(3, Snowball.class), + /** + * Plays the entity death sound and animation + *

+ * This will cause client-glitches! + */ + ENTITY_DEATH(3, LivingEntity.class), + /** + * Plays the fang attack animation + */ + FANG_ATTACK(4, EvokerFangs.class), + /** + * Plays the hoglin attack animation + */ + HOGLIN_ATTACK(4, Hoglin.class), + /** + * Plays the iron golem attack animation + */ + IRON_GOLEN_ATTACK(4, IronGolem.class), + /** + * Plays the ravager attack animation + */ + RAVAGER_ATTACK(4, Ravager.class), + /** + * Plays the warden attack animation + */ + WARDEN_ATTACK(4, Warden.class), + /** + * Plays the zoglin attack animation + */ + ZOGLIN_ATTACK(4, Zoglin.class), // 5 - unused /** - * The smoke when taming a wolf fails. + * The smoke when taming an entity fails. */ WOLF_SMOKE(6, Tameable.class), /** - * The hearts when taming a wolf succeeds. + * The hearts when taming an entity succeeds. */ - WOLF_HEARTS(7, Wolf.class), + WOLF_HEARTS(7, Tameable.class), /** * When a wolf shakes (after being wet). + * + * @see EntityEffect#WOLF_SHAKE_STOP */ WOLF_SHAKE(8, Wolf.class), // 9 - unused /** * When an entity eats a LONG_GRASS block. * - * @deprecated although this effect may trigger other events on non-living - * entities, it's only supported usage is on living ones. + * @deprecated split into individual effects + * @see #SHEEP_EAT_GRASS + * @see #TNT_MINECART_IGNITE */ @Deprecated SHEEP_EAT(10, Entity.class), + /** + * Plays the sheep eating grass animation + */ + SHEEP_EAT_GRASS(10, Sheep.class), + /** + * Causes the TNT minecart to ignite, does not play the ignition sound + *

+ * This will cause client-glitches! + */ + TNT_MINECART_IGNITE(10, ExplosiveMinecart.class), /** * When an Iron Golem gives a rose. */ @@ -213,7 +281,57 @@ public enum EntityEffect { /** * Entity breaks item in boot slot */ - BREAK_EQUIPMENT_BOOTS(52, LivingEntity.class); + BREAK_EQUIPMENT_BOOTS(52, LivingEntity.class), + /** + * Spawns honey block slide particles at the entity's feet + */ + HONEY_BLOCK_SLIDE_PARTICLES(53, Entity.class), + /** + * Spawns honey block fall particles at the entity's feet + */ + HONEY_BLOCK_FALL_PARTICLES(54, LivingEntity.class), + /** + * Entity swaps the items in their hand and offhand + */ + SWAP_HAND_ITEMS(55, LivingEntity.class), + /** + * Stops a wolf that is currently shaking + * + * @see EntityEffect#WOLF_SHAKE + */ + WOLF_SHAKE_STOP(56, Wolf.class), + // 57 - unused + /** + * Goat lowers its head for ramming + * + * @see #GOAT_RAISE_HEAD + */ + GOAT_LOWER_HEAD(58, Goat.class), + /** + * Goat raises its head + * + * @see #GOAT_LOWER_HEAD + */ + GOAT_RAISE_HEAD(59, Goat.class), + /** + * Spawns death smoke particles + */ + SPAWN_DEATH_SMOKE(60, LivingEntity.class), + /** + * Warden shakes its tendrils + */ + WARDEN_TENDRIL_SHAKE(61, Warden.class), + /** + * Warden performs sonic attack animation
+ * Does not play the sound or fire the beam + */ + WARDEN_SONIC_ATTACK(62, Warden.class), + /** + * Plays sniffer digging sound
+ * Sniffer must have a target and be in {@link Sniffer.State#SEARCHING} or + * {@link Sniffer.State#DIGGING} + */ + SNIFFER_DIG(63, Sniffer.class); private final byte data; private final Class applicable; @@ -224,7 +342,7 @@ public enum EntityEffect { } /** - * Gets the data value of this EntityEffect + * Gets the data value of this EntityEffect, may not be unique. * * @return The data value * @deprecated Magic value @@ -243,4 +361,28 @@ public enum EntityEffect { public Class getApplicable() { return applicable; } + + /** + * Checks if this effect is applicable to the given entity. + * + * @param entity the entity to check + * @return true if applicable + */ + public boolean isApplicableTo(@NotNull Entity entity) { + Preconditions.checkArgument(entity != null, "Entity cannot be null"); + + return isApplicableTo(entity.getClass()); + } + + /** + * Checks if this effect is applicable to the given entity class. + * + * @param clazz the entity class to check + * @return true if applicable + */ + public boolean isApplicableTo(@NotNull Class clazz) { + Preconditions.checkArgument(clazz != null, "Class cannot be null"); + + return applicable.isAssignableFrom(clazz); + } } From e979ee952247ea64ae99e494dee0a43cdd8c4f71 Mon Sep 17 00:00:00 2001 From: DerFrZocker Date: Tue, 14 Nov 2023 19:50:23 +1300 Subject: [PATCH 08/22] #935: Change Consumer and Predicates to super --- src/main/java/org/bukkit/Bukkit.java | 2 +- src/main/java/org/bukkit/Material.java | 2 +- src/main/java/org/bukkit/RegionAccessor.java | 8 ++++---- src/main/java/org/bukkit/Server.java | 2 +- src/main/java/org/bukkit/World.java | 14 +++++++------- .../java/org/bukkit/scheduler/BukkitScheduler.java | 12 ++++++------ 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java index b9c18154..001703ba 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -1937,7 +1937,7 @@ public final class Bukkit { * @return new data instance */ @NotNull - public static BlockData createBlockData(@NotNull Material material, @Nullable Consumer consumer) { + public static BlockData createBlockData(@NotNull Material material, @Nullable Consumer consumer) { return server.createBlockData(material, consumer); } diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java index 7ed67f35..f06e06d8 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java @@ -4504,7 +4504,7 @@ public enum Material implements Keyed, Translatable { * @return new data instance */ @NotNull - public BlockData createBlockData(@Nullable Consumer consumer) { + public BlockData createBlockData(@Nullable Consumer consumer) { return Bukkit.createBlockData(this, consumer); } diff --git a/src/main/java/org/bukkit/RegionAccessor.java b/src/main/java/org/bukkit/RegionAccessor.java index 02de62c0..369b95b1 100644 --- a/src/main/java/org/bukkit/RegionAccessor.java +++ b/src/main/java/org/bukkit/RegionAccessor.java @@ -182,7 +182,7 @@ public interface RegionAccessor { * @param stateConsumer The consumer which should get called for every block which gets changed * @return true if the tree was created successfully, otherwise false */ - boolean generateTree(@NotNull Location location, @NotNull Random random, @NotNull TreeType type, @Nullable Consumer stateConsumer); + boolean generateTree(@NotNull Location location, @NotNull Random random, @NotNull TreeType type, @Nullable Consumer stateConsumer); /** * Creates a tree at the given {@link Location} @@ -202,7 +202,7 @@ public interface RegionAccessor { * @param statePredicate The predicate which should get used to test if a block should be set or not. * @return true if the tree was created successfully, otherwise false */ - boolean generateTree(@NotNull Location location, @NotNull Random random, @NotNull TreeType type, @Nullable Predicate statePredicate); + boolean generateTree(@NotNull Location location, @NotNull Random random, @NotNull TreeType type, @Nullable Predicate statePredicate); /** * Creates a entity at the given {@link Location} @@ -309,7 +309,7 @@ public interface RegionAccessor { * {@link Entity} requested cannot be spawned */ @NotNull - T spawn(@NotNull Location location, @NotNull Class clazz, @Nullable Consumer function) throws IllegalArgumentException; + T spawn(@NotNull Location location, @NotNull Class clazz, @Nullable Consumer function) throws IllegalArgumentException; /** * Creates a new entity at the given {@link Location} with the supplied @@ -347,7 +347,7 @@ public interface RegionAccessor { * @throws IllegalArgumentException if either the world or clazz parameter are null. */ @NotNull - public T spawn(@NotNull Location location, @NotNull Class clazz, boolean randomizeData, @Nullable Consumer function) throws IllegalArgumentException; + public T spawn(@NotNull Location location, @NotNull Class clazz, boolean randomizeData, @Nullable Consumer function) throws IllegalArgumentException; /** * Gets the highest non-empty (impassable) coordinate at the given diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java index e033b575..130c169f 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -1649,7 +1649,7 @@ public interface Server extends PluginMessageRecipient { * @return new data instance */ @NotNull - public BlockData createBlockData(@NotNull Material material, @Nullable Consumer consumer); + public BlockData createBlockData(@NotNull Material material, @Nullable Consumer consumer); /** * Creates a new {@link BlockData} instance with material and properties diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java index aecb77d0..682854c0 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -454,7 +454,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * @return ItemDrop entity created as a result of this method */ @NotNull - public Item dropItem(@NotNull Location location, @NotNull ItemStack item, @Nullable Consumer function); + public Item dropItem(@NotNull Location location, @NotNull ItemStack item, @Nullable Consumer function); /** * Drops an item at the specified {@link Location} with a random offset @@ -476,7 +476,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * @return ItemDrop entity created as a result of this method */ @NotNull - public Item dropItemNaturally(@NotNull Location location, @NotNull ItemStack item, @Nullable Consumer function); + public Item dropItemNaturally(@NotNull Location location, @NotNull ItemStack item, @Nullable Consumer function); /** * Creates an {@link Arrow} entity at the given {@link Location} @@ -642,7 +642,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * non-null collection. */ @NotNull - public Collection getNearbyEntities(@NotNull Location location, double x, double y, double z, @Nullable Predicate filter); + public Collection getNearbyEntities(@NotNull Location location, double x, double y, double z, @Nullable Predicate filter); /** * Returns a list of entities within the given bounding box. @@ -672,7 +672,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * be a non-null collection */ @NotNull - public Collection getNearbyEntities(@NotNull BoundingBox boundingBox, @Nullable Predicate filter); + public Collection getNearbyEntities(@NotNull BoundingBox boundingBox, @Nullable Predicate filter); /** * Performs a ray trace that checks for entity collisions. @@ -727,7 +727,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * @see #rayTraceEntities(Location, Vector, double, double, Predicate) */ @Nullable - public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, @Nullable Predicate filter); + public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, @Nullable Predicate filter); /** * Performs a ray trace that checks for entity collisions. @@ -747,7 +747,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * is no hit */ @Nullable - public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, double raySize, @Nullable Predicate filter); + public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, double raySize, @Nullable Predicate filter); /** * Performs a ray trace that checks for block collisions using the blocks' @@ -843,7 +843,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * entity, or null if there is no hit */ @Nullable - public RayTraceResult rayTrace(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, @Nullable Predicate filter); + public RayTraceResult rayTrace(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, @Nullable Predicate filter); /** * Gets the default spawn {@link Location} of this world diff --git a/src/main/java/org/bukkit/scheduler/BukkitScheduler.java b/src/main/java/org/bukkit/scheduler/BukkitScheduler.java index 5aefb7f2..0368e912 100644 --- a/src/main/java/org/bukkit/scheduler/BukkitScheduler.java +++ b/src/main/java/org/bukkit/scheduler/BukkitScheduler.java @@ -227,7 +227,7 @@ public interface BukkitScheduler { * @throws IllegalArgumentException if plugin is null * @throws IllegalArgumentException if task is null */ - public void runTask(@NotNull Plugin plugin, @NotNull Consumer task) throws IllegalArgumentException; + public void runTask(@NotNull Plugin plugin, @NotNull Consumer task) throws IllegalArgumentException; /** * @param plugin the reference to the plugin scheduling task @@ -267,7 +267,7 @@ public interface BukkitScheduler { * @throws IllegalArgumentException if plugin is null * @throws IllegalArgumentException if task is null */ - public void runTaskAsynchronously(@NotNull Plugin plugin, @NotNull Consumer task) throws IllegalArgumentException; + public void runTaskAsynchronously(@NotNull Plugin plugin, @NotNull Consumer task) throws IllegalArgumentException; /** * @param plugin the reference to the plugin scheduling task @@ -305,7 +305,7 @@ public interface BukkitScheduler { * @throws IllegalArgumentException if plugin is null * @throws IllegalArgumentException if task is null */ - public void runTaskLater(@NotNull Plugin plugin, @NotNull Consumer task, long delay) throws IllegalArgumentException; + public void runTaskLater(@NotNull Plugin plugin, @NotNull Consumer task, long delay) throws IllegalArgumentException; /** * @param plugin the reference to the plugin scheduling task @@ -350,7 +350,7 @@ public interface BukkitScheduler { * @throws IllegalArgumentException if plugin is null * @throws IllegalArgumentException if task is null */ - public void runTaskLaterAsynchronously(@NotNull Plugin plugin, @NotNull Consumer task, long delay) throws IllegalArgumentException; + public void runTaskLaterAsynchronously(@NotNull Plugin plugin, @NotNull Consumer task, long delay) throws IllegalArgumentException; /** * @param plugin the reference to the plugin scheduling task @@ -391,7 +391,7 @@ public interface BukkitScheduler { * @throws IllegalArgumentException if plugin is null * @throws IllegalArgumentException if task is null */ - public void runTaskTimer(@NotNull Plugin plugin, @NotNull Consumer task, long delay, long period) throws IllegalArgumentException; + public void runTaskTimer(@NotNull Plugin plugin, @NotNull Consumer task, long delay, long period) throws IllegalArgumentException; /** * @param plugin the reference to the plugin scheduling task @@ -441,7 +441,7 @@ public interface BukkitScheduler { * @throws IllegalArgumentException if plugin is null * @throws IllegalArgumentException if task is null */ - public void runTaskTimerAsynchronously(@NotNull Plugin plugin, @NotNull Consumer task, long delay, long period) throws IllegalArgumentException; + public void runTaskTimerAsynchronously(@NotNull Plugin plugin, @NotNull Consumer task, long delay, long period) throws IllegalArgumentException; /** * @param plugin the reference to the plugin scheduling task From cbfe0ff00b298a8c88b8c1870a3a169936c9b2e0 Mon Sep 17 00:00:00 2001 From: Jishuna Date: Thu, 16 Nov 2023 15:36:28 +1300 Subject: [PATCH 09/22] #937: Minor improvements to World#rayTrace documentation --- src/main/java/org/bukkit/World.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java index 682854c0..ef1ac9cd 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -680,6 +680,9 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * This may not consider entities in currently unloaded chunks. Some * implementations may impose artificial restrictions on the maximum * distance. + *

+ * Note: Due to display entities having a zero size hitbox, this method will not detect them. + * To detect display entities use {@link #rayTraceEntities(Location, Vector, double, double)} with a positive raySize * * @param start the start position * @param direction the ray direction @@ -702,7 +705,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * @param direction the ray direction * @param maxDistance the maximum distance * @param raySize entity bounding boxes will be uniformly expanded (or - * shrinked) by this value before doing collision checks + * shrunk) by this value before doing collision checks * @return the closest ray trace hit result, or null if there * is no hit * @see #rayTraceEntities(Location, Vector, double, double, Predicate) @@ -716,6 +719,9 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * This may not consider entities in currently unloaded chunks. Some * implementations may impose artificial restrictions on the maximum * distance. + *

+ * Note: Due to display entities having a zero size hitbox, this method will not detect them. + * To detect display entities use {@link #rayTraceEntities(Location, Vector, double, double, Predicate)} with a positive raySize * * @param start the start position * @param direction the ray direction @@ -740,7 +746,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * @param direction the ray direction * @param maxDistance the maximum distance * @param raySize entity bounding boxes will be uniformly expanded (or - * shrinked) by this value before doing collision checks + * shrunk) by this value before doing collision checks * @param filter only entities that fulfill this predicate are considered, * or null to consider all entities * @return the closest ray trace hit result, or null if there @@ -836,7 +842,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * @param ignorePassableBlocks whether to ignore passable but collidable * blocks (ex. tall grass, signs, fluids, ..) * @param raySize entity bounding boxes will be uniformly expanded (or - * shrinked) by this value before doing collision checks + * shrunk) by this value before doing collision checks * @param filter only entities that fulfill this predicate are considered, * or null to consider all entities * @return the closest ray trace hit result with either a block or an From 96340858187334c2f24f6acdc904561655c6cbab Mon Sep 17 00:00:00 2001 From: Jishuna Date: Fri, 17 Nov 2023 19:54:43 +1300 Subject: [PATCH 10/22] #938: Various Sound API improvements --- src/main/java/org/bukkit/Instrument.java | 65 ++++++++++------- src/main/java/org/bukkit/Note.java | 18 +++++ src/main/java/org/bukkit/World.java | 76 ++++++++++++++++++++ src/main/java/org/bukkit/entity/Player.java | 79 ++++++++++++++++++--- 4 files changed, 203 insertions(+), 35 deletions(-) diff --git a/src/main/java/org/bukkit/Instrument.java b/src/main/java/org/bukkit/Instrument.java index de976be7..032d7b81 100644 --- a/src/main/java/org/bukkit/Instrument.java +++ b/src/main/java/org/bukkit/Instrument.java @@ -9,110 +9,123 @@ public enum Instrument { /** * Piano is the standard instrument for a note block. */ - PIANO(0x0), + PIANO(0x0, Sound.BLOCK_NOTE_BLOCK_HARP), /** * Bass drum is normally played when a note block is on top of a * stone-like block. */ - BASS_DRUM(0x1), + BASS_DRUM(0x1, Sound.BLOCK_NOTE_BLOCK_BASEDRUM), /** * Snare drum is normally played when a note block is on top of a sandy * block. */ - SNARE_DRUM(0x2), + SNARE_DRUM(0x2, Sound.BLOCK_NOTE_BLOCK_SNARE), /** * Sticks are normally played when a note block is on top of a glass * block. */ - STICKS(0x3), + STICKS(0x3, Sound.BLOCK_NOTE_BLOCK_HAT), /** * Bass guitar is normally played when a note block is on top of a wooden * block. */ - BASS_GUITAR(0x4), + BASS_GUITAR(0x4, Sound.BLOCK_NOTE_BLOCK_BASS), /** * Flute is normally played when a note block is on top of a clay block. */ - FLUTE(0x5), + FLUTE(0x5, Sound.BLOCK_NOTE_BLOCK_FLUTE), /** * Bell is normally played when a note block is on top of a gold block. */ - BELL(0x6), + BELL(0x6, Sound.BLOCK_NOTE_BLOCK_BELL), /** * Guitar is normally played when a note block is on top of a woolen block. */ - GUITAR(0x7), + GUITAR(0x7, Sound.BLOCK_NOTE_BLOCK_GUITAR), /** * Chime is normally played when a note block is on top of a packed ice * block. */ - CHIME(0x8), + CHIME(0x8, Sound.BLOCK_NOTE_BLOCK_CHIME), /** * Xylophone is normally played when a note block is on top of a bone block. */ - XYLOPHONE(0x9), + XYLOPHONE(0x9, Sound.BLOCK_NOTE_BLOCK_XYLOPHONE), /** * Iron Xylophone is normally played when a note block is on top of a iron block. */ - IRON_XYLOPHONE(0xA), + IRON_XYLOPHONE(0xA, Sound.BLOCK_NOTE_BLOCK_IRON_XYLOPHONE), /** * Cow Bell is normally played when a note block is on top of a soul sand block. */ - COW_BELL(0xB), + COW_BELL(0xB, Sound.BLOCK_NOTE_BLOCK_COW_BELL), /** * Didgeridoo is normally played when a note block is on top of a pumpkin block. */ - DIDGERIDOO(0xC), + DIDGERIDOO(0xC, Sound.BLOCK_NOTE_BLOCK_DIDGERIDOO), /** * Bit is normally played when a note block is on top of a emerald block. */ - BIT(0xD), + BIT(0xD, Sound.BLOCK_NOTE_BLOCK_BIT), /** * Banjo is normally played when a note block is on top of a hay block. */ - BANJO(0xE), + BANJO(0xE, Sound.BLOCK_NOTE_BLOCK_BANJO), /** * Pling is normally played when a note block is on top of a glowstone block. */ - PLING(0xF), + PLING(0xF, Sound.BLOCK_NOTE_BLOCK_PLING), /** * Zombie is normally played when a Zombie Head is on top of the note block. */ - ZOMBIE, + ZOMBIE(Sound.BLOCK_NOTE_BLOCK_IMITATE_ZOMBIE), /** * Skeleton is normally played when a Skeleton Head is on top of the note block. */ - SKELETON, + SKELETON(Sound.BLOCK_NOTE_BLOCK_IMITATE_SKELETON), /** * Creeper is normally played when a Creeper Head is on top of the note block. */ - CREEPER, + CREEPER(Sound.BLOCK_NOTE_BLOCK_IMITATE_CREEPER), /** * Dragon is normally played when a Dragon Head is on top of the note block. */ - DRAGON, + DRAGON(Sound.BLOCK_NOTE_BLOCK_IMITATE_ENDER_DRAGON), /** * Wither Skeleton is normally played when a Wither Skeleton Head is on top of the note block. */ - WITHER_SKELETON, + WITHER_SKELETON(Sound.BLOCK_NOTE_BLOCK_IMITATE_WITHER_SKELETON), /** * Piglin is normally played when a Piglin Head is on top of the note block. */ - PIGLIN, + PIGLIN(Sound.BLOCK_NOTE_BLOCK_IMITATE_PIGLIN), /** * Custom Sound is normally played when a Player Head with the required data is on top of the note block. */ - CUSTOM_HEAD; + CUSTOM_HEAD(null); private final byte type; + private final Sound sound; private static final Map BY_DATA = Maps.newHashMap(); - private Instrument() { - this(-1); + private Instrument(final Sound sound) { + this(-1, sound); } - private Instrument(final int type) { + private Instrument(final int type, final Sound sound) { this.type = (byte) type; + this.sound = sound; + } + + /** + * Gets the sound associated with this instrument.
+ * Will be null for {@link Instrument#CUSTOM_HEAD} + * + * @return the sound or null + */ + @Nullable + public Sound getSound() { + return this.sound; } /** diff --git a/src/main/java/org/bukkit/Note.java b/src/main/java/org/bukkit/Note.java index fc3da7ce..48aecc94 100644 --- a/src/main/java/org/bukkit/Note.java +++ b/src/main/java/org/bukkit/Note.java @@ -118,6 +118,14 @@ public class Note { } } + private static final float[] pitchArray = new float[25]; + static { + for (int i = 0; i <= 24; i++) { + // See https://minecraft.wiki/w/Note_Block#Notes + pitchArray[i] = (float) Math.pow(2, (i - 12) / 12f); + } + } + private final byte note; /** @@ -254,6 +262,16 @@ public class Note { return Tone.getById(note).isSharped(note); } + /** + * Gets the pitch of this note. This is the value used with + * {@link World#playSound} or the /playsound command. + * + * @return the pitch + */ + public float getPitch() { + return pitchArray[this.note]; + } + @Override public int hashCode() { final int prime = 31; diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java index ef1ac9cd..16feb5ef 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -2109,6 +2109,18 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient */ void setSpawnLimit(@NotNull SpawnCategory spawnCategory, int limit); + /** + * Play a note at the provided Location in the World.
+ * This will work with cake. + *

+ * This method will fail silently when called with {@link Instrument#CUSTOM_HEAD}. + * + * @param loc The location to play the note + * @param instrument The instrument + * @param note The note + */ + void playNote(@NotNull Location loc, @NotNull Instrument instrument, @NotNull Note note); + /** * Play a Sound at the provided Location in the World. *

@@ -2163,6 +2175,38 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient */ void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch); + /** + * Play a Sound at the provided Location in the World. For sounds with multiple + * variations passing the same seed will always play the same variation. + *

+ * This function will fail silently if Location or Sound are null. + * + * @param location The location to play the sound + * @param sound The sound to play + * @param category the category of the sound + * @param volume The volume of the sound + * @param pitch The pitch of the sound + * @param seed The seed for the sound + */ + void playSound(@NotNull Location location, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + + /** + * Play a Sound at the provided Location in the World. For sounds with multiple + * variations passing the same seed will always play the same variation. + *

+ * This function will fail silently if Location or Sound are null. No sound will + * be heard by the players if their clients do not have the respective sound for + * the value passed. + * + * @param location The location to play the sound + * @param sound The internal sound name to play + * @param category the category of the sound + * @param volume The volume of the sound + * @param pitch The pitch of the sound + * @param seed The seed for the sound + */ + void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + /** * Play a Sound at the location of the provided entity in the World. *

@@ -2213,6 +2257,38 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient */ void playSound(@NotNull Entity entity, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch); + /** + * Play a Sound at the location of the provided entity in the World. For sounds + * with multiple variations passing the same seed will always play the same + * variation. + *

+ * This function will fail silently if Entity or Sound are null. + * + * @param entity The entity to play the sound + * @param sound The sound to play + * @param category The category of the sound + * @param volume The volume of the sound + * @param pitch The pitch of the sound + * @param seed The seed for the sound + */ + void playSound(@NotNull Entity entity, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + + /** + * Play a Sound at the location of the provided entity in the World. For sounds + * with multiple variations passing the same seed will always play the same + * variation. + *

+ * This function will fail silently if Entity or Sound are null. + * + * @param entity The entity to play the sound + * @param sound The sound to play + * @param category The category of the sound + * @param volume The volume of the sound + * @param pitch The pitch of the sound + * @param seed The seed for the sound + */ + void playSound(@NotNull Entity entity, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + /** * Get an array containing the names of all the {@link GameRule}s. * diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java index de462c23..3cf31b08 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -391,11 +391,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM public void setBedSpawnLocation(@Nullable Location location, boolean force); /** - * Play a note for a player at a location. This requires a note block - * at the particular location (as far as the client is concerned). This - * will not work without a note block. This will not work with cake. + * Play a note for the player at a location.
+ * This will work with cake. * - * @param loc The location of a note block. + * @param loc The location to play the note * @param instrument The instrument ID. * @param note The note ID. * @deprecated Magic value @@ -404,11 +403,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM public void playNote(@NotNull Location loc, byte instrument, byte note); /** - * Play a note for a player at a location. This requires a note block - * at the particular location (as far as the client is concerned). This - * will not work without a note block. This will not work with cake. - * - * @param loc The location of a note block + * Play a note for the player at a location.
+ * This will work with cake. + *

+ * This method will fail silently when called with {@link Instrument#CUSTOM_HEAD}. + * @param loc The location to play the note * @param instrument The instrument * @param note The note */ @@ -469,6 +468,38 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch); + /** + * Play a sound for a player at the location. For sounds with multiple + * variations passing the same seed will always play the same variation. + *

+ * This function will fail silently if Location or Sound are null. + * + * @param location The location to play the sound + * @param sound The sound to play + * @param category The category of the sound + * @param volume The volume of the sound + * @param pitch The pitch of the sound + * @param seed The seed for the sound + */ + public void playSound(@NotNull Location location, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + + /** + * Play a sound for a player at the location. For sounds with multiple + * variations passing the same seed will always play the same variation. + *

+ * This function will fail silently if Location or Sound are null. No sound + * will be heard by the player if their client does not have the respective + * sound for the value passed. + * + * @param location The location to play the sound + * @param sound The internal sound name to play + * @param category The category of the sound + * @param volume The volume of the sound + * @param pitch The pitch of the sound + * @param seed The seed for the sound + */ + public void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + /** * Play a sound for a player at the location of the entity. *

@@ -519,6 +550,36 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void playSound(@NotNull Entity entity, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch); + /** + * Play a sound for a player at the location of the entity. For sounds with + * multiple variations passing the same seed will always play the same variation. + *

+ * This function will fail silently if Entity or Sound are null. + * + * @param entity The entity to play the sound + * @param sound The sound to play + * @param category The category of the sound + * @param volume The volume of the sound + * @param pitch The pitch of the sound + * @param seed The seed for the sound + */ + public void playSound(@NotNull Entity entity, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + + /** + * Play a sound for a player at the location of the entity. For sounds with + * multiple variations passing the same seed will always play the same variation. + *

+ * This function will fail silently if Entity or Sound are null. + * + * @param entity The entity to play the sound + * @param sound The sound to play + * @param category The category of the sound + * @param volume The volume of the sound + * @param pitch The pitch of the sound + * @param seed The seed for the sound + */ + public void playSound(@NotNull Entity entity, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + /** * Stop the specified sound from playing. * From 276d0a741fdb6c451a28d02ede4e86b930429b4b Mon Sep 17 00:00:00 2001 From: Jishuna Date: Sun, 19 Nov 2023 19:03:25 +1300 Subject: [PATCH 11/22] #915: Add support for virtual entities --- src/main/java/org/bukkit/RegionAccessor.java | 29 +++ .../org/bukkit/block/CreatureSpawner.java | 80 ++++++- .../org/bukkit/block/spawner/SpawnRule.java | 219 ++++++++++++++++++ .../bukkit/block/spawner/SpawnerEntry.java | 85 +++++++ .../bukkit/block/spawner/package-info.java | 4 + .../ConfigurationSerialization.java | 2 + src/main/java/org/bukkit/entity/Entity.java | 46 +++- .../org/bukkit/entity/EntitySnapshot.java | 39 ++++ .../bukkit/inventory/meta/SpawnEggMeta.java | 24 ++ 9 files changed, 525 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/bukkit/block/spawner/SpawnRule.java create mode 100644 src/main/java/org/bukkit/block/spawner/SpawnerEntry.java create mode 100644 src/main/java/org/bukkit/block/spawner/package-info.java create mode 100644 src/main/java/org/bukkit/entity/EntitySnapshot.java diff --git a/src/main/java/org/bukkit/RegionAccessor.java b/src/main/java/org/bukkit/RegionAccessor.java index 369b95b1..4c9fd558 100644 --- a/src/main/java/org/bukkit/RegionAccessor.java +++ b/src/main/java/org/bukkit/RegionAccessor.java @@ -279,6 +279,24 @@ public interface RegionAccessor { @NotNull Collection getEntitiesByClasses(@NotNull Class... classes); + /** + * Creates an entity of a specific class at the given {@link Location} but + * does not spawn it in the world. + *

+ * Note: The created entity keeps a reference to the world it was + * created in, care should be taken that the entity does not outlive the + * world instance as this will lead to memory leaks. + * + * @param the class of the {@link Entity} to create + * @param location the {@link Location} to create the entity at + * @param clazz the class of the {@link Entity} to spawn + * @return an instance of the created {@link Entity} + * @see #addEntity(Entity) + * @see Entity#createSnapshot() + */ + @NotNull + T createEntity(@NotNull Location location, @NotNull Class clazz); + /** * Spawn an entity of a specific class at the given {@link Location} * @@ -393,4 +411,15 @@ public interface RegionAccessor { * {@link HeightMap} */ public int getHighestBlockYAt(@NotNull Location location, @NotNull HeightMap heightMap); + + /** + * Spawns a previously created entity in the world.
+ * The provided entity must not have already been spawned in a world. + * + * @param the generic type of the entity that is being added. + * @param entity the entity to add + * @return the entity now in the world + */ + @NotNull + public T addEntity(@NotNull T entity); } diff --git a/src/main/java/org/bukkit/block/CreatureSpawner.java b/src/main/java/org/bukkit/block/CreatureSpawner.java index 8dae9611..c33f6573 100644 --- a/src/main/java/org/bukkit/block/CreatureSpawner.java +++ b/src/main/java/org/bukkit/block/CreatureSpawner.java @@ -1,6 +1,12 @@ package org.bukkit.block; +import java.util.Collection; +import java.util.List; +import org.bukkit.block.spawner.SpawnRule; +import org.bukkit.block.spawner.SpawnerEntry; +import org.bukkit.entity.EntitySnapshot; import org.bukkit.entity.EntityType; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -17,7 +23,8 @@ public interface CreatureSpawner extends TileState { public EntityType getSpawnedType(); /** - * Set the spawner's creature type. + * Set the spawner's creature type.
+ * This will override any entities that have been added with {@link #addPotentialSpawn} * * @param creatureType The creature type or null to clear. */ @@ -199,4 +206,75 @@ public interface CreatureSpawner extends TileState { * @see #getSpawnRange() */ public void setSpawnRange(int spawnRange); + + /** + * Gets the {@link EntitySnapshot} that will be spawned by this spawner or null + * if no entities have been assigned to this spawner.
+ *

+ * All applicable data from the spawner will be copied, such as custom name, + * health, and velocity.
+ * + * @return the entity snapshot or null if no entities have been assigned to this + * spawner. + */ + @Nullable + public EntitySnapshot getSpawnedEntity(); + + /** + * Sets the entity that will be spawned by this spawner.
+ * This will override any previous entries that have been added with + * {@link #addPotentialSpawn} + *

+ * All applicable data from the snapshot will be copied, such as custom name, + * health, and velocity.
+ * + * @param snapshot the entity snapshot + */ + public void setSpawnedEntity(@NotNull EntitySnapshot snapshot); + + /** + * Adds a new {@link EntitySnapshot} to the list of entities this spawner can + * spawn. + *

+ * The weight will determine how often this entry is chosen to spawn, higher + * weighted entries will spawn more often than lower weighted ones.
+ * The {@link SpawnRule} will determine under what conditions this entry can + * spawn, passing null will use the default conditions for the given entity. + * + * @param snapshot the snapshot that will be spawned + * @param weight the weight + * @param spawnRule the spawn rule for this entity, or null + */ + public void addPotentialSpawn(@NotNull EntitySnapshot snapshot, int weight, @Nullable SpawnRule spawnRule); + + /** + * Adds a new {@link SpawnerEntry} to the list of entities this spawner can + * spawn.
+ * + * @param spawnerEntry the spawner entry to use + * @see #addPotentialSpawn(EntitySnapshot, int, SpawnRule) + */ + public void addPotentialSpawn(@NotNull final SpawnerEntry spawnerEntry); + + /** + * Sets the list of {@link SpawnerEntry} this spawner can spawn.
+ * This will override any previous entries added with + * {@link #addPotentialSpawn} + * + * @param entries the list of entries + */ + public void setPotentialSpawns(@NotNull final Collection entries); + + /** + * Gets a list of potential spawns from this spawner or an empty list if no + * entities have been assigned to this spawner.
+ * Changes made to the returned list will not be reflected in the spawner unless + * applied with {@link #setPotentialSpawns} + * + * @return a list of potential spawns from this spawner, or an empty list if no + * entities have been assigned to this spawner + * @see #getSpawnedType() + */ + @NotNull + public List getPotentialSpawns(); } diff --git a/src/main/java/org/bukkit/block/spawner/SpawnRule.java b/src/main/java/org/bukkit/block/spawner/SpawnRule.java new file mode 100644 index 00000000..c15ce91a --- /dev/null +++ b/src/main/java/org/bukkit/block/spawner/SpawnRule.java @@ -0,0 +1,219 @@ +package org.bukkit.block.spawner; + +import com.google.common.base.Preconditions; +import java.util.LinkedHashMap; +import java.util.Map; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.SerializableAs; +import org.jetbrains.annotations.NotNull; + +/** + * Represents a spawn rule that controls what conditions an entity from a + * monster spawner can spawn. + */ +@SerializableAs("SpawnRule") +public class SpawnRule implements Cloneable, ConfigurationSerializable { + + private int minBlockLight; + private int maxBlockLight; + private int minSkyLight; + private int maxSkyLight; + + /** + * Constructs a new SpawnRule. + * + * @param minBlockLight The minimum (inclusive) block light required for + * spawning to succeed. + * @param maxBlockLight The maximum (inclusive) block light required for + * spawning to succeed. + * @param minSkyLight The minimum (inclusive) sky light required for + * spawning to succeed. + * @param maxSkyLight The maximum (inclusive) sky light required for + * spawning to succeed. + */ + public SpawnRule(int minBlockLight, int maxBlockLight, int minSkyLight, int maxSkyLight) { + Preconditions.checkArgument(minBlockLight <= maxBlockLight, "minBlockLight must be <= maxBlockLight (%s <= %s)", minBlockLight, maxBlockLight); + Preconditions.checkArgument(minSkyLight <= maxSkyLight, "minSkyLight must be <= maxSkyLight (%s <= %s)", minSkyLight, maxSkyLight); + Preconditions.checkArgument(minBlockLight >= 0, "minBlockLight must be >= 0 (given %s)", minBlockLight); + Preconditions.checkArgument(maxBlockLight >= 0, "maxBlockLight must be >= 0 (given %s)", maxBlockLight); + Preconditions.checkArgument(minSkyLight >= 0, "minSkyLight must be >= 0 (given %s)", minSkyLight); + Preconditions.checkArgument(maxSkyLight >= 0, "maxSkyLight must be >= 0 (given %s)", maxSkyLight); + + this.minBlockLight = minBlockLight; + this.maxBlockLight = maxBlockLight; + this.minSkyLight = minSkyLight; + this.maxSkyLight = maxSkyLight; + } + + /** + * Gets the minimum (inclusive) block light required for spawning to + * succeed. + * + * @return minimum block light + */ + public int getMinBlockLight() { + return minBlockLight; + } + + /** + * Sets the minimum (inclusive) block light required for spawning to + * succeed. + * + * @param minBlockLight minimum block light + */ + public void setMinBlockLight(int minBlockLight) { + Preconditions.checkArgument(minBlockLight >= 0, "minBlockLight must be >= 0 (given %s)", minBlockLight); + Preconditions.checkArgument(minBlockLight <= maxBlockLight, "minBlockLight must be <= maxBlockLight (%s <= %s)", minBlockLight, maxBlockLight); + + this.minBlockLight = minBlockLight; + } + + /** + * Gets the maximum (inclusive) block light required for spawning to + * succeed. + * + * @return maximum block light + */ + public int getMaxBlockLight() { + return maxBlockLight; + } + + /** + * Sets the maximum (inclusive) block light required for spawning to + * succeed. + * + * @param maxBlockLight maximum block light + */ + public void setMaxBlockLight(int maxBlockLight) { + Preconditions.checkArgument(maxBlockLight >= 0, "maxBlockLight must be >= 0 (given %s)", maxBlockLight); + + this.maxBlockLight = maxBlockLight; + } + + /** + * Gets the minimum (inclusive) sky light required for spawning to succeed. + * + * @return minimum sky light + */ + public int getMinSkyLight() { + return minSkyLight; + } + + /** + * Sets the minimum (inclusive) sky light required for spawning to succeed. + * + * @param minSkyLight minimum sky light + */ + public void setMinSkyLight(int minSkyLight) { + Preconditions.checkArgument(minSkyLight >= 0, "minSkyLight must be >= 0 (given %s)", minSkyLight); + Preconditions.checkArgument(minSkyLight <= maxSkyLight, "minSkyLight must be <= maxSkyLight (%s <= %s)", minSkyLight, maxSkyLight); + + this.minSkyLight = minSkyLight; + } + + /** + * Gets the maximum (inclusive) sky light required for spawning to succeed. + * + * @return maximum sky light + */ + public int getMaxSkyLight() { + return maxSkyLight; + } + + /** + * Sets the maximum (inclusive) sky light required for spawning to succeed. + * + * @param maxSkyLight maximum sky light + */ + public void setMaxSkyLight(int maxSkyLight) { + Preconditions.checkArgument(maxSkyLight >= 0, "maxSkyLight must be >= 0 (given %s)", maxSkyLight); + + this.maxSkyLight = maxSkyLight; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof SpawnRule)) { + return false; + } + + SpawnRule other = (SpawnRule) obj; + return minBlockLight == other.minBlockLight && maxBlockLight == other.maxBlockLight && minSkyLight == other.minSkyLight && maxSkyLight == other.maxSkyLight; + } + + @Override + public int hashCode() { + int hash = minBlockLight; + + hash = (hash << 4) + maxBlockLight; + hash = (hash << 4) + minSkyLight; + hash = (hash << 4) + maxSkyLight; + + return hash; + } + + @NotNull + @Override + public SpawnRule clone() { + try { + return (SpawnRule) super.clone(); + } catch (CloneNotSupportedException e) { + throw new Error(e); + } + } + + @Override + @NotNull + public Map serialize() { + Map result = new LinkedHashMap<>(); + Map block = new LinkedHashMap<>(); + Map sky = new LinkedHashMap<>(); + + block.put("min", getMinBlockLight()); + block.put("max", getMaxBlockLight()); + sky.put("min", getMinSkyLight()); + sky.put("max", getMaxSkyLight()); + + result.put("block-light", block); + result.put("sky-light", sky); + + return result; + } + + @NotNull + public static SpawnRule deserialize(@NotNull Map args) { + int minBlock = 0; + int maxBlock = 0; + int minSky = 0; + int maxSky = 0; + + Object block = args.get("block-light"); + Object sky = args.get("sky-light"); + + if (block instanceof Map) { + Map blockMap = (Map) block; + + if (blockMap.containsKey("min")) { + minBlock = (int) blockMap.get("min"); + } + + if (blockMap.containsKey("max")) { + maxBlock = (int) blockMap.get("max"); + } + } + + if (sky instanceof Map) { + Map skyMap = (Map) sky; + + if (skyMap.containsKey("min")) { + minSky = (int) skyMap.get("min"); + } + + if (skyMap.containsKey("max")) { + maxSky = (int) skyMap.get("max"); + } + } + + return new SpawnRule(minBlock, maxBlock, minSky, maxSky); + } +} diff --git a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java new file mode 100644 index 00000000..0043276a --- /dev/null +++ b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java @@ -0,0 +1,85 @@ +package org.bukkit.block.spawner; + +import com.google.common.base.Preconditions; +import org.bukkit.entity.EntitySnapshot; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Represents a weighted spawn potential that can be added to a monster spawner. + */ +public class SpawnerEntry { + + private EntitySnapshot snapshot; + private int spawnWeight; + private SpawnRule spawnRule; + + public SpawnerEntry(@NotNull EntitySnapshot snapshot, int spawnWeight, @Nullable SpawnRule spawnRule) { + Preconditions.checkArgument(snapshot != null, "Snapshot cannot be null"); + + this.snapshot = snapshot; + this.spawnWeight = spawnWeight; + this.spawnRule = spawnRule; + } + + /** + * Gets the {@link EntitySnapshot} for this SpawnerEntry. + * + * @return the snapshot + */ + @NotNull + public EntitySnapshot getSnapshot() { + return snapshot; + } + + /** + * Sets the {@link EntitySnapshot} for this SpawnerEntry. + * + * @param snapshot the snapshot + */ + public void setSnapshot(@NotNull EntitySnapshot snapshot) { + Preconditions.checkArgument(snapshot != null, "Snapshot cannot be null"); + this.snapshot = snapshot; + } + + /** + * Gets the weight for this SpawnerEntry, when added to a spawner entries + * with higher weight will spawn more often. + * + * @return the weight + */ + public int getSpawnWeight() { + return spawnWeight; + } + + /** + * Sets the weight for this SpawnerEntry, when added to a spawner entries + * with higher weight will spawn more often. + * + * @param spawnWeight the new spawn weight + */ + public void setSpawnWeight(int spawnWeight) { + this.spawnWeight = spawnWeight; + } + + /** + * Gets a copy of the {@link SpawnRule} for this SpawnerEntry, or null if + * none has been set. + * + * @return a copy of the spawn rule or null + */ + @Nullable + public SpawnRule getSpawnRule() { + return spawnRule == null ? null : spawnRule.clone(); + } + + /** + * Sets the {@link SpawnRule} for this SpawnerEntry, null may be used to + * clear the current spawn rule. + * + * @param spawnRule the new spawn rule to use or null + */ + public void setSpawnRule(@Nullable SpawnRule spawnRule) { + this.spawnRule = spawnRule; + } +} diff --git a/src/main/java/org/bukkit/block/spawner/package-info.java b/src/main/java/org/bukkit/block/spawner/package-info.java new file mode 100644 index 00000000..9a8e7688 --- /dev/null +++ b/src/main/java/org/bukkit/block/spawner/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes relevant to mob spawners. + */ +package org.bukkit.block.spawner; diff --git a/src/main/java/org/bukkit/configuration/serialization/ConfigurationSerialization.java b/src/main/java/org/bukkit/configuration/serialization/ConfigurationSerialization.java index 2c047062..a6497f42 100644 --- a/src/main/java/org/bukkit/configuration/serialization/ConfigurationSerialization.java +++ b/src/main/java/org/bukkit/configuration/serialization/ConfigurationSerialization.java @@ -14,6 +14,7 @@ import org.bukkit.FireworkEffect; import org.bukkit.Location; import org.bukkit.attribute.AttributeModifier; import org.bukkit.block.banner.Pattern; +import org.bukkit.block.spawner.SpawnRule; import org.bukkit.configuration.Configuration; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; @@ -42,6 +43,7 @@ public class ConfigurationSerialization { registerClass(Location.class); registerClass(AttributeModifier.class); registerClass(BoundingBox.class); + registerClass(SpawnRule.class); } protected ConfigurationSerialization(@NotNull Class clazz) { diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java index 764c502c..dafb5d28 100644 --- a/src/main/java/org/bukkit/entity/Entity.java +++ b/src/main/java/org/bukkit/entity/Entity.java @@ -26,6 +26,9 @@ import org.jetbrains.annotations.Nullable; /** * Represents a base entity in the world + *

+ * Not all methods are guaranteed to work/may have side effects when + * {@link #isInWorld()} is false. */ public interface Entity extends Metadatable, CommandSender, Nameable, PersistentDataHolder { @@ -265,8 +268,8 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent public boolean isDead(); /** - * Returns false if the entity has died or been despawned for some other - * reason. + * Returns false if the entity has died, been despawned for some other + * reason, or has not been added to the world. * * @return True if valid. */ @@ -714,4 +717,43 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent */ @NotNull SpawnCategory getSpawnCategory(); + + /** + * Checks if this entity has been spawned in a world.
+ * Entities not spawned in a world will not tick, be sent to players, or be + * saved to the server files. + * + * @return whether the entity has been spawned in a world + */ + boolean isInWorld(); + + /** + * Crates an {@link EntitySnapshot} representing the current state of this entity. + * + * @return a snapshot representing this entity or null if one cannot be made + */ + @Nullable + @ApiStatus.Experimental + EntitySnapshot createSnapshot(); + + /** + * Creates a copy of this entity and all its data. Does not spawn the copy in + * the world.
+ * Note: Players cannot be copied. + * + * @return a copy of this entity. + */ + @NotNull + @ApiStatus.Experimental + Entity copy(); + + /** + * Creates a copy of this entity and all its data. Spawns the copy at the given location.
+ * Note: Players cannot be copied. + * @param to the location to copy to + * @return a copy of this entity. + */ + @NotNull + @ApiStatus.Experimental + Entity copy(@NotNull Location to); } diff --git a/src/main/java/org/bukkit/entity/EntitySnapshot.java b/src/main/java/org/bukkit/entity/EntitySnapshot.java new file mode 100644 index 00000000..6f34486a --- /dev/null +++ b/src/main/java/org/bukkit/entity/EntitySnapshot.java @@ -0,0 +1,39 @@ +package org.bukkit.entity; + +import org.bukkit.Location; +import org.bukkit.World; +import org.jetbrains.annotations.NotNull; + +/** + * Represents an immutable copy of an entity's state. Can be used at any time to + * create an instance of the stored entity. + */ +public interface EntitySnapshot { + + /** + * Creates an entity using this template. Does not spawn the copy in the world. + *
+ * + * @param world the world to create the entity in + * @return a copy of this entity. + */ + @NotNull + Entity createEntity(@NotNull World world); + + /** + * Creates an entity using this template and spawns it at the provided location. + * + * @param to the location to copy to + * @return the new entity. + */ + @NotNull + Entity createEntity(@NotNull Location to); + + /** + * Gets the type of entity this template holds. + * + * @return the type + */ + @NotNull + EntityType getEntityType(); +} diff --git a/src/main/java/org/bukkit/inventory/meta/SpawnEggMeta.java b/src/main/java/org/bukkit/inventory/meta/SpawnEggMeta.java index 9ae84de4..b3447e22 100644 --- a/src/main/java/org/bukkit/inventory/meta/SpawnEggMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/SpawnEggMeta.java @@ -1,8 +1,10 @@ package org.bukkit.inventory.meta; +import org.bukkit.entity.EntitySnapshot; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Represents a spawn egg and it's spawned type. @@ -30,6 +32,28 @@ public interface SpawnEggMeta extends ItemMeta { @Contract("_ -> fail") void setSpawnedType(EntityType type); + /** + * Gets the {@link EntitySnapshot} that will be spawned by this spawn egg or null if no entity + * has been set.
+ *

+ * All applicable data from the egg will be copied, such as custom name, health, + * and velocity.
+ * + * @return the entity snapshot or null if no entity has been set + */ + @Nullable + EntitySnapshot getSpawnedEntity(); + + /** + * Sets the {@link EntitySnapshot} that will be spawned by this spawn egg.
+ *

+ * All applicable data from the entity will be copied, such as custom name, + * health, and velocity.
+ * + * @param snapshot the snapshot + */ + void setSpawnedEntity(@NotNull EntitySnapshot snapshot); + @NotNull @Override SpawnEggMeta clone(); From ef888c0741538690fb9adff0b401cfc868cb62ff Mon Sep 17 00:00:00 2001 From: DerFrZocker Date: Mon, 27 Nov 2023 19:10:47 +1100 Subject: [PATCH 12/22] #941: Don't allow Player removal via Entity#remove --- src/main/java/org/bukkit/entity/Entity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java index dafb5d28..69ba14b6 100644 --- a/src/main/java/org/bukkit/entity/Entity.java +++ b/src/main/java/org/bukkit/entity/Entity.java @@ -257,6 +257,8 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent /** * Mark the entity's removal. + * + * @throws UnsupportedOperationException if you try to remove a {@link Player} use {@link Player#kickPlayer(String)} in this case instead */ public void remove(); From ad2fd61c8784c7bac6542e39fca7e506c7966865 Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 6 Dec 2023 03:40:00 +1100 Subject: [PATCH 13/22] Update to Minecraft 1.20.3 --- pom.xml | 2 +- src/main/java/org/bukkit/FeatureFlag.java | 3 + src/main/java/org/bukkit/GameRule.java | 23 + src/main/java/org/bukkit/Material.java | 564 ++++++++++++++++-- src/main/java/org/bukkit/Particle.java | 6 + src/main/java/org/bukkit/Sound.java | 102 ++++ src/main/java/org/bukkit/Tag.java | 12 + src/main/java/org/bukkit/block/Crafter.java | 63 ++ .../java/org/bukkit/block/TrialSpawner.java | 12 + .../bukkit/block/data/type/CopperBulb.java | 11 + .../org/bukkit/block/data/type/Crafter.java | 81 +++ .../bukkit/block/data/type/TrialSpawner.java | 39 ++ src/main/java/org/bukkit/entity/Breeze.java | 12 + .../java/org/bukkit/entity/EntityType.java | 8 + src/main/java/org/bukkit/entity/Player.java | 48 ++ .../java/org/bukkit/entity/WindCharge.java | 12 + .../bukkit/event/inventory/InventoryType.java | 8 + .../bukkit/generator/structure/Structure.java | 1 + .../bukkit/inventory/CrafterInventory.java | 11 + src/main/java/org/bukkit/loot/LootTables.java | 13 + 20 files changed, 971 insertions(+), 60 deletions(-) create mode 100644 src/main/java/org/bukkit/block/Crafter.java create mode 100644 src/main/java/org/bukkit/block/TrialSpawner.java create mode 100644 src/main/java/org/bukkit/block/data/type/CopperBulb.java create mode 100644 src/main/java/org/bukkit/block/data/type/Crafter.java create mode 100644 src/main/java/org/bukkit/block/data/type/TrialSpawner.java create mode 100644 src/main/java/org/bukkit/entity/Breeze.java create mode 100644 src/main/java/org/bukkit/entity/WindCharge.java create mode 100644 src/main/java/org/bukkit/inventory/CrafterInventory.java diff --git a/pom.xml b/pom.xml index 4702b7a3..0e37cf72 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.bukkit bukkit - 1.20.2-R0.1-SNAPSHOT + 1.20.3-R0.1-SNAPSHOT jar Bukkit diff --git a/src/main/java/org/bukkit/FeatureFlag.java b/src/main/java/org/bukkit/FeatureFlag.java index 1d93e26b..5269df59 100644 --- a/src/main/java/org/bukkit/FeatureFlag.java +++ b/src/main/java/org/bukkit/FeatureFlag.java @@ -27,4 +27,7 @@ public interface FeatureFlag extends Keyed { @MinecraftExperimental public static final FeatureFlag TRADE_REBALANCE = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("trade_rebalance")); + + @MinecraftExperimental + public static final FeatureFlag UPDATE_121 = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("update_1_21")); } diff --git a/src/main/java/org/bukkit/GameRule.java b/src/main/java/org/bukkit/GameRule.java index 3ac563da..cca52670 100644 --- a/src/main/java/org/bukkit/GameRule.java +++ b/src/main/java/org/bukkit/GameRule.java @@ -61,6 +61,11 @@ public final class GameRule { */ public static final GameRule DO_MOB_LOOT = new GameRule<>("doMobLoot", Boolean.class); + /** + * Whether projectiles can break blocks. + */ + public static final GameRule PROJECTILES_CAN_BREAK_BLOCKS = new GameRule<>("projectilesCanBreakBlocks", Boolean.class); + /** * Whether mobs should naturally spawn. */ @@ -243,6 +248,12 @@ public final class GameRule { */ public static final GameRule MAX_COMMAND_CHAIN_LENGTH = new GameRule<>("maxCommandChainLength", Integer.class); + /** + * Determines the number of different commands/functions which execute + * commands can fork into. + */ + public static final GameRule MAX_COMMAND_FORK_COUNT = new GameRule<>("maxCommandForkCount", Integer.class); + /** * Determines the maximum number of blocks which a command can modify. */ @@ -255,6 +266,18 @@ public final class GameRule { public static final GameRule PLAYERS_SLEEPING_PERCENTAGE = new GameRule<>("playersSleepingPercentage", Integer.class); public static final GameRule SNOW_ACCUMULATION_HEIGHT = new GameRule<>("snowAccumulationHeight", Integer.class); + /** + * The amount of time a player must stand in a nether portal before the + * portal activates. + */ + public static final GameRule PLAYERS_NETHER_PORTAL_DEFAULT_DELAY = new GameRule<>("playersNetherPortalDefaultDelay", Integer.class); + + /** + * The amount of time a player in creative mode must stand in a nether + * portal before the portal activates. + */ + public static final GameRule PLAYERS_NETHER_PORTAL_CREATIVE_DELAY = new GameRule<>("playersNetherPortalCreativeDelay", Integer.class); + // All GameRules instantiated above this for organizational purposes private final String name; private final Class type; diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java index f06e06d8..e15219c9 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java @@ -47,7 +47,9 @@ import org.bukkit.block.data.type.ChiseledBookshelf; import org.bukkit.block.data.type.Cocoa; import org.bukkit.block.data.type.CommandBlock; import org.bukkit.block.data.type.Comparator; +import org.bukkit.block.data.type.CopperBulb; import org.bukkit.block.data.type.CoralWallFan; +import org.bukkit.block.data.type.Crafter; import org.bukkit.block.data.type.DaylightDetector; import org.bukkit.block.data.type.DecoratedPot; import org.bukkit.block.data.type.Dispenser; @@ -103,6 +105,7 @@ import org.bukkit.block.data.type.Switch; import org.bukkit.block.data.type.TNT; import org.bukkit.block.data.type.TechnicalPiston; import org.bukkit.block.data.type.TrapDoor; +import org.bukkit.block.data.type.TrialSpawner; import org.bukkit.block.data.type.Tripwire; import org.bukkit.block.data.type.TripwireHook; import org.bukkit.block.data.type.TurtleEgg; @@ -136,6 +139,59 @@ public enum Material implements Keyed, Translatable { POLISHED_DEEPSLATE(31772), CALCITE(20311), TUFF(24364), + /** + * BlockData: {@link Slab} + */ + @MinecraftExperimental + TUFF_SLAB(19305, Slab.class), + /** + * BlockData: {@link Stairs} + */ + @MinecraftExperimental + TUFF_STAIRS(11268, Stairs.class), + /** + * BlockData: {@link Wall} + */ + @MinecraftExperimental + TUFF_WALL(24395, Wall.class), + @MinecraftExperimental + CHISELED_TUFF(15831), + @MinecraftExperimental + POLISHED_TUFF(17801), + /** + * BlockData: {@link Slab} + */ + @MinecraftExperimental + POLISHED_TUFF_SLAB(31096, Slab.class), + /** + * BlockData: {@link Stairs} + */ + @MinecraftExperimental + POLISHED_TUFF_STAIRS(7964, Stairs.class), + /** + * BlockData: {@link Wall} + */ + @MinecraftExperimental + POLISHED_TUFF_WALL(28886, Wall.class), + @MinecraftExperimental + TUFF_BRICKS(26276), + /** + * BlockData: {@link Slab} + */ + @MinecraftExperimental + TUFF_BRICK_SLAB(11843, Slab.class), + /** + * BlockData: {@link Stairs} + */ + @MinecraftExperimental + TUFF_BRICK_STAIRS(30753, Stairs.class), + /** + * BlockData: {@link Wall} + */ + @MinecraftExperimental + TUFF_BRICK_WALL(11761, Wall.class), + @MinecraftExperimental + CHISELED_TUFF_BRICKS(8601), DRIPSTONE_BLOCK(26227), /** * BlockData: {@link Snowable} @@ -247,6 +303,14 @@ public enum Material implements Keyed, Translatable { EXPOSED_COPPER(28488), WEATHERED_COPPER(19699), OXIDIZED_COPPER(19490), + @MinecraftExperimental + CHISELED_COPPER(12143), + @MinecraftExperimental + EXPOSED_CHISELED_COPPER(4570), + @MinecraftExperimental + WEATHERED_CHISELED_COPPER(30876), + @MinecraftExperimental + OXIDIZED_CHISELED_COPPER(27719), CUT_COPPER(32519), EXPOSED_CUT_COPPER(18000), WEATHERED_CUT_COPPER(21158), @@ -287,6 +351,14 @@ public enum Material implements Keyed, Translatable { WAXED_EXPOSED_COPPER(27989), WAXED_WEATHERED_COPPER(5960), WAXED_OXIDIZED_COPPER(25626), + @MinecraftExperimental + WAXED_CHISELED_COPPER(7500), + @MinecraftExperimental + WAXED_EXPOSED_CHISELED_COPPER(30658), + @MinecraftExperimental + WAXED_WEATHERED_CHISELED_COPPER(5970), + @MinecraftExperimental + WAXED_OXIDIZED_CHISELED_COPPER(7735), WAXED_CUT_COPPER(11030), WAXED_EXPOSED_CUT_COPPER(30043), WAXED_WEATHERED_CUT_COPPER(13823), @@ -548,7 +620,7 @@ public enum Material implements Keyed, Translatable { CHISELED_SANDSTONE(31763), CUT_SANDSTONE(6118), COBWEB(9469), - GRASS(6155), + SHORT_GRASS(6155), FERN(15794), AZALEA(29386), FLOWERING_AZALEA(28270), @@ -767,7 +839,7 @@ public enum Material implements Keyed, Translatable { /** * BlockData: {@link DecoratedPot} */ - DECORATED_POT(8720, 1, DecoratedPot.class), + DECORATED_POT(8720, DecoratedPot.class), MOSSY_COBBLESTONE(21900), OBSIDIAN(32723), TORCH(6063), @@ -2023,6 +2095,46 @@ public enum Material implements Keyed, Translatable { * BlockData: {@link Door} */ WARPED_DOOR(15062, Door.class), + /** + * BlockData: {@link Door} + */ + @MinecraftExperimental + COPPER_DOOR(26809, Door.class), + /** + * BlockData: {@link Door} + */ + @MinecraftExperimental + EXPOSED_COPPER_DOOR(13236, Door.class), + /** + * BlockData: {@link Door} + */ + @MinecraftExperimental + WEATHERED_COPPER_DOOR(10208, Door.class), + /** + * BlockData: {@link Door} + */ + @MinecraftExperimental + OXIDIZED_COPPER_DOOR(5348, Door.class), + /** + * BlockData: {@link Door} + */ + @MinecraftExperimental + WAXED_COPPER_DOOR(9954, Door.class), + /** + * BlockData: {@link Door} + */ + @MinecraftExperimental + WAXED_EXPOSED_COPPER_DOOR(20748, Door.class), + /** + * BlockData: {@link Door} + */ + @MinecraftExperimental + WAXED_WEATHERED_COPPER_DOOR(25073, Door.class), + /** + * BlockData: {@link Door} + */ + @MinecraftExperimental + WAXED_OXIDIZED_COPPER_DOOR(23888, Door.class), /** * BlockData: {@link TrapDoor} */ @@ -2071,6 +2183,46 @@ public enum Material implements Keyed, Translatable { * BlockData: {@link TrapDoor} */ WARPED_TRAPDOOR(7708, TrapDoor.class), + /** + * BlockData: {@link TrapDoor} + */ + @MinecraftExperimental + COPPER_TRAPDOOR(12110, TrapDoor.class), + /** + * BlockData: {@link TrapDoor} + */ + @MinecraftExperimental + EXPOSED_COPPER_TRAPDOOR(19219, TrapDoor.class), + /** + * BlockData: {@link TrapDoor} + */ + @MinecraftExperimental + WEATHERED_COPPER_TRAPDOOR(28254, TrapDoor.class), + /** + * BlockData: {@link TrapDoor} + */ + @MinecraftExperimental + OXIDIZED_COPPER_TRAPDOOR(26518, TrapDoor.class), + /** + * BlockData: {@link TrapDoor} + */ + @MinecraftExperimental + WAXED_COPPER_TRAPDOOR(12626, TrapDoor.class), + /** + * BlockData: {@link TrapDoor} + */ + @MinecraftExperimental + WAXED_EXPOSED_COPPER_TRAPDOOR(11010, TrapDoor.class), + /** + * BlockData: {@link TrapDoor} + */ + @MinecraftExperimental + WAXED_WEATHERED_COPPER_TRAPDOOR(30709, TrapDoor.class), + /** + * BlockData: {@link TrapDoor} + */ + @MinecraftExperimental + WAXED_OXIDIZED_COPPER_TRAPDOOR(21450, TrapDoor.class), /** * BlockData: {@link Gate} */ @@ -2471,6 +2623,11 @@ public enum Material implements Keyed, Translatable { */ BLACK_BED(20490, 1, Bed.class), COOKIE(27431), + /** + * BlockData: {@link Crafter} + */ + @MinecraftExperimental + CRAFTER(25243, Crafter.class), FILLED_MAP(23504), SHEARS(27971, 1, 238), MELON_SLICE(5347), @@ -2508,6 +2665,8 @@ public enum Material implements Keyed, Translatable { BAT_SPAWN_EGG(14607), BEE_SPAWN_EGG(22924), BLAZE_SPAWN_EGG(4759), + @MinecraftExperimental + BREEZE_SPAWN_EGG(7580), CAT_SPAWN_EGG(29583), CAMEL_SPAWN_EGG(14760), CAVE_SPIDER_SPAWN_EGG(23341), @@ -2998,6 +3157,93 @@ public enum Material implements Keyed, Translatable { SHELTER_POTTERY_SHERD(28390), SKULL_POTTERY_SHERD(16980), SNORT_POTTERY_SHERD(15921), + /** + * BlockData: {@link Waterlogged} + */ + @MinecraftExperimental + COPPER_GRATE(16221, Waterlogged.class), + /** + * BlockData: {@link Waterlogged} + */ + @MinecraftExperimental + EXPOSED_COPPER_GRATE(7783, Waterlogged.class), + /** + * BlockData: {@link Waterlogged} + */ + @MinecraftExperimental + WEATHERED_COPPER_GRATE(24954, Waterlogged.class), + /** + * BlockData: {@link Waterlogged} + */ + @MinecraftExperimental + OXIDIZED_COPPER_GRATE(14122, Waterlogged.class), + /** + * BlockData: {@link Waterlogged} + */ + @MinecraftExperimental + WAXED_COPPER_GRATE(11230, Waterlogged.class), + /** + * BlockData: {@link Waterlogged} + */ + @MinecraftExperimental + WAXED_EXPOSED_COPPER_GRATE(20520, Waterlogged.class), + /** + * BlockData: {@link Waterlogged} + */ + @MinecraftExperimental + WAXED_WEATHERED_COPPER_GRATE(16533, Waterlogged.class), + /** + * BlockData: {@link Waterlogged} + */ + @MinecraftExperimental + WAXED_OXIDIZED_COPPER_GRATE(32010, Waterlogged.class), + /** + * BlockData: {@link CopperBulb} + */ + @MinecraftExperimental + COPPER_BULB(21370, CopperBulb.class), + /** + * BlockData: {@link CopperBulb} + */ + @MinecraftExperimental + EXPOSED_COPPER_BULB(11944, CopperBulb.class), + /** + * BlockData: {@link CopperBulb} + */ + @MinecraftExperimental + WEATHERED_COPPER_BULB(10800, CopperBulb.class), + /** + * BlockData: {@link CopperBulb} + */ + @MinecraftExperimental + OXIDIZED_COPPER_BULB(22421, CopperBulb.class), + /** + * BlockData: {@link CopperBulb} + */ + @MinecraftExperimental + WAXED_COPPER_BULB(23756, CopperBulb.class), + /** + * BlockData: {@link CopperBulb} + */ + @MinecraftExperimental + WAXED_EXPOSED_COPPER_BULB(5530, CopperBulb.class), + /** + * BlockData: {@link CopperBulb} + */ + @MinecraftExperimental + WAXED_WEATHERED_COPPER_BULB(13239, CopperBulb.class), + /** + * BlockData: {@link CopperBulb} + */ + @MinecraftExperimental + WAXED_OXIDIZED_COPPER_BULB(26892, CopperBulb.class), + /** + * BlockData: {@link TrialSpawner} + */ + @MinecraftExperimental + TRIAL_SPAWNER(19902, TrialSpawner.class), + @MinecraftExperimental + TRIAL_KEY(12725), /** * BlockData: {@link Levelled} */ @@ -4753,6 +4999,7 @@ public enum Material implements Keyed, Translatable { case CHEST: case CHIPPED_ANVIL: case CHISELED_BOOKSHELF: + case CHISELED_COPPER: case CHISELED_DEEPSLATE: case CHISELED_NETHER_BRICKS: case CHISELED_POLISHED_BLACKSTONE: @@ -4760,6 +5007,8 @@ public enum Material implements Keyed, Translatable { case CHISELED_RED_SANDSTONE: case CHISELED_SANDSTONE: case CHISELED_STONE_BRICKS: + case CHISELED_TUFF: + case CHISELED_TUFF_BRICKS: case CHORUS_FLOWER: case CHORUS_PLANT: case CLAY: @@ -4781,13 +5030,18 @@ public enum Material implements Keyed, Translatable { case COMPOSTER: case CONDUIT: case COPPER_BLOCK: + case COPPER_BULB: + case COPPER_DOOR: + case COPPER_GRATE: case COPPER_ORE: + case COPPER_TRAPDOOR: case CORNFLOWER: case CRACKED_DEEPSLATE_BRICKS: case CRACKED_DEEPSLATE_TILES: case CRACKED_NETHER_BRICKS: case CRACKED_POLISHED_BLACKSTONE_BRICKS: case CRACKED_STONE_BRICKS: + case CRAFTER: case CRAFTING_TABLE: case CREEPER_HEAD: case CREEPER_WALL_HEAD: @@ -4922,7 +5176,12 @@ public enum Material implements Keyed, Translatable { case END_STONE_BRICK_SLAB: case END_STONE_BRICK_STAIRS: case END_STONE_BRICK_WALL: + case EXPOSED_CHISELED_COPPER: case EXPOSED_COPPER: + case EXPOSED_COPPER_BULB: + case EXPOSED_COPPER_DOOR: + case EXPOSED_COPPER_GRATE: + case EXPOSED_COPPER_TRAPDOOR: case EXPOSED_CUT_COPPER: case EXPOSED_CUT_COPPER_SLAB: case EXPOSED_CUT_COPPER_STAIRS: @@ -4951,7 +5210,6 @@ public enum Material implements Keyed, Translatable { case GRANITE_SLAB: case GRANITE_STAIRS: case GRANITE_WALL: - case GRASS: case GRASS_BLOCK: case GRAVEL: case GRAY_BANNER: @@ -5193,7 +5451,12 @@ public enum Material implements Keyed, Translatable { case ORANGE_WALL_BANNER: case ORANGE_WOOL: case OXEYE_DAISY: + case OXIDIZED_CHISELED_COPPER: case OXIDIZED_COPPER: + case OXIDIZED_COPPER_BULB: + case OXIDIZED_COPPER_DOOR: + case OXIDIZED_COPPER_GRATE: + case OXIDIZED_COPPER_TRAPDOOR: case OXIDIZED_CUT_COPPER: case OXIDIZED_CUT_COPPER_SLAB: case OXIDIZED_CUT_COPPER_STAIRS: @@ -5252,6 +5515,10 @@ public enum Material implements Keyed, Translatable { case POLISHED_GRANITE: case POLISHED_GRANITE_SLAB: case POLISHED_GRANITE_STAIRS: + case POLISHED_TUFF: + case POLISHED_TUFF_SLAB: + case POLISHED_TUFF_STAIRS: + case POLISHED_TUFF_WALL: case POPPY: case POTATOES: case POTTED_ACACIA_SAPLING: @@ -5379,6 +5646,7 @@ public enum Material implements Keyed, Translatable { case SEAGRASS: case SEA_LANTERN: case SEA_PICKLE: + case SHORT_GRASS: case SHROOMLIGHT: case SHULKER_BOX: case SKELETON_SKULL: @@ -5479,6 +5747,7 @@ public enum Material implements Keyed, Translatable { case TORCHFLOWER: case TORCHFLOWER_CROP: case TRAPPED_CHEST: + case TRIAL_SPAWNER: case TRIPWIRE: case TRIPWIRE_HOOK: case TUBE_CORAL: @@ -5486,6 +5755,13 @@ public enum Material implements Keyed, Translatable { case TUBE_CORAL_FAN: case TUBE_CORAL_WALL_FAN: case TUFF: + case TUFF_BRICKS: + case TUFF_BRICK_SLAB: + case TUFF_BRICK_STAIRS: + case TUFF_BRICK_WALL: + case TUFF_SLAB: + case TUFF_STAIRS: + case TUFF_WALL: case TURTLE_EGG: case TWISTING_VINES: case TWISTING_VINES_PLANT: @@ -5514,23 +5790,48 @@ public enum Material implements Keyed, Translatable { case WARPED_WART_BLOCK: case WATER: case WATER_CAULDRON: + case WAXED_CHISELED_COPPER: case WAXED_COPPER_BLOCK: + case WAXED_COPPER_BULB: + case WAXED_COPPER_DOOR: + case WAXED_COPPER_GRATE: + case WAXED_COPPER_TRAPDOOR: case WAXED_CUT_COPPER: case WAXED_CUT_COPPER_SLAB: case WAXED_CUT_COPPER_STAIRS: + case WAXED_EXPOSED_CHISELED_COPPER: case WAXED_EXPOSED_COPPER: + case WAXED_EXPOSED_COPPER_BULB: + case WAXED_EXPOSED_COPPER_DOOR: + case WAXED_EXPOSED_COPPER_GRATE: + case WAXED_EXPOSED_COPPER_TRAPDOOR: case WAXED_EXPOSED_CUT_COPPER: case WAXED_EXPOSED_CUT_COPPER_SLAB: case WAXED_EXPOSED_CUT_COPPER_STAIRS: + case WAXED_OXIDIZED_CHISELED_COPPER: case WAXED_OXIDIZED_COPPER: + case WAXED_OXIDIZED_COPPER_BULB: + case WAXED_OXIDIZED_COPPER_DOOR: + case WAXED_OXIDIZED_COPPER_GRATE: + case WAXED_OXIDIZED_COPPER_TRAPDOOR: case WAXED_OXIDIZED_CUT_COPPER: case WAXED_OXIDIZED_CUT_COPPER_SLAB: case WAXED_OXIDIZED_CUT_COPPER_STAIRS: + case WAXED_WEATHERED_CHISELED_COPPER: case WAXED_WEATHERED_COPPER: + case WAXED_WEATHERED_COPPER_BULB: + case WAXED_WEATHERED_COPPER_DOOR: + case WAXED_WEATHERED_COPPER_GRATE: + case WAXED_WEATHERED_COPPER_TRAPDOOR: case WAXED_WEATHERED_CUT_COPPER: case WAXED_WEATHERED_CUT_COPPER_SLAB: case WAXED_WEATHERED_CUT_COPPER_STAIRS: + case WEATHERED_CHISELED_COPPER: case WEATHERED_COPPER: + case WEATHERED_COPPER_BULB: + case WEATHERED_COPPER_DOOR: + case WEATHERED_COPPER_GRATE: + case WEATHERED_COPPER_TRAPDOOR: case WEATHERED_CUT_COPPER: case WEATHERED_CUT_COPPER_SLAB: case WEATHERED_CUT_COPPER_STAIRS: @@ -5942,6 +6243,7 @@ public enum Material implements Keyed, Translatable { case CHEST: case CHIPPED_ANVIL: case CHISELED_BOOKSHELF: + case CHISELED_COPPER: case CHISELED_DEEPSLATE: case CHISELED_NETHER_BRICKS: case CHISELED_POLISHED_BLACKSTONE: @@ -5949,6 +6251,8 @@ public enum Material implements Keyed, Translatable { case CHISELED_RED_SANDSTONE: case CHISELED_SANDSTONE: case CHISELED_STONE_BRICKS: + case CHISELED_TUFF: + case CHISELED_TUFF_BRICKS: case CLAY: case COAL_BLOCK: case COAL_ORE: @@ -5965,12 +6269,17 @@ public enum Material implements Keyed, Translatable { case COMPOSTER: case CONDUIT: case COPPER_BLOCK: + case COPPER_BULB: + case COPPER_DOOR: + case COPPER_GRATE: case COPPER_ORE: + case COPPER_TRAPDOOR: case CRACKED_DEEPSLATE_BRICKS: case CRACKED_DEEPSLATE_TILES: case CRACKED_NETHER_BRICKS: case CRACKED_POLISHED_BLACKSTONE_BRICKS: case CRACKED_STONE_BRICKS: + case CRAFTER: case CRAFTING_TABLE: case CRIMSON_DOOR: case CRIMSON_FENCE: @@ -6088,7 +6397,12 @@ public enum Material implements Keyed, Translatable { case END_STONE_BRICK_SLAB: case END_STONE_BRICK_STAIRS: case END_STONE_BRICK_WALL: + case EXPOSED_CHISELED_COPPER: case EXPOSED_COPPER: + case EXPOSED_COPPER_BULB: + case EXPOSED_COPPER_DOOR: + case EXPOSED_COPPER_GRATE: + case EXPOSED_COPPER_TRAPDOOR: case EXPOSED_CUT_COPPER: case EXPOSED_CUT_COPPER_SLAB: case EXPOSED_CUT_COPPER_STAIRS: @@ -6308,7 +6622,12 @@ public enum Material implements Keyed, Translatable { case ORANGE_TERRACOTTA: case ORANGE_WALL_BANNER: case ORANGE_WOOL: + case OXIDIZED_CHISELED_COPPER: case OXIDIZED_COPPER: + case OXIDIZED_COPPER_BULB: + case OXIDIZED_COPPER_DOOR: + case OXIDIZED_COPPER_GRATE: + case OXIDIZED_COPPER_TRAPDOOR: case OXIDIZED_CUT_COPPER: case OXIDIZED_CUT_COPPER_SLAB: case OXIDIZED_CUT_COPPER_STAIRS: @@ -6355,6 +6674,10 @@ public enum Material implements Keyed, Translatable { case POLISHED_GRANITE: case POLISHED_GRANITE_SLAB: case POLISHED_GRANITE_STAIRS: + case POLISHED_TUFF: + case POLISHED_TUFF_SLAB: + case POLISHED_TUFF_STAIRS: + case POLISHED_TUFF_WALL: case POWDER_SNOW_CAULDRON: case PRISMARINE: case PRISMARINE_BRICKS: @@ -6508,8 +6831,16 @@ public enum Material implements Keyed, Translatable { case TINTED_GLASS: case TNT: case TRAPPED_CHEST: + case TRIAL_SPAWNER: case TUBE_CORAL_BLOCK: case TUFF: + case TUFF_BRICKS: + case TUFF_BRICK_SLAB: + case TUFF_BRICK_STAIRS: + case TUFF_BRICK_WALL: + case TUFF_SLAB: + case TUFF_STAIRS: + case TUFF_WALL: case TURTLE_EGG: case VERDANT_FROGLIGHT: case WARPED_DOOR: @@ -6529,23 +6860,48 @@ public enum Material implements Keyed, Translatable { case WARPED_WALL_SIGN: case WARPED_WART_BLOCK: case WATER_CAULDRON: + case WAXED_CHISELED_COPPER: case WAXED_COPPER_BLOCK: + case WAXED_COPPER_BULB: + case WAXED_COPPER_DOOR: + case WAXED_COPPER_GRATE: + case WAXED_COPPER_TRAPDOOR: case WAXED_CUT_COPPER: case WAXED_CUT_COPPER_SLAB: case WAXED_CUT_COPPER_STAIRS: + case WAXED_EXPOSED_CHISELED_COPPER: case WAXED_EXPOSED_COPPER: + case WAXED_EXPOSED_COPPER_BULB: + case WAXED_EXPOSED_COPPER_DOOR: + case WAXED_EXPOSED_COPPER_GRATE: + case WAXED_EXPOSED_COPPER_TRAPDOOR: case WAXED_EXPOSED_CUT_COPPER: case WAXED_EXPOSED_CUT_COPPER_SLAB: case WAXED_EXPOSED_CUT_COPPER_STAIRS: + case WAXED_OXIDIZED_CHISELED_COPPER: case WAXED_OXIDIZED_COPPER: + case WAXED_OXIDIZED_COPPER_BULB: + case WAXED_OXIDIZED_COPPER_DOOR: + case WAXED_OXIDIZED_COPPER_GRATE: + case WAXED_OXIDIZED_COPPER_TRAPDOOR: case WAXED_OXIDIZED_CUT_COPPER: case WAXED_OXIDIZED_CUT_COPPER_SLAB: case WAXED_OXIDIZED_CUT_COPPER_STAIRS: + case WAXED_WEATHERED_CHISELED_COPPER: case WAXED_WEATHERED_COPPER: + case WAXED_WEATHERED_COPPER_BULB: + case WAXED_WEATHERED_COPPER_DOOR: + case WAXED_WEATHERED_COPPER_GRATE: + case WAXED_WEATHERED_COPPER_TRAPDOOR: case WAXED_WEATHERED_CUT_COPPER: case WAXED_WEATHERED_CUT_COPPER_SLAB: case WAXED_WEATHERED_CUT_COPPER_STAIRS: + case WEATHERED_CHISELED_COPPER: case WEATHERED_COPPER: + case WEATHERED_COPPER_BULB: + case WEATHERED_COPPER_DOOR: + case WEATHERED_COPPER_GRATE: + case WEATHERED_COPPER_TRAPDOOR: case WEATHERED_CUT_COPPER: case WEATHERED_CUT_COPPER_SLAB: case WEATHERED_CUT_COPPER_STAIRS: @@ -6854,7 +7210,6 @@ public enum Material implements Keyed, Translatable { case FERN: case FIRE: case FLOWER_POT: - case GRASS: case GRAY_CARPET: case GREEN_CARPET: case JUNGLE_BUTTON: @@ -6918,6 +7273,7 @@ public enum Material implements Keyed, Translatable { case RED_TULIP: case REPEATER: case ROSE_BUSH: + case SHORT_GRASS: case SKELETON_SKULL: case SKELETON_WALL_SKULL: case SNOW: @@ -7127,7 +7483,6 @@ public enum Material implements Keyed, Translatable { case FLETCHING_TABLE: case FLOWERING_AZALEA_LEAVES: case GLOW_LICHEN: - case GRASS: case GRAY_BANNER: case GRAY_BED: case GRAY_CARPET: @@ -7236,6 +7591,7 @@ public enum Material implements Keyed, Translatable { case RED_WALL_BANNER: case RED_WOOL: case ROSE_BUSH: + case SHORT_GRASS: case SMITHING_TABLE: case SOUL_CAMPFIRE: case SPRUCE_DOOR: @@ -7431,7 +7787,6 @@ public enum Material implements Keyed, Translatable { case FLOWERING_AZALEA: case FLOWERING_AZALEA_LEAVES: case GLOW_LICHEN: - case GRASS: case GRAY_CARPET: case GRAY_WOOL: case GREEN_CARPET: @@ -7493,6 +7848,7 @@ public enum Material implements Keyed, Translatable { case RED_WOOL: case ROSE_BUSH: case SCAFFOLDING: + case SHORT_GRASS: case SMALL_DRIPLEAF: case SPORE_BLOSSOM: case SPRUCE_FENCE: @@ -7983,6 +8339,7 @@ public enum Material implements Keyed, Translatable { case CHERRY_PLANKS: case CHERRY_WOOD: case CHISELED_BOOKSHELF: + case CHISELED_COPPER: case CHISELED_DEEPSLATE: case CHISELED_NETHER_BRICKS: case CHISELED_POLISHED_BLACKSTONE: @@ -7990,6 +8347,8 @@ public enum Material implements Keyed, Translatable { case CHISELED_RED_SANDSTONE: case CHISELED_SANDSTONE: case CHISELED_STONE_BRICKS: + case CHISELED_TUFF: + case CHISELED_TUFF_BRICKS: case CLAY: case COAL_BLOCK: case COAL_ORE: @@ -8004,6 +8363,7 @@ public enum Material implements Keyed, Translatable { case CRACKED_NETHER_BRICKS: case CRACKED_POLISHED_BLACKSTONE_BRICKS: case CRACKED_STONE_BRICKS: + case CRAFTER: case CRAFTING_TABLE: case CRIMSON_HYPHAE: case CRIMSON_NYLIUM: @@ -8051,6 +8411,7 @@ public enum Material implements Keyed, Translatable { case EMERALD_ORE: case END_STONE: case END_STONE_BRICKS: + case EXPOSED_CHISELED_COPPER: case EXPOSED_COPPER: case EXPOSED_CUT_COPPER: case FIRE_CORAL_BLOCK: @@ -8152,6 +8513,7 @@ public enum Material implements Keyed, Translatable { case ORANGE_SHULKER_BOX: case ORANGE_TERRACOTTA: case ORANGE_WOOL: + case OXIDIZED_CHISELED_COPPER: case OXIDIZED_COPPER: case OXIDIZED_CUT_COPPER: case PACKED_ICE: @@ -8171,6 +8533,7 @@ public enum Material implements Keyed, Translatable { case POLISHED_DEEPSLATE: case POLISHED_DIORITE: case POLISHED_GRANITE: + case POLISHED_TUFF: case PRISMARINE: case PRISMARINE_BRICKS: case PUMPKIN: @@ -8254,22 +8617,29 @@ public enum Material implements Keyed, Translatable { case SUSPICIOUS_SAND: case TARGET: case TERRACOTTA: + case TRIAL_SPAWNER: case TUBE_CORAL_BLOCK: case TUFF: + case TUFF_BRICKS: case VERDANT_FROGLIGHT: case WARPED_HYPHAE: case WARPED_NYLIUM: case WARPED_PLANKS: case WARPED_STEM: case WARPED_WART_BLOCK: + case WAXED_CHISELED_COPPER: case WAXED_COPPER_BLOCK: case WAXED_CUT_COPPER: + case WAXED_EXPOSED_CHISELED_COPPER: case WAXED_EXPOSED_COPPER: case WAXED_EXPOSED_CUT_COPPER: + case WAXED_OXIDIZED_CHISELED_COPPER: case WAXED_OXIDIZED_COPPER: case WAXED_OXIDIZED_CUT_COPPER: + case WAXED_WEATHERED_CHISELED_COPPER: case WAXED_WEATHERED_COPPER: case WAXED_WEATHERED_CUT_COPPER: + case WEATHERED_CHISELED_COPPER: case WEATHERED_COPPER: case WEATHERED_CUT_COPPER: case WET_SPONGE: @@ -8675,20 +9045,16 @@ public enum Material implements Keyed, Translatable { case ACACIA_FENCE_GATE: case ACACIA_HANGING_SIGN: case ACACIA_SIGN: - case ACACIA_STAIRS: case ACACIA_TRAPDOOR: case ACACIA_WALL_HANGING_SIGN: case ACACIA_WALL_SIGN: - case ANDESITE_STAIRS: case ANVIL: case BAMBOO_BUTTON: case BAMBOO_DOOR: case BAMBOO_FENCE: case BAMBOO_FENCE_GATE: case BAMBOO_HANGING_SIGN: - case BAMBOO_MOSAIC_STAIRS: case BAMBOO_SIGN: - case BAMBOO_STAIRS: case BAMBOO_TRAPDOOR: case BAMBOO_WALL_HANGING_SIGN: case BAMBOO_WALL_SIGN: @@ -8703,11 +9069,9 @@ public enum Material implements Keyed, Translatable { case BIRCH_FENCE_GATE: case BIRCH_HANGING_SIGN: case BIRCH_SIGN: - case BIRCH_STAIRS: case BIRCH_TRAPDOOR: case BIRCH_WALL_HANGING_SIGN: case BIRCH_WALL_SIGN: - case BLACKSTONE_STAIRS: case BLACK_BED: case BLACK_CANDLE: case BLACK_CANDLE_CAKE: @@ -8718,7 +9082,6 @@ public enum Material implements Keyed, Translatable { case BLUE_CANDLE_CAKE: case BLUE_SHULKER_BOX: case BREWING_STAND: - case BRICK_STAIRS: case BROWN_BED: case BROWN_CANDLE: case BROWN_CANDLE_CAKE: @@ -8738,18 +9101,18 @@ public enum Material implements Keyed, Translatable { case CHERRY_FENCE_GATE: case CHERRY_HANGING_SIGN: case CHERRY_SIGN: - case CHERRY_STAIRS: case CHERRY_TRAPDOOR: case CHERRY_WALL_HANGING_SIGN: case CHERRY_WALL_SIGN: case CHEST: case CHIPPED_ANVIL: case CHISELED_BOOKSHELF: - case COBBLED_DEEPSLATE_STAIRS: - case COBBLESTONE_STAIRS: case COMMAND_BLOCK: case COMPARATOR: case COMPOSTER: + case COPPER_DOOR: + case COPPER_TRAPDOOR: + case CRAFTER: case CRAFTING_TABLE: case CRIMSON_BUTTON: case CRIMSON_DOOR: @@ -8757,11 +9120,9 @@ public enum Material implements Keyed, Translatable { case CRIMSON_FENCE_GATE: case CRIMSON_HANGING_SIGN: case CRIMSON_SIGN: - case CRIMSON_STAIRS: case CRIMSON_TRAPDOOR: case CRIMSON_WALL_HANGING_SIGN: case CRIMSON_WALL_SIGN: - case CUT_COPPER_STAIRS: case CYAN_BED: case CYAN_CANDLE: case CYAN_CANDLE_CAKE: @@ -8773,27 +9134,22 @@ public enum Material implements Keyed, Translatable { case DARK_OAK_FENCE_GATE: case DARK_OAK_HANGING_SIGN: case DARK_OAK_SIGN: - case DARK_OAK_STAIRS: case DARK_OAK_TRAPDOOR: case DARK_OAK_WALL_HANGING_SIGN: case DARK_OAK_WALL_SIGN: - case DARK_PRISMARINE_STAIRS: case DAYLIGHT_DETECTOR: - case DEEPSLATE_BRICK_STAIRS: + case DECORATED_POT: case DEEPSLATE_REDSTONE_ORE: - case DEEPSLATE_TILE_STAIRS: - case DIORITE_STAIRS: case DISPENSER: case DRAGON_EGG: case DROPPER: case ENCHANTING_TABLE: case ENDER_CHEST: - case END_STONE_BRICK_STAIRS: - case EXPOSED_CUT_COPPER_STAIRS: + case EXPOSED_COPPER_DOOR: + case EXPOSED_COPPER_TRAPDOOR: case FLETCHING_TABLE: case FLOWER_POT: case FURNACE: - case GRANITE_STAIRS: case GRAY_BED: case GRAY_CANDLE: case GRAY_CANDLE_CAKE: @@ -8814,7 +9170,6 @@ public enum Material implements Keyed, Translatable { case JUNGLE_FENCE_GATE: case JUNGLE_HANGING_SIGN: case JUNGLE_SIGN: - case JUNGLE_STAIRS: case JUNGLE_TRAPDOOR: case JUNGLE_WALL_HANGING_SIGN: case JUNGLE_WALL_SIGN: @@ -8845,16 +9200,11 @@ public enum Material implements Keyed, Translatable { case MANGROVE_FENCE_GATE: case MANGROVE_HANGING_SIGN: case MANGROVE_SIGN: - case MANGROVE_STAIRS: case MANGROVE_TRAPDOOR: case MANGROVE_WALL_HANGING_SIGN: case MANGROVE_WALL_SIGN: - case MOSSY_COBBLESTONE_STAIRS: - case MOSSY_STONE_BRICK_STAIRS: case MOVING_PISTON: - case MUD_BRICK_STAIRS: case NETHER_BRICK_FENCE: - case NETHER_BRICK_STAIRS: case NOTE_BLOCK: case OAK_BUTTON: case OAK_DOOR: @@ -8862,7 +9212,6 @@ public enum Material implements Keyed, Translatable { case OAK_FENCE_GATE: case OAK_HANGING_SIGN: case OAK_SIGN: - case OAK_STAIRS: case OAK_TRAPDOOR: case OAK_WALL_HANGING_SIGN: case OAK_WALL_SIGN: @@ -8870,18 +9219,13 @@ public enum Material implements Keyed, Translatable { case ORANGE_CANDLE: case ORANGE_CANDLE_CAKE: case ORANGE_SHULKER_BOX: - case OXIDIZED_CUT_COPPER_STAIRS: + case OXIDIZED_COPPER_DOOR: + case OXIDIZED_COPPER_TRAPDOOR: case PINK_BED: case PINK_CANDLE: case PINK_CANDLE_CAKE: case PINK_SHULKER_BOX: - case POLISHED_ANDESITE_STAIRS: - case POLISHED_BLACKSTONE_BRICK_STAIRS: case POLISHED_BLACKSTONE_BUTTON: - case POLISHED_BLACKSTONE_STAIRS: - case POLISHED_DEEPSLATE_STAIRS: - case POLISHED_DIORITE_STAIRS: - case POLISHED_GRANITE_STAIRS: case POTTED_ACACIA_SAPLING: case POTTED_ALLIUM: case POTTED_AZALEA_BUSH: @@ -8917,33 +9261,23 @@ public enum Material implements Keyed, Translatable { case POTTED_WHITE_TULIP: case POTTED_WITHER_ROSE: case POWDER_SNOW_CAULDRON: - case PRISMARINE_BRICK_STAIRS: - case PRISMARINE_STAIRS: case PUMPKIN: case PURPLE_BED: case PURPLE_CANDLE: case PURPLE_CANDLE_CAKE: case PURPLE_SHULKER_BOX: - case PURPUR_STAIRS: - case QUARTZ_STAIRS: case REDSTONE_ORE: case REDSTONE_WIRE: case RED_BED: case RED_CANDLE: case RED_CANDLE_CAKE: - case RED_NETHER_BRICK_STAIRS: - case RED_SANDSTONE_STAIRS: case RED_SHULKER_BOX: case REPEATER: case REPEATING_COMMAND_BLOCK: case RESPAWN_ANCHOR: - case SANDSTONE_STAIRS: case SHULKER_BOX: case SMITHING_TABLE: case SMOKER: - case SMOOTH_QUARTZ_STAIRS: - case SMOOTH_RED_SANDSTONE_STAIRS: - case SMOOTH_SANDSTONE_STAIRS: case SOUL_CAMPFIRE: case SPRUCE_BUTTON: case SPRUCE_DOOR: @@ -8951,14 +9285,11 @@ public enum Material implements Keyed, Translatable { case SPRUCE_FENCE_GATE: case SPRUCE_HANGING_SIGN: case SPRUCE_SIGN: - case SPRUCE_STAIRS: case SPRUCE_TRAPDOOR: case SPRUCE_WALL_HANGING_SIGN: case SPRUCE_WALL_SIGN: case STONECUTTER: - case STONE_BRICK_STAIRS: case STONE_BUTTON: - case STONE_STAIRS: case STRUCTURE_BLOCK: case SWEET_BERRY_BUSH: case TNT: @@ -8969,16 +9300,20 @@ public enum Material implements Keyed, Translatable { case WARPED_FENCE_GATE: case WARPED_HANGING_SIGN: case WARPED_SIGN: - case WARPED_STAIRS: case WARPED_TRAPDOOR: case WARPED_WALL_HANGING_SIGN: case WARPED_WALL_SIGN: case WATER_CAULDRON: - case WAXED_CUT_COPPER_STAIRS: - case WAXED_EXPOSED_CUT_COPPER_STAIRS: - case WAXED_OXIDIZED_CUT_COPPER_STAIRS: - case WAXED_WEATHERED_CUT_COPPER_STAIRS: - case WEATHERED_CUT_COPPER_STAIRS: + case WAXED_COPPER_DOOR: + case WAXED_COPPER_TRAPDOOR: + case WAXED_EXPOSED_COPPER_DOOR: + case WAXED_EXPOSED_COPPER_TRAPDOOR: + case WAXED_OXIDIZED_COPPER_DOOR: + case WAXED_OXIDIZED_COPPER_TRAPDOOR: + case WAXED_WEATHERED_COPPER_DOOR: + case WAXED_WEATHERED_COPPER_TRAPDOOR: + case WEATHERED_COPPER_DOOR: + case WEATHERED_COPPER_TRAPDOOR: case WHITE_BED: case WHITE_CANDLE: case WHITE_CANDLE_CAKE: @@ -9452,8 +9787,11 @@ public enum Material implements Keyed, Translatable { case CHISELED_BOOKSHELF: case CHISELED_POLISHED_BLACKSTONE: case CHISELED_STONE_BRICKS: + case CHISELED_TUFF: + case CHISELED_TUFF_BRICKS: case CRACKED_POLISHED_BLACKSTONE_BRICKS: case CRACKED_STONE_BRICKS: + case CRAFTER: case DARK_PRISMARINE: case DARK_PRISMARINE_SLAB: case DARK_PRISMARINE_STAIRS: @@ -9500,6 +9838,10 @@ public enum Material implements Keyed, Translatable { case POLISHED_GRANITE: case POLISHED_GRANITE_SLAB: case POLISHED_GRANITE_STAIRS: + case POLISHED_TUFF: + case POLISHED_TUFF_SLAB: + case POLISHED_TUFF_STAIRS: + case POLISHED_TUFF_WALL: case PRISMARINE: case PRISMARINE_BRICKS: case PRISMARINE_BRICK_SLAB: @@ -9520,6 +9862,13 @@ public enum Material implements Keyed, Translatable { case STONE_STAIRS: case TUBE_CORAL_BLOCK: case TUFF: + case TUFF_BRICKS: + case TUFF_BRICK_SLAB: + case TUFF_BRICK_STAIRS: + case TUFF_BRICK_WALL: + case TUFF_SLAB: + case TUFF_STAIRS: + case TUFF_WALL: return 1.5F; case BLACK_CONCRETE: case BLUE_CONCRETE: @@ -9735,10 +10084,15 @@ public enum Material implements Keyed, Translatable { case BIRCH_TRAPDOOR: case CHERRY_DOOR: case CHERRY_TRAPDOOR: + case CHISELED_COPPER: case COAL_ORE: case CONDUIT: case COPPER_BLOCK: + case COPPER_BULB: + case COPPER_DOOR: + case COPPER_GRATE: case COPPER_ORE: + case COPPER_TRAPDOOR: case CRIMSON_DOOR: case CRIMSON_TRAPDOOR: case CUT_COPPER: @@ -9755,7 +10109,12 @@ public enum Material implements Keyed, Translatable { case END_STONE_BRICK_SLAB: case END_STONE_BRICK_STAIRS: case END_STONE_BRICK_WALL: + case EXPOSED_CHISELED_COPPER: case EXPOSED_COPPER: + case EXPOSED_COPPER_BULB: + case EXPOSED_COPPER_DOOR: + case EXPOSED_COPPER_GRATE: + case EXPOSED_COPPER_TRAPDOOR: case EXPOSED_CUT_COPPER: case EXPOSED_CUT_COPPER_SLAB: case EXPOSED_CUT_COPPER_STAIRS: @@ -9775,7 +10134,12 @@ public enum Material implements Keyed, Translatable { case OAK_DOOR: case OAK_TRAPDOOR: case OBSERVER: + case OXIDIZED_CHISELED_COPPER: case OXIDIZED_COPPER: + case OXIDIZED_COPPER_BULB: + case OXIDIZED_COPPER_DOOR: + case OXIDIZED_COPPER_GRATE: + case OXIDIZED_COPPER_TRAPDOOR: case OXIDIZED_CUT_COPPER: case OXIDIZED_CUT_COPPER_SLAB: case OXIDIZED_CUT_COPPER_STAIRS: @@ -9786,23 +10150,48 @@ public enum Material implements Keyed, Translatable { case SPRUCE_TRAPDOOR: case WARPED_DOOR: case WARPED_TRAPDOOR: + case WAXED_CHISELED_COPPER: case WAXED_COPPER_BLOCK: + case WAXED_COPPER_BULB: + case WAXED_COPPER_DOOR: + case WAXED_COPPER_GRATE: + case WAXED_COPPER_TRAPDOOR: case WAXED_CUT_COPPER: case WAXED_CUT_COPPER_SLAB: case WAXED_CUT_COPPER_STAIRS: + case WAXED_EXPOSED_CHISELED_COPPER: case WAXED_EXPOSED_COPPER: + case WAXED_EXPOSED_COPPER_BULB: + case WAXED_EXPOSED_COPPER_DOOR: + case WAXED_EXPOSED_COPPER_GRATE: + case WAXED_EXPOSED_COPPER_TRAPDOOR: case WAXED_EXPOSED_CUT_COPPER: case WAXED_EXPOSED_CUT_COPPER_SLAB: case WAXED_EXPOSED_CUT_COPPER_STAIRS: + case WAXED_OXIDIZED_CHISELED_COPPER: case WAXED_OXIDIZED_COPPER: + case WAXED_OXIDIZED_COPPER_BULB: + case WAXED_OXIDIZED_COPPER_DOOR: + case WAXED_OXIDIZED_COPPER_GRATE: + case WAXED_OXIDIZED_COPPER_TRAPDOOR: case WAXED_OXIDIZED_CUT_COPPER: case WAXED_OXIDIZED_CUT_COPPER_SLAB: case WAXED_OXIDIZED_CUT_COPPER_STAIRS: + case WAXED_WEATHERED_CHISELED_COPPER: case WAXED_WEATHERED_COPPER: + case WAXED_WEATHERED_COPPER_BULB: + case WAXED_WEATHERED_COPPER_DOOR: + case WAXED_WEATHERED_COPPER_GRATE: + case WAXED_WEATHERED_COPPER_TRAPDOOR: case WAXED_WEATHERED_CUT_COPPER: case WAXED_WEATHERED_CUT_COPPER_SLAB: case WAXED_WEATHERED_CUT_COPPER_STAIRS: + case WEATHERED_CHISELED_COPPER: case WEATHERED_COPPER: + case WEATHERED_COPPER_BULB: + case WEATHERED_COPPER_DOOR: + case WEATHERED_COPPER_GRATE: + case WEATHERED_COPPER_TRAPDOOR: case WEATHERED_CUT_COPPER: case WEATHERED_CUT_COPPER_SLAB: case WEATHERED_CUT_COPPER_STAIRS: @@ -9874,6 +10263,7 @@ public enum Material implements Keyed, Translatable { case NETHERITE_BLOCK: case OBSIDIAN: case RESPAWN_ANCHOR: + case TRIAL_SPAWNER: return 50.0F; case REINFORCED_DEEPSLATE: return 55.0F; @@ -10516,6 +10906,7 @@ public enum Material implements Keyed, Translatable { case WARPED_TRAPDOOR: return 3.0F; case BLAST_FURNACE: + case CRAFTER: case DISPENSER: case DROPPER: case FURNACE: @@ -10570,10 +10961,13 @@ public enum Material implements Keyed, Translatable { case BRICK_WALL: case BUBBLE_CORAL_BLOCK: case CHAIN: + case CHISELED_COPPER: case CHISELED_DEEPSLATE: case CHISELED_NETHER_BRICKS: case CHISELED_POLISHED_BLACKSTONE: case CHISELED_STONE_BRICKS: + case CHISELED_TUFF: + case CHISELED_TUFF_BRICKS: case COAL_BLOCK: case COBBLED_DEEPSLATE: case COBBLED_DEEPSLATE_SLAB: @@ -10584,6 +10978,10 @@ public enum Material implements Keyed, Translatable { case COBBLESTONE_STAIRS: case COBBLESTONE_WALL: case COPPER_BLOCK: + case COPPER_BULB: + case COPPER_DOOR: + case COPPER_GRATE: + case COPPER_TRAPDOOR: case CRACKED_DEEPSLATE_BRICKS: case CRACKED_DEEPSLATE_TILES: case CRACKED_NETHER_BRICKS: @@ -10617,7 +11015,12 @@ public enum Material implements Keyed, Translatable { case DIORITE_STAIRS: case DIORITE_WALL: case EMERALD_BLOCK: + case EXPOSED_CHISELED_COPPER: case EXPOSED_COPPER: + case EXPOSED_COPPER_BULB: + case EXPOSED_COPPER_DOOR: + case EXPOSED_COPPER_GRATE: + case EXPOSED_COPPER_TRAPDOOR: case EXPOSED_CUT_COPPER: case EXPOSED_CUT_COPPER_SLAB: case EXPOSED_CUT_COPPER_STAIRS: @@ -10647,7 +11050,12 @@ public enum Material implements Keyed, Translatable { case NETHER_BRICK_SLAB: case NETHER_BRICK_STAIRS: case NETHER_BRICK_WALL: + case OXIDIZED_CHISELED_COPPER: case OXIDIZED_COPPER: + case OXIDIZED_COPPER_BULB: + case OXIDIZED_COPPER_DOOR: + case OXIDIZED_COPPER_GRATE: + case OXIDIZED_COPPER_TRAPDOOR: case OXIDIZED_CUT_COPPER: case OXIDIZED_CUT_COPPER_SLAB: case OXIDIZED_CUT_COPPER_STAIRS: @@ -10673,6 +11081,10 @@ public enum Material implements Keyed, Translatable { case POLISHED_GRANITE: case POLISHED_GRANITE_SLAB: case POLISHED_GRANITE_STAIRS: + case POLISHED_TUFF: + case POLISHED_TUFF_SLAB: + case POLISHED_TUFF_STAIRS: + case POLISHED_TUFF_WALL: case PRISMARINE: case PRISMARINE_BRICKS: case PRISMARINE_BRICK_SLAB: @@ -10715,23 +11127,55 @@ public enum Material implements Keyed, Translatable { case STONE_STAIRS: case TUBE_CORAL_BLOCK: case TUFF: + case TUFF_BRICKS: + case TUFF_BRICK_SLAB: + case TUFF_BRICK_STAIRS: + case TUFF_BRICK_WALL: + case TUFF_SLAB: + case TUFF_STAIRS: + case TUFF_WALL: + case WAXED_CHISELED_COPPER: case WAXED_COPPER_BLOCK: + case WAXED_COPPER_BULB: + case WAXED_COPPER_DOOR: + case WAXED_COPPER_GRATE: + case WAXED_COPPER_TRAPDOOR: case WAXED_CUT_COPPER: case WAXED_CUT_COPPER_SLAB: case WAXED_CUT_COPPER_STAIRS: + case WAXED_EXPOSED_CHISELED_COPPER: case WAXED_EXPOSED_COPPER: + case WAXED_EXPOSED_COPPER_BULB: + case WAXED_EXPOSED_COPPER_DOOR: + case WAXED_EXPOSED_COPPER_GRATE: + case WAXED_EXPOSED_COPPER_TRAPDOOR: case WAXED_EXPOSED_CUT_COPPER: case WAXED_EXPOSED_CUT_COPPER_SLAB: case WAXED_EXPOSED_CUT_COPPER_STAIRS: + case WAXED_OXIDIZED_CHISELED_COPPER: case WAXED_OXIDIZED_COPPER: + case WAXED_OXIDIZED_COPPER_BULB: + case WAXED_OXIDIZED_COPPER_DOOR: + case WAXED_OXIDIZED_COPPER_GRATE: + case WAXED_OXIDIZED_COPPER_TRAPDOOR: case WAXED_OXIDIZED_CUT_COPPER: case WAXED_OXIDIZED_CUT_COPPER_SLAB: case WAXED_OXIDIZED_CUT_COPPER_STAIRS: + case WAXED_WEATHERED_CHISELED_COPPER: case WAXED_WEATHERED_COPPER: + case WAXED_WEATHERED_COPPER_BULB: + case WAXED_WEATHERED_COPPER_DOOR: + case WAXED_WEATHERED_COPPER_GRATE: + case WAXED_WEATHERED_COPPER_TRAPDOOR: case WAXED_WEATHERED_CUT_COPPER: case WAXED_WEATHERED_CUT_COPPER_SLAB: case WAXED_WEATHERED_CUT_COPPER_STAIRS: + case WEATHERED_CHISELED_COPPER: case WEATHERED_COPPER: + case WEATHERED_COPPER_BULB: + case WEATHERED_COPPER_DOOR: + case WEATHERED_COPPER_GRATE: + case WEATHERED_COPPER_TRAPDOOR: case WEATHERED_CUT_COPPER: case WEATHERED_CUT_COPPER_SLAB: case WEATHERED_CUT_COPPER_STAIRS: @@ -10743,6 +11187,8 @@ public enum Material implements Keyed, Translatable { case END_STONE_BRICK_STAIRS: case END_STONE_BRICK_WALL: return 9.0F; + case TRIAL_SPAWNER: + return 50.0F; case LAVA: case WATER: return 100.0F; diff --git a/src/main/java/org/bukkit/Particle.java b/src/main/java/org/bukkit/Particle.java index e2adb990..e3c94a56 100644 --- a/src/main/java/org/bukkit/Particle.java +++ b/src/main/java/org/bukkit/Particle.java @@ -131,6 +131,12 @@ public enum Particle implements Keyed { SHRIEK("shriek", Integer.class), CHERRY_LEAVES("cherry_leaves"), EGG_CRACK("egg_crack"), + DUST_PLUME("dust_plume"), + WHITE_SMOKE("white_smoke"), + GUST("gust"), + GUST_EMITTER("gust_emitter"), + GUST_DUST("gust_dust"), + TRIAL_SPAWNER_DETECTION("trial_spawner_detection"), /** * Uses {@link BlockData} as DataType */ diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java index c5ba0f3a..9b1247cd 100644 --- a/src/main/java/org/bukkit/Sound.java +++ b/src/main/java/org/bukkit/Sound.java @@ -214,19 +214,55 @@ public enum Sound implements Keyed { BLOCK_CONDUIT_ATTACK_TARGET("block.conduit.attack.target"), BLOCK_CONDUIT_DEACTIVATE("block.conduit.deactivate"), BLOCK_COPPER_BREAK("block.copper.break"), + @MinecraftExperimental + BLOCK_COPPER_BULB_BREAK("block.copper_bulb.break"), + @MinecraftExperimental + BLOCK_COPPER_BULB_FALL("block.copper_bulb.fall"), + @MinecraftExperimental + BLOCK_COPPER_BULB_HIT("block.copper_bulb.hit"), + @MinecraftExperimental + BLOCK_COPPER_BULB_PLACE("block.copper_bulb.place"), + @MinecraftExperimental + BLOCK_COPPER_BULB_STEP("block.copper_bulb.step"), + @MinecraftExperimental + BLOCK_COPPER_BULB_TURN_OFF("block.copper_bulb.turn_off"), + @MinecraftExperimental + BLOCK_COPPER_BULB_TURN_ON("block.copper_bulb.turn_on"), + @MinecraftExperimental + BLOCK_COPPER_DOOR_CLOSE("block.copper_door.close"), + @MinecraftExperimental + BLOCK_COPPER_DOOR_OPEN("block.copper_door.open"), BLOCK_COPPER_FALL("block.copper.fall"), + @MinecraftExperimental + BLOCK_COPPER_GRATE_BREAK("block.copper_grate.break"), + @MinecraftExperimental + BLOCK_COPPER_GRATE_FALL("block.copper_grate.fall"), + @MinecraftExperimental + BLOCK_COPPER_GRATE_HIT("block.copper_grate.hit"), + @MinecraftExperimental + BLOCK_COPPER_GRATE_PLACE("block.copper_grate.place"), + @MinecraftExperimental + BLOCK_COPPER_GRATE_STEP("block.copper_grate.step"), BLOCK_COPPER_HIT("block.copper.hit"), BLOCK_COPPER_PLACE("block.copper.place"), BLOCK_COPPER_STEP("block.copper.step"), + @MinecraftExperimental + BLOCK_COPPER_TRAPDOOR_CLOSE("block.copper_trapdoor.close"), + @MinecraftExperimental + BLOCK_COPPER_TRAPDOOR_OPEN("block.copper_trapdoor.open"), BLOCK_CORAL_BLOCK_BREAK("block.coral_block.break"), BLOCK_CORAL_BLOCK_FALL("block.coral_block.fall"), BLOCK_CORAL_BLOCK_HIT("block.coral_block.hit"), BLOCK_CORAL_BLOCK_PLACE("block.coral_block.place"), BLOCK_CORAL_BLOCK_STEP("block.coral_block.step"), + BLOCK_CRAFTER_CRAFT("block.crafter.craft"), + BLOCK_CRAFTER_FAIL("block.crafter.fail"), BLOCK_CROP_BREAK("block.crop.break"), BLOCK_DECORATED_POT_BREAK("block.decorated_pot.break"), BLOCK_DECORATED_POT_FALL("block.decorated_pot.fall"), BLOCK_DECORATED_POT_HIT("block.decorated_pot.hit"), + BLOCK_DECORATED_POT_INSERT("block.decorated_pot.insert"), + BLOCK_DECORATED_POT_INSERT_FAIL("block.decorated_pot.insert_fail"), BLOCK_DECORATED_POT_PLACE("block.decorated_pot.place"), BLOCK_DECORATED_POT_SHATTER("block.decorated_pot.shatter"), BLOCK_DECORATED_POT_STEP("block.decorated_pot.step"), @@ -317,6 +353,7 @@ public enum Sound implements Keyed { BLOCK_HANGING_SIGN_HIT("block.hanging_sign.hit"), BLOCK_HANGING_SIGN_PLACE("block.hanging_sign.place"), BLOCK_HANGING_SIGN_STEP("block.hanging_sign.step"), + BLOCK_HANGING_SIGN_WAXED_INTERACT_FAIL("block.hanging_sign.waxed_interact_fail"), BLOCK_HONEY_BLOCK_BREAK("block.honey_block.break"), BLOCK_HONEY_BLOCK_FALL("block.honey_block.fall"), BLOCK_HONEY_BLOCK_HIT("block.honey_block.hit"), @@ -493,6 +530,16 @@ public enum Sound implements Keyed { BLOCK_POLISHED_DEEPSLATE_HIT("block.polished_deepslate.hit"), BLOCK_POLISHED_DEEPSLATE_PLACE("block.polished_deepslate.place"), BLOCK_POLISHED_DEEPSLATE_STEP("block.polished_deepslate.step"), + @MinecraftExperimental + BLOCK_POLISHED_TUFF_BREAK("block.polished_tuff.break"), + @MinecraftExperimental + BLOCK_POLISHED_TUFF_FALL("block.polished_tuff.fall"), + @MinecraftExperimental + BLOCK_POLISHED_TUFF_HIT("block.polished_tuff.hit"), + @MinecraftExperimental + BLOCK_POLISHED_TUFF_PLACE("block.polished_tuff.place"), + @MinecraftExperimental + BLOCK_POLISHED_TUFF_STEP("block.polished_tuff.step"), BLOCK_PORTAL_AMBIENT("block.portal.ambient"), BLOCK_PORTAL_TRAVEL("block.portal.travel"), BLOCK_PORTAL_TRIGGER("block.portal.trigger"), @@ -636,11 +683,43 @@ public enum Sound implements Keyed { BLOCK_SWEET_BERRY_BUSH_BREAK("block.sweet_berry_bush.break"), BLOCK_SWEET_BERRY_BUSH_PICK_BERRIES("block.sweet_berry_bush.pick_berries"), BLOCK_SWEET_BERRY_BUSH_PLACE("block.sweet_berry_bush.place"), + @MinecraftExperimental + BLOCK_TRIAL_SPAWNER_AMBIENT("block.trial_spawner.ambient"), + @MinecraftExperimental + BLOCK_TRIAL_SPAWNER_BREAK("block.trial_spawner.break"), + @MinecraftExperimental + BLOCK_TRIAL_SPAWNER_CLOSE_SHUTTER("block.trial_spawner.close_shutter"), + @MinecraftExperimental + BLOCK_TRIAL_SPAWNER_DETECT_PLAYER("block.trial_spawner.detect_player"), + @MinecraftExperimental + BLOCK_TRIAL_SPAWNER_EJECT_ITEM("block.trial_spawner.eject_item"), + @MinecraftExperimental + BLOCK_TRIAL_SPAWNER_FALL("block.trial_spawner.fall"), + @MinecraftExperimental + BLOCK_TRIAL_SPAWNER_HIT("block.trial_spawner.hit"), + @MinecraftExperimental + BLOCK_TRIAL_SPAWNER_OPEN_SHUTTER("block.trial_spawner.open_shutter"), + @MinecraftExperimental + BLOCK_TRIAL_SPAWNER_PLACE("block.trial_spawner.place"), + @MinecraftExperimental + BLOCK_TRIAL_SPAWNER_SPAWN_MOB("block.trial_spawner.spawn_mob"), + @MinecraftExperimental + BLOCK_TRIAL_SPAWNER_STEP("block.trial_spawner.step"), BLOCK_TRIPWIRE_ATTACH("block.tripwire.attach"), BLOCK_TRIPWIRE_CLICK_OFF("block.tripwire.click_off"), BLOCK_TRIPWIRE_CLICK_ON("block.tripwire.click_on"), BLOCK_TRIPWIRE_DETACH("block.tripwire.detach"), BLOCK_TUFF_BREAK("block.tuff.break"), + @MinecraftExperimental + BLOCK_TUFF_BRICKS_BREAK("block.tuff_bricks.break"), + @MinecraftExperimental + BLOCK_TUFF_BRICKS_FALL("block.tuff_bricks.fall"), + @MinecraftExperimental + BLOCK_TUFF_BRICKS_HIT("block.tuff_bricks.hit"), + @MinecraftExperimental + BLOCK_TUFF_BRICKS_PLACE("block.tuff_bricks.place"), + @MinecraftExperimental + BLOCK_TUFF_BRICKS_STEP("block.tuff_bricks.step"), BLOCK_TUFF_FALL("block.tuff.fall"), BLOCK_TUFF_HIT("block.tuff.hit"), BLOCK_TUFF_PLACE("block.tuff.place"), @@ -729,6 +808,24 @@ public enum Sound implements Keyed { ENTITY_BLAZE_SHOOT("entity.blaze.shoot"), ENTITY_BOAT_PADDLE_LAND("entity.boat.paddle_land"), ENTITY_BOAT_PADDLE_WATER("entity.boat.paddle_water"), + @MinecraftExperimental + ENTITY_BREEZE_DEATH("entity.breeze.death"), + @MinecraftExperimental + ENTITY_BREEZE_HURT("entity.breeze.hurt"), + @MinecraftExperimental + ENTITY_BREEZE_IDLE_AIR("entity.breeze.idle_air"), + @MinecraftExperimental + ENTITY_BREEZE_IDLE_GROUND("entity.breeze.idle_ground"), + @MinecraftExperimental + ENTITY_BREEZE_INHALE("entity.breeze.inhale"), + @MinecraftExperimental + ENTITY_BREEZE_JUMP("entity.breeze.jump"), + @MinecraftExperimental + ENTITY_BREEZE_LAND("entity.breeze.land"), + @MinecraftExperimental + ENTITY_BREEZE_SHOOT("entity.breeze.shoot"), + @MinecraftExperimental + ENTITY_BREEZE_SLIDE("entity.breeze.slide"), ENTITY_CAMEL_AMBIENT("entity.camel.ambient"), ENTITY_CAMEL_DASH("entity.camel.dash"), ENTITY_CAMEL_DASH_READY("entity.camel.dash_ready"), @@ -873,6 +970,8 @@ public enum Sound implements Keyed { ENTITY_GENERIC_SMALL_FALL("entity.generic.small_fall"), ENTITY_GENERIC_SPLASH("entity.generic.splash"), ENTITY_GENERIC_SWIM("entity.generic.swim"), + @MinecraftExperimental + ENTITY_GENERIC_WIND_BURST("entity.generic.wind_burst"), ENTITY_GHAST_AMBIENT("entity.ghast.ambient"), ENTITY_GHAST_DEATH("entity.ghast.death"), ENTITY_GHAST_HURT("entity.ghast.hurt"), @@ -1024,6 +1123,8 @@ public enum Sound implements Keyed { ENTITY_PARROT_FLY("entity.parrot.fly"), ENTITY_PARROT_HURT("entity.parrot.hurt"), ENTITY_PARROT_IMITATE_BLAZE("entity.parrot.imitate.blaze"), + @MinecraftExperimental + ENTITY_PARROT_IMITATE_BREEZE("entity.parrot.imitate.breeze"), ENTITY_PARROT_IMITATE_CREEPER("entity.parrot.imitate.creeper"), ENTITY_PARROT_IMITATE_DROWNED("entity.parrot.imitate.drowned"), ENTITY_PARROT_IMITATE_ELDER_GUARDIAN("entity.parrot.imitate.elder_guardian"), @@ -1108,6 +1209,7 @@ public enum Sound implements Keyed { ENTITY_PLAYER_SPLASH("entity.player.splash"), ENTITY_PLAYER_SPLASH_HIGH_SPEED("entity.player.splash.high_speed"), ENTITY_PLAYER_SWIM("entity.player.swim"), + ENTITY_PLAYER_TELEPORT("entity.player.teleport"), ENTITY_POLAR_BEAR_AMBIENT("entity.polar_bear.ambient"), ENTITY_POLAR_BEAR_AMBIENT_BABY("entity.polar_bear.ambient_baby"), ENTITY_POLAR_BEAR_DEATH("entity.polar_bear.death"), diff --git a/src/main/java/org/bukkit/Tag.java b/src/main/java/org/bukkit/Tag.java index 02f75db7..85c48fa2 100644 --- a/src/main/java/org/bukkit/Tag.java +++ b/src/main/java/org/bukkit/Tag.java @@ -962,6 +962,18 @@ public interface Tag extends Keyed { * Vanilla tag representing entities which are not controlled by their mount. */ Tag ENTITY_TYPES_NON_CONTROLLING_RIDER = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("non_controlling_rider"), EntityType.class); + /** + * Vanilla tag representing entities which deflect arrows. + */ + Tag ENTITY_TYPES_DEFLECTS_ARROWS = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("deflects_arrows"), EntityType.class); + /** + * Vanilla tag representing entities which deflect tridents. + */ + Tag ENTITY_TYPES_DEFLECTS_TRIDENTS = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("deflects_tridents"), EntityType.class); + /** + * Vanilla tag representing entities which can turn in boats. + */ + Tag ENTITY_TYPES_CAN_TURN_IN_BOATS = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("can_turn_in_boats"), EntityType.class); /** * Returns whether or not this tag has an entry for the specified item. diff --git a/src/main/java/org/bukkit/block/Crafter.java b/src/main/java/org/bukkit/block/Crafter.java new file mode 100644 index 00000000..fda6e896 --- /dev/null +++ b/src/main/java/org/bukkit/block/Crafter.java @@ -0,0 +1,63 @@ +package org.bukkit.block; + +import org.bukkit.MinecraftExperimental; +import org.bukkit.loot.Lootable; +import org.jetbrains.annotations.ApiStatus; + +/** + * Represents a captured state of a crafter. + */ +@ApiStatus.Experimental +@MinecraftExperimental +public interface Crafter extends Container, Lootable { + + /** + * Gets the number of ticks which this block will remain in the crafting + * state for. + * + * @return number of ticks remaining + * @see org.bukkit.block.data.type.Crafter#isCrafting() + */ + int getCraftingTicks(); + + /** + * Sets the number of ticks which this block will remain in the crafting + * state for. + * + * @param ticks number of ticks remaining + * @see org.bukkit.block.data.type.Crafter#isCrafting() + */ + void setCraftingTicks(int ticks); + + /** + * Gets whether the slot at the specified index is disabled and will not + * have items placed in it. + * + * @param slot slot index + * @return disabled status + */ + boolean isSlotDisabled(int slot); + + /** + * Sets whether the slot at the specified index is disabled and will not + * have items placed in it. + * + * @param slot slot index + * @param disabled disabled status + */ + void setSlotDisabled(int slot, boolean disabled); + + /** + * Gets whether this Crafter is powered. + * + * @return powered status + */ + boolean isTriggered(); + + /** + * Sets whether this Crafter is powered. + * + * @param triggered powered status + */ + void setTriggered(boolean triggered); +} diff --git a/src/main/java/org/bukkit/block/TrialSpawner.java b/src/main/java/org/bukkit/block/TrialSpawner.java new file mode 100644 index 00000000..66ce87d2 --- /dev/null +++ b/src/main/java/org/bukkit/block/TrialSpawner.java @@ -0,0 +1,12 @@ +package org.bukkit.block; + +import org.bukkit.MinecraftExperimental; +import org.jetbrains.annotations.ApiStatus; + +/** + * Represents a captured state of a trial spawner. + */ +@MinecraftExperimental +@ApiStatus.Experimental +public interface TrialSpawner extends TileState { +} diff --git a/src/main/java/org/bukkit/block/data/type/CopperBulb.java b/src/main/java/org/bukkit/block/data/type/CopperBulb.java new file mode 100644 index 00000000..2257f23c --- /dev/null +++ b/src/main/java/org/bukkit/block/data/type/CopperBulb.java @@ -0,0 +1,11 @@ +package org.bukkit.block.data.type; + +import org.bukkit.MinecraftExperimental; +import org.bukkit.block.data.Lightable; +import org.bukkit.block.data.Powerable; +import org.jetbrains.annotations.ApiStatus; + +@MinecraftExperimental +@ApiStatus.Experimental +public interface CopperBulb extends Lightable, Powerable { +} diff --git a/src/main/java/org/bukkit/block/data/type/Crafter.java b/src/main/java/org/bukkit/block/data/type/Crafter.java new file mode 100644 index 00000000..bc29b8ae --- /dev/null +++ b/src/main/java/org/bukkit/block/data/type/Crafter.java @@ -0,0 +1,81 @@ +package org.bukkit.block.data.type; + +import org.bukkit.MinecraftExperimental; +import org.bukkit.block.data.BlockData; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +/** + * 'orientation' is the direction the block is facing. + *
+ * Similar to {@link Powerable}, 'triggered' indicates whether or not the + * dispenser is currently activated. + *
+ * 'crafting' is whether crafter's mouth is open and top is glowing. + */ +@ApiStatus.Experimental +@MinecraftExperimental +public interface Crafter extends BlockData { + + /** + * Gets the value of the 'crafting' property. + * + * @return the 'crafting' value + */ + boolean isCrafting(); + + /** + * Sets the value of the 'crafting' property. + * + * @param crafting the new 'crafting' value + */ + void setCrafting(boolean crafting); + + /** + * Gets the value of the 'triggered' property. + * + * @return the 'triggered' value + */ + boolean isTriggered(); + + /** + * Sets the value of the 'triggered' property. + * + * @param triggered the new 'triggered' value + */ + void setTriggered(boolean triggered); + + /** + * Gets the value of the 'orientation' property. + * + * @return the 'orientation' value + */ + @NotNull + Orientation getOrientation(); + + /** + * Sets the value of the 'orientation' property. + * + * @param orientation the new 'orientation' value + */ + void setOrientation(@NotNull Orientation orientation); + + /** + * The directions the Crafter can be oriented. + */ + public enum Orientation { + + DOWN_EAST, + DOWN_NORTH, + DOWN_SOUTH, + DOWN_WEST, + UP_EAST, + UP_NORTH, + UP_SOUTH, + UP_WEST, + WEST_UP, + EAST_UP, + NORTH_UP, + SOUTH_UP; + } +} diff --git a/src/main/java/org/bukkit/block/data/type/TrialSpawner.java b/src/main/java/org/bukkit/block/data/type/TrialSpawner.java new file mode 100644 index 00000000..2a205290 --- /dev/null +++ b/src/main/java/org/bukkit/block/data/type/TrialSpawner.java @@ -0,0 +1,39 @@ +package org.bukkit.block.data.type; + +import org.bukkit.MinecraftExperimental; +import org.bukkit.block.data.BlockData; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +/** + * 'trial_spawner_state' indicates the current operational phase of the spawner. + */ +@MinecraftExperimental +@ApiStatus.Experimental +public interface TrialSpawner extends BlockData { + + /** + * Gets the value of the 'trial_spawner_state' property. + * + * @return the 'trial_spawner_state' value + */ + @NotNull + State getTrialSpawnerState(); + + /** + * Sets the value of the 'trial_spawner_state' property. + * + * @param state the new 'trial_spawner_state' value + */ + void setTrialSpawnerState(@NotNull State state); + + public enum State { + + INACTIVE, + WAITING_FOR_PLAYERS, + ACTIVE, + WAITING_FOR_REWARD_EJECTION, + EJECTING_REWARD, + COOLDOWN; + } +} diff --git a/src/main/java/org/bukkit/entity/Breeze.java b/src/main/java/org/bukkit/entity/Breeze.java new file mode 100644 index 00000000..03d9e1f5 --- /dev/null +++ b/src/main/java/org/bukkit/entity/Breeze.java @@ -0,0 +1,12 @@ +package org.bukkit.entity; + +import org.bukkit.MinecraftExperimental; +import org.jetbrains.annotations.ApiStatus; + +/** + * Represents a Breeze. Whoosh! + */ +@MinecraftExperimental +@ApiStatus.Experimental +public interface Breeze extends Monster { +} diff --git a/src/main/java/org/bukkit/entity/EntityType.java b/src/main/java/org/bukkit/entity/EntityType.java index bb9ae818..e3f440c9 100644 --- a/src/main/java/org/bukkit/entity/EntityType.java +++ b/src/main/java/org/bukkit/entity/EntityType.java @@ -6,6 +6,7 @@ import java.util.Map; import org.bukkit.Bukkit; import org.bukkit.Keyed; import org.bukkit.Location; +import org.bukkit.MinecraftExperimental; import org.bukkit.NamespacedKey; import org.bukkit.Translatable; import org.bukkit.World; @@ -18,6 +19,7 @@ import org.bukkit.entity.minecart.SpawnerMinecart; import org.bukkit.entity.minecart.StorageMinecart; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -284,6 +286,12 @@ public enum EntityType implements Keyed, Translatable { ITEM_DISPLAY("item_display", ItemDisplay.class, -1), SNIFFER("sniffer", Sniffer.class, -1), TEXT_DISPLAY("text_display", TextDisplay.class, -1), + @MinecraftExperimental + @ApiStatus.Experimental + BREEZE("breeze", Breeze.class, -1), + @MinecraftExperimental + @ApiStatus.Experimental + WIND_CHARGE("wind_charge", WindCharge.class, -1), /** * A fishing line and bobber. */ diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java index 3cf31b08..57fee6b6 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -7,6 +7,7 @@ import java.time.Instant; import java.util.Collection; import java.util.Date; import java.util.Map; +import java.util.UUID; import org.bukkit.BanEntry; import org.bukkit.DyeColor; import org.bukkit.Effect; @@ -1525,6 +1526,53 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void setResourcePack(@NotNull String url, @Nullable byte[] hash, @Nullable String prompt, boolean force); + /** + * Request that the player's client download and switch resource packs. + *

+ * The player's client will download the new resource pack asynchronously + * in the background, and will automatically switch to it once the + * download is complete. If the client has downloaded and cached a + * resource pack with the same hash in the past it will not download but + * directly apply the cached pack. If the hash is null and the client has + * downloaded and cached the same resource pack in the past, it will + * perform a file size check against the response content to determine if + * the resource pack has changed and needs to be downloaded again. When + * this request is sent for the very first time from a given server, the + * client will first display a confirmation GUI to the player before + * proceeding with the download. + *

+ * Notes: + *

    + *
  • Players can disable server resources on their client, in which + * case this method will have no affect on them. Use the + * {@link PlayerResourcePackStatusEvent} to figure out whether or not + * the player loaded the pack! + *
  • There is no concept of resetting resource packs back to default + * within Minecraft, so players will have to relog to do so or you + * have to send an empty pack. + *
  • The request is sent with empty string as the hash when the hash is + * not provided. This might result in newer versions not loading the + * pack correctly. + *
+ * + * @param id Unique resource pack ID. + * @param url The URL from which the client will download the resource + * pack. The string must contain only US-ASCII characters and should + * be encoded as per RFC 1738. + * @param hash The sha1 hash sum of the resource pack file which is used + * to apply a cached version of the pack directly without downloading + * if it is available. Hast to be 20 bytes long! + * @param prompt The optional custom prompt message to be shown to client. + * @param force If true, the client will be disconnected from the server + * when it declines to use the resource pack. + * @throws IllegalArgumentException Thrown if the URL is null. + * @throws IllegalArgumentException Thrown if the URL is too long. The + * length restriction is an implementation specific arbitrary value. + * @throws IllegalArgumentException Thrown if the hash is not 20 bytes + * long. + */ + public void setResourcePack(@NotNull UUID id, @NotNull String url, @Nullable byte[] hash, @Nullable String prompt, boolean force); + /** * Gets the Scoreboard displayed to this player * diff --git a/src/main/java/org/bukkit/entity/WindCharge.java b/src/main/java/org/bukkit/entity/WindCharge.java new file mode 100644 index 00000000..9294de16 --- /dev/null +++ b/src/main/java/org/bukkit/entity/WindCharge.java @@ -0,0 +1,12 @@ +package org.bukkit.entity; + +import org.bukkit.MinecraftExperimental; +import org.jetbrains.annotations.ApiStatus; + +/** + * Represents a Wind Charge. + */ +@MinecraftExperimental +@ApiStatus.Experimental +public interface WindCharge extends Fireball { +} diff --git a/src/main/java/org/bukkit/event/inventory/InventoryType.java b/src/main/java/org/bukkit/event/inventory/InventoryType.java index ec9f58ea..a2e9bedc 100644 --- a/src/main/java/org/bukkit/event/inventory/InventoryType.java +++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java @@ -1,6 +1,8 @@ package org.bukkit.event.inventory; +import org.bukkit.MinecraftExperimental; import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -142,6 +144,12 @@ public enum InventoryType { * Pseudo jukebox inventory with 1 slot of undefined type. */ JUKEBOX(1, "Jukebox", false), + /** + * A crafter inventory, with 9 CRAFTING slots. + */ + @MinecraftExperimental + @ApiStatus.Experimental + CRAFTER(9, "Crafter"), /** * The new smithing inventory, with 3 CRAFTING slots and 1 RESULT slot. * diff --git a/src/main/java/org/bukkit/generator/structure/Structure.java b/src/main/java/org/bukkit/generator/structure/Structure.java index ca310cfe..1a766e68 100644 --- a/src/main/java/org/bukkit/generator/structure/Structure.java +++ b/src/main/java/org/bukkit/generator/structure/Structure.java @@ -47,6 +47,7 @@ public abstract class Structure implements Keyed { public static final Structure RUINED_PORTAL_NETHER = getStructure("ruined_portal_nether"); public static final Structure ANCIENT_CITY = getStructure("ancient_city"); public static final Structure TRAIL_RUINS = getStructure("trail_ruins"); + public static final Structure TRIAL_CHAMBERS = getStructure("trial_chambers"); private static Structure getStructure(String name) { return Registry.STRUCTURE.get(NamespacedKey.minecraft(name)); diff --git a/src/main/java/org/bukkit/inventory/CrafterInventory.java b/src/main/java/org/bukkit/inventory/CrafterInventory.java new file mode 100644 index 00000000..7cdcd45e --- /dev/null +++ b/src/main/java/org/bukkit/inventory/CrafterInventory.java @@ -0,0 +1,11 @@ +package org.bukkit.inventory; + +import org.bukkit.MinecraftExperimental; +import org.jetbrains.annotations.ApiStatus; + +/** + * Interface to the inventory of a Crafter. + */ +@ApiStatus.Experimental +@MinecraftExperimental +public interface CrafterInventory extends Inventory { } diff --git a/src/main/java/org/bukkit/loot/LootTables.java b/src/main/java/org/bukkit/loot/LootTables.java index 4e8479dc..ddf71b0e 100644 --- a/src/main/java/org/bukkit/loot/LootTables.java +++ b/src/main/java/org/bukkit/loot/LootTables.java @@ -33,6 +33,16 @@ public enum LootTables implements Keyed { ANCIENT_CITY("chests/ancient_city"), ANCIENT_CITY_ICE_BOX("chests/ancient_city_ice_box"), RUINED_PORTAL("chests/ruined_portal"), + TRIAL_CHAMBERS_REWARD("chests/trial_chambers/reward"), + TRIAL_CHAMBERS_SUPPLY("chests/trial_chambers/supply"), + TRIAL_CHAMBERS_CORRIDOR("chests/trial_chambers/corridor"), + TRIAL_CHAMBERS_INTERSECTION("chests/trial_chambers/intersection"), + TRIAL_CHAMBERS_INTERSECTION_BARREL("chests/trial_chambers/intersection_barrel"), + TRIAL_CHAMBERS_ENTRANCE("chests/trial_chambers/entrance"), + TRIAL_CHAMBERS_CORRIDOR_DISPENSER("dispensers/trial_chambers/corridor"), + TRIAL_CHAMBERS_CHAMBER_DISPENSER("dispensers/trial_chambers/chamber"), + TRIAL_CHAMBERS_WATER_DISPENSER("dispensers/trial_chambers/water"), + TRIAL_CHAMBERS_CORRIDOR_POT("pots/trial_chambers/corridor"), SHIPWRECK_MAP("chests/shipwreck_map"), SHIPWRECK_SUPPLY("chests/shipwreck_supply"), SHIPWRECK_TREASURE("chests/shipwreck_treasure"), @@ -157,6 +167,9 @@ public enum LootTables implements Keyed { WEAPONSMITH_GIFT("gameplay/hero_of_the_village/weaponsmith_gift"), SNIFFER_DIGGING("gameplay/sniffer_digging"), PIGLIN_BARTERING("gameplay/piglin_bartering"), + // Spawners + TRIAL_CHAMBER_KEY("spawners/trial_chamber/key"), + RIAL_CHAMBER_CONSUMABLES("spawners/trial_chamber/consumables"), // Archaeology DESERT_WELL_ARCHAEOLOGY("archaeology/desert_well"), DESERT_PYRAMID_ARCHAEOLOGY("archaeology/desert_pyramid"), From 977a1fb45ff48f499c5936f40dc6d9f877bab19c Mon Sep 17 00:00:00 2001 From: DerFrZocker Date: Wed, 6 Dec 2023 03:40:00 +1100 Subject: [PATCH 14/22] SPIGOT-6026: Pull PotionEffectType and Enchantment from registry --- src/main/java/org/bukkit/Registry.java | 31 +-- .../org/bukkit/enchantments/Enchantment.java | 230 +++++++-------- .../enchantments/EnchantmentWrapper.java | 53 +--- .../org/bukkit/potion/PotionEffectType.java | 262 +++++++++--------- .../potion/PotionEffectTypeWrapper.java | 35 +-- 5 files changed, 261 insertions(+), 350 deletions(-) diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java index c373614a..3be42143 100644 --- a/src/main/java/org/bukkit/Registry.java +++ b/src/main/java/org/bukkit/Registry.java @@ -3,7 +3,6 @@ package org.bukkit; import com.google.common.base.Preconditions; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableMap; -import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.Objects; @@ -24,6 +23,7 @@ import org.bukkit.generator.structure.StructureType; import org.bukkit.inventory.meta.trim.TrimMaterial; import org.bukkit.inventory.meta.trim.TrimPattern; import org.bukkit.loot.LootTables; +import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionType; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -110,28 +110,9 @@ public interface Registry extends Iterable { /** * Server enchantments. * - * @see Enchantment#getByKey(org.bukkit.NamespacedKey) + * @see Enchantment */ - Registry ENCHANTMENT = new Registry() { - - @Nullable - @Override - public Enchantment get(@NotNull NamespacedKey key) { - return Enchantment.getByKey(key); - } - - @NotNull - @Override - public Stream stream() { - return StreamSupport.stream(spliterator(), false); - } - - @NotNull - @Override - public Iterator iterator() { - return Arrays.asList(Enchantment.values()).iterator(); - } - }; + Registry ENCHANTMENT = Objects.requireNonNull(Bukkit.getRegistry(Enchantment.class), "No registry present for Enchantment. This is a bug."); /** * Server entity types. * @@ -156,6 +137,12 @@ public interface Registry extends Iterable { * @see Material */ Registry MATERIAL = new SimpleRegistry<>(Material.class, (mat) -> !mat.isLegacy()); + /** + * Server mob effects. + * + * @see PotionEffectType + */ + Registry EFFECT = Objects.requireNonNull(Bukkit.getRegistry(PotionEffectType.class), "No registry present for PotionEffectType. This is a bug."); /** * Server particles. * diff --git a/src/main/java/org/bukkit/enchantments/Enchantment.java b/src/main/java/org/bukkit/enchantments/Enchantment.java index e2800dc9..c349cd16 100644 --- a/src/main/java/org/bukkit/enchantments/Enchantment.java +++ b/src/main/java/org/bukkit/enchantments/Enchantment.java @@ -1,9 +1,10 @@ package org.bukkit.enchantments; -import java.util.HashMap; -import java.util.Map; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; +import org.bukkit.Registry; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -16,213 +17,208 @@ public abstract class Enchantment implements Keyed { /** * Provides protection against environmental damage */ - public static final Enchantment PROTECTION_ENVIRONMENTAL = new EnchantmentWrapper("protection"); + public static final Enchantment PROTECTION_ENVIRONMENTAL = getEnchantment("protection"); /** * Provides protection against fire damage */ - public static final Enchantment PROTECTION_FIRE = new EnchantmentWrapper("fire_protection"); + public static final Enchantment PROTECTION_FIRE = getEnchantment("fire_protection"); /** * Provides protection against fall damage */ - public static final Enchantment PROTECTION_FALL = new EnchantmentWrapper("feather_falling"); + public static final Enchantment PROTECTION_FALL = getEnchantment("feather_falling"); /** * Provides protection against explosive damage */ - public static final Enchantment PROTECTION_EXPLOSIONS = new EnchantmentWrapper("blast_protection"); + public static final Enchantment PROTECTION_EXPLOSIONS = getEnchantment("blast_protection"); /** * Provides protection against projectile damage */ - public static final Enchantment PROTECTION_PROJECTILE = new EnchantmentWrapper("projectile_protection"); + public static final Enchantment PROTECTION_PROJECTILE = getEnchantment("projectile_protection"); /** * Decreases the rate of air loss whilst underwater */ - public static final Enchantment OXYGEN = new EnchantmentWrapper("respiration"); + public static final Enchantment OXYGEN = getEnchantment("respiration"); /** * Increases the speed at which a player may mine underwater */ - public static final Enchantment WATER_WORKER = new EnchantmentWrapper("aqua_affinity"); + public static final Enchantment WATER_WORKER = getEnchantment("aqua_affinity"); /** * Damages the attacker */ - public static final Enchantment THORNS = new EnchantmentWrapper("thorns"); + public static final Enchantment THORNS = getEnchantment("thorns"); /** * Increases walking speed while in water */ - public static final Enchantment DEPTH_STRIDER = new EnchantmentWrapper("depth_strider"); + public static final Enchantment DEPTH_STRIDER = getEnchantment("depth_strider"); /** * Freezes any still water adjacent to ice / frost which player is walking on */ - public static final Enchantment FROST_WALKER = new EnchantmentWrapper("frost_walker"); + public static final Enchantment FROST_WALKER = getEnchantment("frost_walker"); /** * Item cannot be removed */ - public static final Enchantment BINDING_CURSE = new EnchantmentWrapper("binding_curse"); + public static final Enchantment BINDING_CURSE = getEnchantment("binding_curse"); /** * Increases damage against all targets */ - public static final Enchantment DAMAGE_ALL = new EnchantmentWrapper("sharpness"); + public static final Enchantment DAMAGE_ALL = getEnchantment("sharpness"); /** * Increases damage against undead targets */ - public static final Enchantment DAMAGE_UNDEAD = new EnchantmentWrapper("smite"); + public static final Enchantment DAMAGE_UNDEAD = getEnchantment("smite"); /** * Increases damage against arthropod targets */ - public static final Enchantment DAMAGE_ARTHROPODS = new EnchantmentWrapper("bane_of_arthropods"); + public static final Enchantment DAMAGE_ARTHROPODS = getEnchantment("bane_of_arthropods"); /** * All damage to other targets will knock them back when hit */ - public static final Enchantment KNOCKBACK = new EnchantmentWrapper("knockback"); + public static final Enchantment KNOCKBACK = getEnchantment("knockback"); /** * When attacking a target, has a chance to set them on fire */ - public static final Enchantment FIRE_ASPECT = new EnchantmentWrapper("fire_aspect"); + public static final Enchantment FIRE_ASPECT = getEnchantment("fire_aspect"); /** * Provides a chance of gaining extra loot when killing monsters */ - public static final Enchantment LOOT_BONUS_MOBS = new EnchantmentWrapper("looting"); + public static final Enchantment LOOT_BONUS_MOBS = getEnchantment("looting"); /** * Increases damage against targets when using a sweep attack */ - public static final Enchantment SWEEPING_EDGE = new EnchantmentWrapper("sweeping"); + public static final Enchantment SWEEPING_EDGE = getEnchantment("sweeping"); /** * Increases the rate at which you mine/dig */ - public static final Enchantment DIG_SPEED = new EnchantmentWrapper("efficiency"); + public static final Enchantment DIG_SPEED = getEnchantment("efficiency"); /** * Allows blocks to drop themselves instead of fragments (for example, * stone instead of cobblestone) */ - public static final Enchantment SILK_TOUCH = new EnchantmentWrapper("silk_touch"); + public static final Enchantment SILK_TOUCH = getEnchantment("silk_touch"); /** * Decreases the rate at which a tool looses durability */ - public static final Enchantment DURABILITY = new EnchantmentWrapper("unbreaking"); + public static final Enchantment DURABILITY = getEnchantment("unbreaking"); /** * Provides a chance of gaining extra loot when destroying blocks */ - public static final Enchantment LOOT_BONUS_BLOCKS = new EnchantmentWrapper("fortune"); + public static final Enchantment LOOT_BONUS_BLOCKS = getEnchantment("fortune"); /** * Provides extra damage when shooting arrows from bows */ - public static final Enchantment ARROW_DAMAGE = new EnchantmentWrapper("power"); + public static final Enchantment ARROW_DAMAGE = getEnchantment("power"); /** * Provides a knockback when an entity is hit by an arrow from a bow */ - public static final Enchantment ARROW_KNOCKBACK = new EnchantmentWrapper("punch"); + public static final Enchantment ARROW_KNOCKBACK = getEnchantment("punch"); /** * Sets entities on fire when hit by arrows shot from a bow */ - public static final Enchantment ARROW_FIRE = new EnchantmentWrapper("flame"); + public static final Enchantment ARROW_FIRE = getEnchantment("flame"); /** * Provides infinite arrows when shooting a bow */ - public static final Enchantment ARROW_INFINITE = new EnchantmentWrapper("infinity"); + public static final Enchantment ARROW_INFINITE = getEnchantment("infinity"); /** * Decreases odds of catching worthless junk */ - public static final Enchantment LUCK = new EnchantmentWrapper("luck_of_the_sea"); + public static final Enchantment LUCK = getEnchantment("luck_of_the_sea"); /** * Increases rate of fish biting your hook */ - public static final Enchantment LURE = new EnchantmentWrapper("lure"); + public static final Enchantment LURE = getEnchantment("lure"); /** * Causes a thrown trident to return to the player who threw it */ - public static final Enchantment LOYALTY = new EnchantmentWrapper("loyalty"); + public static final Enchantment LOYALTY = getEnchantment("loyalty"); /** * Deals more damage to mobs that live in the ocean */ - public static final Enchantment IMPALING = new EnchantmentWrapper("impaling"); + public static final Enchantment IMPALING = getEnchantment("impaling"); /** * When it is rainy, launches the player in the direction their trident is thrown */ - public static final Enchantment RIPTIDE = new EnchantmentWrapper("riptide"); + public static final Enchantment RIPTIDE = getEnchantment("riptide"); /** * Strikes lightning when a mob is hit with a trident if conditions are * stormy */ - public static final Enchantment CHANNELING = new EnchantmentWrapper("channeling"); + public static final Enchantment CHANNELING = getEnchantment("channeling"); /** * Shoot multiple arrows from crossbows */ - public static final Enchantment MULTISHOT = new EnchantmentWrapper("multishot"); + public static final Enchantment MULTISHOT = getEnchantment("multishot"); /** * Charges crossbows quickly */ - public static final Enchantment QUICK_CHARGE = new EnchantmentWrapper("quick_charge"); + public static final Enchantment QUICK_CHARGE = getEnchantment("quick_charge"); /** * Crossbow projectiles pierce entities */ - public static final Enchantment PIERCING = new EnchantmentWrapper("piercing"); + public static final Enchantment PIERCING = getEnchantment("piercing"); /** * Allows mending the item using experience orbs */ - public static final Enchantment MENDING = new EnchantmentWrapper("mending"); + public static final Enchantment MENDING = getEnchantment("mending"); /** * Item disappears instead of dropping */ - public static final Enchantment VANISHING_CURSE = new EnchantmentWrapper("vanishing_curse"); + public static final Enchantment VANISHING_CURSE = getEnchantment("vanishing_curse"); /** * Walk quicker on soul blocks */ - public static final Enchantment SOUL_SPEED = new EnchantmentWrapper("soul_speed"); + public static final Enchantment SOUL_SPEED = getEnchantment("soul_speed"); /** * Walk quicker while sneaking */ - public static final Enchantment SWIFT_SNEAK = new EnchantmentWrapper("swift_sneak"); - - private static final Map byKey = new HashMap(); - private static final Map byName = new HashMap(); - private static boolean acceptingNew = true; - private final NamespacedKey key; - - public Enchantment(@NotNull NamespacedKey key) { - this.key = key; - } + public static final Enchantment SWIFT_SNEAK = getEnchantment("swift_sneak"); @NotNull - @Override - public NamespacedKey getKey() { - return key; + private static Enchantment getEnchantment(@NotNull String key) { + NamespacedKey namespacedKey = NamespacedKey.minecraft(key); + Enchantment enchantment = Registry.ENCHANTMENT.get(namespacedKey); + + Preconditions.checkNotNull(enchantment, "No Enchantment found for %s. This is a bug.", namespacedKey); + + return enchantment; } /** @@ -300,75 +296,21 @@ public abstract class Enchantment implements Keyed { */ public abstract boolean canEnchantItem(@NotNull ItemStack item); - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (!(obj instanceof Enchantment)) { - return false; - } - final Enchantment other = (Enchantment) obj; - if (!this.key.equals(other.key)) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return key.hashCode(); - } - - @Override - public String toString() { - return "Enchantment[" + key + ", " + getName() + "]"; - } - - /** - * Registers an enchantment with the given ID and object. - *

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

- * Generally not to be used from within a plugin. - * - * @param type PotionType to register - */ - public static void registerPotionEffectType(@NotNull PotionEffectType type) { - if (byId[type.id] != null || byName.containsKey(type.getName().toLowerCase(java.util.Locale.ENGLISH)) || byKey.containsKey(type.key)) { - throw new IllegalArgumentException("Cannot set already-set type"); - } else if (!acceptingNew) { - throw new IllegalStateException( - "No longer accepting new potion effect types (can only be done by the server implementation)"); - } - - byId[type.id] = type; - byName.put(type.getName().toLowerCase(java.util.Locale.ENGLISH), type); - byKey.put(type.key, type); - } - - /** - * Stops accepting any effect type registrations. - */ - public static void stopAcceptingRegistrations() { - acceptingNew = false; - } - - /** - * Returns an array of all the registered {@link PotionEffectType}s. - * This array is not necessarily in any particular order. - * - * @return Array of types. + * @return an array of all known PotionEffectTypes. + * @deprecated use {@link Registry#iterator()}. */ @NotNull + @Deprecated public static PotionEffectType[] values() { - return Arrays.copyOfRange(byId, 1, byId.length); + return Lists.newArrayList(Registry.EFFECT).toArray(new PotionEffectType[0]); + } + + private static String convertLegacy(String from) { + if (from == null) { + return null; + } + + switch (from.toLowerCase()) { + case "slow": + return "slowness"; + case "fast_digging": + return "haste"; + case "slow_digging": + return "mining_fatigue"; + case "increase_damage": + return "strength"; + case "heal": + return "instant_health"; + case "harm": + return "instant_damage"; + case "jump": + return "jump_boost"; + case "confusion": + return "nausea"; + case "damage_resistance": + return "resistance"; + } + + return from; } } diff --git a/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java b/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java index 6994981b..a613debb 100644 --- a/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java +++ b/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java @@ -1,23 +1,13 @@ package org.bukkit.potion; -import org.bukkit.Color; -import org.bukkit.NamespacedKey; import org.jetbrains.annotations.NotNull; -public class PotionEffectTypeWrapper extends PotionEffectType { - protected PotionEffectTypeWrapper(int id, @NotNull String name) { - super(id, NamespacedKey.minecraft(name)); - } - - @Override - public double getDurationModifier() { - return getType().getDurationModifier(); - } - - @NotNull - @Override - public String getName() { - return getType().getName(); +/** + * @deprecated only for backwards compatibility, PotionEffectTypeWrapper is no longer used. + */ +@Deprecated +public abstract class PotionEffectTypeWrapper extends PotionEffectType { + protected PotionEffectTypeWrapper() { } /** @@ -27,17 +17,6 @@ public class PotionEffectTypeWrapper extends PotionEffectType { */ @NotNull public PotionEffectType getType() { - return PotionEffectType.getByKey(getKey()); - } - - @Override - public boolean isInstant() { - return getType().isInstant(); - } - - @NotNull - @Override - public Color getColor() { - return getType().getColor(); + return this; } } From adcf6347c520b143677b2380edfb228661facf0e Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 6 Dec 2023 04:03:59 +1100 Subject: [PATCH 15/22] Fix error in Crafter documentation --- src/main/java/org/bukkit/block/data/type/Crafter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/bukkit/block/data/type/Crafter.java b/src/main/java/org/bukkit/block/data/type/Crafter.java index bc29b8ae..282188ff 100644 --- a/src/main/java/org/bukkit/block/data/type/Crafter.java +++ b/src/main/java/org/bukkit/block/data/type/Crafter.java @@ -2,6 +2,7 @@ package org.bukkit.block.data.type; import org.bukkit.MinecraftExperimental; import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Powerable; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; From 68f5bb6a95aca01e9dcb0c9cfcc43ce945f7ae3a Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 6 Dec 2023 07:07:29 +1100 Subject: [PATCH 16/22] SPIGOT-7526: Add missing PlayerResourcePackStatusEvent statuses --- .../player/PlayerResourcePackStatusEvent.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java b/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java index b9819565..8ed6214e 100644 --- a/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java +++ b/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java @@ -60,6 +60,22 @@ public class PlayerResourcePackStatusEvent extends PlayerEvent { /** * The client accepted the pack and is beginning a download of it. */ - ACCEPTED; + ACCEPTED, + /** + * The client successfully downloaded the pack. + */ + DOWNLOADED, + /** + * The pack URL was invalid. + */ + INVALID_URL, + /** + * The client was unable to reload the pack. + */ + FAILED_RELOAD, + /** + * The pack was discarded by the client. + */ + DISCARDED; } } From d9c1eb83af46e61e089cb899a24a8cc0a66e625b Mon Sep 17 00:00:00 2001 From: Doc Date: Wed, 6 Dec 2023 07:09:16 +1100 Subject: [PATCH 17/22] Add additional @MinecraftExperimental annotations --- src/main/java/org/bukkit/Particle.java | 4 ++++ .../org/bukkit/generator/structure/Structure.java | 2 ++ src/main/java/org/bukkit/loot/LootTables.java | 11 +++++++++++ 3 files changed, 17 insertions(+) diff --git a/src/main/java/org/bukkit/Particle.java b/src/main/java/org/bukkit/Particle.java index e3c94a56..ca6d0eaa 100644 --- a/src/main/java/org/bukkit/Particle.java +++ b/src/main/java/org/bukkit/Particle.java @@ -133,9 +133,13 @@ public enum Particle implements Keyed { EGG_CRACK("egg_crack"), DUST_PLUME("dust_plume"), WHITE_SMOKE("white_smoke"), + @MinecraftExperimental GUST("gust"), + @MinecraftExperimental GUST_EMITTER("gust_emitter"), + @MinecraftExperimental GUST_DUST("gust_dust"), + @MinecraftExperimental TRIAL_SPAWNER_DETECTION("trial_spawner_detection"), /** * Uses {@link BlockData} as DataType diff --git a/src/main/java/org/bukkit/generator/structure/Structure.java b/src/main/java/org/bukkit/generator/structure/Structure.java index 1a766e68..65d3d8fd 100644 --- a/src/main/java/org/bukkit/generator/structure/Structure.java +++ b/src/main/java/org/bukkit/generator/structure/Structure.java @@ -1,6 +1,7 @@ package org.bukkit.generator.structure; import org.bukkit.Keyed; +import org.bukkit.MinecraftExperimental; import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.jetbrains.annotations.NotNull; @@ -47,6 +48,7 @@ public abstract class Structure implements Keyed { public static final Structure RUINED_PORTAL_NETHER = getStructure("ruined_portal_nether"); public static final Structure ANCIENT_CITY = getStructure("ancient_city"); public static final Structure TRAIL_RUINS = getStructure("trail_ruins"); + @MinecraftExperimental public static final Structure TRIAL_CHAMBERS = getStructure("trial_chambers"); private static Structure getStructure(String name) { diff --git a/src/main/java/org/bukkit/loot/LootTables.java b/src/main/java/org/bukkit/loot/LootTables.java index ddf71b0e..d8721444 100644 --- a/src/main/java/org/bukkit/loot/LootTables.java +++ b/src/main/java/org/bukkit/loot/LootTables.java @@ -2,6 +2,7 @@ package org.bukkit.loot; import org.bukkit.Bukkit; import org.bukkit.Keyed; +import org.bukkit.MinecraftExperimental; import org.bukkit.NamespacedKey; import org.jetbrains.annotations.NotNull; @@ -33,15 +34,25 @@ public enum LootTables implements Keyed { ANCIENT_CITY("chests/ancient_city"), ANCIENT_CITY_ICE_BOX("chests/ancient_city_ice_box"), RUINED_PORTAL("chests/ruined_portal"), + @MinecraftExperimental TRIAL_CHAMBERS_REWARD("chests/trial_chambers/reward"), + @MinecraftExperimental TRIAL_CHAMBERS_SUPPLY("chests/trial_chambers/supply"), + @MinecraftExperimental TRIAL_CHAMBERS_CORRIDOR("chests/trial_chambers/corridor"), + @MinecraftExperimental TRIAL_CHAMBERS_INTERSECTION("chests/trial_chambers/intersection"), + @MinecraftExperimental TRIAL_CHAMBERS_INTERSECTION_BARREL("chests/trial_chambers/intersection_barrel"), + @MinecraftExperimental TRIAL_CHAMBERS_ENTRANCE("chests/trial_chambers/entrance"), + @MinecraftExperimental TRIAL_CHAMBERS_CORRIDOR_DISPENSER("dispensers/trial_chambers/corridor"), + @MinecraftExperimental TRIAL_CHAMBERS_CHAMBER_DISPENSER("dispensers/trial_chambers/chamber"), + @MinecraftExperimental TRIAL_CHAMBERS_WATER_DISPENSER("dispensers/trial_chambers/water"), + @MinecraftExperimental TRIAL_CHAMBERS_CORRIDOR_POT("pots/trial_chambers/corridor"), SHIPWRECK_MAP("chests/shipwreck_map"), SHIPWRECK_SUPPLY("chests/shipwreck_supply"), From be2884c416f47ce1fbec697d0aeac7edb85a3c05 Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 6 Dec 2023 20:27:57 +1100 Subject: [PATCH 18/22] Add unique ID to PlayerResourcePackStatusEvent --- .../player/PlayerResourcePackStatusEvent.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java b/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java index 8ed6214e..e2c4f9a0 100644 --- a/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java +++ b/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java @@ -1,5 +1,6 @@ package org.bukkit.event.player; +import java.util.UUID; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; @@ -11,13 +12,25 @@ import org.jetbrains.annotations.NotNull; public class PlayerResourcePackStatusEvent extends PlayerEvent { private static final HandlerList handlers = new HandlerList(); + private final UUID id; private final Status status; - public PlayerResourcePackStatusEvent(@NotNull final Player who, @NotNull Status resourcePackStatus) { + public PlayerResourcePackStatusEvent(@NotNull final Player who, @NotNull UUID id, @NotNull Status resourcePackStatus) { super(who); + this.id = id; this.status = resourcePackStatus; } + /** + * Gets the unique ID of this pack. + * + * @return unique resource pack ID. + */ + @NotNull + public UUID getID() { + return id; + } + /** * Gets the status of this pack. * From 9a294519b082385a41711eed78797c6b7f3c2476 Mon Sep 17 00:00:00 2001 From: Doc Date: Thu, 7 Dec 2023 08:21:27 +1100 Subject: [PATCH 19/22] SPIGOT-7533, 943: Add missing Poses for 1.20.3 --- src/main/java/org/bukkit/entity/Pose.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/bukkit/entity/Pose.java b/src/main/java/org/bukkit/entity/Pose.java index 5122194a..d5e33844 100644 --- a/src/main/java/org/bukkit/entity/Pose.java +++ b/src/main/java/org/bukkit/entity/Pose.java @@ -65,5 +65,17 @@ public enum Pose { /** * Entity is digging. */ - DIGGING; + DIGGING, + /** + * Entity is sliding. + */ + SLIDING, + /** + * Entity is shooting. + */ + SHOOTING, + /** + * Entity is inhaling. + */ + INHALING; } From cdfe62e472085016a8225f356eec9efede9d8b5a Mon Sep 17 00:00:00 2001 From: md_5 Date: Fri, 8 Dec 2023 07:00:00 +1100 Subject: [PATCH 20/22] Update to Minecraft 1.20.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0e37cf72..cada2a07 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.bukkit bukkit - 1.20.3-R0.1-SNAPSHOT + 1.20.4-R0.1-SNAPSHOT jar Bukkit From bc145b90073ea67d5e7b85493ba8081aa2c6ecdc Mon Sep 17 00:00:00 2001 From: Jishuna Date: Fri, 8 Dec 2023 19:24:14 +1100 Subject: [PATCH 21/22] #940: Create registry for banner pattern and cat type --- src/main/java/org/bukkit/Registry.java | 14 +++ .../org/bukkit/block/banner/PatternType.java | 105 ++++++++++-------- src/main/java/org/bukkit/entity/Cat.java | 38 +++++-- 3 files changed, 101 insertions(+), 56 deletions(-) diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java index 3be42143..64551632 100644 --- a/src/main/java/org/bukkit/Registry.java +++ b/src/main/java/org/bukkit/Registry.java @@ -12,8 +12,10 @@ import java.util.stream.StreamSupport; import org.bukkit.advancement.Advancement; import org.bukkit.attribute.Attribute; import org.bukkit.block.Biome; +import org.bukkit.block.banner.PatternType; import org.bukkit.boss.KeyedBossBar; import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Cat; import org.bukkit.entity.EntityType; import org.bukkit.entity.Frog; import org.bukkit.entity.Villager; @@ -75,6 +77,12 @@ public interface Registry extends Iterable { * @see Attribute */ Registry ATTRIBUTE = new SimpleRegistry<>(Attribute.class); + /** + * Server banner patterns. + * + * @see PatternType + */ + Registry BANNER_PATTERN = new SimpleRegistry<>(PatternType.class); /** * Server biomes. * @@ -107,6 +115,12 @@ public interface Registry extends Iterable { return Bukkit.getBossBars(); } }; + /** + * Server cat types. + * + * @see Cat.Type + */ + Registry CAT_VARIANT = new SimpleRegistry<>(Cat.Type.class); /** * Server enchantments. * diff --git a/src/main/java/org/bukkit/block/banner/PatternType.java b/src/main/java/org/bukkit/block/banner/PatternType.java index e6ce94ed..1c5c6303 100644 --- a/src/main/java/org/bukkit/block/banner/PatternType.java +++ b/src/main/java/org/bukkit/block/banner/PatternType.java @@ -2,54 +2,58 @@ package org.bukkit.block.banner; import java.util.HashMap; import java.util.Map; +import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public enum PatternType { - BASE("b"), - SQUARE_BOTTOM_LEFT("bl"), - SQUARE_BOTTOM_RIGHT("br"), - SQUARE_TOP_LEFT("tl"), - SQUARE_TOP_RIGHT("tr"), - STRIPE_BOTTOM("bs"), - STRIPE_TOP("ts"), - STRIPE_LEFT("ls"), - STRIPE_RIGHT("rs"), - STRIPE_CENTER("cs"), - STRIPE_MIDDLE("ms"), - STRIPE_DOWNRIGHT("drs"), - STRIPE_DOWNLEFT("dls"), - STRIPE_SMALL("ss"), - CROSS("cr"), - STRAIGHT_CROSS("sc"), - TRIANGLE_BOTTOM("bt"), - TRIANGLE_TOP("tt"), - TRIANGLES_BOTTOM("bts"), - TRIANGLES_TOP("tts"), - DIAGONAL_LEFT("ld"), - DIAGONAL_RIGHT("rd"), - DIAGONAL_LEFT_MIRROR("lud"), - DIAGONAL_RIGHT_MIRROR("rud"), - CIRCLE_MIDDLE("mc"), - RHOMBUS_MIDDLE("mr"), - HALF_VERTICAL("vh"), - HALF_HORIZONTAL("hh"), - HALF_VERTICAL_MIRROR("vhr"), - HALF_HORIZONTAL_MIRROR("hhb"), - BORDER("bo"), - CURLY_BORDER("cbo"), - CREEPER("cre"), - GRADIENT("gra"), - GRADIENT_UP("gru"), - BRICKS("bri"), - SKULL("sku"), - FLOWER("flo"), - MOJANG("moj"), - GLOBE("glb"), - PIGLIN("pig"); +public enum PatternType implements Keyed { + BASE("b", "base"), + SQUARE_BOTTOM_LEFT("bl", "square_bottom_left"), + SQUARE_BOTTOM_RIGHT("br", "square_bottom_right"), + SQUARE_TOP_LEFT("tl", "square_top_left"), + SQUARE_TOP_RIGHT("tr", "square_top_right"), + STRIPE_BOTTOM("bs", "stripe_bottom"), + STRIPE_TOP("ts", "stripe_top"), + STRIPE_LEFT("ls", "stripe_left"), + STRIPE_RIGHT("rs", "stripe_right"), + STRIPE_CENTER("cs", "stripe_center"), + STRIPE_MIDDLE("ms", "stripe_middle"), + STRIPE_DOWNRIGHT("drs", "stripe_downright"), + STRIPE_DOWNLEFT("dls", "stripe_downleft"), + STRIPE_SMALL("ss", "small_stripes"), + CROSS("cr", "cross"), + STRAIGHT_CROSS("sc", "straight_cross"), + TRIANGLE_BOTTOM("bt", "triangle_bottom"), + TRIANGLE_TOP("tt", "triangle_top"), + TRIANGLES_BOTTOM("bts", "triangles_bottom"), + TRIANGLES_TOP("tts", "triangles_top"), + DIAGONAL_LEFT("ld", "diagonal_left"), + DIAGONAL_RIGHT("rd", "diagonal_up_right"), //PAIL - Why are these keys swapped? + DIAGONAL_LEFT_MIRROR("lud", "diagonal_up_left"), + DIAGONAL_RIGHT_MIRROR("rud", "diagonal_right"), //PAIL - Why are these keys swapped? + CIRCLE_MIDDLE("mc", "circle"), + RHOMBUS_MIDDLE("mr", "rhombus"), + HALF_VERTICAL("vh", "half_vertical"), + HALF_HORIZONTAL("hh", "half_horizontal"), + HALF_VERTICAL_MIRROR("vhr", "half_vertical_right"), + HALF_HORIZONTAL_MIRROR("hhb", "half_horizontal_bottom"), + BORDER("bo", "border"), + CURLY_BORDER("cbo", "curly_border"), + CREEPER("cre", "creeper"), + GRADIENT("gra", "gradient"), + GRADIENT_UP("gru", "gradient_up"), + BRICKS("bri", "bricks"), + SKULL("sku", "skull"), + FLOWER("flo", "flower"), + MOJANG("moj", "mojang"), + GLOBE("glb", "globe"), + PIGLIN("pig", "piglin"); private final String identifier; + private final NamespacedKey key; private static final Map byString = new HashMap(); static { @@ -58,8 +62,15 @@ public enum PatternType { } } - private PatternType(/*@NotNull*/ String key) { - this.identifier = key; + private PatternType(/*@NotNull*/ String identifier, String key) { + this.identifier = identifier; + this.key = NamespacedKey.minecraft(key); + } + + @Override + @NotNull + public NamespacedKey getKey() { + return key; } /** @@ -67,8 +78,11 @@ public enum PatternType { * this pattern type * * @return the pattern's identifier + * @see #getKey + * @deprecated magic value */ @NotNull + @Deprecated public String getIdentifier() { return identifier; } @@ -79,9 +93,12 @@ public enum PatternType { * * @param identifier the identifier * @return the matched pattern type or null + * @see Registry#BANNER_PATTERN + * @deprecated magic value, use {@link Registry#get(NamespacedKey)} instead */ @Contract("null -> null") @Nullable + @Deprecated public static PatternType getByIdentifier(@Nullable String identifier) { return byString.get(identifier); } diff --git a/src/main/java/org/bukkit/entity/Cat.java b/src/main/java/org/bukkit/entity/Cat.java index c2a566b8..d1327761 100644 --- a/src/main/java/org/bukkit/entity/Cat.java +++ b/src/main/java/org/bukkit/entity/Cat.java @@ -1,6 +1,8 @@ package org.bukkit.entity; import org.bukkit.DyeColor; +import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; import org.jetbrains.annotations.NotNull; /** @@ -41,17 +43,29 @@ public interface Cat extends Tameable, Sittable { /** * Represents the various different cat types there are. */ - public enum Type { - TABBY, - BLACK, - RED, - SIAMESE, - BRITISH_SHORTHAIR, - CALICO, - PERSIAN, - RAGDOLL, - WHITE, - JELLIE, - ALL_BLACK; + public enum Type implements Keyed { + TABBY("tabby"), + BLACK("black"), + RED("red"), + SIAMESE("siamese"), + BRITISH_SHORTHAIR("british_shorthair"), + CALICO("calico"), + PERSIAN("persian"), + RAGDOLL("ragdoll"), + WHITE("white"), + JELLIE("jellie"), + ALL_BLACK("all_black"); + + private final NamespacedKey key; + + private Type(String key) { + this.key = NamespacedKey.minecraft(key); + } + + @Override + @NotNull + public NamespacedKey getKey() { + return key; + } } } From 01bb6ba7d0add97af46db9ae8c2c991912033aa7 Mon Sep 17 00:00:00 2001 From: Jishuna Date: Fri, 8 Dec 2023 19:29:36 +1100 Subject: [PATCH 22/22] #936: Add new PersistentDataContainer methods and clean up docs --- .../persistence/PersistentDataContainer.java | 83 +++++++++++++------ 1 file changed, 58 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/bukkit/persistence/PersistentDataContainer.java b/src/main/java/org/bukkit/persistence/PersistentDataContainer.java index bf2a957b..6c156faf 100644 --- a/src/main/java/org/bukkit/persistence/PersistentDataContainer.java +++ b/src/main/java/org/bukkit/persistence/PersistentDataContainer.java @@ -21,15 +21,15 @@ public interface PersistentDataContainer { * * @param key the key this value will be stored under * @param type the type this tag uses - * @param value the value stored in the tag + * @param value the value to store in the tag * @param the generic java type of the tag value * @param the generic type of the object to store * - * @throws NullPointerException if the key is null - * @throws NullPointerException if the type is null - * @throws NullPointerException if the value is null. Removing a tag should + * @throws IllegalArgumentException if the key is null + * @throws IllegalArgumentException if the type is null + * @throws IllegalArgumentException if the value is null. Removing a tag should * be done using {@link #remove(NamespacedKey)} - * @throws IllegalArgumentException if no suitable adapter will be found for + * @throws IllegalArgumentException if no suitable adapter was found for * the {@link PersistentDataType#getPrimitiveType()} */ void set(@NotNull NamespacedKey key, @NotNull PersistentDataType type, @NotNull Z value); @@ -38,7 +38,7 @@ public interface PersistentDataContainer { * Returns if the persistent metadata provider has metadata registered * matching the provided parameters. *

- * This method will only return if the found value has the same primitive + * This method will only return true if the found value has the same primitive * data type as the provided key. *

* Storing a value using a custom {@link PersistentDataType} implementation @@ -49,22 +49,41 @@ public interface PersistentDataContainer { * bytes long. *

* This method is only usable for custom object keys. Overwriting existing - * tags, like the the display name, will not work as the values are stored + * tags, like the display name, will not work as the values are stored * using your namespace. * * @param key the key the value is stored under - * @param type the type which primitive storage type has to match the value + * @param type the type the primative stored value has to match * @param the generic type of the stored primitive * @param the generic type of the eventually created complex object * - * @return if a value + * @return if a value with the provided key and type exists * - * @throws NullPointerException if the key to look up is null - * @throws NullPointerException if the type to cast the found object to is + * @throws IllegalArgumentException if the key to look up is null + * @throws IllegalArgumentException if the type to cast the found object to is * null */ boolean has(@NotNull NamespacedKey key, @NotNull PersistentDataType type); + /** + * Returns if the persistent metadata provider has metadata registered matching + * the provided parameters. + *

+ * This method will return true as long as a value with the given key exists, + * regardless of its type. + *

+ * This method is only usable for custom object keys. Overwriting existing tags, + * like the display name, will not work as the values are stored using your + * namespace. + * + * @param key the key the value is stored under + * + * @return if a value with the provided key exists + * + * @throws IllegalArgumentException if the key to look up is null + */ + boolean has(@NotNull NamespacedKey key); + /** * Returns the metadata value that is stored on the * {@link PersistentDataHolder} instance. @@ -77,12 +96,12 @@ public interface PersistentDataContainer { * @return the value or {@code null} if no value was mapped under the given * value * - * @throws NullPointerException if the key to look up is null - * @throws NullPointerException if the type to cast the found object to is + * @throws IllegalArgumentException if the key to look up is null + * @throws IllegalArgumentException if the type to cast the found object to is * null - * @throws IllegalArgumentException if the value exists under the given key, - * but cannot be access using the given type - * @throws IllegalArgumentException if no suitable adapter will be found for + * @throws IllegalArgumentException if a value exists under the given key, + * but cannot be accessed using the given type + * @throws IllegalArgumentException if no suitable adapter was found for * the {@link * PersistentDataType#getPrimitiveType()} */ @@ -102,21 +121,21 @@ public interface PersistentDataContainer { * @param the generic type of the eventually created complex object * * @return the value or the default value if no value was mapped under the - * given value + * given key * - * @throws NullPointerException if the key to look up is null - * @throws NullPointerException if the type to cast the found object to is + * @throws IllegalArgumentException if the key to look up is null + * @throws IllegalArgumentException if the type to cast the found object to is * null - * @throws IllegalArgumentException if the value exists under the given key, - * but cannot be access using the given type - * @throws IllegalArgumentException if no suitable adapter will be found for + * @throws IllegalArgumentException if a value exists under the given key, + * but cannot be accessed using the given type + * @throws IllegalArgumentException if no suitable adapter was found for * the {@link PersistentDataType#getPrimitiveType()} */ @NotNull Z getOrDefault(@NotNull NamespacedKey key, @NotNull PersistentDataType type, @NotNull Z defaultValue); /** - * Get a set of keys present on this {@link PersistentDataContainer} + * Get the set of keys present on this {@link PersistentDataContainer} * instance. * * Any changes made to the returned set will not be reflected on the @@ -130,9 +149,9 @@ public interface PersistentDataContainer { /** * Removes a custom key from the {@link PersistentDataHolder} instance. * - * @param key the key + * @param key the key to remove * - * @throws NullPointerException if the provided key is null + * @throws IllegalArgumentException if the provided key is null */ void remove(@NotNull NamespacedKey key); @@ -144,6 +163,20 @@ public interface PersistentDataContainer { */ boolean isEmpty(); + /** + * Copies all values from this {@link PersistentDataContainer} to the provided + * container. + *

+ * This method only copies custom object keys. Existing tags, like the display + * name, will not be copied as the values are stored using your namespace. + * + * @param other the container to copy to + * @param replace whether to replace any matching values in the target container + * + * @throws IllegalArgumentException if the other container is null + */ + void copyTo(@NotNull PersistentDataContainer other, boolean replace); + /** * Returns the adapter context this tag container uses. *