JEI Transfer handler for matter entangler, plate press and painting table

This commit is contained in:
DBotThePony 2023-08-21 00:59:54 +07:00
parent 15b718f28a
commit 4356117f7d
Signed by: DBot
GPG Key ID: DCC23B5715498507
5 changed files with 207 additions and 151 deletions

View File

@ -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<ExopackInventoryMenu, CraftingRecipe> {
private val transfer = helper.createUnregisteredRecipeTransferHandler(object : IRecipeTransferInfo<ExopackInventoryMenu, CraftingRecipe> {
override fun getContainerClass(): Class<out ExopackInventoryMenu> {
return ExopackInventoryMenu::class.java
}
override fun getMenuType(): Optional<MenuType<ExopackInventoryMenu>> {
return Optional.empty()
}
override fun getRecipeType(): mezz.jei.api.recipe.RecipeType<CraftingRecipe> {
return RecipeTypes.CRAFTING
}
override fun canHandle(container: ExopackInventoryMenu, recipe: CraftingRecipe): Boolean {
return true
}
override fun getRecipeSlots(
container: ExopackInventoryMenu,
recipe: CraftingRecipe
): List<Slot> {
return container.craftingSlots
}
override fun getInventorySlots(
container: ExopackInventoryMenu,
recipe: CraftingRecipe
): List<Slot> {
return container.playerInventorySlots
}
})
override fun getContainerClass(): Class<out ExopackInventoryMenu> {
return ExopackInventoryMenu::class.java
}
override fun getMenuType(): Optional<MenuType<ExopackInventoryMenu>> {
return Optional.empty()
}
override fun getRecipeType(): mezz.jei.api.recipe.RecipeType<CraftingRecipe> {
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<IRecipeSlotView>()
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<IRecipeSlotView>(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<IRecipeSlotView> {
return combined
}
override fun getSlotViews(role: RecipeIngredientRole): List<IRecipeSlotView> {
return when (role) {
RecipeIngredientRole.INPUT -> filteredInputs
RecipeIngredientRole.OUTPUT -> outputs
RecipeIngredientRole.CATALYST -> catalysts
RecipeIngredientRole.RENDER_ONLY -> render
}
}
override fun findSlotByName(slotName: String): Optional<IRecipeSlotView> {
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)
}
}

View File

@ -1,20 +1,12 @@
package ru.dbotthepony.mc.otm.compat.jei 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.IModPlugin
import mezz.jei.api.JeiPlugin import mezz.jei.api.JeiPlugin
import mezz.jei.api.constants.RecipeTypes import mezz.jei.api.constants.RecipeTypes
import mezz.jei.api.constants.VanillaTypes import mezz.jei.api.constants.VanillaTypes
import mezz.jei.api.gui.handlers.IGuiContainerHandler 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.helpers.IJeiHelpers
import mezz.jei.api.ingredients.ITypedIngredient 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.IGuiHandlerRegistration
import mezz.jei.api.registration.IRecipeCatalystRegistration import mezz.jei.api.registration.IRecipeCatalystRegistration
import mezz.jei.api.registration.IRecipeCategoryRegistration import mezz.jei.api.registration.IRecipeCategoryRegistration
@ -23,22 +15,18 @@ import mezz.jei.api.registration.IRecipeTransferRegistration
import mezz.jei.api.runtime.IClickableIngredient import mezz.jei.api.runtime.IClickableIngredient
import net.minecraft.client.renderer.Rect2i import net.minecraft.client.renderer.Rect2i
import net.minecraft.resources.ResourceLocation 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.ItemStack
import net.minecraft.world.item.crafting.CraftingRecipe
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu
import ru.dbotthepony.mc.otm.core.toImmutableList import ru.dbotthepony.mc.otm.menu.matter.MatterEntanglerMenu
import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu 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.MItems
import ru.dbotthepony.mc.otm.registry.MRecipes import ru.dbotthepony.mc.otm.registry.MRecipes
import java.util.* import java.util.*
import java.util.stream.Collectors import java.util.stream.Collectors
import kotlin.collections.ArrayList
import kotlin.properties.Delegates import kotlin.properties.Delegates
var isJeiLoaded = false var isJeiLoaded = false
@ -93,138 +81,11 @@ class JEIPlugin : IModPlugin {
override fun registerRecipeTransferHandlers(registration: IRecipeTransferRegistration) { override fun registerRecipeTransferHandlers(registration: IRecipeTransferRegistration) {
val helper = registration.transferHelper val helper = registration.transferHelper
registration.addRecipeTransferHandler(object : IRecipeTransferHandler<ExopackInventoryMenu, CraftingRecipe> { registration.addRecipeTransferHandler(ExopackInventoryTransferHandler(helper), RecipeTypes.CRAFTING)
private val transfer = helper.createUnregisteredRecipeTransferHandler(object : IRecipeTransferInfo<ExopackInventoryMenu, CraftingRecipe> { registration.addRecipeTransferHandler(simpleTransferInfo(MatterEntanglerRecipeCategory.recipeType, MatterEntanglerMenu::inputs))
override fun getContainerClass(): Class<out ExopackInventoryMenu> { registration.addRecipeTransferHandler(simpleTransferInfo0(PainterRecipeCategory.recipeType, PainterMenu::inputSlot))
return ExopackInventoryMenu::class.java registration.addRecipeTransferHandler(simpleTransferInfo0(PlatePressRecipeCategory.recipeType, PlatePressMenu::inputSlot))
} registration.addRecipeTransferHandler(simpleTransferInfo(PlatePressRecipeCategory.recipeType, TwinPlatePressMenu::inputSlots))
override fun getMenuType(): Optional<MenuType<ExopackInventoryMenu>> {
return Optional.empty()
}
override fun getRecipeType(): mezz.jei.api.recipe.RecipeType<CraftingRecipe> {
return RecipeTypes.CRAFTING
}
override fun canHandle(container: ExopackInventoryMenu, recipe: CraftingRecipe): Boolean {
return true
}
override fun getRecipeSlots(
container: ExopackInventoryMenu,
recipe: CraftingRecipe
): List<Slot> {
return container.craftingSlots
}
override fun getInventorySlots(
container: ExopackInventoryMenu,
recipe: CraftingRecipe
): List<Slot> {
return container.playerInventorySlots
}
})
override fun getContainerClass(): Class<out ExopackInventoryMenu> {
return ExopackInventoryMenu::class.java
}
override fun getMenuType(): Optional<MenuType<ExopackInventoryMenu>> {
return Optional.empty()
}
override fun getRecipeType(): mezz.jei.api.recipe.RecipeType<CraftingRecipe> {
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<IRecipeSlotView>()
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<IRecipeSlotView>(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<IRecipeSlotView> {
return combined
}
override fun getSlotViews(role: RecipeIngredientRole): List<IRecipeSlotView> {
return when (role) {
RecipeIngredientRole.INPUT -> filteredInputs
RecipeIngredientRole.OUTPUT -> outputs
RecipeIngredientRole.CATALYST -> catalysts
RecipeIngredientRole.RENDER_ONLY -> render
}
}
override fun findSlotByName(slotName: String): Optional<IRecipeSlotView> {
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)
} }
override fun registerGuiHandlers(registration: IGuiHandlerRegistration) { override fun registerGuiHandlers(registration: IGuiHandlerRegistration) {

View File

@ -53,8 +53,8 @@ object MatterEntanglerRecipeCategory : IRecipeCategory<IMatterEntanglerRecipe>,
} }
override fun setRecipe(builder: IRecipeLayoutBuilder, recipe: IMatterEntanglerRecipe, focuses: IFocusGroup) { 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]) builder.addSlot(RecipeIngredientRole.INPUT, 30 + x * 18, 4 + y * 18).addIngredients(recipe.ingredients[x, y])
} }
} }

View File

@ -54,7 +54,7 @@ object PainterRecipeCategory : IRecipeCategory<PainterRecipe>, IDrawable {
var y = 0 var y = 0
for ((dye, count) in recipe.dyes) { 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) }) .addIngredients(VanillaTypes.ITEM_STACK, Ingredient.of(dye.tag).items.map { it.copyWithCount(count) })
y++ y++

View File

@ -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 <reified M : MatteryMenu, R : Recipe<*>> simpleTransferInfo(type: RecipeType<R>, crossinline slots: (M) -> List<Slot>): IRecipeTransferInfo<M, R> {
return object : IRecipeTransferInfo<M, R> {
override fun getContainerClass(): Class<out M> {
return M::class.java
}
override fun getMenuType(): Optional<MenuType<M>> {
return Optional.empty()
}
override fun getRecipeType(): RecipeType<R> {
return type
}
override fun canHandle(container: M, recipe: R): Boolean {
return true
}
override fun getRecipeSlots(container: M, recipe: R): List<Slot> {
return slots.invoke(container)
}
override fun getInventorySlots(container: M, recipe: R): List<Slot> {
return container.playerInventorySlots
}
}
}
inline fun <reified M : MatteryMenu, R : Recipe<*>> simpleTransferInfo0(type: RecipeType<R>, crossinline slot: (M) -> Slot): IRecipeTransferInfo<M, R> {
return simpleTransferInfo(type) { listOf(slot.invoke(it)) }
}