diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java.patch new file mode 100644 index 000000000..f97db2bfb --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java.patch @@ -0,0 +1,39 @@ +--- a/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java ++++ b/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java +@@ -126,9 +126,35 @@ + protected abstract class EntryBase implements LootPoolEntry { + @Override + public int getWeight(float luck) { +- return Math.max(Mth.floor((float)LootPoolSingletonContainer.this.weight + (float)LootPoolSingletonContainer.this.quality * luck), 0); ++ // Paper start - Configurable LootPool luck formula ++ // SEE: https://luckformula.emc.gs for details and data ++ if (LootPoolSingletonContainer.this.lastLuck != null && LootPoolSingletonContainer.this.lastLuck == luck) { ++ return lastWeight; ++ } ++ // This is vanilla ++ float qualityModifer = (float) LootPoolSingletonContainer.this.quality * luck; ++ double baseWeight = (LootPoolSingletonContainer.this.weight + qualityModifer); ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.useAlternativeLuckFormula) { ++ // Random boost to avoid losing precision in the final int cast on return ++ final int weightBoost = 100; ++ baseWeight *= weightBoost; ++ // If we have vanilla 1, bump that down to 0 so nothing is is impacted ++ // vanilla 3 = 300, 200 basis = impact 2% ++ // =($B2*(($B2-100)/100/100)) ++ double impacted = baseWeight * ((baseWeight - weightBoost) / weightBoost / 100); ++ // =($B$7/100) ++ float luckModifier = Math.min(100, luck * 10) / 100; ++ // =B2 - (C2 *($B$7/100)) ++ baseWeight = Math.ceil(baseWeight - (impacted * luckModifier)); ++ } ++ LootPoolSingletonContainer.this.lastLuck = luck; ++ LootPoolSingletonContainer.this.lastWeight = (int) Math.max(Math.floor(baseWeight), 0); ++ return lastWeight; + } + } ++ private Float lastLuck = null; ++ private int lastWeight = 0; ++ // Paper end - Configurable LootPool luck formula + + @FunctionalInterface + protected interface EntryConstructor {