Add PlayerWashItemEvent

This commit is contained in:
Jake Potrebic 2021-12-30 13:48:01 -08:00
parent 7af4cd3647
commit cc054437e5
No known key found for this signature in database
GPG key ID: ECE0B3C133C016C5
2 changed files with 217 additions and 0 deletions

View file

@ -0,0 +1,85 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 30 Dec 2021 13:47:25 -0800
Subject: [PATCH] Add PlayerWashItemEvent
diff --git a/src/main/java/io/papermc/paper/event/block/PlayerWashItemEvent.java b/src/main/java/io/papermc/paper/event/block/PlayerWashItemEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1ec150d0ebc2f41ac7e458eca2f9798218a0c3b
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/PlayerWashItemEvent.java
@@ -0,0 +1,73 @@
+package io.papermc.paper.event.block;
+
+import com.google.common.base.Preconditions;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockState;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.event.block.CauldronLevelChangeEvent;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Objects;
+
+/**
+ * Called when a player washes an item in a cauldron.
+ */
+public class PlayerWashItemEvent extends CauldronLevelChangeEvent {
+
+ private final ItemStack washedItem;
+ private final EquipmentSlot hand;
+
+ @ApiStatus.Internal
+ public PlayerWashItemEvent(@NotNull Block block, @NotNull HumanEntity entity, @NotNull ChangeReason reason, @NotNull BlockState newBlock, @NotNull ItemStack washedItem, @NotNull EquipmentSlot hand) {
+ super(block, entity, reason, newBlock);
+ Preconditions.checkArgument(hand.isHand(), "Only valid equipment slots are the two hands");
+ this.washedItem = washedItem;
+ this.hand = hand;
+ }
+
+ /**
+ * Helper method for {@link #getEntity()} since this event
+ * is only called with a {@link HumanEntity}.
+ *
+ * @return the player who initiated the item wash
+ */
+ public @NotNull HumanEntity getPlayer() {
+ return this.getEntity();
+ }
+
+ @Override
+ public @NotNull HumanEntity getEntity() {
+ return (HumanEntity) Objects.requireNonNull(super.getEntity());
+ }
+
+ /**
+ * Gets the washed item. Changes made to this item
+ * will be reflected in the player's inventory.
+ *
+ * @return the washed item
+ */
+ public @NotNull ItemStack getWashedItem() {
+ return this.washedItem;
+ }
+
+ /**
+ * Gets the item the player is washing.
+ *
+ * @return the item being washed
+ */
+ public @NotNull ItemStack getUnwashedItem() {
+ return this.getPlayer().getInventory().getItem(this.hand);
+ }
+
+ /**
+ * Get the player's hand that initiated the wash.
+ *
+ * @return the hand
+ */
+ public @NotNull EquipmentSlot getHand() {
+ return this.hand;
+ }
+}

View file

