Lenient matter value calculation

This commit is contained in:
DBotThePony 2023-03-09 21:02:32 +07:00
parent 194aca51ea
commit 4dfb4c5234
Signed by: DBot
GPG Key ID: DCC23B5715498507
2 changed files with 101 additions and 14 deletions

View File

@ -201,12 +201,12 @@ dependencies {
compileOnly(fg.deobf("mekanism:Mekanism:${deps_mc_version}-${mekanism_version}:all")) compileOnly(fg.deobf("mekanism:Mekanism:${deps_mc_version}-${mekanism_version}:all"))
runtimeOnly(fg.deobf("curse.maven:cyclops-core-232758:4392602")) // runtimeOnly(fg.deobf("curse.maven:cyclops-core-232758:4392602"))
runtimeOnly(fg.deobf("curse.maven:integrated-dynamics-236307:4391535")) // runtimeOnly(fg.deobf("curse.maven:integrated-dynamics-236307:4391535"))
runtimeOnly(fg.deobf("curse.maven:integrated-crafting-287357:4391487")) // runtimeOnly(fg.deobf("curse.maven:integrated-crafting-287357:4391487"))
runtimeOnly(fg.deobf("curse.maven:integrated-terminals-295910:4400924")) // runtimeOnly(fg.deobf("curse.maven:integrated-terminals-295910:4400924"))
runtimeOnly(fg.deobf("curse.maven:common-capabilities-247007:4391468")) // runtimeOnly(fg.deobf("curse.maven:common-capabilities-247007:4391468"))
runtimeOnly(fg.deobf("curse.maven:integrated-tunnels-251389:4344632")) // runtimeOnly(fg.deobf("curse.maven:integrated-tunnels-251389:4344632"))
} }
} }

View File

