1
1
package cn.elytra.mod.gtnn.modules.simple.module.disassembler
2
2
3
3
import cn.elytra.mod.gtnn.GTNN
4
+ import cn.elytra.mod.gtnn.modules.simple.module.disassembler.DisassemblerHelper.debugMode
4
5
import cn.elytra.mod.gtnn.modules.simple.module.disassembler.DisassemblerHelper.oreDictReplace
6
+ import cn.elytra.mod.gtnn.util.anyInRecipeToString
5
7
import com.google.common.collect.ArrayListMultimap
6
8
import gregtech.api.enums.*
7
9
import gregtech.api.items.MetaGeneratedTool
@@ -11,16 +13,102 @@ import gregtech.api.recipe.RecipeMaps
11
13
import gregtech.api.util.GTModHandler
12
14
import gregtech.api.util.GTOreDictUnificator
13
15
import gregtech.api.util.GTRecipe
16
+ import gregtech.api.util.GTRecipeBuilder
14
17
import gregtech.api.util.GTUtility
15
18
import ic2.api.item.IC2Items
16
19
import net.minecraft.init.Blocks
17
20
import net.minecraft.init.Items
18
21
import net.minecraft.item.ItemStack
19
22
import net.minecraftforge.oredict.OreDictionary
23
+ import java.util.concurrent.atomic.AtomicInteger
24
+ import kotlin.jvm.optionals.getOrNull
20
25
import kotlin.math.min
21
26
22
27
object DisassemblerHelper {
23
28
29
+ private val debugMode = System .getenv(" DEBUG_DISASSEMBLER" ) == " true"
30
+
31
+ sealed interface GeneratedRecipeInfo <T > {
32
+ val original: T
33
+ val debugIndex: Int
34
+
35
+ fun getInfo (): String
36
+ }
37
+
38
+ data class AssemblerReversed (
39
+ override val original : List <GTRecipe >,
40
+ override val debugIndex : Int ,
41
+ val reason : String ,
42
+ ): GeneratedRecipeInfo<List<GTRecipe>> {
43
+ override fun getInfo (): String = buildString {
44
+ appendLine(" [[ Generated from Assembler recipes ]]" )
45
+ appendLine(" Reason = $reason " )
46
+ appendLine(" Debug Index = $debugIndex " )
47
+ original.forEachIndexed { index, recipe ->
48
+ appendLine(" << Original recipe ($index ) >>" )
49
+ append(" inputs = " )
50
+ appendLine(recipe.mInputs.joinToString(" , " , " [" , " ]" ) { anyInRecipeToString(it) })
51
+ }
52
+ }
53
+ }
54
+
55
+ data class CraftingTableReversed (
56
+ override val original : ReversedRecipeRegistry .GTCraftingRecipe ,
57
+ override val debugIndex : Int ,
58
+ ): GeneratedRecipeInfo<ReversedRecipeRegistry.GTCraftingRecipe> {
59
+ override fun getInfo (): String = buildString {
60
+ appendLine(" [[ Generated from GregTech Crafting recipes ]]" )
61
+ appendLine(" Debug Index = $debugIndex " )
62
+ append(" inputs = " )
63
+ appendLine(original.inputs.joinToString(" , " , " [" , " ]" ) { anyInRecipeToString(it) })
64
+ append(" stacktrace = " )
65
+ appendLine(original.adderStackTrace.stackTraceToString())
66
+ }
67
+ }
68
+
69
+ /* *
70
+ * A map records the reversed recipes and its original to find out which part is glitching.
71
+ * Only be not-null when [debugMode] is true.
72
+ */
73
+ val debugRecipeToRecipe: MutableMap <GTRecipe , MutableList <GeneratedRecipeInfo <* >>>? =
74
+ if (debugMode) mutableMapOf () else null
75
+
76
+ val debugIndexToRecipe: MutableMap <Int , GeneratedRecipeInfo <* >>? =
77
+ if (debugMode) mutableMapOf () else null
78
+
79
+ private val debugIndexBumper = AtomicInteger (0 )
80
+
81
+ private fun GTRecipeBuilder.tryRecordAssemblerSourceRecipe (original : List <GTRecipe >, isHardOverride : Boolean = false) =
82
+ apply {
83
+ if (debugRecipeToRecipe != null ) {
84
+ val generated = build().getOrNull()
85
+ if (generated != null ) {
86
+ val recipeInfoList = debugRecipeToRecipe.getOrPut(generated) { mutableListOf () }
87
+ val debugIndex = debugIndexBumper.andIncrement
88
+ val recipeInfo =
89
+ AssemblerReversed (original, debugIndex, if (isHardOverride) " Hard-override" else " Generated" )
90
+ recipeInfoList.add(recipeInfo)
91
+ setNEIDesc(" Debug Index: $debugIndex " )
92
+ debugIndexToRecipe!! [debugIndex] = recipeInfo
93
+ }
94
+ }
95
+ }
96
+
97
+ private fun GTRecipeBuilder.tryRecordCraftingTableSourceRecipe (original : ReversedRecipeRegistry .GTCraftingRecipe ) =
98
+ apply {
99
+ if (debugRecipeToRecipe != null ) {
100
+ val generated = build().getOrNull()
101
+ if (generated != null ) {
102
+ val recipeInfoList = debugRecipeToRecipe.getOrPut(generated) { mutableListOf () }
103
+ val debugIndex = debugIndexBumper.andIncrement
104
+ val recipeInfo = CraftingTableReversed (original, debugIndex)
105
+ recipeInfoList.add(recipeInfo)
106
+ setNEIDesc(" Debug Index: $debugIndex " )
107
+ debugIndexToRecipe!! [debugIndex] = recipeInfo
108
+ }
109
+ }
110
+ }
111
+
24
112
private val alwaysReplace by lazy {
25
113
listOf (
26
114
ItemStack (Blocks .trapped_chest, 1 , OreDictionary .WILDCARD_VALUE ) to
@@ -64,6 +152,9 @@ object DisassemblerHelper {
64
152
val thisMaterial = itemDataInSlotIdx.mMaterial.mMaterial
65
153
if (outputsInOtherRecipes != null ) {
66
154
for (outputsInOtherRecipe in outputsInOtherRecipes) {
155
+ // check array bondary
156
+ if (idx !in outputsInOtherRecipe.indices) continue
157
+
67
158
val dataAgainst = GTOreDictUnificator .getItemData(outputsInOtherRecipe[idx])
68
159
if (! (dataAgainst == null
69
160
|| dataAgainst.mMaterial == null
@@ -307,7 +398,7 @@ object DisassemblerHelper {
307
398
fun loadAssemblerRecipesToDisassembler () {
308
399
val assemblerRecipes = RecipeMaps .assemblerRecipes.allRecipes
309
400
.filter { shouldDisassemble(it.mOutputs) }
310
- .groupBy { it.mOutputs[0 ] }
401
+ .groupBy { GTItemStack ( it.mOutputs[0 ]) }
311
402
312
403
val totalCount = assemblerRecipes.size
313
404
GTNN .logger.info(" Loading reversed assembler recipes, total: $totalCount " )
@@ -329,6 +420,8 @@ object DisassemblerHelper {
329
420
.itemOutputs(overrideOutput)
330
421
.duration(overrideDuration)
331
422
.eut(overrideEUt)
423
+ .setNEIDesc(" Generated from Assembler Recipe (Hard-overriden)" )
424
+ .tryRecordAssemblerSourceRecipe(recipes, true )
332
425
.addTo(MTEDisassembler .RecipeMap )
333
426
334
427
continue @forRecipes
@@ -346,6 +439,8 @@ object DisassemblerHelper {
346
439
.itemOutputs(* outputs.toTypedArray())
347
440
.duration(revDuration)
348
441
.eut(revEUt)
442
+ .setNEIDesc(" Generated from Assembler Recipe" )
443
+ .tryRecordAssemblerSourceRecipe(recipes)
349
444
.addTo(MTEDisassembler .RecipeMap )
350
445
} catch (e: Exception ) {
351
446
// @formatter:off
@@ -410,11 +505,11 @@ object DisassemblerHelper {
410
505
}
411
506
412
507
/* *
413
- * Adds a **REVERSED** recipe to disassembler recipe map.
414
- *
415
- * The passed-in recipe should have been reversed once before, and we don't reverse it again.
508
+ * Reverse a recipe and add to disassembler recipe map.
416
509
*/
417
- fun addCraftingTableReverseRecipe (revRecipe : GTRecipe ) {
510
+ fun handleGTCraftingRecipe (recipe : ReversedRecipeRegistry .GTCraftingRecipe ) {
511
+ val revRecipe = recipe.toReversedSafe() ? : return
512
+
418
513
if (! shouldDisassemble(revRecipe.mInputs)) return
419
514
420
515
try {
@@ -423,6 +518,8 @@ object DisassemblerHelper {
423
518
.itemOutputs(* handleRecipeTransformation(revRecipe.mOutputs, null ).toTypedArray())
424
519
.duration(300 )
425
520
.eut(30 )
521
+ .setNEIDesc(" Generated from GT Crafting Recipe" )
522
+ .tryRecordCraftingTableSourceRecipe(recipe)
426
523
.addTo(MTEDisassembler .RecipeMap )
427
524
} catch (e: Exception ) {
428
525
// @formatter:off
0 commit comments