feat: PlayerSwapWithEquipmentSlotEvent (#13687)

Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com>
This commit is contained in:
Riley Park 2026-03-09 19:54:02 -07:00 committed by GitHub
parent 3f5728e249
commit bd74bf6581
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 97 additions and 0 deletions

View file

@ -0,0 +1,75 @@
package io.papermc.paper.event.player;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
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;
/**
* Triggered when a {@link Player} swaps an item with an equipment slot.
*/
@NullMarked
public class PlayerSwapWithEquipmentSlotEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLERS = new HandlerList();
private final ItemStack itemInHand;
private final EquipmentSlot slot;
private final ItemStack itemToSwap;
private boolean cancelled;
@ApiStatus.Internal
public PlayerSwapWithEquipmentSlotEvent(
final Player player,
final ItemStack itemInHand,
final EquipmentSlot slot,
final ItemStack itemToSwap
) {
super(player);
this.itemInHand = itemInHand;
this.slot = slot;
this.itemToSwap = itemToSwap;
}
/**
* {@return the item in one of the hand slots}
*/
public ItemStack getItemInHand() {
return this.itemInHand.clone();
}
/**
* {@return the slot to swap into}
*/
public EquipmentSlot getSlot() {
return this.slot;
}
/**
* {@return the item to swap}
*/
public ItemStack getItemToSwap() {
return this.itemToSwap.clone();
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
public static HandlerList getHandlerList() {
return HANDLERS;
}
}

View file

@ -0,0 +1,22 @@
--- a/net/minecraft/world/item/equipment/Equippable.java
+++ b/net/minecraft/world/item/equipment/Equippable.java
@@ -129,6 +_,19 @@
ItemStack itemBySlot = player.getItemBySlot(this.slot);
if ((!EnchantmentHelper.has(itemBySlot, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE) || player.isCreative())
&& !ItemStack.isSameItemSameComponents(stack, itemBySlot)) {
+ // Paper start
+ final io.papermc.paper.event.player.PlayerSwapWithEquipmentSlotEvent event = new io.papermc.paper.event.player.PlayerSwapWithEquipmentSlotEvent(
+ (org.bukkit.entity.Player) player.getBukkitEntity(),
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(stack),
+ org.bukkit.craftbukkit.CraftEquipmentSlot.getSlot(this.slot),
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemBySlot)
+ );
+ event.callEvent();
+ if (event.isCancelled()) {
+ ((org.bukkit.entity.Player) player.getBukkitEntity()).updateInventory();
+ return InteractionResult.FAIL;
+ }
+ // Paper end
if (!player.level().isClientSide()) {
player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
}