diff --git a/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch index da2b2d1d8d..608b0c1d5c 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch @@ -24,25 +24,25 @@ } @Override -@@ -216,7 +224,18 @@ - return this.assignProfessionWhenSpawned; - } +@@ -214,7 +222,18 @@ + public boolean assignProfessionWhenSpawned() { + return this.assignProfessionWhenSpawned; ++ } ++ + // Spigot Start - @Override ++ @Override + public void inactiveTick() { + // SPIGOT-3874, SPIGOT-3894, SPIGOT-3846, SPIGOT-5286 :( + if (this.level().spigotConfig.tickInactiveVillagers && this.isEffectiveAi()) { + this.customServerAiStep((ServerLevel) this.level()); + } + super.inactiveTick(); -+ } + } + // Spigot End -+ -+ @Override - protected void customServerAiStep(ServerLevel world) { - ProfilerFiller gameprofilerfiller = Profiler.get(); + @Override + protected void customServerAiStep(ServerLevel world) { @@ -235,7 +254,7 @@ this.increaseProfessionLevelOnUpdate = false; } @@ -82,7 +82,23 @@ } } -@@ -489,7 +520,7 @@ +@@ -459,6 +490,7 @@ + + 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())); + } +@@ -471,6 +503,7 @@ + + 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()); + +@@ -489,7 +522,7 @@ @Override public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); @@ -91,7 +107,7 @@ Logger logger = Villager.LOGGER; Objects.requireNonNull(logger); -@@ -512,7 +543,7 @@ +@@ -512,7 +545,7 @@ public void readAdditionalSaveData(CompoundTag nbt) { super.readAdditionalSaveData(nbt); if (nbt.contains("VillagerData", 10)) { @@ -100,7 +116,7 @@ Logger logger = Villager.LOGGER; Objects.requireNonNull(logger); -@@ -599,7 +630,7 @@ +@@ -599,7 +632,7 @@ } if (offer.shouldRewardExp()) { @@ -109,7 +125,7 @@ } } -@@ -618,7 +649,7 @@ +@@ -618,7 +651,7 @@ @Override public void die(DamageSource damageSource) { @@ -118,7 +134,7 @@ Entity entity = damageSource.getEntity(); if (entity != null) { -@@ -803,12 +834,19 @@ +@@ -803,12 +836,19 @@ @Override public void thunderHit(ServerLevel world, LightningBolt lightning) { if (world.getDifficulty() != Difficulty.PEACEFUL) { @@ -140,7 +156,7 @@ if (entitywitch == null) { super.thunderHit(world, lightning); -@@ -906,7 +944,7 @@ +@@ -906,7 +946,7 @@ }).limit(5L).toList(); if (list1.size() >= requiredCount) { @@ -149,7 +165,7 @@ list.forEach(GolemSensor::golemDetected); } } -@@ -963,7 +1001,7 @@ +@@ -963,7 +1003,7 @@ @Override public void startSleeping(BlockPos pos) { super.startSleeping(pos); @@ -158,7 +174,7 @@ this.brain.eraseMemory(MemoryModuleType.WALK_TARGET); this.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE); } -@@ -971,7 +1009,7 @@ +@@ -971,7 +1011,7 @@ @Override public void stopSleeping() { super.stopSleeping(); diff --git a/paper-server/patches/sources/net/minecraft/world/item/trading/MerchantOffer.java.patch b/paper-server/patches/sources/net/minecraft/world/item/trading/MerchantOffer.java.patch index b2a328fe58..bf956ac4ae 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/trading/MerchantOffer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/trading/MerchantOffer.java.patch @@ -9,27 +9,64 @@ public class MerchantOffer { public static final Codec CODEC = RecordCodecBuilder.create((instance) -> { -@@ -44,7 +46,19 @@ +@@ -31,6 +33,10 @@ + 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 STREAM_CODEC = StreamCodec.of(MerchantOffer::writeToStream, MerchantOffer::createFromStream); +@@ -44,8 +50,22 @@ public int demand; public float priceMultiplier; public int xp; ++ public boolean ignoreDiscounts; // Paper - Add ignore discounts API + // CraftBukkit start + private CraftMerchantRecipe bukkitHandle; +- private MerchantOffer(ItemCost firstBuyItem, Optional secondBuyItem, ItemStack sellItem, int uses, int maxUses, boolean rewardingPlayerExperience, int specialPrice, int demandBonus, float priceMultiplier, int merchantExperience) { + public CraftMerchantRecipe asBukkit() { + return (this.bukkitHandle == null) ? this.bukkitHandle = new CraftMerchantRecipe(this) : this.bukkitHandle; + } + -+ public MerchantOffer(ItemCost baseCostA, Optional costB, ItemStack result, int uses, int maxUses, int experience, float priceMultiplier, int demand, CraftMerchantRecipe bukkit) { ++ public MerchantOffer(ItemCost baseCostA, Optional costB, ItemStack result, int uses, int maxUses, int experience, float priceMultiplier, int demand, final boolean ignoreDiscounts, CraftMerchantRecipe bukkit) { // Paper + this(baseCostA, costB, result, uses, maxUses, experience, priceMultiplier, demand); ++ this.ignoreDiscounts = ignoreDiscounts; // Paper + this.bukkitHandle = bukkit; + } + // CraftBukkit end + - private MerchantOffer(ItemCost firstBuyItem, Optional secondBuyItem, ItemStack sellItem, int uses, int maxUses, boolean rewardingPlayerExperience, int specialPrice, int demandBonus, float priceMultiplier, int merchantExperience) { ++ private MerchantOffer(ItemCost firstBuyItem, Optional secondBuyItem, ItemStack sellItem, int uses, int maxUses, boolean rewardingPlayerExperience, int specialPrice, int demandBonus, float priceMultiplier, int merchantExperience, final boolean ignoreDiscounts) { // Paper this.baseCostA = firstBuyItem; this.costB = secondBuyItem; -@@ -110,7 +124,7 @@ + this.result = sellItem; +@@ -56,6 +76,7 @@ + this.demand = demandBonus; + this.priceMultiplier = priceMultiplier; + this.xp = merchantExperience; ++ this.ignoreDiscounts = ignoreDiscounts; // Paper + } + + public MerchantOffer(ItemCost buyItem, ItemStack sellItem, int maxUses, int merchantExperience, float priceMultiplier) { +@@ -71,11 +92,11 @@ + } + + public MerchantOffer(ItemCost firstBuyItem, Optional 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() { +@@ -110,7 +131,7 @@ } public void updateDemand() { @@ -38,7 +75,7 @@ } public ItemStack assemble() { -@@ -185,7 +199,11 @@ +@@ -185,7 +206,11 @@ if (!this.satisfiedBy(firstBuyStack, secondBuyStack)) { return false; } else { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java index bc1a92707c..e86cee2570 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java @@ -24,11 +24,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(), @@ -38,6 +46,7 @@ public class CraftMerchantRecipe extends MerchantRecipe { experience, priceMultiplier, demand, + ignoreDiscounts, // Paper - add ignoreDiscounts param this ); this.setSpecialPrice(specialPrice); @@ -114,6 +123,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 ingredients = this.getIngredients(); Preconditions.checkState(!ingredients.isEmpty(), "No offered ingredients"); @@ -134,7 +155,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;