diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt index b8c45fff2..95c511b37 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt @@ -546,69 +546,76 @@ object MatterManager { } stream.map { - val width: Int - val height: Int + // avoid reality snap when recipe has no output + val resultItem = it.getResultItem(server.registryAccess()) - if (it is IShapedRecipe<*>) { - width = it.recipeWidth - height = it.recipeHeight + if (resultItem.isEmpty) { + null } else { - width = it.ingredients.size - height = 1 - } + val width: Int + val height: Int - val container = TransientCraftingContainer(object : AbstractContainerMenu(null, 0) { - override fun quickMoveStack(pPlayer: Player, pIndex: Int): ItemStack { - return ItemStack.EMPTY + if (it is IShapedRecipe<*>) { + width = it.recipeWidth + height = it.recipeHeight + } else { + width = it.ingredients.size + height = 1 } - override fun stillValid(pPlayer: Player): Boolean { - return false - } - }, width, height) - - val realIngredients = ArrayList>() - - for (c in it.ingredients.indices) { - if (it.ingredients[c].isActuallyEmpty) { - continue - } - - for ((i, ingredient) in it.ingredients.withIndex()) { - if (i != c) { - container[i] = if (ingredient.isActuallyEmpty) ItemStack.EMPTY else ingredient.items.firstOrNull() ?: ItemStack.EMPTY + val container = TransientCraftingContainer(object : AbstractContainerMenu(null, 0) { + override fun quickMoveStack(pPlayer: Player, pIndex: Int): ItemStack { + return ItemStack.EMPTY } - } - val result = ArrayList() + override fun stillValid(pPlayer: Player): Boolean { + return false + } + }, width, height) - for (item in it.ingredients[c].items) { - container[c] = item + val realIngredients = ArrayList>() - if (!it.assemble(container, server.registryAccess()).isEmpty) { - val residue = it.getRemainingItems(container) + for (c in it.ingredients.indices) { + if (it.ingredients[c].isActuallyEmpty) { + continue + } - val thisResidue = residue[c] - - if (thisResidue.isEmpty) { - result.add(RecipeEntry(item)) - } else { - result.add(RecipeEntry(ImmutableStack(item), ImmutableStack(thisResidue))) + for ((i, ingredient) in it.ingredients.withIndex()) { + if (i != c) { + container[i] = if (ingredient.isActuallyEmpty) ItemStack.EMPTY else ingredient.items.firstOrNull() ?: ItemStack.EMPTY } } + + val result = ArrayList() + + for (item in it.ingredients[c].items) { + container[c] = item + + if (!it.assemble(container, server.registryAccess()).isEmpty) { + val residue = it.getRemainingItems(container) + + val thisResidue = residue[c] + + if (thisResidue.isEmpty) { + result.add(RecipeEntry(item)) + } else { + result.add(RecipeEntry(ImmutableStack(item), ImmutableStack(thisResidue))) + } + } + } + + realIngredients.add(result) } - realIngredients.add(result) + ResolvedRecipe( + realIngredients.stream().map { it.stream() }, + ImmutableStack(resultItem), + isCritical = isCritical, + name = it.id, + allowBacktrack = allowBacktrack + ) } - - ResolvedRecipe( - realIngredients.stream().map { it.stream() }, - ImmutableStack(it.getResultItem(server.registryAccess())), - isCritical = isCritical, - name = it.id, - allowBacktrack = allowBacktrack - ) - }.filter { + }.filterNotNull().filter { if (it.inputs.isEmpty()) { LOGGER.warn("${it.formattedName} with output '${it.output.item.registryName}' ended up with no inputs!") false @@ -1388,6 +1395,11 @@ object MatterManager { val item: Item, val multiplier: Double = 1.0 ) { + init { + require(!multiplier.isNaN()) { "Provided stack cost multiplier is NaN" } + require(!multiplier.isInfinite()) { "Provided stack cost multiplier is infinite" } + } + constructor(item: Item, count: Int) : this(item, 1.0 / count.toDouble()) constructor(item: ItemStack) : this(item.item, item.count) }