1
0
Fork 0
mirror of https://github.com/PaperMC/Paper.git synced 2025-03-31 03:38:13 +02:00

Add EntityEquipmentChangedEvent ()

This commit is contained in:
TonytheMacaroni 2025-02-16 14:46:59 -05:00 committed by GitHub
parent a3781ff3be
commit 2a4a115432
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 154 additions and 5 deletions
paper-api/src/main/java
com/destroystokyo/paper/event/player
io/papermc/paper/event/entity
paper-server/patches/sources/net/minecraft/world/entity

View file

@ -5,6 +5,7 @@ import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@ -16,8 +17,10 @@ import static org.bukkit.Material.*;
* Called when the player themselves change their armor items
* <p>
* 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
@ApiStatus.Obsolete(since = "1.21.4")
public class PlayerArmorChangeEvent extends PlayerEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
@ -38,11 +41,27 @@ public class PlayerArmorChangeEvent extends PlayerEvent {
* Gets the 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() {
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
*
@ -70,6 +89,10 @@ public class PlayerArmorChangeEvent extends PlayerEvent {
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 {
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),

View file

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

View file

@ -1336,20 +1336,57 @@
Map<EquipmentSlot, ItemStack> map = this.collectEquipmentChanges();
if (map != null) {
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);
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) {
+ 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();
+ }
+ // Paper end - PlayerArmorChangeEvent
+ // Paper end - EntityEquipmentChangedEvent, PlayerArmorChangeEvent
if (map == null) {
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 @@
this.lastBodyItemStack = itemStack;
}