|
2 | 2 |
|
3 | 3 | import dev.quarris.fireandflames.data.config.number.INumberProvider; |
4 | 4 | import dev.quarris.fireandflames.data.map.ConverterData; |
| 5 | +import dev.quarris.fireandflames.data.map.ItemMaterialConverter; |
5 | 6 | import dev.quarris.fireandflames.data.tool.material.IMaterialHolder; |
6 | 7 | import dev.quarris.fireandflames.data.tool.material.ToolMaterial; |
7 | 8 | import dev.quarris.fireandflames.setup.RecipeSetup; |
@@ -41,26 +42,77 @@ public ItemStack getResultItem(HolderLookup.Provider registries) { |
41 | 42 | } |
42 | 43 |
|
43 | 44 | public List<ArtisanRecipeOutput> createResults(SingleRecipeInput input, HolderLookup.Provider registries) { |
44 | | - return this.createResults(input, DataMapUtil.getConverters(input.item(), registries)); |
| 45 | + List<ConverterData> converters = DataMapUtil.getConverters(input.item(), registries); |
| 46 | + return this.createResultsFromConverters(input.item().getCount(), DataMapUtil.getAllConverters(registries), converters); |
45 | 47 | } |
46 | 48 |
|
47 | | - public List<ArtisanRecipeOutput> createResults(SingleRecipeInput input, List<ConverterData> converters) { |
| 49 | + public List<ArtisanRecipeOutput> createResultsFromConverters(int inputCount, List<ConverterData> byproductConverters, List<ConverterData> inputConverters) { |
48 | 50 | List<ArtisanRecipeOutput> outputs = new ArrayList<>(); |
49 | | - // TODO Add byproduct based on leftover units |
50 | | - for (ConverterData data : converters) { |
51 | | - if (input.item().getCount() >= data.converter().getCountForUnits(this.units.evaluateInt())) { |
| 51 | + |
| 52 | + inputConverters.stream() |
| 53 | + .filter(data -> data.converter() instanceof ItemMaterialConverter) |
| 54 | + .filter(data -> inputCount >= data.converter().getCountForUnits(this.units.evaluateInt())) |
| 55 | + .forEach(data -> { |
52 | 56 | Holder<ToolMaterial> mat = data.material(); |
53 | 57 |
|
54 | 58 | ItemStack mainOutput = this.result.createItemStack(); |
55 | 59 | if (mainOutput.getItem() instanceof IMaterialHolder materialHolder) { |
56 | 60 | materialHolder.setMaterial(mainOutput, mat); |
57 | 61 | } |
58 | 62 |
|
59 | | - outputs.add(new ArtisanRecipeOutput(data.converter().getCountForUnits(this.units.evaluateInt()), mainOutput, ItemStack.EMPTY)); |
| 63 | + int requiredInputCount = data.converter().getCountForUnits(this.units.evaluateInt()); |
| 64 | + int totalUnitsFromInput = data.converter().getUnits(); |
| 65 | + int usedUnits = this.units.evaluateInt(); |
| 66 | + int leftoverUnits = totalUnitsFromInput - usedUnits; |
| 67 | + |
| 68 | + ItemStack byproduct = calculateBestByproduct(leftoverUnits, mat, byproductConverters.stream().filter(bcData -> bcData.material().equals(mat)).toList()); |
| 69 | + |
| 70 | + outputs.add(new ArtisanRecipeOutput(requiredInputCount, mainOutput, byproduct)); |
| 71 | + }); |
| 72 | + |
| 73 | + return outputs; |
| 74 | + } |
| 75 | + |
| 76 | + private static ItemStack calculateBestByproduct(int leftoverUnits, Holder<ToolMaterial> material, List<ConverterData> converters) { |
| 77 | + if (leftoverUnits <= 0) { |
| 78 | + return ItemStack.EMPTY; |
| 79 | + } |
| 80 | + |
| 81 | + ItemStack bestByproduct = ItemStack.EMPTY; |
| 82 | + int bestRemainder = Integer.MAX_VALUE; |
| 83 | + int bestOutputCount = Integer.MAX_VALUE; |
| 84 | + |
| 85 | + for (ConverterData converterData : converters) { |
| 86 | + // Only consider converters for the same material |
| 87 | + if (!converterData.material().equals(material)) { |
| 88 | + continue; |
| 89 | + } |
| 90 | + |
| 91 | + // Only consider ItemMaterialConverters |
| 92 | + if (!(converterData.converter() instanceof ItemMaterialConverter itemConverter)) { |
| 93 | + continue; |
| 94 | + } |
| 95 | + |
| 96 | + int converterUnits = itemConverter.getUnits(); |
| 97 | + |
| 98 | + // Check if we have enough leftover units for at least one conversion |
| 99 | + if (converterUnits <= leftoverUnits) { |
| 100 | + int outputCount = leftoverUnits / converterUnits; |
| 101 | + int remainder = leftoverUnits % converterUnits; |
| 102 | + |
| 103 | + // Check if this is better (lower remainder, or same remainder but lower output count) |
| 104 | + if (remainder < bestRemainder || (remainder == bestRemainder && outputCount < bestOutputCount)) { |
| 105 | + // Create the output item from this converter |
| 106 | + ItemStack outputItem = itemConverter.item().ingredient().getItems()[0].copyWithCount(outputCount); |
| 107 | + |
| 108 | + bestByproduct = outputItem; |
| 109 | + bestRemainder = remainder; |
| 110 | + bestOutputCount = outputCount; |
| 111 | + } |
60 | 112 | } |
61 | 113 | } |
62 | 114 |
|
63 | | - return outputs; |
| 115 | + return bestByproduct; |
64 | 116 | } |
65 | 117 |
|
66 | 118 | @Override |
|
0 commit comments