@ -0,0 +1,132 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 30 Dec 2021 13:47:39 -0800
Subject: [PATCH] Add PlayerWashItemEvent
diff --git a/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java
index c9cd5fe3e942d1ce0133c17d6dd2747b70878d4e..fbd52dad91ac8f928f6526ddcd42d3b56745fd3f 100644
--- a/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java
+++ b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java
@@ -55,16 +55,16 @@ public interface CauldronInteraction {
return InteractionResult.PASS;
} else {
if (!world.isClientSide) {
- // CraftBukkit start
- if (!LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition, entityhuman, CauldronLevelChangeEvent.ChangeReason.SHULKER_WASH)) {
- return InteractionResult.SUCCESS;
- }
- // CraftBukkit end
ItemStack itemstack1 = new ItemStack(Blocks.SHULKER_BOX);
if (itemstack.hasTag()) {
itemstack1.setTag(itemstack.getTag().copy());
}
+ // CraftBukkit start // Paper - move to after itemstack creation
+ if (!LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition, entityhuman, CauldronLevelChangeEvent.ChangeReason.SHULKER_WASH, itemstack1, enumhand)) {
+ return InteractionResult.SUCCESS;
+ }
+ // CraftBukkit end
entityhuman.setItemInHand(enumhand, itemstack1);
entityhuman.awardStat(Stats.CLEAN_SHULKER_BOX);
@@ -79,15 +79,15 @@ public interface CauldronInteraction {
return InteractionResult.PASS;
} else {
if (!world.isClientSide) {
- // CraftBukkit start
- if (!LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition, entityhuman, CauldronLevelChangeEvent.ChangeReason.BANNER_WASH)) {
- return InteractionResult.SUCCESS;
- }
- // CraftBukkit end
ItemStack itemstack1 = itemstack.copy();
itemstack1.setCount(1);
BannerBlockEntity.removeLastPattern(itemstack1);
+ // CraftBukkit start // Paper - move to after itemstack creation
+ if (!LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition, entityhuman, CauldronLevelChangeEvent.ChangeReason.BANNER_WASH, itemstack1, enumhand)) {
+ return InteractionResult.SUCCESS;
+ }
+ // CraftBukkit end
if (!entityhuman.getAbilities().instabuild) {
itemstack.shrink(1);
}
@@ -119,12 +119,19 @@ public interface CauldronInteraction {
return InteractionResult.PASS;
} else {
if (!world.isClientSide) {
+ // Paper start - make itemstack copy
+ ItemStack copy = itemstack.copy();
+ idyeable.clearColor(copy);
+ // Paper end
// CraftBukkit start
- if (!LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition, entityhuman, CauldronLevelChangeEvent.ChangeReason.ARMOR_WASH)) {
+ if (!LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition, entityhuman, CauldronLevelChangeEvent.ChangeReason.ARMOR_WASH, copy, enumhand)) { // Paper
return InteractionResult.SUCCESS;
}
// CraftBukkit end
- idyeable.clearColor(itemstack);
+ // Paper start - move clear to before event
+ itemstack.setCount(0);
+ entityhuman.setItemInHand(enumhand, copy);
+ // Paper end
entityhuman.awardStat(Stats.CLEAN_ARMOR);
// LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition); // CraftBukkit
}
diff --git a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
index e11eced0bf15dfecaf64f5e1c28e973c38746095..6110c43950a1090d634607513d6ff9fa73703a66 100644
--- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -90,10 +90,15 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
}
public static boolean lowerFillLevel(BlockState iblockdata, Level world, BlockPos blockposition, Entity entity, CauldronLevelChangeEvent.ChangeReason reason) {
+ // Paper start
+ return LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition, entity, reason, null, null);
+ }
+ public static boolean lowerFillLevel(BlockState iblockdata, Level world, BlockPos blockposition, Entity entity, CauldronLevelChangeEvent.ChangeReason reason, @javax.annotation.Nullable net.minecraft.world.item.ItemStack washedItem, @javax.annotation.Nullable net.minecraft.world.InteractionHand hand) {
+ // Paper end
int i = (Integer) iblockdata.getValue(LayeredCauldronBlock.LEVEL) - 1;
BlockState iblockdata1 = i == 0 ? Blocks.CAULDRON.defaultBlockState() : (BlockState) iblockdata.setValue(LayeredCauldronBlock.LEVEL, i);
- return LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, iblockdata1, entity, reason);
+ return LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, iblockdata1, entity, reason, true, washedItem, hand); // Paper
}
// CraftBukkit start
@@ -104,18 +109,34 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, CauldronLevelChangeEvent.ChangeReason reason, boolean sendGameEvent) { // Paper - entity is nullable
// Paper end
+ // Paper start
+ return LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, newBlock, entity, reason, sendGameEvent, null, null);
+ }
+ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, CauldronLevelChangeEvent.ChangeReason reason, boolean sendGameEvent, @javax.annotation.Nullable net.minecraft.world.item.ItemStack washedItem, @javax.annotation.Nullable net.minecraft.world.InteractionHand hand) {
+ // Paper end
CraftBlockState newState = CraftBlockStates.getBlockState(world, blockposition);
newState.setData(newBlock);
- CauldronLevelChangeEvent event = new CauldronLevelChangeEvent(
+ // Paper start
+ CauldronLevelChangeEvent event = null;
+ if (washedItem == null || hand == null) {
+ event = new CauldronLevelChangeEvent(
+ // Paper end
world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()),
(entity == null) ? null : entity.getBukkitEntity(), reason, newState
);
+ // Paper start
+ } else if (entity instanceof net.minecraft.world.entity.player.Player player) {
+ event = new io.papermc.paper.event.block.PlayerWashItemEvent(org.bukkit.craftbukkit.block.CraftBlock.at(world, blockposition), player.getBukkitEntity(), reason, newState, org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(washedItem), ((hand == net.minecraft.world.InteractionHand.OFF_HAND) ? org.bukkit.inventory.EquipmentSlot.OFF_HAND : org.bukkit.inventory.EquipmentSlot.HAND));
+ }
+ if (event != null) {
+ // Paper end
world.getCraftServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return false;
}
newState.update(true);
+ } // Paper
if (sendGameEvent) world.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(newBlock)); // Paper
return true;
}