Add EntityEquipmentChangedEvent (#12011)
This commit is contained in:
@ -5,6 +5,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
import org.bukkit.event.player.PlayerEvent;
|
import org.bukkit.event.player.PlayerEvent;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jspecify.annotations.NullMarked;
|
import org.jspecify.annotations.NullMarked;
|
||||||
@ -16,8 +17,10 @@ import static org.bukkit.Material.*;
|
|||||||
* Called when the player themselves change their armor items
|
* Called when the player themselves change their armor items
|
||||||
* <p>
|
* <p>
|
||||||
* Not currently called for environmental factors though it <strong>MAY BE IN THE FUTURE</strong>
|
* Not currently called for environmental factors though it <strong>MAY BE IN THE FUTURE</strong>
|
||||||
|
* @apiNote Use {@link io.papermc.paper.event.entity.EntityEquipmentChangedEvent} for all entity equipment changes
|
||||||
*/
|
*/
|
||||||
@NullMarked
|
@NullMarked
|
||||||
|
@ApiStatus.Obsolete(since = "1.21.4")
|
||||||
public class PlayerArmorChangeEvent extends PlayerEvent {
|
public class PlayerArmorChangeEvent extends PlayerEvent {
|
||||||
|
|
||||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
@ -38,11 +41,27 @@ public class PlayerArmorChangeEvent extends PlayerEvent {
|
|||||||
* Gets the type of slot being altered.
|
* Gets the type of slot being altered.
|
||||||
*
|
*
|
||||||
* @return type of slot being altered
|
* @return type of slot being altered
|
||||||
|
* @deprecated {@link SlotType} does not accurately represent what item types are valid in each slot. Use {@link #getSlot()} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "1.21.4")
|
||||||
public SlotType getSlotType() {
|
public SlotType getSlotType() {
|
||||||
return this.slotType;
|
return this.slotType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the slot being altered.
|
||||||
|
*
|
||||||
|
* @return slot being altered
|
||||||
|
*/
|
||||||
|
public EquipmentSlot getSlot() {
|
||||||
|
return switch (this.slotType) {
|
||||||
|
case HEAD -> EquipmentSlot.HEAD;
|
||||||
|
case CHEST -> EquipmentSlot.CHEST;
|
||||||
|
case LEGS -> EquipmentSlot.LEGS;
|
||||||
|
case FEET -> EquipmentSlot.FEET;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the existing item that's being replaced
|
* Gets the existing item that's being replaced
|
||||||
*
|
*
|
||||||
@ -70,6 +89,10 @@ public class PlayerArmorChangeEvent extends PlayerEvent {
|
|||||||
return HANDLER_LIST;
|
return HANDLER_LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated {@link SlotType} does not accurately represent what item types are valid in each slot.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "1.21.4")
|
||||||
public enum SlotType {
|
public enum SlotType {
|
||||||
HEAD(NETHERITE_HELMET, DIAMOND_HELMET, GOLDEN_HELMET, IRON_HELMET, CHAINMAIL_HELMET, LEATHER_HELMET, CARVED_PUMPKIN, PLAYER_HEAD, SKELETON_SKULL, ZOMBIE_HEAD, CREEPER_HEAD, WITHER_SKELETON_SKULL, TURTLE_HELMET, DRAGON_HEAD, PIGLIN_HEAD),
|
HEAD(NETHERITE_HELMET, DIAMOND_HELMET, GOLDEN_HELMET, IRON_HELMET, CHAINMAIL_HELMET, LEATHER_HELMET, CARVED_PUMPKIN, PLAYER_HEAD, SKELETON_SKULL, ZOMBIE_HEAD, CREEPER_HEAD, WITHER_SKELETON_SKULL, TURTLE_HELMET, DRAGON_HEAD, PIGLIN_HEAD),
|
||||||
CHEST(NETHERITE_CHESTPLATE, DIAMOND_CHESTPLATE, GOLDEN_CHESTPLATE, IRON_CHESTPLATE, CHAINMAIL_CHESTPLATE, LEATHER_CHESTPLATE, ELYTRA),
|
CHEST(NETHERITE_CHESTPLATE, DIAMOND_CHESTPLATE, GOLDEN_CHESTPLATE, IRON_CHESTPLATE, CHAINMAIL_CHESTPLATE, LEATHER_CHESTPLATE, ELYTRA),
|
||||||
|
|||||||
@ -0,0 +1,89 @@
|
|||||||
|
package io.papermc.paper.event.entity;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.entity.EntityEvent;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called whenever a change to an entity's equipment has been detected. This event is called after effects from
|
||||||
|
* attribute modifiers and enchantments have been updated.
|
||||||
|
* <p>
|
||||||
|
* Examples of actions that can trigger this event:
|
||||||
|
* <ul>
|
||||||
|
* <li>An entity being added to a world.</li>
|
||||||
|
* <li>A player logging in.</li>
|
||||||
|
* <li>The durability of an equipment item changing.</li>
|
||||||
|
* <li>A dispenser equipping an item onto an entity.</li>
|
||||||
|
* <li>An entity picking up an armor or weapon item from the ground.</li>
|
||||||
|
* <li>A player changing their equipped armor.</li>
|
||||||
|
* <li>A player changes their currently held item.</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
public class EntityEquipmentChangedEvent extends EntityEvent {
|
||||||
|
|
||||||
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
|
||||||
|
private final Map<EquipmentSlot, EquipmentChange> equipmentChanges;
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public EntityEquipmentChangedEvent(final LivingEntity entity, final Map<EquipmentSlot, EquipmentChange> equipmentChanges) {
|
||||||
|
super(entity);
|
||||||
|
|
||||||
|
this.equipmentChanges = equipmentChanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LivingEntity getEntity() {
|
||||||
|
return (LivingEntity) this.entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a map of changed slots to their respective equipment changes.
|
||||||
|
*
|
||||||
|
* @return the equipment changes map
|
||||||
|
*/
|
||||||
|
public @Unmodifiable Map<EquipmentSlot, EquipmentChange> getEquipmentChanges() {
|
||||||
|
return Collections.unmodifiableMap(this.equipmentChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return HANDLER_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return HANDLER_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a change in equipment for a single equipment slot.
|
||||||
|
*/
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
public interface EquipmentChange {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the existing item that is being replaced.
|
||||||
|
*
|
||||||
|
* @return the existing item
|
||||||
|
*/
|
||||||
|
@Contract(pure = true, value = "-> new")
|
||||||
|
ItemStack oldItem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the new item that is replacing the existing item.
|
||||||
|
*
|
||||||
|
* @return the new item
|
||||||
|
*/
|
||||||
|
@Contract(pure = true, value = "-> new")
|
||||||
|
ItemStack newItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1336,20 +1336,57 @@
|
|||||||
Map<EquipmentSlot, ItemStack> map = this.collectEquipmentChanges();
|
Map<EquipmentSlot, ItemStack> map = this.collectEquipmentChanges();
|
||||||
if (map != null) {
|
if (map != null) {
|
||||||
this.handleHandSwap(map);
|
this.handleHandSwap(map);
|
||||||
@@ -2595,6 +_,13 @@
|
@@ -2586,6 +_,20 @@
|
||||||
|
@Nullable
|
||||||
|
private Map<EquipmentSlot, ItemStack> collectEquipmentChanges() {
|
||||||
|
Map<EquipmentSlot, ItemStack> map = null;
|
||||||
|
+ // Paper start - EntityEquipmentChangedEvent
|
||||||
|
+ record EquipmentChangeImpl(org.bukkit.inventory.ItemStack oldItem, org.bukkit.inventory.ItemStack newItem) implements io.papermc.paper.event.entity.EntityEquipmentChangedEvent.EquipmentChange {
|
||||||
|
+ @Override
|
||||||
|
+ public org.bukkit.inventory.ItemStack oldItem() {
|
||||||
|
+ return this.oldItem.clone();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public org.bukkit.inventory.ItemStack newItem() {
|
||||||
|
+ return this.newItem.clone();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ Map<org.bukkit.inventory.EquipmentSlot, io.papermc.paper.event.entity.EntityEquipmentChangedEvent.EquipmentChange> equipmentChanges = null;
|
||||||
|
+ // Paper end - EntityEquipmentChangedEvent
|
||||||
|
|
||||||
|
for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
|
||||||
|
ItemStack itemStack = switch (equipmentSlot.getType()) {
|
||||||
|
@@ -2595,11 +_,20 @@
|
||||||
};
|
};
|
||||||
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
|
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
|
||||||
if (this.equipmentHasChanged(itemStack, itemBySlot)) {
|
if (this.equipmentHasChanged(itemStack, itemBySlot)) {
|
||||||
+ // Paper start - PlayerArmorChangeEvent
|
+ // Paper start - EntityEquipmentChangedEvent, PlayerArmorChangeEvent
|
||||||
|
+ final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemStack);
|
||||||
|
+ final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemBySlot);
|
||||||
+ if (this instanceof ServerPlayer && equipmentSlot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) {
|
+ if (this instanceof ServerPlayer && equipmentSlot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) {
|
||||||
+ final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemStack);
|
|
||||||
+ final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemBySlot);
|
|
||||||
+ new com.destroystokyo.paper.event.player.PlayerArmorChangeEvent((org.bukkit.entity.Player) this.getBukkitEntity(), com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType.valueOf(equipmentSlot.name()), oldItem, newItem).callEvent();
|
+ new com.destroystokyo.paper.event.player.PlayerArmorChangeEvent((org.bukkit.entity.Player) this.getBukkitEntity(), com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType.valueOf(equipmentSlot.name()), oldItem, newItem).callEvent();
|
||||||
+ }
|
+ }
|
||||||
+ // Paper end - PlayerArmorChangeEvent
|
+ // Paper end - EntityEquipmentChangedEvent, PlayerArmorChangeEvent
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
map = Maps.newEnumMap(EquipmentSlot.class);
|
map = Maps.newEnumMap(EquipmentSlot.class);
|
||||||
|
+ equipmentChanges = Maps.newEnumMap(org.bukkit.inventory.EquipmentSlot.class); // Paper - EntityEquipmentChangedEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
map.put(equipmentSlot, itemBySlot);
|
||||||
|
+ equipmentChanges.put(org.bukkit.craftbukkit.CraftEquipmentSlot.getSlot(equipmentSlot), new EquipmentChangeImpl(oldItem, newItem)); // Paper - EntityEquipmentChangedEvent
|
||||||
|
AttributeMap attributes = this.getAttributes();
|
||||||
|
if (!itemStack.isEmpty()) {
|
||||||
|
this.stopLocationBasedEffects(itemStack, equipmentSlot, attributes);
|
||||||
|
@@ -2624,6 +_,8 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ new io.papermc.paper.event.entity.EntityEquipmentChangedEvent(this.getBukkitLivingEntity(), equipmentChanges).callEvent(); // Paper - EntityEquipmentChangedEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
@@ -2664,7 +_,7 @@
|
@@ -2664,7 +_,7 @@
|
||||||
this.lastBodyItemStack = itemStack;
|
this.lastBodyItemStack = itemStack;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user