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
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<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)
}
}, 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) {

View File

@ -53,8 +53,8 @@ object MatterEntanglerRecipeCategory : IRecipeCategory<IMatterEntanglerRecipe>,
}
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])
}
}

View File

@ -54,7 +54,7 @@ object PainterRecipeCategory : IRecipeCategory<PainterRecipe>, 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++

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)) }
}