From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Mon, 9 Nov 2020 20:44:51 +0100
Subject: [PATCH] Add ignore discounts API


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 4d7f95d2bd415bacccee145bfc47f2b480530c11..4d3a04e1d7910c4e71ac9a1cebb58e482958671a 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
@@ -491,6 +491,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
 
             while (iterator.hasNext()) {
                 MerchantOffer merchantrecipe = (MerchantOffer) iterator.next();
+                if (merchantrecipe.ignoreDiscounts) continue; // Paper - Add ignore discounts API
 
                 merchantrecipe.addToSpecialPriceDiff(-Mth.floor((float) i * merchantrecipe.getPriceMultiplier()));
             }
@@ -503,6 +504,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
 
             while (iterator1.hasNext()) {
                 MerchantOffer merchantrecipe1 = (MerchantOffer) iterator1.next();
+                if (merchantrecipe1.ignoreDiscounts) continue; // Paper - Add ignore discounts API
                 double d0 = 0.3D + 0.0625D * (double) j;
                 int k = (int) Math.floor(d0 * (double) merchantrecipe1.getBaseCostA().getCount());
 
diff --git a/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java b/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java
index 89982d25f60c8b60ba91e559ef88278f338fe215..bffa088b13312d525efaab3d7988a08953c4d9c3 100644
--- a/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java
+++ b/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java
@@ -33,6 +33,10 @@ public class MerchantOffer {
             return merchantrecipe.priceMultiplier;
         }), Codec.INT.lenientOptionalFieldOf("xp", 1).forGetter((merchantrecipe) -> {
             return merchantrecipe.xp;
+        // Paper start
+        }), Codec.BOOL.lenientOptionalFieldOf("Paper.IgnoreDiscounts", false).forGetter((merchantrecipe) -> {
+            return merchantrecipe.ignoreDiscounts;
+        // Paper end
         })).apply(instance, MerchantOffer::new);
     });
     public static final StreamCodec<RegistryFriendlyByteBuf, MerchantOffer> STREAM_CODEC = StreamCodec.of(MerchantOffer::writeToStream, MerchantOffer::createFromStream);
