aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/kotlin/features/items/recipes/ArrowWidget.kt38
-rw-r--r--src/main/kotlin/features/items/recipes/ComponentWidget.kt27
-rw-r--r--src/main/kotlin/features/items/recipes/EntityWidget.kt22
-rw-r--r--src/main/kotlin/features/items/recipes/FireWidget.kt20
-rw-r--r--src/main/kotlin/features/items/recipes/ItemSlotWidget.kt126
-rw-r--r--src/main/kotlin/features/items/recipes/RecipeRegistry.kt110
-rw-r--r--src/main/kotlin/features/items/recipes/RecipeScreen.kt29
-rw-r--r--src/main/kotlin/features/items/recipes/RecipeWidget.kt33
-rw-r--r--src/main/kotlin/features/items/recipes/RenderableRecipe.kt27
-rw-r--r--src/main/kotlin/features/items/recipes/StandaloneRecipeRenderer.kt74
-rw-r--r--src/main/kotlin/features/items/recipes/TooltipWidget.kt27
-rw-r--r--src/main/kotlin/repo/recipes/GenericRecipeRenderer.kt2
-rw-r--r--src/main/kotlin/repo/recipes/RecipeLayouter.kt7
-rw-r--r--src/main/kotlin/util/mc/Rectangle.kt11
14 files changed, 550 insertions, 3 deletions
diff --git a/src/main/kotlin/features/items/recipes/ArrowWidget.kt b/src/main/kotlin/features/items/recipes/ArrowWidget.kt
new file mode 100644
index 0000000..93c768a
--- /dev/null
+++ b/src/main/kotlin/features/items/recipes/ArrowWidget.kt
@@ -0,0 +1,38 @@
+package moe.nea.firmament.features.items.recipes
+
+import me.shedaniel.math.Dimension
+import me.shedaniel.math.Point
+import me.shedaniel.math.Rectangle
+import net.minecraft.client.gui.GuiGraphics
+import net.minecraft.client.renderer.RenderPipelines
+import net.minecraft.resources.ResourceLocation
+
+class ArrowWidget(val point: Point) : RecipeWidget() {
+ override val rect: Rectangle
+ get() = Rectangle(point, Dimension(14, 14))
+
+ companion object {
+ val arrowSprite = ResourceLocation.withDefaultNamespace("container/furnace/lit_progress")
+ }
+
+ override fun render(
+ guiGraphics: GuiGraphics,
+ mouseX: Int,
+ mouseY: Int,
+ partialTick: Float
+ ) {
+ guiGraphics.blitSprite(
+ RenderPipelines.GUI_TEXTURED,
+ arrowSprite,
+ 14,
+ 14,
+ 0,
+ 0,
+ point.x,
+ point.y,
+ 14,
+ 14
+ )
+ }
+
+}
diff --git a/src/main/kotlin/features/items/recipes/ComponentWidget.kt b/src/main/kotlin/features/items/recipes/ComponentWidget.kt
new file mode 100644
index 0000000..b5c4211
--- /dev/null
+++ b/src/main/kotlin/features/items/recipes/ComponentWidget.kt
@@ -0,0 +1,27 @@
+package moe.nea.firmament.features.items.recipes
+
+import me.shedaniel.math.Dimension
+import me.shedaniel.math.Point
+import me.shedaniel.math.Rectangle
+import net.minecraft.client.gui.GuiGraphics
+import net.minecraft.network.chat.Component
+import moe.nea.firmament.repo.recipes.RecipeLayouter
+import moe.nea.firmament.util.MC
+
+class ComponentWidget(val point: Point, var text: Component) : RecipeWidget(), RecipeLayouter.Updater<Component> {
+ override fun update(newValue: Component) {
+ this.text = newValue
+ }
+
+ override val rect: Rectangle
+ get() = Rectangle(point, Dimension(MC.font.width(text), MC.font.lineHeight))
+
+ override fun render(
+ guiGraphics: GuiGraphics,
+ mouseX: Int,
+ mouseY: Int,
+ partialTick: Float
+ ) {
+ guiGraphics.drawString(MC.font, text, point.x, point.y, -1)
+ }
+}
diff --git a/src/main/kotlin/features/items/recipes/EntityWidget.kt b/src/main/kotlin/features/items/recipes/EntityWidget.kt
new file mode 100644
index 0000000..88d91ad
--- /dev/null
+++ b/src/main/kotlin/features/items/recipes/EntityWidget.kt
@@ -0,0 +1,22 @@
+package moe.nea.firmament.features.items.recipes
+
+import me.shedaniel.math.Rectangle
+import net.minecraft.client.gui.GuiGraphics
+import net.minecraft.world.entity.LivingEntity
+import moe.nea.firmament.gui.entity.EntityRenderer
+
+class EntityWidget(override val rect: Rectangle, val entity: LivingEntity) : RecipeWidget() {
+ override fun render(
+ guiGraphics: GuiGraphics,
+ mouseX: Int,
+ mouseY: Int,
+ partialTick: Float
+ ) {
+ EntityRenderer.renderEntity(
+ entity, guiGraphics,
+ rect.x, rect.y,
+ rect.width.toDouble(), rect.height.toDouble(),
+ mouseX.toDouble(), mouseY.toDouble()
+ )
+ }
+}
diff --git a/src/main/kotlin/features/items/recipes/FireWidget.kt b/src/main/kotlin/features/items/recipes/FireWidget.kt
new file mode 100644
index 0000000..0594d0a
--- /dev/null
+++ b/src/main/kotlin/features/items/recipes/FireWidget.kt
@@ -0,0 +1,20 @@
+package moe.nea.firmament.features.items.recipes
+
+import me.shedaniel.math.Dimension
+import me.shedaniel.math.Point
+import me.shedaniel.math.Rectangle
+import net.minecraft.client.gui.GuiGraphics
+
+class FireWidget(val point: Point, val animationTicks: Int) : RecipeWidget() {
+ override val rect: Rectangle
+ get() = Rectangle(point, Dimension(10, 10))
+
+ override fun render(
+ guiGraphics: GuiGraphics,
+ mouseX: Int,
+ mouseY: Int,
+ partialTick: Float
+ ) {
+ TODO("Not yet implemented")
+ }
+}
diff --git a/src/main/kotlin/features/items/recipes/ItemSlotWidget.kt b/src/main/kotlin/features/items/recipes/ItemSlotWidget.kt
new file mode 100644
index 0000000..ef0b7d6
--- /dev/null
+++ b/src/main/kotlin/features/items/recipes/ItemSlotWidget.kt
@@ -0,0 +1,126 @@
+package moe.nea.firmament.features.items.recipes
+
+import java.util.Optional
+import me.shedaniel.math.Dimension
+import me.shedaniel.math.Point
+import me.shedaniel.math.Rectangle
+import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback
+import net.minecraft.client.gui.GuiGraphics
+import net.minecraft.client.gui.components.Tooltip
+import net.minecraft.network.chat.Component
+import net.minecraft.util.FormattedCharSequence
+import net.minecraft.world.inventory.tooltip.TooltipComponent
+import net.minecraft.world.item.Item
+import net.minecraft.world.item.ItemStack
+import net.minecraft.world.item.TooltipFlag
+import moe.nea.firmament.events.ItemTooltipEvent
+import moe.nea.firmament.keybindings.GenericInputAction
+import moe.nea.firmament.keybindings.SavedKeyBinding
+import moe.nea.firmament.repo.ExpensiveItemCacheApi
+import moe.nea.firmament.repo.SBItemStack
+import moe.nea.firmament.repo.recipes.RecipeLayouter
+import moe.nea.firmament.util.ErrorUtil
+import moe.nea.firmament.util.FirmFormatters
+import moe.nea.firmament.util.FirmFormatters.shortFormat
+import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.TimeMark
+import moe.nea.firmament.util.darkGrey
+import moe.nea.firmament.util.mc.displayNameAccordingToNbt
+import moe.nea.firmament.util.mc.loreAccordingToNbt
+
+class ItemSlotWidget(
+ val point: Point,
+ var content: List<SBItemStack>,
+ val slotKind: RecipeLayouter.SlotKind
+) : RecipeWidget(),
+ RecipeLayouter.CyclingItemSlot {
+ val backgroundTopLeft =
+ if (slotKind.isBig) Point(point.x - 4, point.y - 4)
+ else Point(point.x - 1, point.y - 1)
+ val backgroundSize =
+ if (slotKind.isBig) Dimension(16 + 8, 16 + 8)
+ else Dimension(18, 18)
+ val itemRect = Rectangle(point, Dimension(16, 16))
+ override val rect: Rectangle
+ get() = Rectangle(backgroundTopLeft, backgroundSize)
+
+ @OptIn(ExpensiveItemCacheApi::class)
+ override fun render(
+ guiGraphics: GuiGraphics,
+ mouseX: Int,
+ mouseY: Int,
+ partialTick: Float
+ ) {
+ val stack = current().asImmutableItemStack()
+ // TODO: draw slot background
+ if (stack.isEmpty) return
+ guiGraphics.renderItem(stack, point.x, point.y)
+ guiGraphics.renderItemDecorations(
+ MC.font, stack, point.x, point.y,
+ if (stack.count >= SHORT_NUM_CUTOFF) shortFormat(stack.count.toDouble())
+ else null
+ )
+ if (itemRect.contains(mouseX, mouseY))
+ guiGraphics.setTooltipForNextFrame(
+ MC.font, getTooltip(stack), Optional.empty(),
+ mouseX, mouseY
+ )
+ }
+
+ companion object {
+ val SHORT_NUM_CUTOFF = 1000
+ var canUseTooltipEvent = true
+ }
+
+ fun getTooltip(itemStack: ItemStack): List<Component> {
+ val lore = mutableListOf(itemStack.displayNameAccordingToNbt)
+ lore.addAll(itemStack.loreAccordingToNbt)
+ if (canUseTooltipEvent) {
+ try {
+ ItemTooltipCallback.EVENT.invoker().getTooltip(
+ itemStack, Item.TooltipContext.EMPTY,
+ TooltipFlag.NORMAL, lore
+ )
+ } catch (ex: Exception) {
+ canUseTooltipEvent = false
+ ErrorUtil.softError("Failed to use vanilla tooltips", ex)
+ }
+ } else {
+ ItemTooltipEvent.publish(
+ ItemTooltipEvent(
+ itemStack,
+ Item.TooltipContext.EMPTY,
+ TooltipFlag.NORMAL,
+ lore
+ )
+ )
+ }
+ if (itemStack.count >= SHORT_NUM_CUTOFF && lore.isNotEmpty())
+ lore.add(1, Component.literal("${itemStack.count}x").darkGrey())
+ return lore
+ }
+
+ override fun tick() {
+ if (SavedKeyBinding.isShiftDown()) return
+ if (content.size <= 1) return
+ if (MC.currentTick % 5 != 0) return
+ index = (index + 1) % content.size
+ }
+
+ var index = 0
+ var onUpdate: () -> Unit = {}
+
+ override fun onUpdate(action: () -> Unit) {
+ this.onUpdate = action
+ }
+
+ override fun current(): SBItemStack {
+ return content.getOrElse(index) { SBItemStack.EMPTY }
+ }
+
+ override fun update(newValue: SBItemStack) {
+ content = listOf(newValue)
+ // SAFE: content was just assigned to a non-empty list
+ index = index.coerceIn(content.indices)
+ }
+}
diff --git a/src/main/kotlin/features/items/recipes/RecipeRegistry.kt b/src/main/kotlin/features/items/recipes/RecipeRegistry.kt
new file mode 100644
index 0000000..158f9a4
--- /dev/null
+++ b/src/main/kotlin/features/items/recipes/RecipeRegistry.kt
@@ -0,0 +1,110 @@
+package moe.nea.firmament.features.items.recipes
+
+import com.mojang.blaze3d.platform.InputConstants
+import io.github.moulberry.repo.IReloadable
+import io.github.moulberry.repo.NEURepository
+import net.fabricmc.fabric.mixin.client.gametest.input.InputUtilMixin
+import moe.nea.firmament.annotations.Subscribe
+import moe.nea.firmament.events.HandledScreenKeyPressedEvent
+import moe.nea.firmament.events.ReloadRegistrationEvent
+import moe.nea.firmament.keybindings.SavedKeyBinding
+import moe.nea.firmament.repo.RepoManager
+import moe.nea.firmament.repo.SBItemStack
+import moe.nea.firmament.repo.recipes.GenericRecipeRenderer
+import moe.nea.firmament.repo.recipes.SBCraftingRecipeRenderer
+import moe.nea.firmament.repo.recipes.SBEssenceUpgradeRecipeRenderer
+import moe.nea.firmament.repo.recipes.SBForgeRecipeRenderer
+import moe.nea.firmament.repo.recipes.SBReforgeRecipeRenderer
+import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.SkyblockId
+import moe.nea.firmament.util.focusedItemStack
+
+object RecipeRegistry {
+ val recipeTypes: List<GenericRecipeRenderer<*>> = listOf(
+ SBCraftingRecipeRenderer,
+ SBForgeRecipeRenderer,
+ SBReforgeRecipeRenderer,
+ SBEssenceUpgradeRecipeRenderer,
+ )
+
+
+ @Subscribe
+ fun onDebugRecipe(event: HandledScreenKeyPressedEvent) {
+ if (event.matches(SavedKeyBinding.keyWithoutMods(InputConstants.KEY_R))) {
+ val stack = event.screen.focusedItemStack ?: return
+ val recipes = getRecipesFor(SBItemStack(stack))
+ MC.screen = RecipeScreen(recipes.firstOrNull() ?: return)
+ }
+ }
+
+
+ object RecipeIndexes : IReloadable {
+
+ private fun <T : Any> createIndexFor(
+ neuRepository: NEURepository,
+ recipeRenderer: GenericRecipeRenderer<T>,
+ outputs: Boolean,
+ ): List<Pair<SkyblockId, RenderableRecipe<T>>> {
+ val indexer: (T) -> Collection<SBItemStack> =
+ if (outputs) recipeRenderer::getOutputs
+ else recipeRenderer::getInputs
+ return recipeRenderer.findAllRecipes(neuRepository)
+ .flatMap {
+ val wrappedRecipe = RenderableRecipe(it, recipeRenderer, null)
+ indexer(it).map { it.skyblockId to wrappedRecipe }
+ }
+ }
+
+ fun createIndex(outputs: Boolean): MutableMap<SkyblockId, List<RenderableRecipe<*>>> {
+ val m: MutableMap<SkyblockId, List<RenderableRecipe<*>>> = mutableMapOf()
+ recipeTypes.forEach { renderer ->
+ createIndexFor(RepoManager.neuRepo, renderer, outputs)
+ .forEach { (stack, recipe) ->
+ m.merge(stack, listOf(recipe)) { a, b -> a + b }
+ }
+ }
+ return m
+ }
+
+ lateinit var recipesForIndex : Map<SkyblockId, List<RenderableRecipe<*>>>
+ lateinit var usagesForIndex : Map<SkyblockId, List<RenderableRecipe<*>>>
+ override fun reload(recipe: NEURepository) {
+ recipesForIndex = createIndex(true)
+ usagesForIndex = createIndex(false)
+ }
+ }
+
+ @Subscribe
+ fun onRepoBuild(event: ReloadRegistrationEvent) {
+ event.repo.registerReloadListener(RecipeIndexes)
+ }
+
+
+ fun getRecipesFor(itemStack: SBItemStack): Set<RenderableRecipe<*>> {
+ val recipes = LinkedHashSet<RenderableRecipe<*>>()
+ recipeTypes.forEach { injectRecipesFor(it, recipes, itemStack, true) }
+ recipes.addAll(RecipeIndexes.recipesForIndex[itemStack.skyblockId] ?: emptyList())
+ return recipes
+ }
+
+ fun getUsagesFor(itemStack: SBItemStack): Set<RenderableRecipe<*>> {
+ val recipes = LinkedHashSet<RenderableRecipe<*>>()
+ recipeTypes.forEach { injectRecipesFor(it, recipes, itemStack, false) }
+ recipes.addAll(RecipeIndexes.usagesForIndex[itemStack.skyblockId] ?: emptyList())
+ return recipes
+ }
+
+ private fun <T : Any> injectRecipesFor(
+ recipeRenderer: GenericRecipeRenderer<T>,
+ collector: MutableCollection<RenderableRecipe<*>>,
+ relevantItem: SBItemStack,
+ mustBeInOutputs: Boolean
+ ) {
+ collector.addAll(
+ recipeRenderer.discoverExtraRecipes(RepoManager.neuRepo, relevantItem, mustBeInOutputs)
+ .map { RenderableRecipe(it, recipeRenderer, relevantItem) }
+ )
+ }
+
+
+}
diff --git a/src/main/kotlin/features/items/recipes/RecipeScreen.kt b/src/main/kotlin/features/items/recipes/RecipeScreen.kt
new file mode 100644
index 0000000..c94839d
--- /dev/null
+++ b/src/main/kotlin/features/items/recipes/RecipeScreen.kt
@@ -0,0 +1,29 @@
+package moe.nea.firmament.features.items.recipes
+
+import me.shedaniel.math.Rectangle
+import net.minecraft.client.gui.screens.Screen
+import moe.nea.firmament.repo.SBItemStack
+import moe.nea.firmament.util.tr
+
+class RecipeScreen(
+ val recipes: RenderableRecipe<*>,
+) : Screen(tr("firmament.recipe.screen", "SkyBlock Recipe")) {
+
+ lateinit var layoutedRecipe: StandaloneRecipeRenderer
+ override fun init() {// TODO: wrap all of this in a scroll layout
+ super.init()
+ val bounds = Rectangle(
+ width / 2 - recipes.renderer.displayWidth / 2,
+ height / 2 - recipes.renderer.displayHeight / 2,
+ recipes.renderer.displayWidth,
+ recipes.renderer.displayHeight
+ )
+ layoutedRecipe = recipes.render(bounds)
+ layoutedRecipe.widgets.forEach(this::addRenderableWidget)
+ }
+
+ override fun tick() {
+ super.tick()
+ layoutedRecipe.tick()
+ }
+}
diff --git a/src/main/kotlin/features/items/recipes/RecipeWidget.kt b/src/main/kotlin/features/items/recipes/RecipeWidget.kt
new file mode 100644
index 0000000..2818d05
--- /dev/null
+++ b/src/main/kotlin/features/items/recipes/RecipeWidget.kt
@@ -0,0 +1,33 @@
+package moe.nea.firmament.features.items.recipes
+
+import me.shedaniel.math.Rectangle
+import net.minecraft.client.gui.components.Renderable
+import net.minecraft.client.gui.components.events.GuiEventListener
+import net.minecraft.client.gui.narration.NarratableEntry
+import net.minecraft.client.gui.narration.NarrationElementOutput
+import net.minecraft.client.gui.navigation.ScreenRectangle
+import moe.nea.firmament.util.mc.asScreenRectangle
+
+abstract class RecipeWidget : GuiEventListener, Renderable, NarratableEntry {
+ override fun narrationPriority(): NarratableEntry.NarrationPriority? {
+ return NarratableEntry.NarrationPriority.NONE// I am so sorry
+ }
+
+ override fun updateNarration(narrationElementOutput: NarrationElementOutput) {
+ }
+
+ open fun tick() {}
+ private var _focused = false
+ abstract val rect: Rectangle
+ override fun setFocused(focused: Boolean) {
+ this._focused = focused
+ }
+
+ override fun getRectangle(): ScreenRectangle {
+ return rect.asScreenRectangle()
+ }
+
+ override fun isFocused(): Boolean {
+ return this._focused
+ }
+}
diff --git a/src/main/kotlin/features/items/recipes/RenderableRecipe.kt b/src/main/kotlin/features/items/recipes/RenderableRecipe.kt
new file mode 100644
index 0000000..3601e9e
--- /dev/null
+++ b/src/main/kotlin/features/items/recipes/RenderableRecipe.kt
@@ -0,0 +1,27 @@
+package moe.nea.firmament.features.items.recipes
+
+import java.util.Objects
+import me.shedaniel.math.Rectangle
+import moe.nea.firmament.repo.SBItemStack
+import moe.nea.firmament.repo.recipes.GenericRecipeRenderer
+
+class RenderableRecipe<T : Any>(
+ val recipe: T,
+ val renderer: GenericRecipeRenderer<T>,
+ val mainItemStack: SBItemStack?,
+) {
+ fun render(bounds: Rectangle): StandaloneRecipeRenderer {
+ val layouter = StandaloneRecipeRenderer()
+ renderer.render(recipe, bounds, layouter, mainItemStack)
+ return layouter
+ }
+
+// override fun equals(other: Any?): Boolean {
+// if (other !is RenderableRecipe<*>) return false
+// return renderer == other.renderer && recipe == other.recipe
+// }
+//
+// override fun hashCode(): Int {
+// return Objects.hash(recipe, renderer)
+// }
+}
diff --git a/src/main/kotlin/features/items/recipes/StandaloneRecipeRenderer.kt b/src/main/kotlin/features/items/recipes/StandaloneRecipeRenderer.kt
new file mode 100644
index 0000000..df7c4de
--- /dev/null
+++ b/src/main/kotlin/features/items/recipes/StandaloneRecipeRenderer.kt
@@ -0,0 +1,74 @@
+package moe.nea.firmament.features.items.recipes
+
+import io.github.notenoughupdates.moulconfig.gui.GuiComponent
+import me.shedaniel.math.Point
+import me.shedaniel.math.Rectangle
+import net.minecraft.client.gui.components.events.AbstractContainerEventHandler
+import net.minecraft.client.gui.components.events.GuiEventListener
+import net.minecraft.network.chat.Component
+import net.minecraft.world.entity.LivingEntity
+import moe.nea.firmament.repo.SBItemStack
+import moe.nea.firmament.repo.recipes.RecipeLayouter
+
+class StandaloneRecipeRenderer : AbstractContainerEventHandler(), RecipeLayouter {
+
+ fun tick() {
+ widgets.forEach { it.tick() }
+ }
+
+ fun <T : RecipeWidget> addWidget(widget: T): T {
+ this.widgets.add(widget)
+ return widget
+ }
+
+ override fun createCyclingItemSlot(
+ x: Int,
+ y: Int,
+ content: List<SBItemStack>,
+ slotKind: RecipeLayouter.SlotKind
+ ): RecipeLayouter.CyclingItemSlot {
+ return addWidget(ItemSlotWidget(Point(x, y), content, slotKind))
+ }
+
+ override fun createTooltip(
+ rectangle: Rectangle,
+ label: List<Component>
+ ) {
+ addWidget(TooltipWidget(rectangle, label))
+ }
+
+ override fun createLabel(
+ x: Int,
+ y: Int,
+ text: Component
+ ): RecipeLayouter.Updater<Component> {
+ return addWidget(ComponentWidget(Point(x, y), text))
+ }
+
+ override fun createArrow(x: Int, y: Int): Rectangle {
+ return addWidget(ArrowWidget(Point(x, y))).rect
+ }
+
+ override fun createMoulConfig(
+ x: Int,
+ y: Int,
+ w: Int,
+ h: Int,
+ component: GuiComponent
+ ) {
+ TODO("Not yet implemented")
+ }
+
+ override fun createFire(point: Point, animationTicks: Int) {
+ addWidget(FireWidget(point, animationTicks))
+ }
+
+ override fun createEntity(rectangle: Rectangle, entity: LivingEntity) {
+ addWidget(EntityWidget(rectangle, entity))
+ }
+
+ val widgets: MutableList<RecipeWidget> = mutableListOf()
+ override fun children(): List<GuiEventListener> {
+ return widgets
+ }
+}
diff --git a/src/main/kotlin/features/items/recipes/TooltipWidget.kt b/src/main/kotlin/features/items/recipes/TooltipWidget.kt
new file mode 100644
index 0000000..cf9c09a
--- /dev/null
+++ b/src/main/kotlin/features/items/recipes/TooltipWidget.kt
@@ -0,0 +1,27 @@
+package moe.nea.firmament.features.items.recipes
+
+import me.shedaniel.math.Rectangle
+import net.minecraft.client.gui.GuiGraphics
+import net.minecraft.network.chat.Component
+import moe.nea.firmament.repo.recipes.RecipeLayouter
+
+class TooltipWidget(
+ override val rect: Rectangle,
+ label: List<Component>
+) : RecipeWidget(), RecipeLayouter.Updater<List<Component>> {
+ override fun update(newValue: List<Component>) {
+ this.formattedComponent = newValue.map { it.visualOrderText }
+ }
+
+ var formattedComponent = label.map { it.visualOrderText }
+ override fun render(
+ guiGraphics: GuiGraphics,
+ mouseX: Int,
+ mouseY: Int,
+ partialTick: Float
+ ) {
+ if (rect.contains(mouseX, mouseY))
+ guiGraphics.setTooltipForNextFrame(formattedComponent, mouseX, mouseY)
+ }
+
+}
diff --git a/src/main/kotlin/repo/recipes/GenericRecipeRenderer.kt b/src/main/kotlin/repo/recipes/GenericRecipeRenderer.kt
index c029494..84f1f48 100644
--- a/src/main/kotlin/repo/recipes/GenericRecipeRenderer.kt
+++ b/src/main/kotlin/repo/recipes/GenericRecipeRenderer.kt
@@ -16,6 +16,8 @@ interface GenericRecipeRenderer<T : Any> {
val title: Component
val identifier: ResourceLocation
fun findAllRecipes(neuRepository: NEURepository): Iterable<T>
+ fun discoverExtraRecipes(neuRepository: NEURepository, itemStack: SBItemStack, mustBeInOutputs: Boolean): Iterable<T> = emptyList()
val displayHeight: Int get() = 66
+ val displayWidth: Int get() = 150
val typ: Class<T>
}
diff --git a/src/main/kotlin/repo/recipes/RecipeLayouter.kt b/src/main/kotlin/repo/recipes/RecipeLayouter.kt
index b211d9c..7a63941 100644
--- a/src/main/kotlin/repo/recipes/RecipeLayouter.kt
+++ b/src/main/kotlin/repo/recipes/RecipeLayouter.kt
@@ -18,7 +18,8 @@ interface RecipeLayouter {
* Create a bigger background and mark the slot as output. The coordinates should still refer the upper left corner of the item stack, not of the bigger background.
*/
BIG_OUTPUT,
- DISPLAY,
+ DISPLAY,;
+ val isBig get() = this == BIG_OUTPUT
}
@@ -32,7 +33,7 @@ interface RecipeLayouter {
x: Int, y: Int,
content: SBItemStack?,
slotKind: SlotKind,
- ): ItemSlot
+ ): ItemSlot = createCyclingItemSlot(x, y, listOfNotNull(content), slotKind)
interface CyclingItemSlot : ItemSlot {
fun onUpdate(action: () -> Unit)
@@ -59,7 +60,7 @@ interface RecipeLayouter {
fun createArrow(x: Int, y: Int): Rectangle
fun createMoulConfig(x: Int, y: Int, w: Int, h: Int, component: GuiComponent)
- fun createFire(ingredientsCenter: Point, animationTicks: Int)
+ fun createFire(point: Point, animationTicks: Int)
fun createEntity(rectangle: Rectangle, entity: LivingEntity)
}
diff --git a/src/main/kotlin/util/mc/Rectangle.kt b/src/main/kotlin/util/mc/Rectangle.kt
new file mode 100644
index 0000000..6495c29
--- /dev/null
+++ b/src/main/kotlin/util/mc/Rectangle.kt
@@ -0,0 +1,11 @@
+package moe.nea.firmament.util.mc
+
+import me.shedaniel.math.Rectangle
+import net.minecraft.client.gui.navigation.ScreenAxis
+import net.minecraft.client.gui.navigation.ScreenRectangle
+
+fun Rectangle.asScreenRectangle() =
+ ScreenRectangle.of(
+ ScreenAxis.HORIZONTAL,
+ x, y, width, height
+ )