Skip to content

Commit 9e163a4

Browse files
Add EntityEquipmentChangedEvent
1 parent cafef9c commit 9e163a4

File tree

2 files changed

+106
-5
lines changed

2 files changed

+106
-5
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package io.papermc.paper.event.entity;
2+
3+
import java.util.Collections;
4+
import java.util.Map;
5+
import org.bukkit.entity.LivingEntity;
6+
import org.bukkit.event.HandlerList;
7+
import org.bukkit.event.entity.EntityEvent;
8+
import org.bukkit.inventory.EquipmentSlot;
9+
import org.bukkit.inventory.ItemStack;
10+
import org.jetbrains.annotations.ApiStatus;
11+
import org.jetbrains.annotations.Unmodifiable;
12+
import org.jspecify.annotations.NullMarked;
13+
14+
/**
15+
* Called whenever a change to an entity's equipment has been detected. This event is called after effects from
16+
* attribute modifiers and enchantments have been updated.
17+
* <p>
18+
* Examples of actions that can trigger this event:
19+
* <ul>
20+
* <li>An entity being added to a world.</li>
21+
* <li>A player logging in.</li>
22+
* <li>The durability of an equipment item changing.</li>
23+
* <li>A dispenser equipping an item onto an entity.</li>
24+
* <li>An entity picking up an armor or weapon item from the ground.</li>
25+
* <li>A player changing their equipped armor.</li>
26+
* <li>A player changes their currently held item.</li>
27+
* </ul>
28+
*/
29+
@NullMarked
30+
public class EntityEquipmentChangedEvent extends EntityEvent {
31+
32+
private static final HandlerList HANDLER_LIST = new HandlerList();
33+
34+
private final Map<EquipmentSlot, EquipmentChange> equipmentChanges;
35+
36+
@ApiStatus.Internal
37+
public EntityEquipmentChangedEvent(final LivingEntity entity, final Map<EquipmentSlot, EquipmentChange> equipmentChanges) {
38+
super(entity);
39+
40+
this.equipmentChanges = Collections.unmodifiableMap(equipmentChanges);
41+
}
42+
43+
@Override
44+
public LivingEntity getEntity() {
45+
return (LivingEntity) entity;
46+
}
47+
48+
/**
49+
* Gets a map of changed slots to their respective equipment changes.
50+
*
51+
* @return the equipment changes map
52+
*/
53+
@Unmodifiable
54+
public Map<EquipmentSlot, EquipmentChange> getEquipmentChanges() {
55+
return equipmentChanges;
56+
}
57+
58+
@Override
59+
public HandlerList getHandlers() {
60+
return HANDLER_LIST;
61+
}
62+
63+
public static HandlerList getHandlerList() {
64+
return HANDLER_LIST;
65+
}
66+
67+
/**
68+
* Represents a change in equipment for a single equipment slot.
69+
*
70+
* @param oldItem the existing item that is being replaced
71+
* @param newItem the new item that is replacing the existing item
72+
*/
73+
public record EquipmentChange(ItemStack oldItem, ItemStack newItem) {
74+
75+
}
76+
77+
}

paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,20 +1336,44 @@
13361336
Map<EquipmentSlot, ItemStack> map = this.collectEquipmentChanges();
13371337
if (map != null) {
13381338
this.handleHandSwap(map);
1339-
@@ -2595,6 +_,13 @@
1339+
@@ -2586,6 +_,7 @@
1340+
@Nullable
1341+
private Map<EquipmentSlot, ItemStack> collectEquipmentChanges() {
1342+
Map<EquipmentSlot, ItemStack> map = null;
1343+
+ Map<org.bukkit.inventory.EquipmentSlot, io.papermc.paper.event.entity.EntityEquipmentChangedEvent.EquipmentChange> equipmentChanges = null; // Paper - EntityEquipmentChangedEvent
1344+
1345+
for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
1346+
ItemStack itemStack = switch (equipmentSlot.getType()) {
1347+
@@ -2595,11 +_,20 @@
13401348
};
13411349
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
13421350
if (this.equipmentHasChanged(itemStack, itemBySlot)) {
1343-
+ // Paper start - PlayerArmorChangeEvent
1351+
+ // Paper start - EntityEquipmentChangedEvent, PlayerArmorChangeEvent
1352+
+ final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemStack);
1353+
+ final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemBySlot);
13441354
+ if (this instanceof ServerPlayer && equipmentSlot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) {
1345-
+ final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemStack);
1346-
+ final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemBySlot);
13471355
+ 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();
13481356
+ }
1349-
+ // Paper end - PlayerArmorChangeEvent
1357+
+ // Paper end - EntityEquipmentChangedEvent, PlayerArmorChangeEvent
13501358
if (map == null) {
13511359
map = Maps.newEnumMap(EquipmentSlot.class);
1360+
+ equipmentChanges = Maps.newEnumMap(org.bukkit.inventory.EquipmentSlot.class); // Paper - EntityEquipmentChangedEvent
1361+
}
1362+
1363+
map.put(equipmentSlot, itemBySlot);
1364+
+ equipmentChanges.put(org.bukkit.craftbukkit.CraftEquipmentSlot.getSlot(equipmentSlot), new io.papermc.paper.event.entity.EntityEquipmentChangedEvent.EquipmentChange(oldItem, newItem)); // Paper - EntityEquipmentChangedEvent
1365+
AttributeMap attributes = this.getAttributes();
1366+
if (!itemStack.isEmpty()) {
1367+
this.stopLocationBasedEffects(itemStack, equipmentSlot, attributes);
1368+
@@ -2624,6 +_,8 @@
1369+
}
13521370
}
1371+
}
1372+
+
1373+
+ new io.papermc.paper.event.entity.EntityEquipmentChangedEvent(this.getBukkitLivingEntity(), equipmentChanges).callEvent(); // Paper - EntityEquipmentChangedEvent
1374+
}
1375+
1376+
return map;
13531377
@@ -2664,7 +_,7 @@
13541378
this.lastBodyItemStack = itemStack;
13551379
}

0 commit comments

Comments
 (0)