refactor: forge recipe as item list agnostic
This commit is contained in:
@@ -22,7 +22,6 @@ import net.minecraft.util.ActionResult
|
|||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
import moe.nea.firmament.compat.rei.recipes.GenericREIRecipe
|
import moe.nea.firmament.compat.rei.recipes.GenericREIRecipe
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBEssenceUpgradeRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBEssenceUpgradeRecipe
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBForgeRecipe
|
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBKatRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBKatRecipe
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBMobDropRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBMobDropRecipe
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBRecipe
|
||||||
@@ -34,6 +33,7 @@ import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen
|
|||||||
import moe.nea.firmament.repo.RepoManager
|
import moe.nea.firmament.repo.RepoManager
|
||||||
import moe.nea.firmament.repo.SBItemStack
|
import moe.nea.firmament.repo.SBItemStack
|
||||||
import moe.nea.firmament.repo.recipes.SBCraftingRecipeRenderer
|
import moe.nea.firmament.repo.recipes.SBCraftingRecipeRenderer
|
||||||
|
import moe.nea.firmament.repo.recipes.SBForgeRecipeRenderer
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
import moe.nea.firmament.util.guessRecipeId
|
import moe.nea.firmament.util.guessRecipeId
|
||||||
@@ -84,12 +84,11 @@ class FirmamentReiPlugin : REIClientPlugin {
|
|||||||
|
|
||||||
val generics = listOf<GenericREIRecipe<*>>( // Order matters: The order in here is the order in which they show up in REI
|
val generics = listOf<GenericREIRecipe<*>>( // Order matters: The order in here is the order in which they show up in REI
|
||||||
GenericREIRecipe(SBCraftingRecipeRenderer),
|
GenericREIRecipe(SBCraftingRecipeRenderer),
|
||||||
|
GenericREIRecipe(SBForgeRecipeRenderer),
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun registerCategories(registry: CategoryRegistry) {
|
override fun registerCategories(registry: CategoryRegistry) {
|
||||||
registry.add(generics)
|
registry.add(generics)
|
||||||
registry.add(SBForgeRecipe.Category)
|
|
||||||
registry.add(SBMobDropRecipe.Category)
|
registry.add(SBMobDropRecipe.Category)
|
||||||
registry.add(SBKatRecipe.Category)
|
registry.add(SBKatRecipe.Category)
|
||||||
registry.add(SBReforgeRecipe.Category)
|
registry.add(SBReforgeRecipe.Category)
|
||||||
@@ -110,9 +109,6 @@ class FirmamentReiPlugin : REIClientPlugin {
|
|||||||
SBReforgeRecipe.catIdentifier,
|
SBReforgeRecipe.catIdentifier,
|
||||||
SBReforgeRecipe.DynamicGenerator
|
SBReforgeRecipe.DynamicGenerator
|
||||||
)
|
)
|
||||||
registry.registerDisplayGenerator(
|
|
||||||
SBForgeRecipe.Category.categoryIdentifier,
|
|
||||||
SkyblockForgeRecipeDynamicGenerator)
|
|
||||||
registry.registerDisplayGenerator(
|
registry.registerDisplayGenerator(
|
||||||
SBMobDropRecipe.Category.categoryIdentifier,
|
SBMobDropRecipe.Category.categoryIdentifier,
|
||||||
SkyblockMobDropRecipeDynamicGenerator)
|
SkyblockMobDropRecipeDynamicGenerator)
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import moe.nea.firmament.repo.recipes.RecipeLayouter
|
|||||||
|
|
||||||
class REIRecipeLayouter : RecipeLayouter {
|
class REIRecipeLayouter : RecipeLayouter {
|
||||||
val container: MutableList<Widget> = mutableListOf()
|
val container: MutableList<Widget> = mutableListOf()
|
||||||
|
fun <T: Widget> add(t: T): T = t.also(container::add)
|
||||||
|
|
||||||
override fun createItemSlot(
|
override fun createItemSlot(
|
||||||
x: Int,
|
x: Int,
|
||||||
y: Int,
|
y: Int,
|
||||||
@@ -27,19 +29,22 @@ class REIRecipeLayouter : RecipeLayouter {
|
|||||||
RecipeLayouter.SlotKind.SMALL_OUTPUT -> slot.markOutput()
|
RecipeLayouter.SlotKind.SMALL_OUTPUT -> slot.markOutput()
|
||||||
RecipeLayouter.SlotKind.BIG_OUTPUT -> {
|
RecipeLayouter.SlotKind.BIG_OUTPUT -> {
|
||||||
slot.markOutput().disableBackground()
|
slot.markOutput().disableBackground()
|
||||||
container.add(Widgets.createResultSlotBackground(Point(x, y)))
|
add(Widgets.createResultSlotBackground(Point(x, y)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
container.add(slot)
|
add(slot)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTooltip(rectangle: Rectangle, label: Text) {
|
||||||
|
add(Widgets.createTooltip(rectangle, label))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createLabel(x: Int, y: Int, text: Text) {
|
override fun createLabel(x: Int, y: Int, text: Text) {
|
||||||
container.add(Widgets.createLabel(Point(x, y), text))
|
add(Widgets.createLabel(Point(x, y), text))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createArrow(x: Int, y: Int) {
|
override fun createArrow(x: Int, y: Int) =
|
||||||
container.add(Widgets.createArrow(Point(x, y)))
|
add(Widgets.createArrow(Point(x, y))).bounds
|
||||||
}
|
|
||||||
|
|
||||||
override fun createMoulConfig(
|
override fun createMoulConfig(
|
||||||
x: Int,
|
x: Int,
|
||||||
@@ -48,6 +53,10 @@ class REIRecipeLayouter : RecipeLayouter {
|
|||||||
h: Int,
|
h: Int,
|
||||||
component: GuiComponent
|
component: GuiComponent
|
||||||
) {
|
) {
|
||||||
container.add(wrapWidget(Rectangle(Point(x, y), Dimension(w, h)), component))
|
add(wrapWidget(Rectangle(Point(x, y), Dimension(w, h)), component))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createFire(ingredientsCenter: Point, animationTicks: Int) {
|
||||||
|
add(Widgets.createBurningFire(ingredientsCenter).animationDurationTicks(animationTicks.toDouble()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import me.shedaniel.rei.api.client.view.ViewSearchBuilder
|
|||||||
import me.shedaniel.rei.api.common.display.Display
|
import me.shedaniel.rei.api.common.display.Display
|
||||||
import me.shedaniel.rei.api.common.entry.EntryStack
|
import me.shedaniel.rei.api.common.entry.EntryStack
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBEssenceUpgradeRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBEssenceUpgradeRecipe
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBForgeRecipe
|
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBKatRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBKatRecipe
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBMobDropRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBMobDropRecipe
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBShopRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBShopRecipe
|
||||||
@@ -20,9 +19,6 @@ import moe.nea.firmament.repo.RepoManager
|
|||||||
import moe.nea.firmament.repo.SBItemStack
|
import moe.nea.firmament.repo.SBItemStack
|
||||||
|
|
||||||
|
|
||||||
val SkyblockForgeRecipeDynamicGenerator =
|
|
||||||
neuDisplayGenerator<SBForgeRecipe, NEUForgeRecipe> { SBForgeRecipe(it) }
|
|
||||||
|
|
||||||
val SkyblockMobDropRecipeDynamicGenerator =
|
val SkyblockMobDropRecipeDynamicGenerator =
|
||||||
neuDisplayGenerator<SBMobDropRecipe, NEUMobDropRecipe> { SBMobDropRecipe(it) }
|
neuDisplayGenerator<SBMobDropRecipe, NEUMobDropRecipe> { SBMobDropRecipe(it) }
|
||||||
val SkyblockShopRecipeDynamicGenerator =
|
val SkyblockShopRecipeDynamicGenerator =
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package moe.nea.firmament.compat.rei.recipes
|
package moe.nea.firmament.compat.rei.recipes
|
||||||
|
|
||||||
import io.github.moulberry.repo.data.NEUCraftingRecipe
|
import io.github.moulberry.repo.data.NEUCraftingRecipe
|
||||||
|
import io.github.moulberry.repo.data.NEURecipe
|
||||||
import me.shedaniel.math.Rectangle
|
import me.shedaniel.math.Rectangle
|
||||||
import me.shedaniel.rei.api.client.gui.Renderer
|
import me.shedaniel.rei.api.client.gui.Renderer
|
||||||
import me.shedaniel.rei.api.client.gui.widgets.Widget
|
import me.shedaniel.rei.api.client.gui.widgets.Widget
|
||||||
@@ -14,7 +15,7 @@ import moe.nea.firmament.compat.rei.REIRecipeLayouter
|
|||||||
import moe.nea.firmament.compat.rei.neuDisplayGeneratorWithItem
|
import moe.nea.firmament.compat.rei.neuDisplayGeneratorWithItem
|
||||||
import moe.nea.firmament.repo.recipes.GenericRecipeRenderer
|
import moe.nea.firmament.repo.recipes.GenericRecipeRenderer
|
||||||
|
|
||||||
class GenericREIRecipe<T : NEUCraftingRecipe>(
|
class GenericREIRecipe<T : NEURecipe>(
|
||||||
val renderer: GenericRecipeRenderer<T>,
|
val renderer: GenericRecipeRenderer<T>,
|
||||||
) : DisplayCategory<GenericRecipe<T>> {
|
) : DisplayCategory<GenericRecipe<T>> {
|
||||||
private val dynamicGenerator =
|
private val dynamicGenerator =
|
||||||
@@ -25,6 +26,10 @@ class GenericREIRecipe<T : NEUCraftingRecipe>(
|
|||||||
return categoryIdentifier
|
return categoryIdentifier
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getDisplayHeight(): Int {
|
||||||
|
return renderer.displayHeight
|
||||||
|
}
|
||||||
|
|
||||||
override fun getTitle(): Text? {
|
override fun getTitle(): Text? {
|
||||||
return renderer.title
|
return renderer.title
|
||||||
}
|
}
|
||||||
@@ -45,7 +50,7 @@ class GenericREIRecipe<T : NEUCraftingRecipe>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GenericRecipe<T : NEUCraftingRecipe>(
|
class GenericRecipe<T : NEURecipe>(
|
||||||
override val neuRecipe: T,
|
override val neuRecipe: T,
|
||||||
val id: CategoryIdentifier<GenericRecipe<T>>
|
val id: CategoryIdentifier<GenericRecipe<T>>
|
||||||
) : SBRecipe() {
|
) : SBRecipe() {
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
package moe.nea.firmament.compat.rei.recipes
|
|
||||||
|
|
||||||
import io.github.moulberry.repo.data.NEUForgeRecipe
|
|
||||||
import me.shedaniel.math.Point
|
|
||||||
import me.shedaniel.math.Rectangle
|
|
||||||
import me.shedaniel.rei.api.client.gui.Renderer
|
|
||||||
import me.shedaniel.rei.api.client.gui.widgets.Widget
|
|
||||||
import me.shedaniel.rei.api.client.gui.widgets.Widgets
|
|
||||||
import me.shedaniel.rei.api.client.registry.display.DisplayCategory
|
|
||||||
import me.shedaniel.rei.api.common.category.CategoryIdentifier
|
|
||||||
import kotlin.math.cos
|
|
||||||
import kotlin.math.sin
|
|
||||||
import kotlin.time.Duration.Companion.seconds
|
|
||||||
import net.minecraft.block.Blocks
|
|
||||||
import net.minecraft.text.Text
|
|
||||||
import moe.nea.firmament.Firmament
|
|
||||||
import moe.nea.firmament.compat.rei.SBItemEntryDefinition
|
|
||||||
import moe.nea.firmament.compat.rei.plus
|
|
||||||
|
|
||||||
class SBForgeRecipe(override val neuRecipe: NEUForgeRecipe) : SBRecipe() {
|
|
||||||
override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.categoryIdentifier
|
|
||||||
|
|
||||||
object Category : DisplayCategory<SBForgeRecipe> {
|
|
||||||
override fun getCategoryIdentifier(): CategoryIdentifier<SBForgeRecipe> =
|
|
||||||
CategoryIdentifier.of(Firmament.MOD_ID, "forge_recipe")
|
|
||||||
|
|
||||||
override fun getTitle(): Text = Text.literal("Forge Recipes")
|
|
||||||
override fun getDisplayHeight(): Int {
|
|
||||||
return 104
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getIcon(): Renderer = SBItemEntryDefinition.getPassthrough(Blocks.ANVIL)
|
|
||||||
override fun setupDisplay(display: SBForgeRecipe, bounds: Rectangle): List<Widget> {
|
|
||||||
return buildList {
|
|
||||||
add(Widgets.createRecipeBase(bounds))
|
|
||||||
add(Widgets.createResultSlotBackground(Point(bounds.minX + 124, bounds.minY + 46)))
|
|
||||||
val arrow = Widgets.createArrow(Point(bounds.minX + 90, bounds.minY + 54 - 18 / 2))
|
|
||||||
add(arrow)
|
|
||||||
add(Widgets.createTooltip(arrow.bounds,
|
|
||||||
Text.stringifiedTranslatable("firmament.recipe.forge.time",
|
|
||||||
display.neuRecipe.duration.seconds)))
|
|
||||||
val ingredientsCenter = Point(bounds.minX + 49 - 8, bounds.minY + 54 - 8)
|
|
||||||
add(Widgets.createBurningFire(ingredientsCenter).animationDurationTicks(25.0))
|
|
||||||
val count = display.neuRecipe.inputs.size
|
|
||||||
if (count == 1) {
|
|
||||||
add(
|
|
||||||
Widgets.createSlot(Point(ingredientsCenter.x, ingredientsCenter.y)).markInput()
|
|
||||||
.entry(SBItemEntryDefinition.getEntry(display.neuRecipe.inputs.single()))
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
display.neuRecipe.inputs.forEachIndexed { idx, ingredient ->
|
|
||||||
val rad = Math.PI * 2 * idx / count
|
|
||||||
add(
|
|
||||||
Widgets.createSlot(
|
|
||||||
Point(
|
|
||||||
cos(rad) * 30,
|
|
||||||
sin(rad) * 30,
|
|
||||||
) + ingredientsCenter
|
|
||||||
).markInput().entry(SBItemEntryDefinition.getEntry(ingredient))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
add(
|
|
||||||
Widgets.createSlot(Point(bounds.minX + 124, bounds.minY + 46)).markOutput().disableBackground()
|
|
||||||
.entry(SBItemEntryDefinition.getEntry(display.neuRecipe.outputStack))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -16,5 +16,6 @@ interface GenericRecipeRenderer<T : NEURecipe> {
|
|||||||
val title: Text
|
val title: Text
|
||||||
val identifier: Identifier
|
val identifier: Identifier
|
||||||
fun findAllRecipes(neuRepository: NEURepository): Iterable<T>
|
fun findAllRecipes(neuRepository: NEURepository): Iterable<T>
|
||||||
|
val displayHeight: Int get() = 66
|
||||||
val typ: Class<T>
|
val typ: Class<T>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package moe.nea.firmament.repo.recipes
|
package moe.nea.firmament.repo.recipes
|
||||||
|
|
||||||
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
|
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
|
||||||
|
import me.shedaniel.math.Point
|
||||||
|
import me.shedaniel.math.Rectangle
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import moe.nea.firmament.repo.SBItemStack
|
import moe.nea.firmament.repo.SBItemStack
|
||||||
|
|
||||||
@@ -21,13 +23,16 @@ interface RecipeLayouter {
|
|||||||
slotKind: SlotKind,
|
slotKind: SlotKind,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun createTooltip(rectangle: Rectangle, label: Text)
|
||||||
|
|
||||||
fun createLabel(
|
fun createLabel(
|
||||||
x: Int, y: Int,
|
x: Int, y: Int,
|
||||||
text: Text
|
text: Text
|
||||||
)
|
)
|
||||||
|
|
||||||
fun createArrow(x: Int, y: Int)
|
fun createArrow(x: Int, y: Int): Rectangle
|
||||||
|
|
||||||
fun createMoulConfig(x: Int, y: Int, w: Int, h: Int, component: GuiComponent)
|
fun createMoulConfig(x: Int, y: Int, w: Int, h: Int, component: GuiComponent)
|
||||||
|
fun createFire(ingredientsCenter: Point, animationTicks: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
82
src/main/kotlin/repo/recipes/SBForgeRecipeRenderer.kt
Normal file
82
src/main/kotlin/repo/recipes/SBForgeRecipeRenderer.kt
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package moe.nea.firmament.repo.recipes
|
||||||
|
|
||||||
|
import io.github.moulberry.repo.NEURepository
|
||||||
|
import io.github.moulberry.repo.data.NEUCraftingRecipe
|
||||||
|
import io.github.moulberry.repo.data.NEUForgeRecipe
|
||||||
|
import me.shedaniel.math.Point
|
||||||
|
import me.shedaniel.math.Rectangle
|
||||||
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.sin
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
import net.minecraft.block.Blocks
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import moe.nea.firmament.Firmament
|
||||||
|
import moe.nea.firmament.repo.SBItemStack
|
||||||
|
import moe.nea.firmament.util.tr
|
||||||
|
|
||||||
|
object SBForgeRecipeRenderer : GenericRecipeRenderer<NEUForgeRecipe> {
|
||||||
|
override fun render(
|
||||||
|
recipe: NEUForgeRecipe,
|
||||||
|
bounds: Rectangle,
|
||||||
|
layouter: RecipeLayouter
|
||||||
|
) {
|
||||||
|
val arrow = layouter.createArrow(bounds.minX + 90, bounds.minY + 54 - 18 / 2)
|
||||||
|
layouter.createTooltip(
|
||||||
|
arrow,
|
||||||
|
Text.stringifiedTranslatable(
|
||||||
|
"firmament.recipe.forge.time",
|
||||||
|
recipe.duration.seconds
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val ingredientsCenter = Point(bounds.minX + 49 - 8, bounds.minY + 54 - 8)
|
||||||
|
layouter.createFire(ingredientsCenter, 25)
|
||||||
|
val count = recipe.inputs.size
|
||||||
|
if (count == 1) {
|
||||||
|
layouter.createItemSlot(
|
||||||
|
ingredientsCenter.x, ingredientsCenter.y - 18,
|
||||||
|
SBItemStack(recipe.inputs.single()),
|
||||||
|
RecipeLayouter.SlotKind.SMALL_INPUT,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
recipe.inputs.forEachIndexed { idx, ingredient ->
|
||||||
|
val rad = Math.PI * 2 * idx / count
|
||||||
|
layouter.createItemSlot(
|
||||||
|
(ingredientsCenter.x + cos(rad) * 30).toInt(), (ingredientsCenter.y + sin(rad) * 30).toInt(),
|
||||||
|
SBItemStack(ingredient),
|
||||||
|
RecipeLayouter.SlotKind.SMALL_INPUT,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layouter.createItemSlot(
|
||||||
|
bounds.minX + 124, bounds.minY + 46,
|
||||||
|
SBItemStack(recipe.outputStack),
|
||||||
|
RecipeLayouter.SlotKind.BIG_OUTPUT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val displayHeight: Int
|
||||||
|
get() = 104
|
||||||
|
|
||||||
|
override fun getInputs(recipe: NEUForgeRecipe): Collection<SBItemStack> {
|
||||||
|
return recipe.inputs.mapNotNull { SBItemStack(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOutputs(recipe: NEUForgeRecipe): Collection<SBItemStack> {
|
||||||
|
return listOfNotNull(SBItemStack(recipe.outputStack))
|
||||||
|
}
|
||||||
|
|
||||||
|
override val icon: ItemStack = ItemStack(Blocks.ANVIL)
|
||||||
|
override val title: Text = tr("firmament.category.forge", "Forge Recipes")
|
||||||
|
override val identifier: Identifier = Firmament.identifier("forge_recipe")
|
||||||
|
|
||||||
|
override fun findAllRecipes(neuRepository: NEURepository): Iterable<NEUForgeRecipe> {
|
||||||
|
// TODO: theres gotta be an index for these tbh.
|
||||||
|
return neuRepository.items.items.values.flatMap { it.recipes }.filterIsInstance<NEUForgeRecipe>()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val typ: Class<NEUForgeRecipe>
|
||||||
|
get() = NEUForgeRecipe::class.java
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user