Recipe backtracking
This commit is contained in:
parent
36dcc83f35
commit
caa5464641
@ -65,7 +65,19 @@ object RecipeResolverManager : SimpleJsonResourceReloadListener(GsonBuilder().se
|
|||||||
* if we can't resolve one of ingredient's matter value - consider output also having no matter value
|
* if we can't resolve one of ingredient's matter value - consider output also having no matter value
|
||||||
*/
|
*/
|
||||||
val isCritical: Boolean = true,
|
val isCritical: Boolean = true,
|
||||||
val name: ResourceLocation? = null
|
val name: ResourceLocation? = null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whenever to allow "backtracking" recipe ingredients to recipe outputs.
|
||||||
|
*
|
||||||
|
* When an item has no recipes, but takes part in recipes with output of already determined matter value
|
||||||
|
* (e.g. 4 rabbit hides -> 1 leather), we can assume that we can determine matter value of ingredients based on matter value of output
|
||||||
|
*
|
||||||
|
* "Backtrack" can happen if everything of the next holds true:
|
||||||
|
* * All recipes with item in question contains only that item; and
|
||||||
|
* * All recipes allow backtracking
|
||||||
|
*/
|
||||||
|
val allowBacktrack: Boolean = true,
|
||||||
) {
|
) {
|
||||||
val inputs: List<List<ImmutableStack>> = inputs
|
val inputs: List<List<ImmutableStack>> = inputs
|
||||||
.map { it.filter { it.multiplier > 0.0 }.collect(ImmutableList.toImmutableList()) }
|
.map { it.filter { it.multiplier > 0.0 }.collect(ImmutableList.toImmutableList()) }
|
||||||
@ -92,6 +104,8 @@ object RecipeResolverManager : SimpleJsonResourceReloadListener(GsonBuilder().se
|
|||||||
*
|
*
|
||||||
* Internally, OTM separate parallel streams from sequential so sequential streams happen strictly on server thread
|
* Internally, OTM separate parallel streams from sequential so sequential streams happen strictly on server thread
|
||||||
* (if you can't avoid side effects, or don't bother with synchronization).
|
* (if you can't avoid side effects, or don't bother with synchronization).
|
||||||
|
*
|
||||||
|
* You can safely call [MatterManager.getDirect] inside returned stream, both parallel and sequential.
|
||||||
*/
|
*/
|
||||||
fun find(server: MinecraftServer, json: JsonObject): Stream<ResolvedRecipe>
|
fun find(server: MinecraftServer, json: JsonObject): Stream<ResolvedRecipe>
|
||||||
}
|
}
|
||||||
@ -118,6 +132,7 @@ object RecipeResolverManager : SimpleJsonResourceReloadListener(GsonBuilder().se
|
|||||||
|
|
||||||
val isCritical = data["is_critical"]?.asBoolean ?: true
|
val isCritical = data["is_critical"]?.asBoolean ?: true
|
||||||
val ignoreDamageables = data["ignore_damageables"]?.asBoolean ?: false
|
val ignoreDamageables = data["ignore_damageables"]?.asBoolean ?: false
|
||||||
|
val allowBacktrack = data["allow_backtrack"]?.asBoolean ?: true
|
||||||
|
|
||||||
server.recipeManager.byType(findRecipeType).values.parallelStream()
|
server.recipeManager.byType(findRecipeType).values.parallelStream()
|
||||||
.filter { !it.isIncomplete && !it.ingredients.stream().anyMatch { it.isActuallyEmpty } } // get rid of invalid recipes, second "isActuallyEmpty" is required because we do care about ingredients being "missing"
|
.filter { !it.isIncomplete && !it.ingredients.stream().anyMatch { it.isActuallyEmpty } } // get rid of invalid recipes, second "isActuallyEmpty" is required because we do care about ingredients being "missing"
|
||||||
@ -129,7 +144,8 @@ object RecipeResolverManager : SimpleJsonResourceReloadListener(GsonBuilder().se
|
|||||||
it.ingredients.stream().map { Arrays.stream(it.items).map { ImmutableStack(it) } },
|
it.ingredients.stream().map { Arrays.stream(it.items).map { ImmutableStack(it) } },
|
||||||
ImmutableStack(it.resultItem),
|
ImmutableStack(it.resultItem),
|
||||||
isCritical = isCritical,
|
isCritical = isCritical,
|
||||||
name = it.id
|
name = it.id,
|
||||||
|
allowBacktrack = allowBacktrack
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.filter { it.inputs.isNotEmpty() }
|
.filter { it.inputs.isNotEmpty() }
|
||||||
@ -291,9 +307,45 @@ object RecipeResolverManager : SimpleJsonResourceReloadListener(GsonBuilder().se
|
|||||||
|
|
||||||
val recipes = output2Recipes[item]
|
val recipes = output2Recipes[item]
|
||||||
|
|
||||||
if (recipes == null) {
|
if (recipes == null || recipes.isEmpty()) {
|
||||||
commentary[item] = TextComponent("Item '${item.registryName}' has no recipes")
|
val recipes2 = input2Recipes[item]
|
||||||
return Result.MISSING
|
|
||||||
|
if (recipes2 == null || recipes2.isEmpty() || !recipes2.all { it.allowBacktrack } || !recipes2.all { it.inputs.all { it.all { it.item == item } } }) {
|
||||||
|
commentary[item] = TextComponent("Item '${item.registryName}' has no recipes")
|
||||||
|
return Result.MISSING
|
||||||
|
}
|
||||||
|
|
||||||
|
var minimal: IMatterValue? = null
|
||||||
|
var minimalMultiplier = 0.0
|
||||||
|
var foundRecipe: ResolvedRecipe? = null
|
||||||
|
|
||||||
|
for (recipe in recipes2) {
|
||||||
|
val value = MatterManager.getDirect(recipe.output.item)
|
||||||
|
|
||||||
|
if (value.hasMatterValue) {
|
||||||
|
if (minimal == null || minimal < value) {
|
||||||
|
minimal = value
|
||||||
|
minimalMultiplier = recipe.output.multiplier / recipe.inputs.size
|
||||||
|
foundRecipe = recipe
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
minimal = null
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minimal == null) {
|
||||||
|
commentary[item] = TextComponent("Item '${item.registryName}' has no valid backtracking recipes, and no output recipes")
|
||||||
|
return Result.MISSING
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = MatterValue(minimal.matter * minimalMultiplier, minimal.complexity * minimalMultiplier)
|
||||||
|
|
||||||
|
changes = true
|
||||||
|
determinedValues[item] = result
|
||||||
|
commentary[item] = TextComponent("Matter value backtracked from ${foundRecipe!!.formattedName}")
|
||||||
|
|
||||||
|
return Result(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
var hadSkips = false
|
var hadSkips = false
|
||||||
|
Loading…
Reference in New Issue
Block a user