From da230d521cccf6db68a1a00f4cbb3b2eee31fac9 Mon Sep 17 00:00:00 2001
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Date: Wed, 23 Nov 2022 22:38:49 +0100
Subject: [PATCH] More vanilla friendly methods to update trades (#8478)

---
 ...la-friendly-methods-to-update-trades.patch | 57 ++++++++++++++
 ...la-friendly-methods-to-update-trades.patch | 75 +++++++++++++++++++
 2 files changed, 132 insertions(+)
 create mode 100644 patches/api/0408-More-vanilla-friendly-methods-to-update-trades.patch
 create mode 100644 patches/server/0942-More-vanilla-friendly-methods-to-update-trades.patch

diff --git a/patches/api/0408-More-vanilla-friendly-methods-to-update-trades.patch b/patches/api/0408-More-vanilla-friendly-methods-to-update-trades.patch
new file mode 100644
index 000000000..b2dadf139
--- /dev/null
+++ b/patches/api/0408-More-vanilla-friendly-methods-to-update-trades.patch
@@ -0,0 +1,57 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
+Date: Sun, 16 Oct 2022 15:58:38 +0200
+Subject: [PATCH] More vanilla friendly methods to update trades
+
+
+diff --git a/src/main/java/org/bukkit/entity/Villager.java b/src/main/java/org/bukkit/entity/Villager.java
+index d61855b83da0776fe910dee8cde184c720571a71..c61e7e41aeb3d4f5f4ac47da8890051d8e97340d 100644
+--- a/src/main/java/org/bukkit/entity/Villager.java
++++ b/src/main/java/org/bukkit/entity/Villager.java
+@@ -60,8 +60,11 @@ public interface Villager extends AbstractVillager {
+      * A villager with a level of 1 and no experience is liable to lose its
+      * profession.
+      *
++     * This doesn't update the trades of this villager.
++     *
+      * @param level the new level
+      * @throws IllegalArgumentException if level not between [1, 5]
++     * @see #increaseLevel(int)
+      */
+     public void setVillagerLevel(int level);
+ 
+@@ -81,6 +84,34 @@ public interface Villager extends AbstractVillager {
+     public void setVillagerExperience(int experience);
+ 
+     // Paper start
++    /**
++     * Increases the level of this villager.
++     * The villager will also unlock new recipes unlike the raw
++     * method {@link #setVillagerLevel(int)}.
++     * <p>
++     * A villager with a level of 1 and no experience is liable to lose its
++     * profession.
++     * <p>
++     * A master villager has a level of 5 in its profession and
++     * will unlock 10 trades (2 per level).
++     *
++     * @param amount The amount of level
++     * @return Whether trades are unlocked
++     * @throws IllegalArgumentException if current level plus the amount
++     * isn't between [1, 5] or the amount isn't positive
++     * @see #setVillagerLevel(int)
++     */
++    boolean increaseLevel(int amount);
++
++    /**
++     * Gives to this villager some potential new trades
++     * based to its profession and level.
++     * @param amount The amount of trades to give
++     * @return Whether trades are added
++     * @throws IllegalArgumentException if the amount isn't positive
++     */
++    boolean addTrades(int amount);
++
+     /**
+      * Gets the amount of times a villager has restocked their trades today
+      * @return The amount of trade restocks.
diff --git a/patches/server/0942-More-vanilla-friendly-methods-to-update-trades.patch b/patches/server/0942-More-vanilla-friendly-methods-to-update-trades.patch
new file mode 100644
index 000000000..892c36776
--- /dev/null
+++ b/patches/server/0942-More-vanilla-friendly-methods-to-update-trades.patch
@@ -0,0 +1,75 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
+Date: Sun, 16 Oct 2022 16:12:49 +0200
+Subject: [PATCH] More vanilla friendly methods to update trades
+
+
+diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
+index 10b45ec24a5a0867106d1694312385ad1e267f43..49f82c954155115b2caa87d7624521a9f7982be2 100644
+--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
++++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
+@@ -919,6 +919,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+ 
+     @Override
+     protected void updateTrades() {
++        // Paper start
++        updateTrades(TRADES_PER_LEVEL);
++    }
++
++    public boolean updateTrades(int amount) {
++        // Paper end
+         VillagerData villagerdata = this.getVillagerData();
+         Int2ObjectMap<VillagerTrades.ItemListing[]> int2objectmap = (Int2ObjectMap) VillagerTrades.TRADES.get(villagerdata.getProfession());
+ 
+@@ -928,9 +934,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+             if (avillagertrades_imerchantrecipeoption != null) {
+                 MerchantOffers merchantrecipelist = this.getOffers();
+ 
+-                this.addOffersFromItemListings(merchantrecipelist, avillagertrades_imerchantrecipeoption, 2);
++                this.addOffersFromItemListings(merchantrecipelist, avillagertrades_imerchantrecipeoption, amount); // Paper
++                return true; // Paper
+             }
+         }
++        return false; // Paper
+     }
+ 
+     public void gossip(ServerLevel world, Villager villager, long time) {
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
+index d1f5e1292246e0fb252d3d3409bbf37cc8166bbc..9220b1a7aa30ba59ac8dc6196859923b0675d8ec 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
+@@ -99,6 +99,34 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
+     }
+ 
+     // Paper start
++    @Override
++    public boolean increaseLevel(int amount) {
++        Preconditions.checkArgument(amount > 0, "Level earned must be positive");
++        int supposedFinalLevel = this.getVillagerLevel() + amount;
++        Preconditions.checkArgument(net.minecraft.world.entity.npc.VillagerData.MIN_VILLAGER_LEVEL <= supposedFinalLevel && supposedFinalLevel <= net.minecraft.world.entity.npc.VillagerData.MAX_VILLAGER_LEVEL,
++            "Final level reached after the donation (%d) must be between [%d, %d]".formatted(supposedFinalLevel, net.minecraft.world.entity.npc.VillagerData.MIN_VILLAGER_LEVEL, net.minecraft.world.entity.npc.VillagerData.MAX_VILLAGER_LEVEL));
++
++        it.unimi.dsi.fastutil.ints.Int2ObjectMap<net.minecraft.world.entity.npc.VillagerTrades.ItemListing[]> trades =
++            net.minecraft.world.entity.npc.VillagerTrades.TRADES.get(this.getHandle().getVillagerData().getProfession());
++
++        if (trades == null || trades.isEmpty()) {
++            this.getHandle().setVillagerData(this.getHandle().getVillagerData().setLevel(supposedFinalLevel));
++            return false;
++        }
++
++        while (amount > 0) {
++            this.getHandle().increaseMerchantCareer();
++            amount--;
++        }
++        return true;
++    }
++
++    @Override
++    public boolean addTrades(int amount) {
++        Preconditions.checkArgument(amount > 0, "Number of trades unlocked must be positive");
++        return this.getHandle().updateTrades(amount);
++    }
++
+     @Override
+     public int getRestocksToday() {
+         return getHandle().numberOfRestocksToday;