@@ -46,6 +50,7 @@ public class MerchantOffer {
     public int demand;
     public float priceMultiplier;
     public int xp;
+    public boolean ignoreDiscounts; // Paper - Add ignore discounts API
     // CraftBukkit start
     private CraftMerchantRecipe bukkitHandle;
 
@@ -59,7 +64,7 @@ public class MerchantOffer {
     }
     // CraftBukkit end
 
-    private MerchantOffer(ItemCost firstBuyItem, Optional<ItemCost> secondBuyItem, ItemStack sellItem, int uses, int maxUses, boolean rewardingPlayerExperience, int specialPrice, int demandBonus, float priceMultiplier, int merchantExperience) {
+    private MerchantOffer(ItemCost firstBuyItem, Optional<ItemCost> secondBuyItem, ItemStack sellItem, int uses, int maxUses, boolean rewardingPlayerExperience, int specialPrice, int demandBonus, float priceMultiplier, int merchantExperience, boolean ignoreDiscounts) { // Paper
         this.baseCostA = firstBuyItem;
         this.costB = secondBuyItem;
         this.result = sellItem;
@@ -70,6 +75,7 @@ public class MerchantOffer {
         this.demand = demandBonus;
         this.priceMultiplier = priceMultiplier;
         this.xp = merchantExperience;
+        this.ignoreDiscounts = ignoreDiscounts;
     }
 
     public MerchantOffer(ItemCost buyItem, ItemStack sellItem, int maxUses, int merchantExperience, float priceMultiplier) {
@@ -85,11 +91,11 @@ public class MerchantOffer {
     }
 
     public MerchantOffer(ItemCost firstBuyItem, Optional<ItemCost> secondBuyItem, ItemStack sellItem, int uses, int maxUses, int merchantExperience, float priceMultiplier, int demandBonus) {
-        this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, true, 0, demandBonus, priceMultiplier, merchantExperience);
+        this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, true, 0, demandBonus, priceMultiplier, merchantExperience, false); // Paper
     }
 
     private MerchantOffer(MerchantOffer offer) {
-        this(offer.baseCostA, offer.costB, offer.result.copy(), offer.uses, offer.maxUses, offer.rewardExp, offer.specialPriceDiff, offer.demand, offer.priceMultiplier, offer.xp);
+        this(offer.baseCostA, offer.costB, offer.result.copy(), offer.uses, offer.maxUses, offer.rewardExp, offer.specialPriceDiff, offer.demand, offer.priceMultiplier, offer.xp, offer.ignoreDiscounts); // Paper
     }
 
     public ItemStack getBaseCostA() {
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java
index 3bf9b5c016fa638fd0377d2a031a7359430b79ce..a18088125254178d362fdd283bff704a9ccdd0a7 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java
@@ -22,11 +22,19 @@ public class CraftMerchantRecipe extends MerchantRecipe {
 
     @Deprecated
     public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward, int experience, float priceMultiplier) {
-        this(result, uses, maxUses, experienceReward, experience, priceMultiplier, 0, 0);
+        // Paper start - add ignoreDiscounts param
+        this(result, uses, maxUses, experienceReward, experience, priceMultiplier, 0, 0, false);
+    }
+    public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward, int experience, float priceMultiplier, boolean ignoreDiscounts) {
+        this(result, uses, maxUses, experienceReward, experience, priceMultiplier, 0, 0, ignoreDiscounts);
     }
 
     public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward, int experience, float priceMultiplier, int demand, int specialPrice) {
-        super(result, uses, maxUses, experienceReward, experience, priceMultiplier, demand, specialPrice);
+        this(result, uses, maxUses, experienceReward, experience, priceMultiplier, demand, specialPrice, false);
+    }
+    public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward, int experience, float priceMultiplier, int demand, int specialPrice, boolean ignoreDiscounts) {
+        super(result, uses, maxUses, experienceReward, experience, priceMultiplier, demand, specialPrice, ignoreDiscounts);
+        // Paper end
         this.handle = new net.minecraft.world.item.trading.MerchantOffer(
                 new ItemCost(Items.AIR),
                 Optional.empty(),
@@ -36,6 +44,7 @@ public class CraftMerchantRecipe extends MerchantRecipe {
                 experience,
                 priceMultiplier,
                 demand,
+                ignoreDiscounts, // Paper - add ignoreDiscounts param
                 this
         );
         this.setSpecialPrice(specialPrice);
@@ -112,6 +121,18 @@ public class CraftMerchantRecipe extends MerchantRecipe {
         this.handle.priceMultiplier = priceMultiplier;
     }
 
+    // Paper start
+    @Override
+    public boolean shouldIgnoreDiscounts() {
+        return this.handle.ignoreDiscounts;
+    }
+
+    @Override
+    public void setIgnoreDiscounts(boolean ignoreDiscounts) {
+        this.handle.ignoreDiscounts = ignoreDiscounts;
+    }
+    // Paper end
+
     public net.minecraft.world.item.trading.MerchantOffer toMinecraft() {
         List<ItemStack> ingredients = this.getIngredients();
         Preconditions.checkState(!ingredients.isEmpty(), "No offered ingredients");
@@ -128,7 +149,7 @@ public class CraftMerchantRecipe extends MerchantRecipe {
         if (recipe instanceof CraftMerchantRecipe) {
             return (CraftMerchantRecipe) recipe;
         } else {
-            CraftMerchantRecipe craft = new CraftMerchantRecipe(recipe.getResult(), recipe.getUses(), recipe.getMaxUses(), recipe.hasExperienceReward(), recipe.getVillagerExperience(), recipe.getPriceMultiplier(), recipe.getDemand(), recipe.getSpecialPrice());
+            CraftMerchantRecipe craft = new CraftMerchantRecipe(recipe.getResult(), recipe.getUses(), recipe.getMaxUses(), recipe.hasExperienceReward(), recipe.getVillagerExperience(), recipe.getPriceMultiplier(), recipe.getDemand(), recipe.getSpecialPrice(), recipe.shouldIgnoreDiscounts()); // Paper - shouldIgnoreDiscounts
             craft.setIngredients(recipe.getIngredients());
 
             return craft;