From f403ce90514194bbf3e61826dcca06ceda7df106 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Wed, 8 Mar 2023 19:59:58 +0700 Subject: [PATCH 1/5] Remove query panel when pressing escape --- .../otm/client/screen/panels/input/QueryUserPanel.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/QueryUserPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/QueryUserPanel.kt index 78e634dec..4b7a8ec99 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/QueryUserPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/QueryUserPanel.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.client.screen.panels.input +import com.mojang.blaze3d.platform.InputConstants import net.minecraft.client.gui.screens.Screen import net.minecraft.network.chat.Component import ru.dbotthepony.mc.otm.client.screen.MatteryScreen @@ -63,4 +64,14 @@ open class QueryUserPanel( toScreenCenter() } + + override fun keyPressedInternal(key: Int, scancode: Int, mods: Int): Boolean { + if (key == InputConstants.KEY_ESCAPE) { + onCancel?.run() + remove() + return true + } + + return super.keyPressedInternal(key, scancode, mods) + } } From 3c66f2a9d808fcee52f7f6b19a006ad777e8d583 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 9 Mar 2023 15:28:34 +0700 Subject: [PATCH 2/5] Add missing prismarine shard matter value --- src/data/kotlin/ru/dbotthepony/mc/otm/datagen/MatterData.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/MatterData.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/MatterData.kt index 6312d20f2..2b070eb1a 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/MatterData.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/MatterData.kt @@ -209,6 +209,7 @@ fun addMatterData(provider: MatterDataProvider) { relative(Items.HONEY_BLOCK, 6, 1.75) relative(Tags.Items.GEMS_PRISMARINE, 6, 2.75) + relative(Items.PRISMARINE_SHARD, 6, 2.75) relative(Tags.Items.RODS_BLAZE, 1.4, 2) relative(Items.GHAST_TEAR, 2.5, 2.5) From 4810894d72c955221233b2fa2bd7a95d66397f14 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 9 Mar 2023 15:32:13 +0700 Subject: [PATCH 3/5] fix no_exosuit to no_exopack --- .../dbotthepony/mc/otm/item/AbstractExoPackSlotUpgradeItem.kt | 2 +- .../ru/dbotthepony/mc/otm/item/ExoPackCraftingUpgradeItem.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/AbstractExoPackSlotUpgradeItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/AbstractExoPackSlotUpgradeItem.kt index 37f7b0d12..2fc022a71 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/AbstractExoPackSlotUpgradeItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/AbstractExoPackSlotUpgradeItem.kt @@ -43,7 +43,7 @@ abstract class AbstractExoPackSlotUpgradeItem(properties: Properties = defaultPr } if (!alreadyHasExosuit) { - tooltip.add(TranslatableComponent("otm.gui.exopack_upgrades.no_exosuit").withStyle(ChatFormatting.GRAY)) + tooltip.add(TranslatableComponent("otm.gui.exopack_upgrades.no_exopack").withStyle(ChatFormatting.GRAY)) if (runIfClient(false) { minecraft.player?.isCreative != true }) { return diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ExoPackCraftingUpgradeItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ExoPackCraftingUpgradeItem.kt index cac3c7778..b753f7291 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ExoPackCraftingUpgradeItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ExoPackCraftingUpgradeItem.kt @@ -28,7 +28,7 @@ class ExoPackCraftingUpgradeItem : Item(Properties().stacksTo(1).rarity(Rarity.R } if (!alreadyHasExosuit) { - tooltip.add(TranslatableComponent("otm.gui.exopack_upgrades.no_exosuit").withStyle(ChatFormatting.GRAY)) + tooltip.add(TranslatableComponent("otm.gui.exopack_upgrades.no_exopack").withStyle(ChatFormatting.GRAY)) if (runIfClient(false) { minecraft.player?.isCreative != true }) { return From 194aca51ea6f7a0f4119d24dff99a21ef2b7db1e Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 9 Mar 2023 16:51:30 +0700 Subject: [PATCH 4/5] Add matter value and complexity sorters --- .../mc/otm/datagen/lang/English.kt | 2 ++ .../mc/otm/datagen/lang/Russian.kt | 2 ++ .../mc/otm/core/util/ItemSorter.kt | 24 ++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt index eaf589cda..7c4275819 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt @@ -633,6 +633,8 @@ private fun gui(provider: MatteryLanguageProvider) { gui("sorting.count", "Sort by amount") gui("sorting.ascending", "Ascending") gui("sorting.descending", "Descending") + gui("sorting.matter_value", "Matter value") + gui("sorting.matter_complexity", "Replication complexity") gui("matter_panel.increase_by", "+%s") gui("matter_panel.decrease_by", "-%s") diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt index cdce390c5..6054bcecf 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt @@ -641,6 +641,8 @@ private fun gui(provider: MatteryLanguageProvider) { gui("sorting.count", "Сортировка по количеству") gui("sorting.ascending", "Возрастающая") gui("sorting.descending", "Убывающая") + gui("sorting.matter_value", "Значение материи") + gui("sorting.matter_complexity", "Сложность репликации") gui("matter_panel.send", "Запросить") gui("matter_panel.close", "Закрыть") diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ItemSorter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ItemSorter.kt index 76a467de8..fe6c1b229 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ItemSorter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/ItemSorter.kt @@ -9,6 +9,7 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.nullsFirst import ru.dbotthepony.mc.otm.core.nullsLast import ru.dbotthepony.mc.otm.core.registryName +import ru.dbotthepony.mc.otm.matter.MatterManager object CreativeMenuComparator : Comparator { override fun compare(o1: Item, o2: Item): Int { @@ -42,6 +43,24 @@ object CreativeMenuComparator : Comparator { val NullsLast = nullsLast() } +object MatterValueComparator : Comparator { + override fun compare(o1: Item, o2: Item): Int { + return MatterManager.get(o1).matter.compareTo(MatterManager.get(o2).matter) + } + + val NullsFirst = nullsFirst() + val NullsLast = nullsLast() +} + +object MatterComplexityComparator : Comparator { + override fun compare(o1: Item, o2: Item): Int { + return MatterManager.get(o1).complexity.compareTo(MatterManager.get(o2).complexity) + } + + val NullsFirst = nullsFirst() + val NullsLast = nullsLast() +} + object ItemLocalizedNameComparator : Comparator { override fun compare(o1: Item, o2: Item): Int { return o1.description.string.compareTo(o2.description.string) @@ -77,7 +96,10 @@ enum class ItemSorter(val comparator: Comparator, private val sTitle: Com DEFAULT(CreativeMenuComparator.NullsFirst, TranslatableComponent("otm.gui.sorting.default")), NAME(ItemLocalizedNameComparator.NullsFirst.thenComparing(CreativeMenuComparator.NullsFirst), TranslatableComponent("otm.gui.sorting.name")), ID(ItemIDComparator.NullsFirst.thenComparing(CreativeMenuComparator.NullsFirst), TranslatableComponent("otm.gui.sorting.id")), - MOD(ItemModComparator.NullsFirst.thenComparing(CreativeMenuComparator.NullsFirst), TranslatableComponent("otm.gui.sorting.modid")); + MOD(ItemModComparator.NullsFirst.thenComparing(CreativeMenuComparator.NullsFirst), TranslatableComponent("otm.gui.sorting.modid")), + MATTER_VALUE(MatterValueComparator.NullsFirst.thenComparing(MatterComplexityComparator.NullsFirst).thenComparing(CreativeMenuComparator.NullsFirst), TranslatableComponent("otm.gui.sorting.matter_value")), + MATTER_COMPLEXITY(MatterComplexityComparator.NullsFirst.thenComparing(MatterValueComparator.NullsFirst).thenComparing(CreativeMenuComparator.NullsFirst), TranslatableComponent("otm.gui.sorting.matter_complexity")), + ; val title: Component get() = sTitle.copy() } From 4dfb4c52344cda33037b47fa2e8539c83e538f8f Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 9 Mar 2023 21:02:32 +0700 Subject: [PATCH 5/5] Lenient matter value calculation --- build.gradle.kts | 12 +- .../mc/otm/matter/MatterManager.kt | 103 ++++++++++++++++-- 2 files changed, 101 insertions(+), 14 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index dfcea109e..361d035c9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -201,12 +201,12 @@ dependencies { 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:integrated-dynamics-236307:4391535")) - runtimeOnly(fg.deobf("curse.maven:integrated-crafting-287357:4391487")) - runtimeOnly(fg.deobf("curse.maven:integrated-terminals-295910:4400924")) - runtimeOnly(fg.deobf("curse.maven:common-capabilities-247007:4391468")) - runtimeOnly(fg.deobf("curse.maven:integrated-tunnels-251389:4344632")) + // runtimeOnly(fg.deobf("curse.maven:cyclops-core-232758:4392602")) + // runtimeOnly(fg.deobf("curse.maven:integrated-dynamics-236307:4391535")) + // runtimeOnly(fg.deobf("curse.maven:integrated-crafting-287357:4391487")) + // runtimeOnly(fg.deobf("curse.maven:integrated-terminals-295910:4400924")) + // runtimeOnly(fg.deobf("curse.maven:common-capabilities-247007:4391468")) + // runtimeOnly(fg.deobf("curse.maven:integrated-tunnels-251389:4344632")) } } 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 c9839c011..3c93b2f80 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt @@ -14,6 +14,7 @@ import it.unimi.dsi.fastutil.io.FastByteArrayInputStream import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream import it.unimi.dsi.fastutil.objects.Object2BooleanFunction 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.Reference2BooleanOpenHashMap 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.RegistryNetworkChannel import ru.dbotthepony.mc.otm.registry.RegistryDelegate +import ru.dbotthepony.mc.otm.secondTime import ru.dbotthepony.mc.otm.storage.ItemStackWrapper import java.io.DataInputStream import java.io.DataOutputStream @@ -105,6 +107,7 @@ import kotlin.collections.ArrayDeque import kotlin.collections.ArrayList import kotlin.collections.HashMap import kotlin.collections.LinkedHashMap +import kotlin.jvm.optionals.getOrNull import kotlin.math.pow import kotlin.math.roundToInt @@ -596,6 +599,8 @@ object MatterManager { private val seenItems = ArrayDeque() private var changes = false + private var iteration = 0 + private var lenientStage = false private var cachedIterationResults = Reference2ObjectOpenHashMap() private fun doTryToBacktrack(item: Item, makeCommentary: Boolean): Result { @@ -708,6 +713,8 @@ object MatterManager { inputsLoop@ for ((i, inputs) in recipe.inputs.withIndex()) { var minimal: IMatterValue? = null var minimalMultiplier = 0.0 + val skips = ArrayList() + val recursiveSkips = ArrayList() innerInputsLoop@ for (input in inputs) { val ivalue = determineValue(input.item) @@ -715,13 +722,19 @@ object MatterManager { if (ivalue.isMissing) { 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 } else { - continue@recipesLoop + if (recipe.isCritical) { + skips.add(input) + continue@innerInputsLoop + } else { + continue@recipesLoop + } } } else if (ivalue.isSkipped) { comment(item, TextComponent("Input '${input.item.registryName}' at input slot $i in ${recipe.formattedName} is recursive")) + recursiveSkips.add(input) if (inputs.size == 1) { 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>() + val tagSetsMissing = Object2IntArrayMap>() + + 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) { comment(item, TextComponent("'${recipe.formattedName}' has invalid input at slot $i (possible inputs: ${inputs.joinToString(", ", transform = { it.item.registryName.toString() }) }) (???)")) return Result.MISSING @@ -907,6 +967,26 @@ object MatterManager { 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) { ops += cachedIterationResults.size cachedIterationResults = Reference2ObjectOpenHashMap() @@ -936,8 +1016,6 @@ object MatterManager { } } - var iteration = 0 - internal fun compute(value: Item): Result { return Resolver.determineValue(value) } @@ -1132,11 +1210,20 @@ object MatterManager { if (commentary != null) { 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) { - event.toolTip.add(commentary[i].withStyle(ChatFormatting.DARK_GRAY)) + for (i in 0 .. 2) { + 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)) + } } } }