aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAlexander <[email protected]>2021-05-24 11:51:06 +0100
committerGitHub <[email protected]>2021-05-24 10:51:06 +0000
commitafe0785bfe28edf438cba6548a6fface3a72dfaa (patch)
tree59a938e9d057ff3c65e30d136940979f557fbc42
parent615df3d8a6bc2ac08f584a87606fd54f03d13fd8 (diff)
downloadPaper-afe0785bfe28edf438cba6548a6fface3a72dfaa.tar.gz
Paper-afe0785bfe28edf438cba6548a6fface3a72dfaa.zip
Added PlayerPurchaseEvent for standalone Merchant GUIs (#5583)
-rw-r--r--Spigot-API-Patches/0244-added-PlayerTradeEvent.patch93
-rw-r--r--Spigot-Server-Patches/0743-Have-CraftMerchantCustom-emit-PlayerPurchaseEvent.patch59
2 files changed, 122 insertions, 30 deletions
diff --git a/Spigot-API-Patches/0244-added-PlayerTradeEvent.patch b/Spigot-API-Patches/0244-added-PlayerTradeEvent.patch
index 5288a11205..e09b088160 100644
--- a/Spigot-API-Patches/0244-added-PlayerTradeEvent.patch
+++ b/Spigot-API-Patches/0244-added-PlayerTradeEvent.patch
@@ -1,78 +1,75 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <[email protected]>
Date: Thu, 2 Jul 2020 16:10:10 -0700
-Subject: [PATCH] added PlayerTradeEvent
+Subject: [PATCH] Added PlayerTradeEvent
+[Amendment: Alexander <[email protected]>]
+PlayerTradeEvent is used for player purchases from villagers and wandering
+traders, but not custom merchants created via Bukkit.createMerchant(). During
+discussions in Discord it was decided that it'd be better to add a new event
+that PlayerTradeEvent inherits from than change getVillager()'s annotation to
+@Nullable, especially since that'd also infringe on the implication of the
+event being about villager trades.
-diff --git a/src/main/java/io/papermc/paper/event/player/PlayerTradeEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerTradeEvent.java
-new file mode 100755
-index 0000000000000000000000000000000000000000..198e5464eae6b961c83148a57c18f91a4bb33cf6
+diff --git a/src/main/java/io/papermc/paper/event/player/PlayerPurchaseEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerPurchaseEvent.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..c5648055c5e815474bf1e564a5c192ff5c0624fb
--- /dev/null
-+++ b/src/main/java/io/papermc/paper/event/player/PlayerTradeEvent.java
-@@ -0,0 +1,121 @@
++++ b/src/main/java/io/papermc/paper/event/player/PlayerPurchaseEvent.java
+@@ -0,0 +1,112 @@
+package io.papermc.paper.event.player;
+
-+import org.bukkit.entity.AbstractVillager;
++import java.util.Objects;
+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.MerchantRecipe;
+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
+
+/**
-+ * Called when a player trades with a villager or wandering trader
++ * Called when a player trades with a standalone merchant GUI.
+ */
-+public class PlayerTradeEvent extends PlayerEvent implements Cancellable {
-+
++public class PlayerPurchaseEvent extends PlayerEvent implements Cancellable {
+ private static final HandlerList handlers = new HandlerList();
+ private boolean cancelled;
+
+ private boolean increaseTradeUses;
+ private boolean rewardExp;
-+ private final AbstractVillager villager;
+ private MerchantRecipe trade;
+
-+ public PlayerTradeEvent(@NotNull Player player, @NotNull AbstractVillager villager, @NotNull MerchantRecipe trade, boolean rewardExp, boolean increaseTradeUses) {
-+ super(player);
-+ this.villager = villager;
-+ this.trade = trade;
++ public PlayerPurchaseEvent(@NotNull Player player,
++ @NotNull MerchantRecipe trade,
++ boolean rewardExp,
++ boolean increaseTradeUses) {
++ super(Objects.requireNonNull(player, "Player cannot be null!"));
++ setTrade(trade);
+ this.rewardExp = rewardExp;
+ this.increaseTradeUses = increaseTradeUses;
+ }
+
+ /**
-+ * Gets the Villager or Wandering trader associated with this event
-+ * @return the villager or wandering trader
-+ */
-+ @NotNull
-+ public AbstractVillager getVillager() {
-+ return villager;
-+ }
-+
-+ /**
+ * Gets the associated trade with this event
+ * @return the trade
+ */
+ @NotNull
+ public MerchantRecipe getTrade() {
-+ return trade;
++ return this.trade;
+ }
+
+ /**
+ * Sets the trade. This is then used to determine the next prices
+ * @param trade the trade to use
+ */
-+ public void setTrade(@Nullable MerchantRecipe trade) {
-+ this.trade = trade;
++ public void setTrade(@NotNull MerchantRecipe trade) {
++ this.trade = Objects.requireNonNull(trade, "Trade cannot be null!");
+ }
+
+ /**
+ * @return will trade try to reward exp
+ */
+ public boolean isRewardingExp() {
-+ return rewardExp;
++ return this.rewardExp;
+ }
+
+ /**
@@ -87,7 +84,7 @@ index 0000000000000000000000000000000000000000..198e5464eae6b961c83148a57c18f91a
+ * @return whether or not the trade will count as a use of the trade
+ */
+ public boolean willIncreaseTradeUses() {
-+ return increaseTradeUses;
++ return this.increaseTradeUses;
+ }
+
+ /**
@@ -130,4 +127,40 @@ index 0000000000000000000000000000000000000000..198e5464eae6b961c83148a57c18f91a
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
++
++}
+diff --git a/src/main/java/io/papermc/paper/event/player/PlayerTradeEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerTradeEvent.java
+new file mode 100755
+index 0000000000000000000000000000000000000000..a41fc186746b87f76347dfcc1f80d0969398322b
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/event/player/PlayerTradeEvent.java
+@@ -0,0 +1,29 @@
++package io.papermc.paper.event.player;
++
++import org.bukkit.entity.AbstractVillager;
++import org.bukkit.entity.Player;
++import org.bukkit.inventory.MerchantRecipe;
++import org.jetbrains.annotations.NotNull;
++
++/**
++ * Called when a player trades with a villager or wandering trader
++ */
++public class PlayerTradeEvent extends PlayerPurchaseEvent {
++
++ private final AbstractVillager villager;
++
++ public PlayerTradeEvent(@NotNull Player player, @NotNull AbstractVillager villager, @NotNull MerchantRecipe trade, boolean rewardExp, boolean increaseTradeUses) {
++ super(player, trade, rewardExp, increaseTradeUses);
++ this.villager = villager;
++ }
++
++ /**
++ * Gets the Villager or Wandering trader associated with this event
++ * @return the villager or wandering trader
++ */
++ @NotNull
++ public AbstractVillager getVillager() {
++ return this.villager;
++ }
++
+}
diff --git a/Spigot-Server-Patches/0743-Have-CraftMerchantCustom-emit-PlayerPurchaseEvent.patch b/Spigot-Server-Patches/0743-Have-CraftMerchantCustom-emit-PlayerPurchaseEvent.patch
new file mode 100644
index 0000000000..154ff25eb1
--- /dev/null
+++ b/Spigot-Server-Patches/0743-Have-CraftMerchantCustom-emit-PlayerPurchaseEvent.patch
@@ -0,0 +1,59 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Alexander <[email protected]>
+Date: Thu, 6 May 2021 13:01:25 +0100
+Subject: [PATCH] Have CraftMerchantCustom emit PlayerPurchaseEvent
+
+
+diff --git a/src/main/java/net/minecraft/world/item/trading/IMerchant.java b/src/main/java/net/minecraft/world/item/trading/IMerchant.java
+index 5644affeadc51ac3209ee9a087b3d2dd887e401c..7c54ca6af424b9d31f73187df9015f5df84762f4 100644
+--- a/src/main/java/net/minecraft/world/item/trading/IMerchant.java
++++ b/src/main/java/net/minecraft/world/item/trading/IMerchant.java
+@@ -19,7 +19,7 @@ public interface IMerchant {
+
+ MerchantRecipeList getOffers();
+
+- void a(MerchantRecipe merchantrecipe);
++ void a(MerchantRecipe merchantrecipe); default void handlePurchase(MerchantRecipe merchantRecipe) { a(merchantRecipe); } // Paper - OBFHELPER
+
+ void k(ItemStack itemstack);
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java
+index 206c133ebc6c44038585236b0628543b8bed278c..a7230776b8e85d5d1873ab2dc4e10c5bf78889bb 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java
+@@ -81,6 +81,35 @@ public class CraftMerchantCustom extends CraftMerchant {
+
+ @Override
+ public void a(MerchantRecipe merchantrecipe) {
++ // Paper start
++ /** Based on {@link net.minecraft.world.entity.npc.EntityVillagerAbstract#b(MerchantRecipe)} */
++ if (getTrader() instanceof net.minecraft.server.level.EntityPlayer) {
++ final net.minecraft.server.level.EntityPlayer trader = (net.minecraft.server.level.EntityPlayer) getTrader();
++ final io.papermc.paper.event.player.PlayerPurchaseEvent event = new io.papermc.paper.event.player.PlayerPurchaseEvent(
++ trader.getBukkitEntity(),
++ merchantrecipe.asBukkit(),
++ false, // reward xp?
++ true); // should increase uses?
++ event.callEvent();
++ if (event.isCancelled()) {
++ return;
++ }
++ final org.bukkit.inventory.MerchantRecipe eventTrade = event.getTrade();
++ if (event.willIncreaseTradeUses()) {
++ eventTrade.setUses(eventTrade.getUses() + 1);
++ }
++ if (event.isRewardingExp() && eventTrade.hasExperienceReward()) {
++ /** Based on {@link net.minecraft.world.entity.npc.EntityVillagerTrader#b(MerchantRecipe)} */
++ final int xp = 3 + net.minecraft.world.entity.Entity.SHARED_RANDOM.nextInt(4);
++ final World world = trader.getWorld();
++ world.addEntity(new net.minecraft.world.entity.EntityExperienceOrb(
++ world, trader.locX(), trader.locY() + 0.5d, trader.locZ(), xp,
++ org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, trader, null));
++ }
++ return;
++ }
++ // Paper end
++
+ // increase recipe's uses
+ merchantrecipe.increaseUses();
+ }