Add super craft to the move item REI button

This commit is contained in:
Linnea Gräf
2024-10-18 17:47:32 +02:00
parent c71fca6cc6
commit a27f8e6fed
5 changed files with 170 additions and 126 deletions

View File

@@ -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()}"
)
}
}
}

View File

@@ -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<SBItemStack>.asItemEntry(): EntryStack<ItemStack> {
return EntryStack.of(VanillaEntryTypes.ITEM, value.asImmutableItemStack())
}
companion object {
fun EntryStack<SBItemStack>.asItemEntry(): EntryStack<ItemStack> {
return EntryStack.of(VanillaEntryTypes.ITEM, value.asImmutableItemStack())
}
val SKYBLOCK_ITEM_TYPE_ID = Identifier.of("firmament", "skyblockitems")
}
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 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 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 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 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 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 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 <R : Screen?> isHandingScreen(screen: Class<R>?): Boolean {
return screen == StorageOverlayScreen::class.java
}
override fun registerScreens(registry: ScreenRegistry) {
registry.registerDecider(object : OverlayDecider {
override fun <R : Screen?> isHandingScreen(screen: Class<R>?): Boolean {
return screen == StorageOverlayScreen::class.java
}
override fun <R : Screen?> shouldScreenBeOverlaid(screen: R): ActionResult {
return ActionResult.SUCCESS
}
})
registry.registerFocusedStack(SkyblockItemIdFocusedStackProvider)
}
override fun <R : Screen?> 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))
}
}
override fun registerEntries(registry: EntryRegistry) {
registry.removeEntryIf { true }
RepoManager.neuRepo.items?.items?.values?.forEach { neuItem ->
registry.addEntry(SBItemEntryDefinition.getEntry(neuItem.skyblockId))
}
}
}

View File

@@ -40,6 +40,8 @@ object RepoManager {
save()
RepoManager.launchAsyncUpdate(true)
}
val alwaysSuperCraft by toggle("enable-super-craft") { true }
}
val currentDownloadedSha by RepoDownloadManager::latestSavedVersionHash

View File

@@ -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,

View File

@@ -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",