Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions patches/api/0419-Add-PlayerWashItemEvent.patch
Original file line number Diff line number Diff line change
@@ -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;
+ }
+}
132 changes: 132 additions & 0 deletions patches/server/0969-Add-PlayerWashItemEvent.patch
Original file line number Diff line number Diff line change
@@ -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;
}