diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/ExopackInventoryTransferHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/ExopackInventoryTransferHandler.kt new file mode 100644 index 000000000..3572f1770 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/ExopackInventoryTransferHandler.kt @@ -0,0 +1,154 @@ +package ru.dbotthepony.mc.otm.compat.jei + +import it.unimi.dsi.fastutil.ints.Int2IntArrayMap +import it.unimi.dsi.fastutil.ints.IntArraySet +import mezz.jei.api.constants.RecipeTypes +import mezz.jei.api.gui.ingredient.IRecipeSlotView +import mezz.jei.api.gui.ingredient.IRecipeSlotsView +import mezz.jei.api.recipe.RecipeIngredientRole +import mezz.jei.api.recipe.transfer.IRecipeTransferError +import mezz.jei.api.recipe.transfer.IRecipeTransferHandler +import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper +import mezz.jei.api.recipe.transfer.IRecipeTransferInfo +import net.minecraft.world.entity.player.Player +import net.minecraft.world.inventory.MenuType +import net.minecraft.world.inventory.Slot +import net.minecraft.world.item.crafting.CraftingRecipe +import ru.dbotthepony.mc.otm.core.TranslatableComponent +import ru.dbotthepony.mc.otm.core.toImmutableList +import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu +import java.util.* +import kotlin.collections.ArrayList + +class ExopackInventoryTransferHandler(private val helper: IRecipeTransferHandlerHelper) : IRecipeTransferHandler { + private val transfer = helper.createUnregisteredRecipeTransferHandler(object : IRecipeTransferInfo { + override fun getContainerClass(): Class { + return ExopackInventoryMenu::class.java + } + + override fun getMenuType(): Optional> { + return Optional.empty() + } + + override fun getRecipeType(): mezz.jei.api.recipe.RecipeType { + return RecipeTypes.CRAFTING + } + + override fun canHandle(container: ExopackInventoryMenu, recipe: CraftingRecipe): Boolean { + return true + } + + override fun getRecipeSlots( + container: ExopackInventoryMenu, + recipe: CraftingRecipe + ): List { + return container.craftingSlots + } + + override fun getInventorySlots( + container: ExopackInventoryMenu, + recipe: CraftingRecipe + ): List { + return container.playerInventorySlots + } + }) + + override fun getContainerClass(): Class { + return ExopackInventoryMenu::class.java + } + + override fun getMenuType(): Optional> { + return Optional.empty() + } + + override fun getRecipeType(): mezz.jei.api.recipe.RecipeType { + return RecipeTypes.CRAFTING + } + + private val validSlots = IntArraySet().also { + it.add(0) + it.add(1) + it.add(3) + it.add(4) + } + + private val directMap = Int2IntArrayMap().also { + for (i in 0 .. 8) { + it.put(i, i) + } + } + + private val smallMap = Int2IntArrayMap().also { + var i = 0 + it.put(0, i++) + it.put(1, i++) + it.put(3, i++) + it.put(4, i) + } + + override fun transferRecipe( + container: ExopackInventoryMenu, + recipe: CraftingRecipe, + recipeSlots: IRecipeSlotsView, + player: Player, + maxTransfer: Boolean, + doTransfer: Boolean + ): IRecipeTransferError? { + val inputs = recipeSlots.getSlotViews(RecipeIngredientRole.INPUT) + + if (inputs.size != 9) { + return IRecipeTransferError { IRecipeTransferError.Type.INTERNAL } + } + + if (container.craftingSlots.size != 9) { + for ((i, ingredient) in inputs.withIndex()) { + if (!ingredient.isEmpty && i !in validSlots) { + return helper.createUserErrorWithTooltip(TranslatableComponent("jei.tooltip.error.recipe.transfer.too.large.player.inventory")) + } + } + + val filteredInputs = ArrayList() + + for ((i, ingredient) in inputs.withIndex()) { + if (i in validSlots) { + filteredInputs.add(ingredient) + } + } + + val outputs = recipeSlots.getSlotViews(RecipeIngredientRole.OUTPUT).toImmutableList() + val catalysts = recipeSlots.getSlotViews(RecipeIngredientRole.CATALYST).toImmutableList() + val render = recipeSlots.getSlotViews(RecipeIngredientRole.RENDER_ONLY).toImmutableList() + + val combine = ArrayList(filteredInputs.size + outputs.size + render.size) + + combine.addAll(filteredInputs) + combine.addAll(outputs) + combine.addAll(render) + + val combined = combine.toImmutableList() + + val newView = object : IRecipeSlotsView { + override fun getSlotViews(): List { + return combined + } + + override fun getSlotViews(role: RecipeIngredientRole): List { + return when (role) { + RecipeIngredientRole.INPUT -> filteredInputs + RecipeIngredientRole.OUTPUT -> outputs + RecipeIngredientRole.CATALYST -> catalysts + RecipeIngredientRole.RENDER_ONLY -> render + } + } + + override fun findSlotByName(slotName: String): Optional { + return combined.stream().filter { it.slotName.orElse(null) == slotName }.findAny() + } + } + + return this.transfer.transferRecipe(container, recipe, newView, player, maxTransfer, doTransfer) + } + + return this.transfer.transferRecipe(container, recipe, recipeSlots, player, maxTransfer, doTransfer) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt index fcc0617eb..70ada7c72 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt @@ -1,20 +1,12 @@ package ru.dbotthepony.mc.otm.compat.jei -import it.unimi.dsi.fastutil.ints.Int2IntArrayMap -import it.unimi.dsi.fastutil.ints.IntArraySet import mezz.jei.api.IModPlugin import mezz.jei.api.JeiPlugin import mezz.jei.api.constants.RecipeTypes import mezz.jei.api.constants.VanillaTypes import mezz.jei.api.gui.handlers.IGuiContainerHandler -import mezz.jei.api.gui.ingredient.IRecipeSlotView -import mezz.jei.api.gui.ingredient.IRecipeSlotsView import mezz.jei.api.helpers.IJeiHelpers import mezz.jei.api.ingredients.ITypedIngredient -import mezz.jei.api.recipe.RecipeIngredientRole -import mezz.jei.api.recipe.transfer.IRecipeTransferError -import mezz.jei.api.recipe.transfer.IRecipeTransferHandler -import mezz.jei.api.recipe.transfer.IRecipeTransferInfo import mezz.jei.api.registration.IGuiHandlerRegistration import mezz.jei.api.registration.IRecipeCatalystRegistration import mezz.jei.api.registration.IRecipeCategoryRegistration @@ -23,22 +15,18 @@ import mezz.jei.api.registration.IRecipeTransferRegistration import mezz.jei.api.runtime.IClickableIngredient import net.minecraft.client.renderer.Rect2i import net.minecraft.resources.ResourceLocation -import net.minecraft.world.entity.player.Player -import net.minecraft.world.inventory.MenuType -import net.minecraft.world.inventory.Slot import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.crafting.CraftingRecipe import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.screen.MatteryScreen -import ru.dbotthepony.mc.otm.core.TranslatableComponent -import ru.dbotthepony.mc.otm.core.toImmutableList -import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu +import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu +import ru.dbotthepony.mc.otm.menu.matter.MatterEntanglerMenu +import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu +import ru.dbotthepony.mc.otm.menu.tech.TwinPlatePressMenu import ru.dbotthepony.mc.otm.registry.MItems import ru.dbotthepony.mc.otm.registry.MRecipes import java.util.* import java.util.stream.Collectors -import kotlin.collections.ArrayList import kotlin.properties.Delegates var isJeiLoaded = false @@ -93,138 +81,11 @@ class JEIPlugin : IModPlugin { override fun registerRecipeTransferHandlers(registration: IRecipeTransferRegistration) { val helper = registration.transferHelper - registration.addRecipeTransferHandler(object : IRecipeTransferHandler { - private val transfer = helper.createUnregisteredRecipeTransferHandler(object : IRecipeTransferInfo { - override fun getContainerClass(): Class { - return ExopackInventoryMenu::class.java - } - - override fun getMenuType(): Optional> { - return Optional.empty() - } - - override fun getRecipeType(): mezz.jei.api.recipe.RecipeType { - return RecipeTypes.CRAFTING - } - - override fun canHandle(container: ExopackInventoryMenu, recipe: CraftingRecipe): Boolean { - return true - } - - override fun getRecipeSlots( - container: ExopackInventoryMenu, - recipe: CraftingRecipe - ): List { - return container.craftingSlots - } - - override fun getInventorySlots( - container: ExopackInventoryMenu, - recipe: CraftingRecipe - ): List { - return container.playerInventorySlots - } - }) - - override fun getContainerClass(): Class { - return ExopackInventoryMenu::class.java - } - - override fun getMenuType(): Optional> { - return Optional.empty() - } - - override fun getRecipeType(): mezz.jei.api.recipe.RecipeType { - return RecipeTypes.CRAFTING - } - - private val validSlots = IntArraySet().also { - it.add(0) - it.add(1) - it.add(3) - it.add(4) - } - - private val directMap = Int2IntArrayMap().also { - for (i in 0 .. 8) { - it.put(i, i) - } - } - - private val smallMap = Int2IntArrayMap().also { - var i = 0 - it.put(0, i++) - it.put(1, i++) - it.put(3, i++) - it.put(4, i) - } - - override fun transferRecipe( - container: ExopackInventoryMenu, - recipe: CraftingRecipe, - recipeSlots: IRecipeSlotsView, - player: Player, - maxTransfer: Boolean, - doTransfer: Boolean - ): IRecipeTransferError? { - val inputs = recipeSlots.getSlotViews(RecipeIngredientRole.INPUT) - - if (inputs.size != 9) { - return IRecipeTransferError { IRecipeTransferError.Type.INTERNAL } - } - - if (container.craftingSlots.size != 9) { - for ((i, ingredient) in inputs.withIndex()) { - if (!ingredient.isEmpty && i !in validSlots) { - return helper.createUserErrorWithTooltip(TranslatableComponent("jei.tooltip.error.recipe.transfer.too.large.player.inventory")) - } - } - - val filteredInputs = ArrayList() - - for ((i, ingredient) in inputs.withIndex()) { - if (i in validSlots) { - filteredInputs.add(ingredient) - } - } - - val outputs = recipeSlots.getSlotViews(RecipeIngredientRole.OUTPUT).toImmutableList() - val catalysts = recipeSlots.getSlotViews(RecipeIngredientRole.CATALYST).toImmutableList() - val render = recipeSlots.getSlotViews(RecipeIngredientRole.RENDER_ONLY).toImmutableList() - - val combine = ArrayList(filteredInputs.size + outputs.size + render.size) - - combine.addAll(filteredInputs) - combine.addAll(outputs) - combine.addAll(render) - - val combined = combine.toImmutableList() - - val newView = object : IRecipeSlotsView { - override fun getSlotViews(): List { - return combined - } - - override fun getSlotViews(role: RecipeIngredientRole): List { - return when (role) { - RecipeIngredientRole.INPUT -> filteredInputs - RecipeIngredientRole.OUTPUT -> outputs - RecipeIngredientRole.CATALYST -> catalysts - RecipeIngredientRole.RENDER_ONLY -> render - } - } - - override fun findSlotByName(slotName: String): Optional { - return combined.stream().filter { it.slotName.orElse(null) == slotName }.findAny() - } - } - - return this.transfer.transferRecipe(container, recipe, newView, player, maxTransfer, doTransfer) - } - - return this.transfer.transferRecipe(container, recipe, recipeSlots, player, maxTransfer, doTransfer) - } - }, RecipeTypes.CRAFTING) + registration.addRecipeTransferHandler(ExopackInventoryTransferHandler(helper), RecipeTypes.CRAFTING) + registration.addRecipeTransferHandler(simpleTransferInfo(MatterEntanglerRecipeCategory.recipeType, MatterEntanglerMenu::inputs)) + registration.addRecipeTransferHandler(simpleTransferInfo0(PainterRecipeCategory.recipeType, PainterMenu::inputSlot)) + registration.addRecipeTransferHandler(simpleTransferInfo0(PlatePressRecipeCategory.recipeType, PlatePressMenu::inputSlot)) + registration.addRecipeTransferHandler(simpleTransferInfo(PlatePressRecipeCategory.recipeType, TwinPlatePressMenu::inputSlots)) } override fun registerGuiHandlers(registration: IGuiHandlerRegistration) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/MatterEntanglerRecipeCategory.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/MatterEntanglerRecipeCategory.kt index 763f17658..c01c26672 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/MatterEntanglerRecipeCategory.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/MatterEntanglerRecipeCategory.kt @@ -53,8 +53,8 @@ object MatterEntanglerRecipeCategory : IRecipeCategory, } override fun setRecipe(builder: IRecipeLayoutBuilder, recipe: IMatterEntanglerRecipe, focuses: IFocusGroup) { - for (x in 0 until recipe.ingredients.width) { - for (y in 0 until recipe.ingredients.height) { + for (y in 0 until recipe.ingredients.height) { + for (x in 0 until recipe.ingredients.width) { builder.addSlot(RecipeIngredientRole.INPUT, 30 + x * 18, 4 + y * 18).addIngredients(recipe.ingredients[x, y]) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PainterRecipeCategory.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PainterRecipeCategory.kt index bda128ad6..a948eae2f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PainterRecipeCategory.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PainterRecipeCategory.kt @@ -54,7 +54,7 @@ object PainterRecipeCategory : IRecipeCategory, IDrawable { var y = 0 for ((dye, count) in recipe.dyes) { - builder.addSlot(RecipeIngredientRole.INPUT, 1 + x * 18, 1 + y * 18) + builder.addSlot(RecipeIngredientRole.CATALYST, 1 + x * 18, 1 + y * 18) .addIngredients(VanillaTypes.ITEM_STACK, Ingredient.of(dye.tag).items.map { it.copyWithCount(count) }) y++ diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/SimpleTransferInfo.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/SimpleTransferInfo.kt new file mode 100644 index 000000000..1e6d6c465 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/SimpleTransferInfo.kt @@ -0,0 +1,41 @@ +package ru.dbotthepony.mc.otm.compat.jei + +import mezz.jei.api.recipe.RecipeType +import mezz.jei.api.recipe.transfer.IRecipeTransferInfo +import net.minecraft.world.inventory.MenuType +import net.minecraft.world.inventory.Slot +import net.minecraft.world.item.crafting.Recipe +import ru.dbotthepony.mc.otm.menu.MatteryMenu +import java.util.* + +inline fun > simpleTransferInfo(type: RecipeType, crossinline slots: (M) -> List): IRecipeTransferInfo { + return object : IRecipeTransferInfo { + override fun getContainerClass(): Class { + return M::class.java + } + + override fun getMenuType(): Optional> { + return Optional.empty() + } + + override fun getRecipeType(): RecipeType { + return type + } + + override fun canHandle(container: M, recipe: R): Boolean { + return true + } + + override fun getRecipeSlots(container: M, recipe: R): List { + return slots.invoke(container) + } + + override fun getInventorySlots(container: M, recipe: R): List { + return container.playerInventorySlots + } + } +} + +inline fun > simpleTransferInfo0(type: RecipeType, crossinline slot: (M) -> Slot): IRecipeTransferInfo { + return simpleTransferInfo(type) { listOf(slot.invoke(it)) } +}