From a27f8e6fed4f8f6565e311fe3684beb0377229f7 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Fri, 18 Oct 2024 17:47:32 +0200 Subject: Add super craft to the move item REI button --- .../kotlin/features/inventory/CraftingOverlay.kt | 105 ++++++----- src/main/kotlin/rei/FirmamentReiPlugin.kt | 192 +++++++++++---------- src/main/kotlin/repo/RepoManager.kt | 2 + src/main/kotlin/util/SkyblockId.kt | 13 ++ .../resources/assets/firmament/lang/en_us.json | 4 +- 5 files changed, 180 insertions(+), 136 deletions(-) (limited to 'src') diff --git a/src/main/kotlin/features/inventory/CraftingOverlay.kt b/src/main/kotlin/features/inventory/CraftingOverlay.kt index 031ef78..8e75478 100644 --- a/src/main/kotlin/features/inventory/CraftingOverlay.kt +++ b/src/main/kotlin/features/inventory/CraftingOverlay.kt @@ -1,11 +1,10 @@ - - package moe.nea.firmament.features.inventory import net.minecraft.client.gui.screen.ingame.GenericContainerScreen import net.minecraft.item.ItemStack import net.minecraft.util.Formatting import moe.nea.firmament.annotations.Subscribe +import moe.nea.firmament.events.ScreenChangeEvent import moe.nea.firmament.events.SlotRenderEvents import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.rei.FirmamentReiPlugin.Companion.asItemEntry @@ -15,52 +14,66 @@ import moe.nea.firmament.util.MC object CraftingOverlay : FirmamentFeature { - private var screen: GenericContainerScreen? = null - private var recipe: SBCraftingRecipe? = null - private val craftingOverlayIndices = listOf( - 10, 11, 12, - 19, 20, 21, - 28, 29, 30, - ) + private var screen: GenericContainerScreen? = null + private var recipe: SBCraftingRecipe? = null + private var useNextScreen = false + private val craftingOverlayIndices = listOf( + 10, 11, 12, + 19, 20, 21, + 28, 29, 30, + ) + val CRAFTING_SCREEN_NAME = "Craft Item" + fun setOverlay(screen: GenericContainerScreen?, recipe: SBCraftingRecipe) { + this.screen = screen + if (screen == null) { + useNextScreen = true + } + this.recipe = recipe + } - fun setOverlay(screen: GenericContainerScreen, recipe: SBCraftingRecipe) { - this.screen = screen - this.recipe = recipe - } + @Subscribe + fun onScreenChange(event: ScreenChangeEvent) { + if (useNextScreen && event.new is GenericContainerScreen + && event.new.title?.string == "Craft Item" + ) { + useNextScreen = false + screen = event.new + } + } - override val identifier: String - get() = "crafting-overlay" + override val identifier: String + get() = "crafting-overlay" - @Subscribe - fun onSlotRender(event: SlotRenderEvents.After) { - val slot = event.slot - val recipe = this.recipe ?: return - if (slot.inventory != screen?.screenHandler?.inventory) return - val recipeIndex = craftingOverlayIndices.indexOf(slot.index) - if (recipeIndex < 0) return - val expectedItem = recipe.neuRecipe.inputs[recipeIndex] - val actualStack = slot.stack ?: ItemStack.EMPTY!! - val actualEntry = SBItemEntryDefinition.getEntry(actualStack).value - if ((actualEntry.skyblockId.neuItem != expectedItem.itemId || actualEntry.getStackSize() < expectedItem.amount) && expectedItem.amount.toInt() != 0) { - event.context.fill( - event.slot.x, - event.slot.y, - event.slot.x + 16, - event.slot.y + 16, - 0x80FF0000.toInt() - ) - } - if (!slot.hasStack()) { - val itemStack = SBItemEntryDefinition.getEntry(expectedItem).asItemEntry().value - event.context.drawItem(itemStack, event.slot.x, event.slot.y) - event.context.drawItemInSlot( - MC.font, - itemStack, - event.slot.x, - event.slot.y, - "${Formatting.RED}${expectedItem.amount.toInt()}" - ) - } - } + @Subscribe + fun onSlotRender(event: SlotRenderEvents.After) { + val slot = event.slot + val recipe = this.recipe ?: return + if (slot.inventory != screen?.screenHandler?.inventory) return + val recipeIndex = craftingOverlayIndices.indexOf(slot.index) + if (recipeIndex < 0) return + val expectedItem = recipe.neuRecipe.inputs[recipeIndex] + val actualStack = slot.stack ?: ItemStack.EMPTY!! + val actualEntry = SBItemEntryDefinition.getEntry(actualStack).value + if ((actualEntry.skyblockId.neuItem != expectedItem.itemId || actualEntry.getStackSize() < expectedItem.amount) && expectedItem.amount.toInt() != 0) { + event.context.fill( + event.slot.x, + event.slot.y, + event.slot.x + 16, + event.slot.y + 16, + 0x80FF0000.toInt() + ) + } + if (!slot.hasStack()) { + val itemStack = SBItemEntryDefinition.getEntry(expectedItem).asItemEntry().value + event.context.drawItem(itemStack, event.slot.x, event.slot.y) + event.context.drawItemInSlot( + MC.font, + itemStack, + event.slot.x, + event.slot.y, + "${Formatting.RED}${expectedItem.amount.toInt()}" + ) + } + } } diff --git a/src/main/kotlin/rei/FirmamentReiPlugin.kt b/src/main/kotlin/rei/FirmamentReiPlugin.kt index b585336..f234f3e 100644 --- a/src/main/kotlin/rei/FirmamentReiPlugin.kt +++ b/src/main/kotlin/rei/FirmamentReiPlugin.kt @@ -1,5 +1,3 @@ - - package moe.nea.firmament.rei import me.shedaniel.rei.api.client.plugins.REIClientPlugin @@ -31,98 +29,114 @@ import moe.nea.firmament.rei.recipes.SBForgeRecipe import moe.nea.firmament.rei.recipes.SBKatRecipe import moe.nea.firmament.rei.recipes.SBMobDropRecipe import moe.nea.firmament.repo.RepoManager +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 import moe.nea.firmament.util.unformattedString class FirmamentReiPlugin : REIClientPlugin { - companion object { - fun EntryStack.asItemEntry(): EntryStack { - return EntryStack.of(VanillaEntryTypes.ITEM, value.asImmutableItemStack()) - } - - val SKYBLOCK_ITEM_TYPE_ID = Identifier.of("firmament", "skyblockitems") - } - - override fun registerTransferHandlers(registry: TransferHandlerRegistry) { - registry.register(TransferHandler { context -> - val screen = context.containerScreen - val display = context.display - if (display !is SBCraftingRecipe || screen !is GenericContainerScreen || screen.title?.unformattedString != "Craft Item") { - return@TransferHandler TransferHandler.Result.createNotApplicable() - } - if (context.isActuallyCrafting) - CraftingOverlay.setOverlay(screen, display) - return@TransferHandler TransferHandler.Result.createSuccessful().blocksFurtherHandling(true) - }) - } - - override fun registerEntryTypes(registry: EntryTypeRegistry) { - registry.register(SKYBLOCK_ITEM_TYPE_ID, SBItemEntryDefinition) - } - - override fun registerCategories(registry: CategoryRegistry) { - registry.add(SBCraftingRecipe.Category) - registry.add(SBForgeRecipe.Category) - registry.add(SBMobDropRecipe.Category) - registry.add(SBKatRecipe.Category) - registry.add(SBEssenceUpgradeRecipe.Category) - } - - override fun registerExclusionZones(zones: ExclusionZones) { - zones.register(HandledScreen::class.java) { HandledScreenPushREIEvent.publish(HandledScreenPushREIEvent(it)).rectangles } - zones.register(StorageOverlayScreen::class.java) { it.getBounds() } - } - - override fun registerDisplays(registry: DisplayRegistry) { - registry.registerDisplayGenerator( - SBCraftingRecipe.Category.catIdentifier, - SkyblockCraftingRecipeDynamicGenerator) - registry.registerDisplayGenerator( - SBForgeRecipe.Category.categoryIdentifier, - SkyblockForgeRecipeDynamicGenerator) - registry.registerDisplayGenerator( - SBMobDropRecipe.Category.categoryIdentifier, - SkyblockMobDropRecipeDynamicGenerator) - registry.registerDisplayGenerator( - SBKatRecipe.Category.categoryIdentifier, - SkyblockKatRecipeDynamicGenerator) - registry.registerDisplayGenerator( - SBEssenceUpgradeRecipe.Category.categoryIdentifier, - SkyblockEssenceRecipeDynamicGenerator - ) - } - - override fun registerCollapsibleEntries(registry: CollapsibleEntryRegistry) { - if (!RepoManager.Config.disableItemGroups) - RepoManager.neuRepo.constants.parents.parents - .forEach { (parent, children) -> - registry.group( - SkyblockId(parent).identifier, - Text.literal(RepoManager.getNEUItem(SkyblockId(parent))?.displayName ?: parent), - (children + parent).map { SBItemEntryDefinition.getEntry(SkyblockId(it)) }) - } - } - - override fun registerScreens(registry: ScreenRegistry) { - registry.registerDecider(object : OverlayDecider { - override fun isHandingScreen(screen: Class?): Boolean { - return screen == StorageOverlayScreen::class.java - } - - override fun shouldScreenBeOverlaid(screen: R): ActionResult { - return ActionResult.SUCCESS - } - }) - registry.registerFocusedStack(SkyblockItemIdFocusedStackProvider) - } - - override fun registerEntries(registry: EntryRegistry) { - registry.removeEntryIf { true } - RepoManager.neuRepo.items?.items?.values?.forEach { neuItem -> - registry.addEntry(SBItemEntryDefinition.getEntry(neuItem.skyblockId)) - } - } + companion object { + fun EntryStack.asItemEntry(): EntryStack { + return EntryStack.of(VanillaEntryTypes.ITEM, value.asImmutableItemStack()) + } + + val SKYBLOCK_ITEM_TYPE_ID = Identifier.of("firmament", "skyblockitems") + } + + override fun registerTransferHandlers(registry: TransferHandlerRegistry) { + registry.register(TransferHandler { context -> + val screen = context.containerScreen + val display = context.display + if (display !is SBCraftingRecipe) return@TransferHandler TransferHandler.Result.createNotApplicable() + val neuItem = RepoManager.getNEUItem(SkyblockId(display.neuRecipe.output.itemId)) + ?: error("Could not find neu item ${display.neuRecipe.output.itemId} which is used in a recipe output") + val useSuperCraft = context.isStackedCrafting || RepoManager.Config.alwaysSuperCraft + if (neuItem.isVanilla && useSuperCraft) return@TransferHandler TransferHandler.Result.createFailed(Text.translatable( + "firmament.recipe.novanilla")) + var shouldReturn = true + if (context.isActuallyCrafting && !useSuperCraft) { + if (screen !is GenericContainerScreen || screen.title?.unformattedString != CraftingOverlay.CRAFTING_SCREEN_NAME) { + MC.sendCommand("craft") + shouldReturn = false + } + CraftingOverlay.setOverlay(screen as? GenericContainerScreen, display) + } + if (context.isActuallyCrafting && useSuperCraft) { + shouldReturn = false + MC.sendCommand("viewrecipe ${neuItem.guessRecipeId()}") + } + return@TransferHandler TransferHandler.Result.createSuccessful().blocksFurtherHandling(shouldReturn) + }) + } + + override fun registerEntryTypes(registry: EntryTypeRegistry) { + registry.register(SKYBLOCK_ITEM_TYPE_ID, SBItemEntryDefinition) + } + + override fun registerCategories(registry: CategoryRegistry) { + registry.add(SBCraftingRecipe.Category) + registry.add(SBForgeRecipe.Category) + registry.add(SBMobDropRecipe.Category) + registry.add(SBKatRecipe.Category) + registry.add(SBEssenceUpgradeRecipe.Category) + } + + override fun registerExclusionZones(zones: ExclusionZones) { + zones.register(HandledScreen::class.java) { HandledScreenPushREIEvent.publish(HandledScreenPushREIEvent(it)).rectangles } + zones.register(StorageOverlayScreen::class.java) { it.getBounds() } + } + + override fun registerDisplays(registry: DisplayRegistry) { + registry.registerDisplayGenerator( + SBCraftingRecipe.Category.catIdentifier, + SkyblockCraftingRecipeDynamicGenerator) + registry.registerDisplayGenerator( + SBForgeRecipe.Category.categoryIdentifier, + SkyblockForgeRecipeDynamicGenerator) + registry.registerDisplayGenerator( + SBMobDropRecipe.Category.categoryIdentifier, + SkyblockMobDropRecipeDynamicGenerator) + registry.registerDisplayGenerator( + SBKatRecipe.Category.categoryIdentifier, + SkyblockKatRecipeDynamicGenerator) + registry.registerDisplayGenerator( + SBEssenceUpgradeRecipe.Category.categoryIdentifier, + SkyblockEssenceRecipeDynamicGenerator + ) + } + + override fun registerCollapsibleEntries(registry: CollapsibleEntryRegistry) { + if (!RepoManager.Config.disableItemGroups) + RepoManager.neuRepo.constants.parents.parents + .forEach { (parent, children) -> + registry.group( + SkyblockId(parent).identifier, + Text.literal(RepoManager.getNEUItem(SkyblockId(parent))?.displayName ?: parent), + (children + parent).map { SBItemEntryDefinition.getEntry(SkyblockId(it)) }) + } + } + + override fun registerScreens(registry: ScreenRegistry) { + registry.registerDecider(object : OverlayDecider { + override fun isHandingScreen(screen: Class?): Boolean { + return screen == StorageOverlayScreen::class.java + } + + override fun shouldScreenBeOverlaid(screen: R): ActionResult { + return ActionResult.SUCCESS + } + }) + registry.registerFocusedStack(SkyblockItemIdFocusedStackProvider) + } + + override fun registerEntries(registry: EntryRegistry) { + registry.removeEntryIf { true } + RepoManager.neuRepo.items?.items?.values?.forEach { neuItem -> + registry.addEntry(SBItemEntryDefinition.getEntry(neuItem.skyblockId)) + } + } } diff --git a/src/main/kotlin/repo/RepoManager.kt b/src/main/kotlin/repo/RepoManager.kt index 5cf84bd..ab0d9cf 100644 --- a/src/main/kotlin/repo/RepoManager.kt +++ b/src/main/kotlin/repo/RepoManager.kt @@ -40,6 +40,8 @@ object RepoManager { save() RepoManager.launchAsyncUpdate(true) } + val alwaysSuperCraft by toggle("enable-super-craft") { true } + } val currentDownloadedSha by RepoDownloadManager::latestSavedVersionHash diff --git a/src/main/kotlin/util/SkyblockId.kt b/src/main/kotlin/util/SkyblockId.kt index 5b96dfa..31227e2 100644 --- a/src/main/kotlin/util/SkyblockId.kt +++ b/src/main/kotlin/util/SkyblockId.kt @@ -13,8 +13,10 @@ import kotlin.jvm.optionals.getOrNull import net.minecraft.component.DataComponentTypes import net.minecraft.component.type.NbtComponent import net.minecraft.item.ItemStack +import net.minecraft.item.Items import net.minecraft.nbt.NbtCompound import net.minecraft.util.Identifier +import moe.nea.firmament.repo.ItemCache.asItemStack import moe.nea.firmament.repo.set import moe.nea.firmament.util.collections.WeakCache import moe.nea.firmament.util.json.DashlessUUIDSerializer @@ -69,6 +71,17 @@ value class SkyblockId(val neuItem: String) { val NEUItem.skyblockId get() = SkyblockId(skyblockItemId) +fun NEUItem.guessRecipeId(): String? { + if (!skyblockItemId.contains(";")) return skyblockItemId + val item = this.asItemStack() + val (id, extraId) = skyblockItemId.split(";") + if (item.item == Items.ENCHANTED_BOOK) { + return "ENCHANTED_BOOK_${id}_${extraId}" + } + if (item.petData != null) return id + return null +} + @Serializable data class HypixelPetInfo( val type: String, diff --git a/src/main/resources/assets/firmament/lang/en_us.json b/src/main/resources/assets/firmament/lang/en_us.json index 9a204f7..fef8996 100644 --- a/src/main/resources/assets/firmament/lang/en_us.json +++ b/src/main/resources/assets/firmament/lang/en_us.json @@ -81,6 +81,7 @@ "firmament.config.repo.branch.hint": "dangerous", "firmament.config.repo.reset": "Reset", "firmament.config.repo.disable-item-groups": "Disable Item Groups", + "firmament.config.repo.enable-super-craft": "Always use Super Craft", "firmament.config.repo.reload": "Reload Item List", "firmament.config.repo.redownload": "Redownload Item List", "firmament.config.pets": "Pets", @@ -178,7 +179,7 @@ "firmament.config.slot-locking.lock": "Lock Slot", "firmament.config.slot-locking.lock-uuid": "Lock UUID (Lock Item)", "firmament.config.slot-locking.bind": "Bind Slot", - "firmament.config.slot-locking.require-quick-move": "Require Shift-Click for Bind", + "firmament.config.slot-locking.require-quick-move": "Require Shift-Click for Bound Slots", "firmament.config.fixes.auto-sprint": "Auto Sprint", "firmament.config.fixes.auto-sprint-keybinding": "Auto Sprint KeyBinding", "firmament.config.fixes.auto-sprint-hud": "Sprint State Hud", @@ -187,6 +188,7 @@ "firmament.fixes.auto-sprint.on": "Sprint toggled", "firmament.fixes.auto-sprint.sprinting": "Sprinting", "firmament.fixes.auto-sprint.not-sprinting": "Not Sprinting", + "firmament.recipe.novanilla": "Hypixel cannot super craft vanilla recipes", "firmament.config.custom-skyblock-textures": "Custom SkyBlock Item Textures", "firmament.config.custom-skyblock-textures.cache-duration": "Model Cache Duration", "firmament.config.custom-skyblock-textures.model-overrides": "Enable model overrides/predicates", -- cgit