feat: Add npc shop recipes

This commit is contained in:
Linnea Gräf
2025-01-21 02:09:11 +01:00
parent bb56231d43
commit 2a3a4c07f5
9 changed files with 117 additions and 5 deletions

View File

@@ -25,6 +25,7 @@ import moe.nea.firmament.compat.rei.recipes.SBForgeRecipe
import moe.nea.firmament.compat.rei.recipes.SBKatRecipe
import moe.nea.firmament.compat.rei.recipes.SBMobDropRecipe
import moe.nea.firmament.compat.rei.recipes.SBReforgeRecipe
import moe.nea.firmament.compat.rei.recipes.SBShopRecipe
import moe.nea.firmament.events.HandledScreenPushREIEvent
import moe.nea.firmament.features.inventory.CraftingOverlay
import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen
@@ -81,6 +82,7 @@ class FirmamentReiPlugin : REIClientPlugin {
registry.add(SBKatRecipe.Category)
registry.add(SBReforgeRecipe.Category)
registry.add(SBEssenceUpgradeRecipe.Category)
registry.add(SBShopRecipe.Category)
}
override fun registerExclusionZones(zones: ExclusionZones) {
@@ -102,6 +104,9 @@ class FirmamentReiPlugin : REIClientPlugin {
registry.registerDisplayGenerator(
SBMobDropRecipe.Category.categoryIdentifier,
SkyblockMobDropRecipeDynamicGenerator)
registry.registerDisplayGenerator(
SBShopRecipe.Category.categoryIdentifier,
SkyblockShopRecipeDynamicGenerator)
registry.registerDisplayGenerator(
SBKatRecipe.Category.categoryIdentifier,
SkyblockKatRecipeDynamicGenerator)

View File

@@ -18,10 +18,13 @@ import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
import net.minecraft.item.tooltip.TooltipType
import net.minecraft.text.Text
import moe.nea.firmament.compat.rei.FirmamentReiPlugin.Companion.asItemEntry
import moe.nea.firmament.events.ItemTooltipEvent
import moe.nea.firmament.repo.SBItemStack
import moe.nea.firmament.util.ErrorUtil
import moe.nea.firmament.util.FirmFormatters
import moe.nea.firmament.util.darkGrey
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
import moe.nea.firmament.util.mc.loreAccordingToNbt
@@ -40,8 +43,12 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack> {
context.matrices.translate(bounds.centerX.toFloat(), bounds.centerY.toFloat(), 0F)
context.matrices.scale(bounds.width.toFloat() / 16F, bounds.height.toFloat() / 16F, 1f)
val item = entry.asItemEntry().value
context.drawItemWithoutEntity(item, -8, -8, )
context.drawStackOverlay(minecraft.textRenderer, item, -8, -8)
context.drawItemWithoutEntity(item, -8, -8)
context.drawStackOverlay(minecraft.textRenderer, item, -8, -8,
if (entry.value.getStackSize() > 1000) FirmFormatters.shortFormat(entry.value.getStackSize()
.toDouble())
else null
)
context.matrices.pop()
}
@@ -70,6 +77,8 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack> {
lore
))
}
if (entry.value.getStackSize() > 1000 && lore.isNotEmpty())
lore.add(1, Text.literal("${entry.value.getStackSize()}x").darkGrey())
// TODO: tags aren't sent as early now so some tooltip components that use tags will crash the game
// stack.getTooltip(
// Item.TooltipContext.create(

View File

@@ -4,6 +4,7 @@ import io.github.moulberry.repo.data.NEUCraftingRecipe
import io.github.moulberry.repo.data.NEUForgeRecipe
import io.github.moulberry.repo.data.NEUKatUpgradeRecipe
import io.github.moulberry.repo.data.NEUMobDropRecipe
import io.github.moulberry.repo.data.NEUNpcShopRecipe
import io.github.moulberry.repo.data.NEURecipe
import java.util.Optional
import me.shedaniel.rei.api.client.registry.display.DynamicDisplayGenerator
@@ -15,6 +16,7 @@ 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.SBMobDropRecipe
import moe.nea.firmament.compat.rei.recipes.SBShopRecipe
import moe.nea.firmament.repo.EssenceRecipeProvider
import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.repo.SBItemStack
@@ -28,7 +30,8 @@ val SkyblockForgeRecipeDynamicGenerator =
val SkyblockMobDropRecipeDynamicGenerator =
neuDisplayGenerator<SBMobDropRecipe, NEUMobDropRecipe> { SBMobDropRecipe(it) }
val SkyblockShopRecipeDynamicGenerator =
neuDisplayGenerator<SBShopRecipe, NEUNpcShopRecipe> { SBShopRecipe(it) }
val SkyblockKatRecipeDynamicGenerator =
neuDisplayGenerator<SBKatRecipe, NEUKatUpgradeRecipe> { SBKatRecipe(it) }
val SkyblockEssenceRecipeDynamicGenerator =

