|
12 | 12 | import net.minecraft.core.component.DataComponents; |
13 | 13 | import net.minecraft.core.registries.Registries; |
14 | 14 | import net.minecraft.server.level.ServerLevel; |
| 15 | +import net.minecraft.util.random.Weighted; |
15 | 16 | import net.minecraft.world.item.BlockItem; |
16 | 17 | import net.minecraft.world.item.Item; |
17 | 18 | import net.minecraft.world.item.ItemStackTemplate; |
| 19 | +import net.minecraft.world.item.component.Compostable; |
18 | 20 | import net.minecraft.world.item.component.CookingFuel; |
19 | 21 | import net.minecraft.world.item.component.ItemAttributeModifiers; |
20 | 22 | import net.minecraft.world.level.storage.loot.LootContext; |
21 | 23 | import net.minecraft.world.level.storage.loot.LootParams; |
22 | 24 | import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; |
| 25 | +import net.minecraft.world.level.storage.loot.providers.number.ints.ContextIntProvider; |
23 | 26 | import net.minecraft.world.level.storage.loot.providers.number.ints.ResolvableInt; |
| 27 | +import net.minecraft.world.level.storage.loot.providers.number.ints.WeightedListValue; |
24 | 28 | import org.bukkit.Bukkit; |
25 | 29 | import org.bukkit.Material; |
26 | 30 | import org.bukkit.Registry; |
@@ -193,9 +197,32 @@ public boolean isCompostable() { |
193 | 197 |
|
194 | 198 | @Override |
195 | 199 | public float getCompostChance() { |
196 | | - Preconditions.checkArgument(this.isCompostable(), "The item type " + this.getKey() + " is not compostable"); |
197 | | - // TODO - snapshot - how can get the chance if the component require context? |
198 | | - return ComposterBlock.COMPOSTABLES.getFloat(this.getHandle()); |
| 200 | + // TODO - snapshot - this cover vanilla but custom ones can break this.. maybe better deprecate this... |
| 201 | + final net.minecraft.world.item.ItemStack stack = new net.minecraft.world.item.ItemStack(this.getHandle()); |
| 202 | + Compostable compostable = stack.get(DataComponents.COMPOSTABLE); |
| 203 | + Preconditions.checkArgument(compostable != null, "The item type " + this.getKey() + " is not compostable"); |
| 204 | + if (compostable.layers() instanceof ResolvableInt.Constant) { |
| 205 | + // Constant (ex: [minecraft:compostable={layers:10}]) case it's the 100% of cases add layers to the composter. |
| 206 | + return 1; |
| 207 | + } else if (compostable.layers() instanceof ResolvableInt.Reference reference) { |
| 208 | + final ServerLevel serverLevel = ((CraftWorld) Bukkit.getWorlds().getFirst()).getHandle(); |
| 209 | + final LootContext lootContext = new LootContext.Builder( |
| 210 | + new LootParams.Builder(serverLevel).create(LootContextParamSets.EMPTY) |
| 211 | + ).create(Optional.empty()); |
| 212 | + |
| 213 | + return reference.getProvider(lootContext) |
| 214 | + .map(contextIntProvider -> { |
| 215 | + if (contextIntProvider instanceof WeightedListValue( |
| 216 | + net.minecraft.util.random.WeightedList<Holder<ContextIntProvider>> distribution |
| 217 | + )) { |
| 218 | + return distribution.unwrap().stream().mapToInt(Weighted::weight).max().orElse(0); |
| 219 | + } else { |
| 220 | + return 1; |
| 221 | + } |
| 222 | + }).orElse(0); |
| 223 | + } |
| 224 | + |
| 225 | + return 0; |
199 | 226 | } |
200 | 227 |
|
201 | 228 | @Override |
|
0 commit comments