@ -14,6 +14,7 @@ import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
import it.unimi.dsi.fastutil.objects.Object2BooleanFunction import it.unimi.dsi.fastutil.objects.Object2BooleanFunction
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap
import it.unimi.dsi.fastutil.objects.Reference2BooleanFunction import it.unimi.dsi.fastutil.objects.Reference2BooleanFunction
import it.unimi.dsi.fastutil.objects.Reference2BooleanOpenHashMap import it.unimi.dsi.fastutil.objects.Reference2BooleanOpenHashMap
import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction
@ -88,6 +89,7 @@ import ru.dbotthepony.mc.otm.milliTime
import ru.dbotthepony.mc.otm.network.MatteryPacket import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.network.RegistryNetworkChannel import ru.dbotthepony.mc.otm.network.RegistryNetworkChannel
import ru.dbotthepony.mc.otm.registry.RegistryDelegate import ru.dbotthepony.mc.otm.registry.RegistryDelegate
import ru.dbotthepony.mc.otm.secondTime
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
import java.io.DataInputStream import java.io.DataInputStream
import java.io.DataOutputStream import java.io.DataOutputStream
@ -105,6 +107,7 @@ import kotlin.collections.ArrayDeque
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.collections.HashMap import kotlin.collections.HashMap
import kotlin.collections.LinkedHashMap import kotlin.collections.LinkedHashMap
import kotlin.jvm.optionals.getOrNull
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -596,6 +599,8 @@ object MatterManager {
private val seenItems = ArrayDeque<Item>() private val seenItems = ArrayDeque<Item>()
private var changes = false private var changes = false
private var iteration = 0
private var lenientStage = false
private var cachedIterationResults = Reference2ObjectOpenHashMap<Item, Result>() private var cachedIterationResults = Reference2ObjectOpenHashMap<Item, Result>()
private fun doTryToBacktrack(item: Item, makeCommentary: Boolean): Result { private fun doTryToBacktrack(item: Item, makeCommentary: Boolean): Result {
@ -708,6 +713,8 @@ object MatterManager {
inputsLoop@ for ((i, inputs) in recipe.inputs.withIndex()) { inputsLoop@ for ((i, inputs) in recipe.inputs.withIndex()) {
var minimal: IMatterValue? = null var minimal: IMatterValue? = null
var minimalMultiplier = 0.0 var minimalMultiplier = 0.0
val skips = ArrayList<ImmutableStack>()
val recursiveSkips = ArrayList<ImmutableStack>()
innerInputsLoop@ for (input in inputs) { innerInputsLoop@ for (input in inputs) {
val ivalue = determineValue(input.item) val ivalue = determineValue(input.item)
@ -715,13 +722,19 @@ object MatterManager {
if (ivalue.isMissing) { if (ivalue.isMissing) {
comment(item, TextComponent("Input '${input.item.registryName}' at input slot $i in ${recipe.formattedName} has no matter value")) comment(item, TextComponent("Input '${input.item.registryName}' at input slot $i in ${recipe.formattedName} has no matter value"))
if (recipe.isCritical) { if (recipe.isCritical && !lenientStage) {
return Result.MISSING return Result.MISSING
} else { } else {
continue@recipesLoop if (recipe.isCritical) {
skips.add(input)
continue@innerInputsLoop
} else {
continue@recipesLoop
}
} }
} else if (ivalue.isSkipped) { } else if (ivalue.isSkipped) {
comment(item, TextComponent("Input '${input.item.registryName}' at input slot $i in ${recipe.formattedName} is recursive")) comment(item, TextComponent("Input '${input.item.registryName}' at input slot $i in ${recipe.formattedName} is recursive"))
recursiveSkips.add(input)
if (inputs.size == 1) { if (inputs.size == 1) {
hadSkips = true hadSkips = true
@ -737,6 +750,53 @@ object MatterManager {
} }
} }
if (skips.size > inputs.size / 2 || skips.isNotEmpty() && inputs.size == 1) {
comment(item, TextComponent("More than half inputs (${skips.joinToString(", ") { it.item.registryName.toString() }}) at input slot $i in ${recipe.formattedName} have no matter values"))
return Result.MISSING
} else if (skips.isNotEmpty()) {
/**
* Эвристический анализ тегов
*
* Если у 60% <= предметов со значением материи есть тег, и он есть у всех
* предметов без значения материи, то предметы без материи игнорируются
*/
val manager = ForgeRegistries.ITEMS.tags()!!
val tagSetsPresent = Object2IntArrayMap<TagKey<Item>>()
val tagSetsMissing = Object2IntArrayMap<TagKey<Item>>()
for (input in inputs) {
if (input in recursiveSkips) {
continue
}
val list = manager.getReverseTag(input.item).getOrNull()?.tagKeys?.collect(ImmutableList.toImmutableList()) ?: ImmutableList.of()
if (input !in skips) {
for (tag in list)
tagSetsPresent.computeInt(tag) { _, e -> (e ?: 0) + 1 }
} else {
for (tag in list)
tagSetsMissing.computeInt(tag) { _, e -> (e ?: 0) + 1 }
}
}
val filtered = tagSetsPresent.object2IntEntrySet()
.filter { it.intValue.toDouble() >= (inputs.size - skips.size - recursiveSkips.size) * 0.6 }
val result = filtered.all { tagSetsMissing.getInt(it.key) == skips.size }
if (!result) {
comment(item, TextComponent("More than half inputs (${skips.joinToString(", ") { it.item.registryName.toString() }}) at input slot $i in ${recipe.formattedName} have no matter values"))
return Result.MISSING
} else {
comment(item, TextComponent("${recipe.formattedName} with inputs at slot $i without matter values were allowed to be skipped due to next tags:"))
for (tag in filtered) {
comment(item, TextComponent(tag.key.location.toString()))
}
}
}
if (minimal == null || !minimal.hasMatterValue) { if (minimal == null || !minimal.hasMatterValue) {
comment(item, TextComponent("'${recipe.formattedName}' has invalid input at slot $i (possible inputs: ${inputs.joinToString(", ", transform = { it.item.registryName.toString() }) }) (???)")) comment(item, TextComponent("'${recipe.formattedName}' has invalid input at slot $i (possible inputs: ${inputs.joinToString(", ", transform = { it.item.registryName.toString() }) }) (???)"))
return Result.MISSING return Result.MISSING
@ -907,6 +967,26 @@ object MatterManager {
time = SystemTime() time = SystemTime()
lenientStage = false
while (changes) {
ops += cachedIterationResults.size
cachedIterationResults = Reference2ObjectOpenHashMap()
changes = false
iteration++
val iterator = toDetermine.iterator()
for (value in iterator) {
if (determineValue(value).value?.hasMatterValue == true) {
iterator.remove()
}
}
}
lenientStage = true
changes = true
while (changes) { while (changes) {
ops += cachedIterationResults.size ops += cachedIterationResults.size
cachedIterationResults = Reference2ObjectOpenHashMap() cachedIterationResults = Reference2ObjectOpenHashMap()
@ -936,8 +1016,6 @@ object MatterManager {
} }
} }
var iteration = 0
internal fun compute(value: Item): Result { internal fun compute(value: Item): Result {
return Resolver.determineValue(value) return Resolver.determineValue(value)
} }
@ -1132,11 +1210,20 @@ object MatterManager {
if (commentary != null) { if (commentary != null) {
if (commentary.size > 3) { if (commentary.size > 3) {
event.toolTip.add(TextComponent("...").withStyle(ChatFormatting.DARK_GRAY)) var index = ((secondTime / 3L) % commentary.size).toInt()
}
for (i in (commentary.size - 3).coerceAtLeast(0) until commentary.size) { for (i in 0 .. 2) {
event.toolTip.add(commentary[i].withStyle(ChatFormatting.DARK_GRAY)) if (index == commentary.size) {
event.toolTip.add(TextComponent("=========").withStyle(ChatFormatting.DARK_GRAY))
index = 0
}
event.toolTip.add(commentary[index++].withStyle(ChatFormatting.DARK_GRAY))
}
} else {
for (comment in commentary) {
event.toolTip.add(comment.withStyle(ChatFormatting.DARK_GRAY))
}
} }
} }
} }