View File

@@ -22,7 +22,7 @@ class SBCraftingRecipe(override val neuRecipe: NEUCraftingRecipe) : SBRecipe() {
override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.catIdentifier
object Category : DisplayCategory<SBCraftingRecipe> {
val catIdentifier = CategoryIdentifier.of<SBCraftingRecipe>(Firmament.MOD_ID, "crafing_recipe")
val catIdentifier = CategoryIdentifier.of<SBCraftingRecipe>(Firmament.MOD_ID, "crafting_recipe")
override fun getCategoryIdentifier(): CategoryIdentifier<out SBCraftingRecipe> = catIdentifier
override fun getTitle(): Text = Text.literal("SkyBlock Crafting")

View File

@@ -8,7 +8,6 @@ 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 me.shedaniel.rei.api.common.util.EntryStacks
import kotlin.math.cos
import kotlin.math.sin
import kotlin.time.Duration.Companion.seconds
@@ -41,6 +40,7 @@ class SBForgeRecipe(override val neuRecipe: NEUForgeRecipe) : SBRecipe() {
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(

View File

@@ -0,0 +1,61 @@
package moe.nea.firmament.compat.rei.recipes
import io.github.moulberry.repo.data.NEUNpcShopRecipe
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 me.shedaniel.rei.api.common.entry.EntryIngredient
import net.minecraft.item.Items
import net.minecraft.text.Text
import moe.nea.firmament.Firmament
import moe.nea.firmament.compat.rei.SBItemEntryDefinition
import moe.nea.firmament.util.skyblockId
class SBShopRecipe(override val neuRecipe: NEUNpcShopRecipe) : SBRecipe() {
override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.catIdentifier
val merchant = SBItemEntryDefinition.getEntry(neuRecipe.isSoldBy.skyblockId)
override fun getInputEntries(): List<EntryIngredient> {
return listOf(EntryIngredient.of(merchant)) + super.getInputEntries()
}
object Category : DisplayCategory<SBShopRecipe> {
val catIdentifier = CategoryIdentifier.of<SBShopRecipe>(Firmament.MOD_ID, "npc_shopping")
override fun getCategoryIdentifier(): CategoryIdentifier<SBShopRecipe> = catIdentifier
override fun getTitle(): Text = Text.literal("SkyBlock NPC Shopping")
override fun getIcon(): Renderer = SBItemEntryDefinition.getPassthrough(Items.EMERALD)
override fun setupDisplay(display: SBShopRecipe, bounds: Rectangle): List<Widget> {
val point = Point(bounds.centerX, bounds.centerY)
return buildList {
add(Widgets.createRecipeBase(bounds))
add(Widgets.createSlot(Point(point.x - 2 - 18 / 2, point.y - 18 - 6))
.unmarkInputOrOutput()
.entry(display.merchant)
.disableBackground())
add(Widgets.createArrow(Point(point.x - 2 - 24 / 2, point.y - 6)))
val cost = display.neuRecipe.cost
for ((i, item) in cost.withIndex()) {
add(Widgets.createSlot(Point(
point.x - 14 - 18,
point.y + i * 18 - 18 * cost.size / 2))
.entry(SBItemEntryDefinition.getEntry(item))
.markInput())
// TODO: fix frame clipping
}
add(Widgets.createResultSlotBackground(Point(point.x + 18, point.y - 18 / 2)))
add(
Widgets.createSlot(Point(point.x + 18, point.y - 18 / 2))
.entry(SBItemEntryDefinition.getEntry(display.neuRecipe.result))
.disableBackground().markOutput()
)
}
}
}
}