diff options
19 files changed, 601 insertions, 621 deletions
diff --git a/build.gradle.kts b/build.gradle.kts index 70f20f6..b157f58 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -106,16 +106,12 @@ fun String.capitalizeN() = replaceFirstChar { it.uppercaseChar() } val unpackAllJars by tasks.registering fun innerJarsOf(name: String, dependency: Dependency): Provider<FileTree> { val task = tasks.create("unpackInnerJarsFor${name.capitalizeN()}", InnerJarsUnpacker::class) { - doFirst { - println("Unpacking JARs for $name") - } this.inputJars.setFrom(files(configurations.detachedConfiguration(dependency))) this.outputDir.set(layout.buildDirectory.dir("unpackedJars/$name").also { it.get().asFile.mkdirs() }) } unpackAllJars { dependsOn(task) } - println("Constructed innerJars task: ${project.files(task).asFileTree.toList().map { it to it.exists() }}") return project.provider { project.files(task).asFileTree } @@ -217,8 +213,7 @@ val yaclSourceSet = createIsolatedSourceSet("yacl") val explosiveEnhancementSourceSet = createIsolatedSourceSet("explosiveEnhancement", isEnabled = false) // TODO: wait for their port val wildfireGenderSourceSet = createIsolatedSourceSet("wildfireGender", isEnabled = false) // TODO: wait on their port val modmenuSourceSet = createIsolatedSourceSet("modmenu") -val reiSourceSet = - createIsolatedSourceSet("rei", isEnabled = false) // TODO: read through https://hackmd.io/@shedaniel/rei17_primer +val reiSourceSet = createIsolatedSourceSet("rei") // TODO: read through https://hackmd.io/@shedaniel/rei17_primer dependencies { // Minecraft dependencies diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index efdc56d..117704f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -120,7 +120,7 @@ basicMath = { module = "me.shedaniel.cloth:basic-math", version.ref = "basicMath [bundles] runtime_required = [ -# "rei_fabric", + "rei_fabric", # "notenoughanimations", "hypixelmodapi_fabric", ] diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/EntityWidget.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/EntityWidget.kt index 9b7b190..b0efc98 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/EntityWidget.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/EntityWidget.kt @@ -4,32 +4,32 @@ import me.shedaniel.math.Dimension import me.shedaniel.math.Point import me.shedaniel.math.Rectangle import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds -import moe.nea.firmament.gui.entity.EntityRenderer import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.Element import net.minecraft.entity.LivingEntity +import moe.nea.firmament.gui.entity.EntityRenderer class EntityWidget(val entity: LivingEntity, val point: Point) : WidgetWithBounds() { - override fun children(): List<Element> { - return emptyList() - } + override fun children(): List<Element> { + return emptyList() + } - var hasErrored = false + var hasErrored = false - override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { - try { - if (!hasErrored) - EntityRenderer.renderEntity(entity, context, point.x, point.y, mouseX.toFloat(), mouseY.toFloat()) - } catch (ex: Exception) { - EntityRenderer.logger.error("Failed to render constructed entity: $entity", ex) - hasErrored = true - } - if (hasErrored) { - context.fill(point.x, point.y, point.x + 50, point.y + 80, 0xFFAA2222.toInt()) - } - } + override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { + try { + if (!hasErrored) + EntityRenderer.renderEntity(entity, context, point.x, point.y, mouseX.toFloat(), mouseY.toFloat()) + } catch (ex: Exception) { + EntityRenderer.logger.error("Failed to render constructed entity: $entity", ex) + hasErrored = true + } + if (hasErrored) { + context.fill(point.x, point.y, point.x + 50, point.y + 80, 0xFFAA2222.toInt()) + } + } - override fun getBounds(): Rectangle { - return Rectangle(point, Dimension(50, 80)) - } + override fun getBounds(): Rectangle { + return Rectangle(point, Dimension(50, 80)) + } } diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/FirmamentReiCommonPlugin.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/FirmamentReiCommonPlugin.kt new file mode 100644 index 0000000..98ac276 --- /dev/null +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/FirmamentReiCommonPlugin.kt @@ -0,0 +1,10 @@ +package moe.nea.firmament.compat.rei + +import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry +import me.shedaniel.rei.api.common.plugins.REICommonPlugin + +class FirmamentReiCommonPlugin : REICommonPlugin { + override fun registerEntryTypes(registry: EntryTypeRegistry) { + registry.register(FirmamentReiPlugin.SKYBLOCK_ITEM_TYPE_ID, SBItemEntryDefinition) + } +} diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/FirmamentReiPlugin.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/FirmamentReiPlugin.kt index d95d2d1..f576eda 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/FirmamentReiPlugin.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/FirmamentReiPlugin.kt @@ -11,7 +11,6 @@ import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry import me.shedaniel.rei.api.client.registry.transfer.TransferHandler import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRegistry import me.shedaniel.rei.api.common.entry.EntryStack -import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes import net.minecraft.client.gui.screen.Screen import net.minecraft.client.gui.screen.ingame.GenericContainerScreen @@ -20,18 +19,17 @@ import net.minecraft.item.ItemStack import net.minecraft.text.Text import net.minecraft.util.ActionResult import net.minecraft.util.Identifier -import moe.nea.firmament.events.HandledScreenPushREIEvent -import moe.nea.firmament.features.inventory.CraftingOverlay -import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen import moe.nea.firmament.compat.rei.recipes.SBCraftingRecipe 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.events.HandledScreenPushREIEvent +import moe.nea.firmament.features.inventory.CraftingOverlay +import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.repo.SBItemStack import moe.nea.firmament.util.MC -import moe.nea.firmament.util.ScreenUtil import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.guessRecipeId import moe.nea.firmament.util.skyblockId @@ -74,9 +72,6 @@ class FirmamentReiPlugin : REIClientPlugin { }) } - override fun registerEntryTypes(registry: EntryTypeRegistry) { - registry.register(SKYBLOCK_ITEM_TYPE_ID, SBItemEntryDefinition) - } override fun registerCategories(registry: CategoryRegistry) { registry.add(SBCraftingRecipe.Category) diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/HoveredItemStackProvider.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/HoveredItemStackProvider.kt index 3d21b66..b917c3e 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/HoveredItemStackProvider.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/HoveredItemStackProvider.kt @@ -21,6 +21,7 @@ class ScreenRegistryHoveredItemStackProvider : HoveredItemStackProvider { return entryStack.value as? ItemStack ?: entryStack.cheatsAs().value } } + @AutoService(HoveredItemStackProvider::class) @CompatLoader.RequireMod("roughlyenoughitems") class OverlayHoveredItemStackProvider : HoveredItemStackProvider { diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntryRenderer.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntryRenderer.kt index a02742b..da0b645 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntryRenderer.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntryRenderer.kt @@ -25,163 +25,120 @@ import net.minecraft.client.render.LightmapTextureManager import net.minecraft.client.render.OverlayTexture import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.model.BakedModel -import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.texture.SpriteAtlasTexture import net.minecraft.item.Item -import net.minecraft.item.ItemStack +import net.minecraft.item.ModelTransformationMode import net.minecraft.item.tooltip.TooltipType import moe.nea.firmament.compat.rei.FirmamentReiPlugin.Companion.asItemEntry import moe.nea.firmament.repo.SBItemStack +import moe.nea.firmament.util.MC object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<SBItemStack, BakedModel> { - override fun render( - entry: EntryStack<SBItemStack>, - context: DrawContext, - bounds: Rectangle, - mouseX: Int, - mouseY: Int, - delta: Float - ) { - entry.asItemEntry().render(context, bounds, mouseX, mouseY, delta) - } - - val minecraft = MinecraftClient.getInstance() - - override fun getTooltip(entry: EntryStack<SBItemStack>, tooltipContext: TooltipContext): Tooltip? { - val stack = entry.value.asImmutableItemStack() - val lore = stack.getTooltip( - Item.TooltipContext.DEFAULT, - null, - TooltipType.BASIC - ) - return Tooltip.create(lore) - } - - override fun getExtraData(entry: EntryStack<SBItemStack>): BakedModel { - return minecraft.itemRenderer.getModel(entry.asItemEntry().value, minecraft.world, minecraft.player, 0) - } - - override fun getBatchIdentifier(entry: EntryStack<SBItemStack>?, bounds: Rectangle?, extraData: BakedModel): Int { - return 1738923 + if (extraData.isSideLit) 1 else 0 - } - - override fun startBatch( - entry: EntryStack<SBItemStack>, - model: BakedModel, - graphics: DrawContext, - delta: Float - ) { - val modelViewStack = RenderSystem.getModelViewStack() - modelViewStack.pushMatrix() - modelViewStack.scale(20.0f, 20.0f, 1.0f) - RenderSystem.applyModelViewMatrix() - setupGL(model) - } - - fun setupGL(model: BakedModel) { - minecraft.textureManager.getTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE) - .setFilter(false, false) - RenderSystem.setShaderTexture(0, SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE) - RenderSystem.enableBlend() - RenderSystem.blendFunc(SrcFactor.SRC_ALPHA, DstFactor.ONE_MINUS_SRC_ALPHA) - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f) - val sideLit = model.isSideLit - if (!sideLit) { - DiffuseLighting.disableGuiDepthLighting() - } - } - - override fun renderBase( - entry: EntryStack<SBItemStack>, - model: BakedModel, - graphics: DrawContext, - immediate: VertexConsumerProvider.Immediate, - bounds: Rectangle, - mouseX: Int, - mouseY: Int, - delta: Float - ) { - if (entry.isEmpty) return - val value = entry.asItemEntry().value - graphics.matrices.push() - graphics.matrices.translate(bounds.centerX.toFloat() / 20.0f, bounds.centerY.toFloat() / 20.0f, 0.0f) - graphics.matrices.scale( - bounds.getWidth().toFloat() / 20.0f, - -(bounds.getWidth() + bounds.getHeight()).toFloat() / 2.0f / 20.0f, - 1.0f - ) - minecraft - .itemRenderer - .renderItem( - value, - ModelTransformationMode.GUI, - false, - graphics.matrices, - immediate, - LightmapTextureManager.MAX_LIGHT_COORDINATE, - OverlayTexture.DEFAULT_UV, - model - ) - graphics.matrices.pop() - - } - - override fun afterBase( - entry: EntryStack<SBItemStack>, - model: BakedModel, - graphics: DrawContext, - delta: Float - ) { - RenderSystem.getModelViewStack().popMatrix() - RenderSystem.applyModelViewMatrix() - this.endGL(model) - } - - fun endGL(model: BakedModel) { - RenderSystem.enableDepthTest() - val sideLit = model.isSideLit - if (!sideLit) { - DiffuseLighting.enableGuiDepthLighting() - } - } - - override fun renderOverlay( - entry: EntryStack<SBItemStack>, - extraData: BakedModel, - graphics: DrawContext, - immediate: VertexConsumerProvider.Immediate, - bounds: Rectangle, - mouseX: Int, - mouseY: Int, - delta: Float - ) { - val modelViewStack = RenderSystem.getModelViewStack() - modelViewStack.pushMatrix() - modelViewStack.mul(graphics.matrices.peek().positionMatrix) - modelViewStack.translate(bounds.x.toFloat(), bounds.y.toFloat(), 0.0f) - modelViewStack.scale( - bounds.width.toFloat() / 16.0f, - -(bounds.getWidth() + bounds.getHeight()).toFloat() / 2.0f / 16.0f, - 1.0f - ) - RenderSystem.applyModelViewMatrix() - renderOverlay(DrawContext(minecraft, graphics.vertexConsumers), entry.asItemEntry()) - modelViewStack.popMatrix() - RenderSystem.applyModelViewMatrix() - } - - fun renderOverlay(graphics: DrawContext, entry: EntryStack<ItemStack>) { - if (!entry.isEmpty) { - graphics.drawItemInSlot(MinecraftClient.getInstance().textRenderer, entry.value, 0, 0, null) - } - } - - override fun endBatch( - entry: EntryStack<SBItemStack>?, - extraData: BakedModel?, - graphics: DrawContext?, - delta: Float - ) { - } + override fun render( + entry: EntryStack<SBItemStack>, + context: DrawContext, + bounds: Rectangle, + mouseX: Int, + mouseY: Int, + delta: Float + ) { + entry.asItemEntry().render(context, bounds, mouseX, mouseY, delta) + } + + val minecraft = MinecraftClient.getInstance() + + override fun getTooltip(entry: EntryStack<SBItemStack>, tooltipContext: TooltipContext): Tooltip? { + val stack = entry.value.asImmutableItemStack() + val lore = stack.getTooltip( + Item.TooltipContext.DEFAULT, + null, + TooltipType.BASIC + ) + return Tooltip.create(lore) + } + + override fun getExtraData(entry: EntryStack<SBItemStack>): BakedModel { + return MC.itemRenderer.getModel(entry.asItemEntry().value, + MC.world, + MC.player, 0) + + } + + override fun getBatchIdentifier(entry: EntryStack<SBItemStack>, bounds: Rectangle?, extraData: BakedModel): Int { + return 1738923 + if (extraData.isSideLit) 1 else 0 + } + + + override fun startBatch(entryStack: EntryStack<SBItemStack>, e: BakedModel, drawContext: DrawContext, v: Float) { + MC.textureManager.getTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE) + .setFilter(false, false) + RenderSystem.setShaderTexture(0, SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE) + RenderSystem.enableBlend() + RenderSystem.blendFunc(SrcFactor.SRC_ALPHA, DstFactor.ONE_MINUS_SRC_ALPHA) + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f) + if (!e.isSideLit) { + DiffuseLighting.disableGuiDepthLighting() + } + } + + override fun renderBase( + entryStack: EntryStack<SBItemStack>, + model: BakedModel, + drawContext: DrawContext, + immediate: VertexConsumerProvider.Immediate, + bounds: Rectangle, + i: Int, + i1: Int, + v: Float + ) { + if (entryStack.isEmpty) return + drawContext.matrices.push() + drawContext.matrices.translate(bounds.centerX.toDouble(), bounds.centerY.toDouble(), 0.0) + // TODO: check the scaling here again + drawContext.matrices.scale( + bounds.width.toFloat(), + (bounds.height + bounds.height) / -2F, + (bounds.width + bounds.height) / 2f) + MC.itemRenderer.renderItem( + entryStack.value.asImmutableItemStack(), + ModelTransformationMode.GUI, + false, drawContext.matrices, + immediate, LightmapTextureManager.MAX_LIGHT_COORDINATE, + OverlayTexture.DEFAULT_UV, + model + ) + drawContext.matrices.pop() + } + + override fun afterBase(entryStack: EntryStack<SBItemStack>?, e: BakedModel, drawContext: DrawContext?, v: Float) { + RenderSystem.enableDepthTest() + if (!e.isSideLit) + DiffuseLighting.enableGuiDepthLighting() + } + + override fun renderOverlay( + entryStack: EntryStack<SBItemStack>, + e: BakedModel, + drawContext: DrawContext, + immediate: VertexConsumerProvider.Immediate, + bounds: Rectangle, + i: Int, + i1: Int, + v: Float + ) { + if (entryStack.isEmpty) return + val modelViewStack = RenderSystem.getModelViewStack() + modelViewStack.pushMatrix() + modelViewStack.mul(drawContext.matrices.peek().positionMatrix) + modelViewStack.translate(bounds.x.toFloat(), bounds.y.toFloat(), 0F) + modelViewStack.scale(bounds.width / 16.0f, + (bounds.width + bounds.height) / 2.0f / 16.0f, + 1.0f) // TODO: weird scale again + drawContext.drawStackOverlay(MC.font, entryStack.value.asImmutableItemStack(), 0, 0, null) + modelViewStack.popMatrix() + } + + override fun endBatch(entryStack: EntryStack<SBItemStack>?, e: BakedModel?, drawContext: DrawContext?, v: Float) { + } } diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntrySerializer.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntrySerializer.kt index 6a03a48..724d193 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntrySerializer.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntrySerializer.kt @@ -1,30 +1,17 @@ - - package moe.nea.firmament.compat.rei +import com.mojang.serialization.Codec import me.shedaniel.rei.api.common.entry.EntrySerializer -import me.shedaniel.rei.api.common.entry.EntryStack -import net.minecraft.nbt.NbtCompound +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec import moe.nea.firmament.repo.SBItemStack -import moe.nea.firmament.util.SkyblockId object NEUItemEntrySerializer : EntrySerializer<SBItemStack> { - const val SKYBLOCK_ID_ENTRY = "SKYBLOCK_ID" - const val SKYBLOCK_ITEM_COUNT = "SKYBLOCK_ITEM_COUNT" - - override fun supportSaving(): Boolean = true - override fun supportReading(): Boolean = true - - override fun read(tag: NbtCompound): SBItemStack { - val id = SkyblockId(tag.getString(SKYBLOCK_ID_ENTRY)) - val count = if (tag.contains(SKYBLOCK_ITEM_COUNT)) tag.getInt(SKYBLOCK_ITEM_COUNT) else 1 - return SBItemStack(id, count) - } + override fun codec(): Codec<SBItemStack> { + return SBItemStack.CODEC + } - override fun save(entry: EntryStack<SBItemStack>, value: SBItemStack): NbtCompound { - return NbtCompound().apply { - putString(SKYBLOCK_ID_ENTRY, value.skyblockId.neuItem) - putInt(SKYBLOCK_ITEM_COUNT, value.getStackSize()) - } - } + override fun streamCodec(): PacketCodec<RegistryByteBuf, SBItemStack> { + return SBItemStack.PACKET_CODEC.cast() + } } diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/math.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/math.kt index 7db36f2..f4808c7 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/math.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/math.kt @@ -1,10 +1,8 @@ - - package moe.nea.firmament.compat.rei import me.shedaniel.math.Point operator fun Point.plus(other: Point): Point = Point( - this.x + other.x, - this.y + other.y, + this.x + other.x, + this.y + other.y, ) diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBCraftingRecipe.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBCraftingRecipe.kt index ed18c6e..fd04abc 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBCraftingRecipe.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBCraftingRecipe.kt @@ -1,5 +1,3 @@ - - package moe.nea.firmament.compat.rei.recipes import io.github.moulberry.repo.data.NEUCraftingRecipe @@ -11,6 +9,8 @@ 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.display.Display +import me.shedaniel.rei.api.common.display.DisplaySerializer import me.shedaniel.rei.api.common.util.EntryStacks import net.minecraft.block.Blocks import net.minecraft.text.Text @@ -18,38 +18,38 @@ import moe.nea.firmament.Firmament import moe.nea.firmament.compat.rei.SBItemEntryDefinition 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") - override fun getCategoryIdentifier(): CategoryIdentifier<out SBCraftingRecipe> = catIdentifier - - override fun getTitle(): Text = Text.literal("SkyBlock Crafting") - - override fun getIcon(): Renderer = EntryStacks.of(Blocks.CRAFTING_TABLE) - override fun setupDisplay(display: SBCraftingRecipe, bounds: Rectangle): List<Widget> { - val point = Point(bounds.centerX - 58, bounds.centerY - 27) - return buildList { - add(Widgets.createRecipeBase(bounds)) - add(Widgets.createArrow(Point(point.x + 60, point.y + 18))) - add(Widgets.createResultSlotBackground(Point(point.x + 95, point.y + 19))) - for (i in 0 until 3) { - for (j in 0 until 3) { - val slot = Widgets.createSlot(Point(point.x + 1 + i * 18, point.y + 1 + j * 18)).markInput() - add(slot) - val item = display.neuRecipe.inputs[i + j * 3] - if (item == NEUIngredient.SENTINEL_EMPTY) continue - slot.entry(SBItemEntryDefinition.getEntry(item)) // TODO: make use of stackable item entries - } - } - add( - Widgets.createSlot(Point(point.x + 95, point.y + 19)) - .entry(SBItemEntryDefinition.getEntry(display.neuRecipe.output)) - .disableBackground().markOutput() - ) - } - } - - } + override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.catIdentifier + + object Category : DisplayCategory<SBCraftingRecipe> { + val catIdentifier = CategoryIdentifier.of<SBCraftingRecipe>(Firmament.MOD_ID, "crafing_recipe") + override fun getCategoryIdentifier(): CategoryIdentifier<out SBCraftingRecipe> = catIdentifier + + override fun getTitle(): Text = Text.literal("SkyBlock Crafting") + + override fun getIcon(): Renderer = EntryStacks.of(Blocks.CRAFTING_TABLE) + override fun setupDisplay(display: SBCraftingRecipe, bounds: Rectangle): List<Widget> { + val point = Point(bounds.centerX - 58, bounds.centerY - 27) + return buildList { + add(Widgets.createRecipeBase(bounds)) + add(Widgets.createArrow(Point(point.x + 60, point.y + 18))) + add(Widgets.createResultSlotBackground(Point(point.x + 95, point.y + 19))) + for (i in 0 until 3) { + for (j in 0 until 3) { + val slot = Widgets.createSlot(Point(point.x + 1 + i * 18, point.y + 1 + j * 18)).markInput() + add(slot) + val item = display.neuRecipe.inputs[i + j * 3] + if (item == NEUIngredient.SENTINEL_EMPTY) continue + slot.entry(SBItemEntryDefinition.getEntry(item)) // TODO: make use of stackable item entries + } + } + add( + Widgets.createSlot(Point(point.x + 95, point.y + 19)) + .entry(SBItemEntryDefinition.getEntry(display.neuRecipe.output)) + .disableBackground().markOutput() + ) + } + } + + } } diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBEssenceUpgradeRecipe.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBEssenceUpgradeRecipe.kt index f81d529..ec71ec8 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBEssenceUpgradeRecipe.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBEssenceUpgradeRecipe.kt @@ -1,4 +1,3 @@ - package moe.nea.firmament.compat.rei.recipes import me.shedaniel.math.Point @@ -16,47 +15,47 @@ import moe.nea.firmament.repo.SBItemStack import moe.nea.firmament.util.SkyblockId class SBEssenceUpgradeRecipe(override val neuRecipe: EssenceRecipeProvider.EssenceUpgradeRecipe) : SBRecipe() { - object Category : DisplayCategory<SBEssenceUpgradeRecipe> { - override fun getCategoryIdentifier(): CategoryIdentifier<SBEssenceUpgradeRecipe> = - CategoryIdentifier.of(Firmament.MOD_ID, "essence_upgrade") + object Category : DisplayCategory<SBEssenceUpgradeRecipe> { + override fun getCategoryIdentifier(): CategoryIdentifier<SBEssenceUpgradeRecipe> = + CategoryIdentifier.of(Firmament.MOD_ID, "essence_upgrade") - override fun getTitle(): Text { - return Text.literal("Essence Upgrades") - } + override fun getTitle(): Text { + return Text.literal("Essence Upgrades") + } - override fun getIcon(): Renderer { - return SBItemEntryDefinition.getEntry(SkyblockId("ESSENCE_WITHER")) - } + override fun getIcon(): Renderer { + return SBItemEntryDefinition.getEntry(SkyblockId("ESSENCE_WITHER")) + } - override fun setupDisplay(display: SBEssenceUpgradeRecipe, bounds: Rectangle): List<Widget> { - val recipe = display.neuRecipe - val list = mutableListOf<Widget>() - list.add(Widgets.createRecipeBase(bounds)) - list.add(Widgets.createSlot(Point(bounds.minX + 12, bounds.centerY - 8 - 18 / 2)) - .markInput() - .entry(SBItemEntryDefinition.getEntry(SBItemStack(recipe.itemId).copy(stars = recipe.starCountAfter - 1)))) - list.add(Widgets.createSlot(Point(bounds.minX + 12, bounds.centerY - 8 + 18 / 2)) - .markInput() - .entry(SBItemEntryDefinition.getEntry(recipe.essenceIngredient))) - list.add(Widgets.createSlot(Point(bounds.maxX - 12 - 16, bounds.centerY - 8)) - .markOutput() - .entry(SBItemEntryDefinition.getEntry(SBItemStack(recipe.itemId).copy(stars = recipe.starCountAfter)))) - val extraItems = recipe.extraItems - list.add(Widgets.createArrow(Point(bounds.centerX - 24 / 2, - if (extraItems.isEmpty()) bounds.centerY - 17 / 2 - else bounds.centerY + 18 / 2))) - for ((index, item) in extraItems.withIndex()) { - list.add(Widgets.createSlot( - Point(bounds.centerX - extraItems.size * 16 / 2 - 2 / 2 + index * 18, - bounds.centerY - 18 / 2)) - .markInput() - .entry(SBItemEntryDefinition.getEntry(item))) - } - return list - } - } + override fun setupDisplay(display: SBEssenceUpgradeRecipe, bounds: Rectangle): List<Widget> { + val recipe = display.neuRecipe + val list = mutableListOf<Widget>() + list.add(Widgets.createRecipeBase(bounds)) + list.add(Widgets.createSlot(Point(bounds.minX + 12, bounds.centerY - 8 - 18 / 2)) + .markInput() + .entry(SBItemEntryDefinition.getEntry(SBItemStack(recipe.itemId).copy(stars = recipe.starCountAfter - 1)))) + list.add(Widgets.createSlot(Point(bounds.minX + 12, bounds.centerY - 8 + 18 / 2)) + .markInput() + .entry(SBItemEntryDefinition.getEntry(recipe.essenceIngredient))) + list.add(Widgets.createSlot(Point(bounds.maxX - 12 - 16, bounds.centerY - 8)) + .markOutput() + .entry(SBItemEntryDefinition.getEntry(SBItemStack(recipe.itemId).copy(stars = recipe.starCountAfter)))) + val extraItems = recipe.extraItems + list.add(Widgets.createArrow(Point(bounds.centerX - 24 / 2, + if (extraItems.isEmpty()) bounds.centerY - 17 / 2 + else bounds.centerY + 18 / 2))) + for ((index, item) in extraItems.withIndex()) { + list.add(Widgets.createSlot( + Point(bounds.centerX - extraItems.size * 16 / 2 - 2 / 2 + index * 18, + bounds.centerY - 18 / 2)) + .markInput() + .entry(SBItemEntryDefinition.getEntry(item))) + } + return list + } + } - override fun getCategoryIdentifier(): CategoryIdentifier<*> { - return Category.categoryIdentifier - } + override fun getCategoryIdentifier(): CategoryIdentifier<*> { + return Category.categoryIdentifier + } } diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBForgeRecipe.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBForgeRecipe.kt index bb51021..96af3fd 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBForgeRecipe.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBForgeRecipe.kt @@ -1,5 +1,3 @@ - - package moe.nea.firmament.compat.rei.recipes import io.github.moulberry.repo.data.NEUForgeRecipe @@ -21,51 +19,53 @@ 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 + override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.categoryIdentifier - object Category : DisplayCategory<SBForgeRecipe> { - override fun getCategoryIdentifier(): CategoryIdentifier<SBForgeRecipe> = - CategoryIdentifier.of(Firmament.MOD_ID, "forge_recipe") + 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 getTitle(): Text = Text.literal("Forge Recipes") + override fun getDisplayHeight(): Int { + return 104 + } - override fun getIcon(): Renderer = EntryStacks.of(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) - 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)) - ) - } - } - } + override fun getIcon(): Renderer = EntryStacks.of(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) + 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)) + ) + } + } + } } diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBKatRecipe.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBKatRecipe.kt index fc77fa6..bafbdcc 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBKatRecipe.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBKatRecipe.kt @@ -1,4 +1,3 @@ - package moe.nea.firmament.compat.rei.recipes import io.github.moulberry.repo.data.NEUKatUpgradeRecipe @@ -20,7 +19,6 @@ 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.time.Duration.Companion.seconds -import net.minecraft.block.Blocks import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.Element import net.minecraft.item.Items @@ -34,191 +32,191 @@ import moe.nea.firmament.util.MC import moe.nea.firmament.util.SkyblockId class SBKatRecipe(override val neuRecipe: NEUKatUpgradeRecipe) : SBRecipe() { - override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.categoryIdentifier - - object Category : DisplayCategory<SBKatRecipe> { - override fun getCategoryIdentifier(): CategoryIdentifier<SBKatRecipe> = - CategoryIdentifier.of(Firmament.MOD_ID, "kat_recipe") - - override fun getTitle(): Text = Text.literal("Kat Pet Upgrade") - override fun getDisplayHeight(): Int { - return 100 - } - - override fun getIcon(): Renderer = EntryStacks.of(Items.BONE) - override fun setupDisplay(display: SBKatRecipe, bounds: Rectangle): List<Widget> { - return buildList { - val arrowWidth = 24 - val recipe = display.neuRecipe - val levelValue = Property.upgrade(GetSetter.floating(0F)) - val slider = SliderComponent(levelValue, 1F, 100F, 1f, 100) - val outputStack = SBItemStack(SkyblockId(recipe.output.itemId)) - val inputStack = SBItemStack(SkyblockId(recipe.input.itemId)) - val inputLevelLabelCenter = Point(bounds.minX + 30 - 18 + 5 + 8, bounds.minY + 25) - val inputLevelLabel = Widgets.createLabel( - inputLevelLabelCenter, - Text.literal("")).centered() - val outputLevelLabelCenter = Point(bounds.maxX - 30 + 8, bounds.minY + 25) - val outputLevelLabel = Widgets.createLabel( - outputLevelLabelCenter, - Text.literal("")).centered() - val coinStack = SBItemStack(SkyblockId.COINS, recipe.coins.toInt()) - levelValue.whenChanged { oldValue, newValue -> - if (oldValue.toInt() == newValue.toInt()) return@whenChanged - val oldInput = inputStack.getPetData() ?: return@whenChanged - val newInput = PetData.forLevel(oldInput.petId, oldInput.rarity, newValue.toInt()) - inputStack.setPetData(newInput) - val oldOutput = outputStack.getPetData() ?: return@whenChanged - val newOutput = PetData(oldOutput.rarity, oldOutput.petId, newInput.exp) - outputStack.setPetData(newOutput) - inputLevelLabel.message = Text.literal(newInput.levelData.currentLevel.toString()) - inputLevelLabel.bounds.location = Point( - inputLevelLabelCenter.x - MC.font.getWidth(inputLevelLabel.message) / 2, - inputLevelLabelCenter.y) - outputLevelLabel.message = Text.literal(newOutput.levelData.currentLevel.toString()) - outputLevelLabel.bounds.location = Point( - outputLevelLabelCenter.x - MC.font.getWidth(outputLevelLabel.message) / 2, - outputLevelLabelCenter.y) - coinStack.setStackSize((recipe.coins * (1 - 0.3 * newValue / 100)).toInt()) - } - levelValue.set(1F) - add(Widgets.createRecipeBase(bounds)) - add(wrapWidget(Rectangle(bounds.centerX - slider.width / 2, - bounds.maxY - 30, - slider.width, - slider.height), - slider)) - add(Widgets.withTooltip( - Widgets.createArrow(Point(bounds.centerX - arrowWidth / 2, bounds.minY + 40)), - Text.literal("Upgrade time: " + FirmFormatters.formatTimespan(recipe.seconds.seconds)))) - - add(Widgets.createResultSlotBackground(Point(bounds.maxX - 30, bounds.minY + 40))) - add(inputLevelLabel) - add(outputLevelLabel) - add(Widgets.createSlot(Point(bounds.maxX - 30, bounds.minY + 40)).markOutput().disableBackground() - .entry(SBItemEntryDefinition.getEntry(outputStack))) - add(Widgets.createSlot(Point(bounds.minX + 30 - 18 + 5, bounds.minY + 40)).markInput() - .entry(SBItemEntryDefinition.getEntry(inputStack))) - - val allInputs = recipe.items.map { SBItemEntryDefinition.getEntry(it) } + - listOf(SBItemEntryDefinition.getEntry(coinStack)) - for ((index, item) in allInputs.withIndex()) { - add(Widgets.createSlot( - Point(bounds.centerX + index * 20 - allInputs.size * 18 / 2 - (allInputs.size - 1) * 2 / 2, - bounds.minY + 20)) - .markInput() - .entry(item)) - } - } - } - } + override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.categoryIdentifier + + object Category : DisplayCategory<SBKatRecipe> { + override fun getCategoryIdentifier(): CategoryIdentifier<SBKatRecipe> = + CategoryIdentifier.of(Firmament.MOD_ID, "kat_recipe") + + override fun getTitle(): Text = Text.literal("Kat Pet Upgrade") + override fun getDisplayHeight(): Int { + return 100 + } + + override fun getIcon(): Renderer = EntryStacks.of(Items.BONE) + override fun setupDisplay(display: SBKatRecipe, bounds: Rectangle): List<Widget> { + return buildList { + val arrowWidth = 24 + val recipe = display.neuRecipe + val levelValue = Property.upgrade(GetSetter.floating(0F)) + val slider = SliderComponent(levelValue, 1F, 100F, 1f, 100) + val outputStack = SBItemStack(SkyblockId(recipe.output.itemId)) + val inputStack = SBItemStack(SkyblockId(recipe.input.itemId)) + val inputLevelLabelCenter = Point(bounds.minX + 30 - 18 + 5 + 8, bounds.minY + 25) + val inputLevelLabel = Widgets.createLabel( + inputLevelLabelCenter, + Text.literal("")).centered() + val outputLevelLabelCenter = Point(bounds.maxX - 30 + 8, bounds.minY + 25) + val outputLevelLabel = Widgets.createLabel( + outputLevelLabelCenter, + Text.literal("")).centered() + val coinStack = SBItemStack(SkyblockId.COINS, recipe.coins.toInt()) + levelValue.whenChanged { oldValue, newValue -> + if (oldValue.toInt() == newValue.toInt()) return@whenChanged + val oldInput = inputStack.getPetData() ?: return@whenChanged + val newInput = PetData.forLevel(oldInput.petId, oldInput.rarity, newValue.toInt()) + inputStack.setPetData(newInput) + val oldOutput = outputStack.getPetData() ?: return@whenChanged + val newOutput = PetData(oldOutput.rarity, oldOutput.petId, newInput.exp) + outputStack.setPetData(newOutput) + inputLevelLabel.message = Text.literal(newInput.levelData.currentLevel.toString()) + inputLevelLabel.bounds.location = Point( + inputLevelLabelCenter.x - MC.font.getWidth(inputLevelLabel.message) / 2, + inputLevelLabelCenter.y) + outputLevelLabel.message = Text.literal(newOutput.levelData.currentLevel.toString()) + outputLevelLabel.bounds.location = Point( + outputLevelLabelCenter.x - MC.font.getWidth(outputLevelLabel.message) / 2, + outputLevelLabelCenter.y) + coinStack.setStackSize((recipe.coins * (1 - 0.3 * newValue / 100)).toInt()) + } + levelValue.set(1F) + add(Widgets.createRecipeBase(bounds)) + add(wrapWidget(Rectangle(bounds.centerX - slider.width / 2, + bounds.maxY - 30, + slider.width, + slider.height), + slider)) + add(Widgets.withTooltip( + Widgets.createArrow(Point(bounds.centerX - arrowWidth / 2, bounds.minY + 40)), + Text.literal("Upgrade time: " + FirmFormatters.formatTimespan(recipe.seconds.seconds)))) + + add(Widgets.createResultSlotBackground(Point(bounds.maxX - 30, bounds.minY + 40))) + add(inputLevelLabel) + add(outputLevelLabel) + add(Widgets.createSlot(Point(bounds.maxX - 30, bounds.minY + 40)).markOutput().disableBackground() + .entry(SBItemEntryDefinition.getEntry(outputStack))) + add(Widgets.createSlot(Point(bounds.minX + 30 - 18 + 5, bounds.minY + 40)).markInput() + .entry(SBItemEntryDefinition.getEntry(inputStack))) + + val allInputs = recipe.items.map { SBItemEntryDefinition.getEntry(it) } + + listOf(SBItemEntryDefinition.getEntry(coinStack)) + for ((index, item) in allInputs.withIndex()) { + add(Widgets.createSlot( + Point(bounds.centerX + index * 20 - allInputs.size * 18 / 2 - (allInputs.size - 1) * 2 / 2, + bounds.minY + 20)) + .markInput() + .entry(item)) + } + } + } + } } fun wrapWidget(bounds: Rectangle, component: GuiComponent): Widget { - return object : WidgetWithBounds() { - override fun getBounds(): Rectangle { - return bounds - } - - override fun children(): List<Element> { - return listOf() - } - - override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { - context.matrices.push() - context.matrices.translate(bounds.minX.toFloat(), bounds.minY.toFloat(), 0F) - component.render( - GuiImmediateContext( - ModernRenderContext(context), - bounds.minX, bounds.minY, - bounds.width, bounds.height, - mouseX - bounds.minX, mouseY - bounds.minY, - mouseX, mouseY, - mouseX.toFloat(), mouseY.toFloat() - )) - context.matrices.pop() - } - - override fun mouseMoved(mouseX: Double, mouseY: Double) { - val mouseXInt = mouseX.toInt() - val mouseYInt = mouseY.toInt() - component.mouseEvent(MouseEvent.Move(0F, 0F), - GuiImmediateContext( - IMinecraft.instance.provideTopLevelRenderContext(), - bounds.minX, bounds.minY, - bounds.width, bounds.height, - mouseXInt - bounds.minX, mouseYInt - bounds.minY, - mouseXInt, mouseYInt, - mouseX.toFloat(), mouseY.toFloat() - )) - } - - override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean { - val mouseXInt = mouseX.toInt() - val mouseYInt = mouseY.toInt() - return component.mouseEvent(MouseEvent.Click(button, true), - GuiImmediateContext( - IMinecraft.instance.provideTopLevelRenderContext(), - bounds.minX, bounds.minY, - bounds.width, bounds.height, - mouseXInt - bounds.minX, mouseYInt - bounds.minY, - mouseXInt, mouseYInt, - mouseX.toFloat(), mouseY.toFloat() - )) - } - - override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean { - val mouseXInt = mouseX.toInt() - val mouseYInt = mouseY.toInt() - return component.mouseEvent(MouseEvent.Click(button, false), - GuiImmediateContext( - IMinecraft.instance.provideTopLevelRenderContext(), - bounds.minX, bounds.minY, - bounds.width, bounds.height, - mouseXInt - bounds.minX, mouseYInt - bounds.minY, - mouseXInt, mouseYInt, - mouseX.toFloat(), mouseY.toFloat() - )) - } - - override fun mouseDragged( - mouseX: Double, - mouseY: Double, - button: Int, - deltaX: Double, - deltaY: Double - ): Boolean { - val mouseXInt = mouseX.toInt() - val mouseYInt = mouseY.toInt() - return component.mouseEvent(MouseEvent.Move(deltaX.toFloat(), deltaY.toFloat()), - GuiImmediateContext( - IMinecraft.instance.provideTopLevelRenderContext(), - bounds.minX, bounds.minY, - bounds.width, bounds.height, - mouseXInt - bounds.minX, mouseYInt - bounds.minY, - mouseXInt, mouseYInt, - mouseX.toFloat(), mouseY.toFloat() - )) - - } - - override fun mouseScrolled( - mouseX: Double, - mouseY: Double, - horizontalAmount: Double, - verticalAmount: Double - ): Boolean { - val mouseXInt = mouseX.toInt() - val mouseYInt = mouseY.toInt() - return component.mouseEvent(MouseEvent.Scroll(verticalAmount.toFloat()), - GuiImmediateContext( - IMinecraft.instance.provideTopLevelRenderContext(), - bounds.minX, bounds.minY, - bounds.width, bounds.height, - mouseXInt - bounds.minX, mouseYInt - bounds.minY, - mouseXInt, mouseYInt, - mouseX.toFloat(), mouseY.toFloat() - )) - } - } + return object : WidgetWithBounds() { + override fun getBounds(): Rectangle { + return bounds + } + + override fun children(): List<Element> { + return listOf() + } + + override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { + context.matrices.push() + context.matrices.translate(bounds.minX.toFloat(), bounds.minY.toFloat(), 0F) + component.render( + GuiImmediateContext( + ModernRenderContext(context), + bounds.minX, bounds.minY, + bounds.width, bounds.height, + mouseX - bounds.minX, mouseY - bounds.minY, + mouseX, mouseY, + mouseX.toFloat(), mouseY.toFloat() + )) + context.matrices.pop() + } + + override fun mouseMoved(mouseX: Double, mouseY: Double) { + val mouseXInt = mouseX.toInt() + val mouseYInt = mouseY.toInt() + component.mouseEvent(MouseEvent.Move(0F, 0F), + GuiImmediateContext( + IMinecraft.instance.provideTopLevelRenderContext(), + bounds.minX, bounds.minY, + bounds.width, bounds.height, + mouseXInt - bounds.minX, mouseYInt - bounds.minY, + mouseXInt, mouseYInt, + mouseX.toFloat(), mouseY.toFloat() + )) + } + + override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean { + val mouseXInt = mouseX.toInt() + val mouseYInt = mouseY.toInt() + return component.mouseEvent(MouseEvent.Click(button, true), + GuiImmediateContext( + IMinecraft.instance.provideTopLevelRenderContext(), + bounds.minX, bounds.minY, + bounds.width, bounds.height, + mouseXInt - bounds.minX, mouseYInt - bounds.minY, + mouseXInt, mouseYInt, + mouseX.toFloat(), mouseY.toFloat() + )) + } + + override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean { + val mouseXInt = mouseX.toInt() + val mouseYInt = mouseY.toInt() + return component.mouseEvent(MouseEvent.Click(button, false), + GuiImmediateContext( + IMinecraft.instance.provideTopLevelRenderContext(), + bounds.minX, bounds.minY, + bounds.width, bounds.height, + mouseXInt - bounds.minX, mouseYInt - bounds.minY, + mouseXInt, mouseYInt, + mouseX.toFloat(), mouseY.toFloat() + )) + } + + override fun mouseDragged( + mouseX: Double, + mouseY: Double, + button: Int, + deltaX: Double, + deltaY: Double + ): Boolean { + val mouseXInt = mouseX.toInt() + val mouseYInt = mouseY.toInt() + return component.mouseEvent(MouseEvent.Move(deltaX.toFloat(), deltaY.toFloat()), + GuiImmediateContext( + IMinecraft.instance.provideTopLevelRenderContext(), + bounds.minX, bounds.minY, + bounds.width, bounds.height, + mouseXInt - bounds.minX, mouseYInt - bounds.minY, + mouseXInt, mouseYInt, + mouseX.toFloat(), mouseY.toFloat() + )) + + } + + override fun mouseScrolled( + mouseX: Double, + mouseY: Double, + horizontalAmount: Double, + verticalAmount: Double + ): Boolean { + val mouseXInt = mouseX.toInt() + val mouseYInt = mouseY.toInt() + return component.mouseEvent(MouseEvent.Scroll(verticalAmount.toFloat()), + GuiImmediateContext( + IMinecraft.instance.provideTopLevelRenderContext(), + bounds.minX, bounds.minY, + bounds.width, bounds.height, + mouseXInt - bounds.minX, mouseYInt - bounds.minY, + mouseXInt, mouseYInt, + mouseX.toFloat(), mouseY.toFloat() + )) + } + } } diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBMobDropRecipe.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBMobDropRecipe.kt index cb240fc..81ec41b 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBMobDropRecipe.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBMobDropRecipe.kt @@ -1,4 +1,3 @@ - package moe.nea.firmament.compat.rei.recipes import io.github.moulberry.repo.data.NEUMobDropRecipe @@ -14,95 +13,95 @@ import net.minecraft.item.Items import net.minecraft.text.Text import net.minecraft.util.Identifier import moe.nea.firmament.Firmament -import moe.nea.firmament.gui.entity.EntityRenderer import moe.nea.firmament.compat.rei.EntityWidget import moe.nea.firmament.compat.rei.SBItemEntryDefinition +import moe.nea.firmament.gui.entity.EntityRenderer class SBMobDropRecipe(override val neuRecipe: NEUMobDropRecipe) : SBRecipe() { - override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.categoryIdentifier + override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.categoryIdentifier - object Category : DisplayCategory<SBMobDropRecipe> { - override fun getCategoryIdentifier(): CategoryIdentifier<SBMobDropRecipe> = - CategoryIdentifier.of(Firmament.MOD_ID, "mob_drop_recipe") + object Category : DisplayCategory<SBMobDropRecipe> { + override fun getCategoryIdentifier(): CategoryIdentifier<SBMobDropRecipe> = + CategoryIdentifier.of(Firmament.MOD_ID, "mob_drop_recipe") - override fun getTitle(): Text = Text.literal("Mob Drops") - override fun getDisplayHeight(): Int { - return 100 - } + override fun getTitle(): Text = Text.literal("Mob Drops") + override fun getDisplayHeight(): Int { + return 100 + } - override fun getIcon(): Renderer = EntryStacks.of(Items.DIAMOND_SWORD) - override fun setupDisplay(display: SBMobDropRecipe, bounds: Rectangle): List<Widget> { - return buildList { - add(Widgets.createRecipeBase(bounds)) - val source = display.neuRecipe.render - val entity = if (source.startsWith("@")) { - EntityRenderer.constructEntity(Identifier.of(source.substring(1))) - } else { - EntityRenderer.applyModifiers(source, listOf()) - } - if (entity != null) { - val level = display.neuRecipe.level - val fullMobName = - if (level > 0) Text.translatable("firmament.recipe.mobs.name", level, display.neuRecipe.name) - else Text.translatable("firmament.recipe.mobs.name.nolevel", display.neuRecipe.name) - val tt = mutableListOf<Text>() - tt.add((fullMobName)) - tt.add(Text.literal("")) - if (display.neuRecipe.coins > 0) { - tt.add(Text.stringifiedTranslatable("firmament.recipe.mobs.coins", display.neuRecipe.coins)) - } - if (display.neuRecipe.combatExperience > 0) { - tt.add( - Text.stringifiedTranslatable( - "firmament.recipe.mobs.combat", - display.neuRecipe.combatExperience - ) - ) - } - if (display.neuRecipe.enchantingExperience > 0) { - tt.add( - Text.stringifiedTranslatable( - "firmament.recipe.mobs.exp", - display.neuRecipe.enchantingExperience - ) - ) - } - if (display.neuRecipe.extra != null) - display.neuRecipe.extra.mapTo(tt) { Text.literal(it) } - if (tt.size == 2) - tt.removeAt(1) - add( - Widgets.withTooltip( - EntityWidget(entity, Point(bounds.minX + 5, bounds.minY + 15)), - tt - ) - ) - } - add( - Widgets.createLabel(Point(bounds.minX + 15, bounds.minY + 5), Text.literal(display.neuRecipe.name)) - .leftAligned() - ) - var x = bounds.minX + 60 - var y = bounds.minY + 20 - for (drop in display.neuRecipe.drops) { - val lore = drop.extra.mapTo(mutableListOf()) { Text.literal(it) } - if (drop.chance != null) { - lore += listOf(Text.translatable("firmament.recipe.mobs.drops", drop.chance)) - } - val item = SBItemEntryDefinition.getEntry(drop.dropItem) - .value.copy(extraLore = lore) - add( - Widgets.createSlot(Point(x, y)).markOutput() - .entries(listOf(SBItemEntryDefinition.getEntry(item))) - ) - x += 18 - if (x > bounds.maxX - 30) { - x = bounds.minX + 60 - y += 18 - } - } - } - } - } + override fun getIcon(): Renderer = EntryStacks.of(Items.DIAMOND_SWORD) + override fun setupDisplay(display: SBMobDropRecipe, bounds: Rectangle): List<Widget> { + return buildList { + add(Widgets.createRecipeBase(bounds)) + val source = display.neuRecipe.render + val entity = if (source.startsWith("@")) { + EntityRenderer.constructEntity(Identifier.of(source.substring(1))) + } else { + EntityRenderer.applyModifiers(source, listOf()) + } + if (entity != null) { + val level = display.neuRecipe.level + val fullMobName = + if (level > 0) Text.translatable("firmament.recipe.mobs.name", level, display.neuRecipe.name) + else Text.translatable("firmament.recipe.mobs.name.nolevel", display.neuRecipe.name) + val tt = mutableListOf<Text>() + tt.add((fullMobName)) + tt.add(Text.literal("")) + if (display.neuRecipe.coins > 0) { + tt.add(Text.stringifiedTranslatable("firmament.recipe.mobs.coins", display.neuRecipe.coins)) + } + if (display.neuRecipe.combatExperience > 0) { + tt.add( + Text.stringifiedTranslatable( + "firmament.recipe.mobs.combat", + display.neuRecipe.combatExperience + ) + ) + } + if (display.neuRecipe.enchantingExperience > 0) { + tt.add( + Text.stringifiedTranslatable( + "firmament.recipe.mobs.exp", + display.neuRecipe.enchantingExperience + ) + ) + } + if (display.neuRecipe.extra != null) + display.neuRecipe.extra.mapTo(tt) { Text.literal(it) } + if (tt.size == 2) + tt.removeAt(1) + add( + Widgets.withTooltip( + EntityWidget(entity, Point(bounds.minX + 5, bounds.minY + 15)), + tt + ) + ) + } + add( + Widgets.createLabel(Point(bounds.minX + 15, bounds.minY + 5), Text.literal(display.neuRecipe.name)) + .leftAligned() + ) + var x = bounds.minX + 60 + var y = bounds.minY + 20 + for (drop in display.neuRecipe.drops) { + val lore = drop.extra.mapTo(mutableListOf()) { Text.literal(it) } + if (drop.chance != null) { + lore += listOf(Text.translatable("firmament.recipe.mobs.drops", drop.chance)) + } + val item = SBItemEntryDefinition.getEntry(drop.dropItem) + .value.copy(extraLore = lore) + add( + Widgets.createSlot(Point(x, y)).markOutput() + .entries(listOf(SBItemEntryDefinition.getEntry(item))) + ) + x += 18 + if (x > bounds.maxX - 30) { + x = bounds.minX + 60 + y += 18 + } + } + } + } + } } diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBRecipe.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBRecipe.kt index a66a529..de7779f 100644 --- a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBRecipe.kt +++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBRecipe.kt @@ -2,28 +2,41 @@ package moe.nea.firmament.compat.rei.recipes import io.github.moulberry.repo.data.NEUIngredient import io.github.moulberry.repo.data.NEURecipe +import java.util.Optional import me.shedaniel.rei.api.common.display.Display +import me.shedaniel.rei.api.common.display.DisplaySerializer import me.shedaniel.rei.api.common.entry.EntryIngredient +import net.minecraft.util.Identifier import moe.nea.firmament.compat.rei.SBItemEntryDefinition import moe.nea.firmament.util.SkyblockId abstract class SBRecipe : Display { - abstract val neuRecipe: NEURecipe - override fun getInputEntries(): List<EntryIngredient> { - return neuRecipe.allInputs - .filter { it.itemId != NEUIngredient.NEU_SENTINEL_EMPTY } - .map { - val entryStack = SBItemEntryDefinition.getEntry(SkyblockId(it.itemId)) - EntryIngredient.of(entryStack) - } - } + override fun getDisplayLocation(): Optional<Identifier> { + // In theory, we could return a location for the neuRecipe here. (Something along the lines of neurepo:items/item_id.json/0 for the 0th recipe in the items/item_id.json recipes array). + return Optional.empty() + } - override fun getOutputEntries(): List<EntryIngredient> { - return neuRecipe.allOutputs - .filter { it.itemId != NEUIngredient.NEU_SENTINEL_EMPTY } - .map { - val entryStack = SBItemEntryDefinition.getEntry(SkyblockId(it.itemId)) - EntryIngredient.of(entryStack) - } - } + override fun getSerializer(): DisplaySerializer<out Display>? { + // While returning null here is discouraged, we are fine to do so, since this recipe will never travel through the network + return null + } + + abstract val neuRecipe: NEURecipe + override fun getInputEntries(): List<EntryIngredient> { + return neuRecipe.allInputs + .filter { it.itemId != NEUIngredient.NEU_SENTINEL_EMPTY } + .map { + val entryStack = SBItemEntryDefinition.getEntry(SkyblockId(it.itemId)) + EntryIngredient.of(entryStack) + } + } + + override fun getOutputEntries(): List<EntryIngredient> { + return neuRecipe.allOutputs + .filter { it.itemId != NEUIngredient.NEU_SENTINEL_EMPTY } + .map { + val entryStack = SBItemEntryDefinition.getEntry(SkyblockId(it.itemId)) + EntryIngredient.of(entryStack) + } + } } diff --git a/src/main/kotlin/repo/RepoManager.kt b/src/main/kotlin/repo/RepoManager.kt index e5103fc..725642e 100644 --- a/src/main/kotlin/repo/RepoManager.kt +++ b/src/main/kotlin/repo/RepoManager.kt @@ -79,7 +79,7 @@ object RepoManager { private fun trySendClientboundUpdateRecipesPacket(): Boolean { return MinecraftClient.getInstance().world != null && MinecraftClient.getInstance().networkHandler?.onSynchronizeRecipes( - SynchronizeRecipesS2CPacket(mutableMapOf(), CuttingRecipeDisplay.Grouping.empty()) // TODO: check https://hackmd.io/@shedaniel/rei17_primer and source to see if this still resyncs + SynchronizeRecipesS2CPacket(mutableMapOf(), CuttingRecipeDisplay.Grouping.empty()) ) != null } @@ -94,7 +94,7 @@ object RepoManager { fun launchAsyncUpdate(force: Boolean = false) { Firmament.coroutineScope.launch { - ItemCache.ReloadProgressHud.reportProgress("Downloading", 0, -1) // TODO: replace with a proper boundy bar + ItemCache.ReloadProgressHud.reportProgress("Downloading", 0, -1) // TODO: replace with a proper bouncy bar ItemCache.ReloadProgressHud.isEnabled = true try { RepoDownloadManager.downloadUpdate(force) diff --git a/src/main/kotlin/repo/SBItemStack.kt b/src/main/kotlin/repo/SBItemStack.kt index 281075d..e1cbdbb 100644 --- a/src/main/kotlin/repo/SBItemStack.kt +++ b/src/main/kotlin/repo/SBItemStack.kt @@ -1,9 +1,14 @@ package moe.nea.firmament.repo +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder import io.github.moulberry.repo.constants.PetNumbers import io.github.moulberry.repo.data.NEUIngredient import io.github.moulberry.repo.data.NEUItem import net.minecraft.item.ItemStack +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.codec.PacketCodecs import net.minecraft.text.Text import net.minecraft.util.Formatting import moe.nea.firmament.repo.ItemCache.asItemStack @@ -40,6 +45,20 @@ data class SBItemStack constructor( } companion object { + val PACKET_CODEC: PacketCodec<in RegistryByteBuf, SBItemStack> = PacketCodec.tuple( + SkyblockId.PACKET_CODEC, { it.skyblockId }, + PacketCodecs.VAR_INT, { it.stackSize }, + { id, count -> SBItemStack(id, count) } + ) + val CODEC: Codec<SBItemStack> = RecordCodecBuilder.create { + it.group( + SkyblockId.CODEC.fieldOf("skyblockId").forGetter { it.skyblockId }, + Codec.INT.fieldOf("count").forGetter { it.stackSize }, + ).apply(it) { id, count -> + SBItemStack(id, count) + } + } + operator fun invoke(itemStack: ItemStack): SBItemStack { val skyblockId = itemStack.skyBlockId ?: SkyblockId.NULL return SBItemStack( diff --git a/src/main/kotlin/util/MC.kt b/src/main/kotlin/util/MC.kt index 27b9457..33825f1 100644 --- a/src/main/kotlin/util/MC.kt +++ b/src/main/kotlin/util/MC.kt @@ -6,6 +6,7 @@ import net.minecraft.client.MinecraftClient import net.minecraft.client.gui.screen.ingame.HandledScreen import net.minecraft.client.option.GameOptions import net.minecraft.client.render.WorldRenderer +import net.minecraft.client.render.item.ItemRenderer import net.minecraft.item.Item import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket import net.minecraft.registry.BuiltinRegistries @@ -69,6 +70,7 @@ object MC { inline val resourceManager get() = (instance.resourceManager as ReloadableResourceManagerImpl) + inline val itemRenderer: ItemRenderer get() = instance.itemRenderer inline val worldRenderer: WorldRenderer get() = instance.worldRenderer inline val networkHandler get() = player?.networkHandler inline val instance get() = MinecraftClient.getInstance() diff --git a/src/main/kotlin/util/SkyblockId.kt b/src/main/kotlin/util/SkyblockId.kt index 059e746..9c9287b 100644 --- a/src/main/kotlin/util/SkyblockId.kt +++ b/src/main/kotlin/util/SkyblockId.kt @@ -2,6 +2,7 @@ package moe.nea.firmament.util +import com.mojang.serialization.Codec import io.github.moulberry.repo.data.NEUIngredient import io.github.moulberry.repo.data.NEUItem import io.github.moulberry.repo.data.Rarity @@ -16,6 +17,9 @@ import net.minecraft.component.type.NbtComponent import net.minecraft.item.ItemStack import net.minecraft.item.Items import net.minecraft.nbt.NbtCompound +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.codec.PacketCodecs import net.minecraft.util.Identifier import moe.nea.firmament.repo.ItemCache.asItemStack import moe.nea.firmament.repo.set @@ -68,6 +72,9 @@ value class SkyblockId(val neuItem: String) { val NULL: SkyblockId = SkyblockId("null") val PET_NULL: SkyblockId = SkyblockId("null_pet") private val illlegalPathRegex = "[^a-z0-9_.-/]".toRegex() + val CODEC = Codec.STRING.xmap({ SkyblockId(it) }, { it.neuItem }) + val PACKET_CODEC: PacketCodec<in RegistryByteBuf, SkyblockId> = + PacketCodecs.STRING.xmap({ SkyblockId(it) }, { it.neuItem }) } } |