Make special recipe finder for crafting table recipes, make use of residue logic
This commit is contained in:
parent
574035774f
commit
8ce67a7fae
@ -15,6 +15,7 @@ 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.Object2IntArrayMap
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet
|
||||||
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
|
||||||
@ -35,12 +36,16 @@ import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener
|
|||||||
import net.minecraft.tags.TagKey
|
import net.minecraft.tags.TagKey
|
||||||
import net.minecraft.util.profiling.ProfilerFiller
|
import net.minecraft.util.profiling.ProfilerFiller
|
||||||
import net.minecraft.world.Container
|
import net.minecraft.world.Container
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
|
import net.minecraft.world.inventory.CraftingContainer
|
||||||
import net.minecraft.world.item.Item
|
import net.minecraft.world.item.Item
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.crafting.Recipe
|
import net.minecraft.world.item.crafting.Recipe
|
||||||
import net.minecraft.world.item.crafting.RecipeType
|
import net.minecraft.world.item.crafting.RecipeType
|
||||||
import net.minecraft.world.level.ItemLike
|
import net.minecraft.world.level.ItemLike
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
|
import net.minecraftforge.common.crafting.IShapedRecipe
|
||||||
import net.minecraftforge.event.AddReloadListenerEvent
|
import net.minecraftforge.event.AddReloadListenerEvent
|
||||||
import net.minecraftforge.event.OnDatapackSyncEvent
|
import net.minecraftforge.event.OnDatapackSyncEvent
|
||||||
import net.minecraftforge.event.RegisterCommandsEvent
|
import net.minecraftforge.event.RegisterCommandsEvent
|
||||||
@ -64,6 +69,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
|||||||
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive
|
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive
|
||||||
import ru.dbotthepony.mc.otm.client.isShiftDown
|
import ru.dbotthepony.mc.otm.client.isShiftDown
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
import ru.dbotthepony.mc.otm.container.stream
|
import ru.dbotthepony.mc.otm.container.stream
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||||
@ -494,7 +500,7 @@ object MatterManager {
|
|||||||
ResolvedRecipe(
|
ResolvedRecipe(
|
||||||
it.ingredients.stream()
|
it.ingredients.stream()
|
||||||
.filter { !it.isActuallyEmpty }
|
.filter { !it.isActuallyEmpty }
|
||||||
.map { it.items.stream().map(::ImmutableStack) },
|
.map { it.items.stream().map(::RecipeEntry) },
|
||||||
ImmutableStack(it.resultItem),
|
ImmutableStack(it.resultItem),
|
||||||
isCritical = isCritical,
|
isCritical = isCritical,
|
||||||
name = it.id,
|
name = it.id,
|
||||||
@ -511,6 +517,91 @@ object MatterManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registrar.register("crafting") {
|
||||||
|
Finder { server, data ->
|
||||||
|
val allowBacktrack = data["allow_backtrack"]?.asBoolean ?: true
|
||||||
|
val ignoreDamageables = data["ignore_damageables"]?.asBoolean ?: false
|
||||||
|
val isCritical = data["is_critical"]?.asBoolean ?: true
|
||||||
|
var stream = server.recipeManager.byType(RecipeType.CRAFTING).values.parallelStream().filter { !it.isIncomplete }
|
||||||
|
|
||||||
|
if (ignoreDamageables) {
|
||||||
|
stream = stream.filter { it.ingredients.stream().flatMap { it.items.stream() }.noneMatch { it.isDamageableItem } }
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.map {
|
||||||
|
val width: Int
|
||||||
|
val height: Int
|
||||||
|
|
||||||
|
if (it is IShapedRecipe<*>) {
|
||||||
|
width = it.recipeWidth
|
||||||
|
height = it.recipeHeight
|
||||||
|
} else {
|
||||||
|
width = it.ingredients.size
|
||||||
|
height = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
val container = CraftingContainer(object : AbstractContainerMenu(null, 0) {
|
||||||
|
override fun quickMoveStack(pPlayer: Player, pIndex: Int): ItemStack {
|
||||||
|
return ItemStack.EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stillValid(pPlayer: Player): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}, width, height)
|
||||||
|
|
||||||
|
val realIngredients = ArrayList<ArrayList<RecipeEntry>>()
|
||||||
|
|
||||||
|
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 result = ArrayList<RecipeEntry>()
|
||||||
|
|
||||||
|
for (item in it.ingredients[c].items) {
|
||||||
|
container[c] = item
|
||||||
|
|
||||||
|
if (!it.assemble(container).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)
|
||||||
|
}
|
||||||
|
|
||||||
|
ResolvedRecipe(
|
||||||
|
realIngredients.stream().map { it.stream() },
|
||||||
|
ImmutableStack(it.resultItem),
|
||||||
|
isCritical = isCritical,
|
||||||
|
name = it.id,
|
||||||
|
allowBacktrack = allowBacktrack
|
||||||
|
)
|
||||||
|
}.filter {
|
||||||
|
if (it.inputs.isEmpty()) {
|
||||||
|
LOGGER.warn("${it.formattedName} with output '${it.output.item.registryName}' ended up with no inputs!")
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var foundResolvers: Map<ResourceLocation, Pair<Finder, JsonObject>> = ImmutableMap.of()
|
private var foundResolvers: Map<ResourceLocation, Pair<Finder, JsonObject>> = ImmutableMap.of()
|
||||||
@ -586,7 +677,7 @@ object MatterManager {
|
|||||||
|
|
||||||
for (input1 in recipe.inputs) {
|
for (input1 in recipe.inputs) {
|
||||||
for (input in input1) {
|
for (input in input1) {
|
||||||
input2Recipes.computeIfAbsent(input.item, Reference2ObjectFunction { ReferenceOpenHashSet() }).add(recipe)
|
input2Recipes.computeIfAbsent(input.input.item, Reference2ObjectFunction { ReferenceOpenHashSet() }).add(recipe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -606,7 +697,7 @@ object MatterManager {
|
|||||||
private fun doTryToBacktrack(item: Item, makeCommentary: Boolean): Result {
|
private fun doTryToBacktrack(item: Item, makeCommentary: Boolean): Result {
|
||||||
val recipes = input2Recipes[item]
|
val recipes = input2Recipes[item]
|
||||||
|
|
||||||
if (recipes == null || recipes.isEmpty() || !recipes.all { it.allowBacktrack } || !recipes.all { it.inputs.all { it.all { it.item == item } } }) {
|
if (recipes == null || recipes.isEmpty() || !recipes.all { it.allowBacktrack } || !recipes.all { it.inputs.all { it.all { it.input.item == item } } }) {
|
||||||
if (makeCommentary)
|
if (makeCommentary)
|
||||||
comment(item, TextComponent("Item '${item.registryName}' has no recipes"))
|
comment(item, TextComponent("Item '${item.registryName}' has no recipes"))
|
||||||
|
|
||||||
@ -713,28 +804,29 @@ 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 skips = ArrayList<RecipeEntry>()
|
||||||
val recursiveSkips = ArrayList<ImmutableStack>()
|
val recursiveSkips = ArrayList<RecipeEntry>()
|
||||||
|
var hadResidue = false
|
||||||
|
|
||||||
innerInputsLoop@ for (input in inputs) {
|
innerInputsLoop@ for (entry in inputs) {
|
||||||
val ivalue = determineValue(input.item)
|
val ivalue = determineValue(entry.input.item)
|
||||||
|
|
||||||
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 $entry at input slot $i in ${recipe.formattedName} has no matter value"))
|
||||||
|
|
||||||
if (recipe.isCritical && !lenientStage) {
|
if (recipe.isCritical && !lenientStage) {
|
||||||
return Result.MISSING
|
return Result.MISSING
|
||||||
} else {
|
} else {
|
||||||
if (recipe.isCritical) {
|
if (recipe.isCritical) {
|
||||||
skips.add(input)
|
skips.add(entry)
|
||||||
continue@innerInputsLoop
|
continue@innerInputsLoop
|
||||||
} else {
|
} else {
|
||||||
continue@recipesLoop
|
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 $entry at input slot $i in ${recipe.formattedName} is recursive"))
|
||||||
recursiveSkips.add(input)
|
recursiveSkips.add(entry)
|
||||||
|
|
||||||
if (inputs.size == 1) {
|
if (inputs.size == 1) {
|
||||||
hadSkips = true
|
hadSkips = true
|
||||||
@ -744,14 +836,52 @@ object MatterManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minimal == null || minimal > ivalue.value!!) {
|
var realValue = ivalue.value!!
|
||||||
minimal = ivalue.value
|
val ivalue2 = entry.remainder?.item?.let(::determineValue)
|
||||||
minimalMultiplier = input.multiplier
|
|
||||||
|
if (ivalue2 != null) {
|
||||||
|
if (ivalue2.isMissing) {
|
||||||
|
comment(item, TextComponent("Remainder of $entry at input slot $i in ${recipe.formattedName} has no matter value"))
|
||||||
|
|
||||||
|
if (recipe.isCritical && !lenientStage) {
|
||||||
|
return Result.MISSING
|
||||||
|
} else {
|
||||||
|
if (recipe.isCritical) {
|
||||||
|
skips.add(entry)
|
||||||
|
continue@innerInputsLoop
|
||||||
|
} else {
|
||||||
|
continue@recipesLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ivalue2.isSkipped) {
|
||||||
|
comment(item, TextComponent("Remainder of $entry at input slot $i in ${recipe.formattedName} is recursive"))
|
||||||
|
recursiveSkips.add(entry)
|
||||||
|
|
||||||
|
if (inputs.size == 1) {
|
||||||
|
hadSkips = true
|
||||||
|
continue@recipesLoop
|
||||||
|
} else {
|
||||||
|
continue@innerInputsLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
realValue = MatterValue(realValue.matter - ivalue2.value!!.matter, realValue.complexity - ivalue2.value.complexity)
|
||||||
|
hadResidue = true
|
||||||
|
|
||||||
|
if (realValue.matter.isNegative || realValue.complexity < 0.0) {
|
||||||
|
comment(item, TextComponent("Entry $entry at input slot $i in ${recipe.formattedName} ended up with negative matter value or/and complexity"))
|
||||||
|
return Result.MISSING
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minimal == null || minimal > realValue) {
|
||||||
|
minimal = realValue
|
||||||
|
minimalMultiplier = entry.input.multiplier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skips.size > inputs.size / 2 || skips.isNotEmpty() && inputs.size == 1) {
|
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"))
|
comment(item, TextComponent("More than half inputs (${skips.joinToString(", ")}) at input slot $i in ${recipe.formattedName} have no matter values"))
|
||||||
return Result.MISSING
|
return Result.MISSING
|
||||||
} else if (skips.isNotEmpty()) {
|
} else if (skips.isNotEmpty()) {
|
||||||
/**
|
/**
|
||||||
@ -769,7 +899,7 @@ object MatterManager {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val list = manager.getReverseTag(input.item).getOrNull()?.tagKeys?.collect(ImmutableList.toImmutableList()) ?: ImmutableList.of()
|
val list = manager.getReverseTag(input.input.item).getOrNull()?.tagKeys?.collect(ImmutableList.toImmutableList()) ?: ImmutableList.of()
|
||||||
|
|
||||||
if (input !in skips) {
|
if (input !in skips) {
|
||||||
for (tag in list)
|
for (tag in list)
|
||||||
@ -786,7 +916,7 @@ object MatterManager {
|
|||||||
val result = filtered.all { tagSetsMissing.getInt(it.key) == skips.size }
|
val result = filtered.all { tagSetsMissing.getInt(it.key) == skips.size }
|
||||||
|
|
||||||
if (!result) {
|
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"))
|
comment(item, TextComponent("More than half inputs (${skips.joinToString(", ")}) at input slot $i in ${recipe.formattedName} have no matter values"))
|
||||||
return Result.MISSING
|
return Result.MISSING
|
||||||
} else {
|
} else {
|
||||||
comment(item, TextComponent("${recipe.formattedName} with inputs at slot $i without matter values were allowed to be skipped due to next tags:"))
|
comment(item, TextComponent("${recipe.formattedName} with inputs at slot $i without matter values were allowed to be skipped due to next tags:"))
|
||||||
@ -797,8 +927,13 @@ object MatterManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (minimal != null && !minimal.hasMatterValue && hadResidue && inputs.size == 1) {
|
||||||
|
// ингредиент ничего не стоит ибо не потребляется в крафте
|
||||||
|
continue@inputsLoop
|
||||||
|
}
|
||||||
|
|
||||||
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(", ")}) (???)"))
|
||||||
return Result.MISSING
|
return Result.MISSING
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1241,8 +1376,20 @@ object MatterManager {
|
|||||||
constructor(item: ItemStack) : this(item.item, item.count)
|
constructor(item: ItemStack) : this(item.item, item.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class RecipeEntry(
|
||||||
|
val input: ImmutableStack,
|
||||||
|
val remainder: ImmutableStack? = null
|
||||||
|
) {
|
||||||
|
constructor(item: Item, count: Int) : this(ImmutableStack(item, count))
|
||||||
|
constructor(item: ItemStack) : this(ImmutableStack(item))
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "RecipeEntry[${input.item.registryName} to ${remainder?.item?.registryName}]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ResolvedRecipe(
|
class ResolvedRecipe(
|
||||||
inputs: Stream<Stream<ImmutableStack>>,
|
inputs: Stream<Stream<RecipeEntry>>,
|
||||||
val output: ImmutableStack,
|
val output: ImmutableStack,
|
||||||
val transformMatterValue: (Decimal) -> Decimal = { it },
|
val transformMatterValue: (Decimal) -> Decimal = { it },
|
||||||
val transformComplexity: (Double) -> Double = { it },
|
val transformComplexity: (Double) -> Double = { it },
|
||||||
@ -1260,25 +1407,42 @@ object MatterManager {
|
|||||||
* (e.g. 4 rabbit hides -> 1 leather), we can assume that we can determine matter value of ingredients based on matter value of output
|
* (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:
|
* "Backtrack" can happen if everything of the next holds true:
|
||||||
* * All recipes with item in question contains only that item; and
|
* * All recipes with item in question contains only that item;
|
||||||
* * All recipes allow backtracking
|
* * All recipes allow backtracking
|
||||||
*/
|
*/
|
||||||
val allowBacktrack: Boolean = true,
|
val allowBacktrack: Boolean = true,
|
||||||
) {
|
) {
|
||||||
val inputs: List<List<ImmutableStack>> = inputs
|
val inputs: List<List<RecipeEntry>> = inputs
|
||||||
.map { it.filter { it.multiplier > 0.0 }.collect(ImmutableList.toImmutableList()) }
|
.map { it.filter { it.input.multiplier > 0.0 }.collect(ImmutableList.toImmutableList()) }
|
||||||
.filter { it.isNotEmpty() }
|
.filter { it.isNotEmpty() }
|
||||||
.collect(ImmutableList.toImmutableList())
|
.collect(ImmutableList.toImmutableList())
|
||||||
|
|
||||||
constructor(
|
|
||||||
inputs: Collection<Collection<ImmutableStack>>,
|
|
||||||
output: ImmutableStack,
|
|
||||||
transformMatterValue: (Decimal) -> Decimal = { it },
|
|
||||||
transformComplexity: (Double) -> Double = { it },
|
|
||||||
) : this(inputs.stream().map { it.stream() }, output, transformMatterValue, transformComplexity)
|
|
||||||
|
|
||||||
val formattedName: String
|
val formattedName: String
|
||||||
get() = if (name == null) "One of recipes" else "Recipe '$name'"
|
get() = if (name == null) "One of recipes" else "Recipe '$name'"
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is ResolvedRecipe) return false
|
||||||
|
|
||||||
|
if (output != other.output) return false
|
||||||
|
if (transformMatterValue != other.transformMatterValue) return false
|
||||||
|
if (transformComplexity != other.transformComplexity) return false
|
||||||
|
if (isCritical != other.isCritical) return false
|
||||||
|
if (allowBacktrack != other.allowBacktrack) return false
|
||||||
|
if (inputs != other.inputs) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = output.hashCode()
|
||||||
|
result = 31 * result + transformMatterValue.hashCode()
|
||||||
|
result = 31 * result + transformComplexity.hashCode()
|
||||||
|
result = 31 * result + isCritical.hashCode()
|
||||||
|
result = 31 * result + allowBacktrack.hashCode()
|
||||||
|
result = 31 * result + inputs.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun interface Finder {
|
fun interface Finder {
|
||||||
@ -1293,7 +1457,7 @@ object MatterManager {
|
|||||||
*
|
*
|
||||||
* You can safely call [MatterManager.getDirect] inside returned stream, both parallel and sequential.
|
* 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, data: JsonObject): Stream<ResolvedRecipe>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1304,7 +1468,18 @@ object MatterManager {
|
|||||||
return Registry.direct(value)
|
return Registry.direct(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access recipe finders registry
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if calling too early
|
||||||
|
*/
|
||||||
@JvmStatic val recipeFinders get() = Resolver.delegate.get()
|
@JvmStatic val recipeFinders get() = Resolver.delegate.get()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access recipe finders registry key
|
||||||
|
*
|
||||||
|
* Use this with your [DeferredRegister]
|
||||||
|
*/
|
||||||
@JvmStatic val recipeFindersKey get() = Resolver.delegate.key
|
@JvmStatic val recipeFindersKey get() = Resolver.delegate.key
|
||||||
|
|
||||||
private val commentary = Reference2ObjectOpenHashMap<Item, ArrayList<Component>>()
|
private val commentary = Reference2ObjectOpenHashMap<Item, ArrayList<Component>>()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"recipe_type": "minecraft:crafting",
|
"recipe_type": "minecraft:crafting",
|
||||||
"type": "overdrive_that_matters:simple",
|
"type": "overdrive_that_matters:crafting",
|
||||||
"is_critical": true
|
"is_critical": true
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user