From ca17fe502d2ddee6ba0ae62d0b6e8458c6ded2b9 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Wed, 10 Jul 2024 04:50:31 +0200 Subject: Allow using arrows to navigate in storage overview --- .../nea/firmament/mixins/SlotClickEventPatch.java | 16 ++++++- src/main/kotlin/moe/nea/firmament/commands/rome.kt | 9 +++- .../inventory/storageoverlay/StorageOverlay.kt | 54 +++++++++++++++++++--- .../storageoverlay/StorageOverlayCustom.kt | 6 +-- .../storageoverlay/StorageOverviewScreen.kt | 8 ++-- .../moe/nea/firmament/rei/FirmamentReiPlugin.kt | 12 +++++ 6 files changed, 90 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/main/java/moe/nea/firmament/mixins/SlotClickEventPatch.java b/src/main/java/moe/nea/firmament/mixins/SlotClickEventPatch.java index 4e6d766..d1d05a2 100644 --- a/src/main/java/moe/nea/firmament/mixins/SlotClickEventPatch.java +++ b/src/main/java/moe/nea/firmament/mixins/SlotClickEventPatch.java @@ -7,12 +7,17 @@ package moe.nea.firmament.mixins; import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; import moe.nea.firmament.events.SlotClickEvent; import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.slot.SlotActionType; +import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -20,12 +25,19 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ClientPlayerInteractionManager.class) public class SlotClickEventPatch { + @Inject(method = "clickSlot", at = @At(value = "FIELD", target = "Lnet/minecraft/screen/ScreenHandler;slots:Lnet/minecraft/util/collection/DefaultedList;", opcode = Opcodes.GETFIELD)) + private void onSlotClickSaveSlot(int syncId, int slotId, int button, SlotActionType actionType, PlayerEntity player, CallbackInfo ci, @Local ScreenHandler handler, @Share("slotContent") LocalRef slotContent) { + if (0 <= slotId && slotId < handler.slots.size()) { + slotContent.set(handler.getSlot(slotId).getStack().copy()); + } + } + @Inject(method = "clickSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V")) - private void onSlotClick(int syncId, int slotId, int button, SlotActionType actionType, PlayerEntity player, CallbackInfo ci, @Local ScreenHandler handler) { + private void onSlotClick(int syncId, int slotId, int button, SlotActionType actionType, PlayerEntity player, CallbackInfo ci, @Local ScreenHandler handler, @Share("slotContent") LocalRef slotContent) { if (0 <= slotId && slotId < handler.slots.size()) { SlotClickEvent.Companion.publish(new SlotClickEvent( handler.getSlot(slotId), - handler.getSlot(slotId).getStack(), + slotContent.get(), button, actionType )); diff --git a/src/main/kotlin/moe/nea/firmament/commands/rome.kt b/src/main/kotlin/moe/nea/firmament/commands/rome.kt index 4211963..a50cc75 100644 --- a/src/main/kotlin/moe/nea/firmament/commands/rome.kt +++ b/src/main/kotlin/moe/nea/firmament/commands/rome.kt @@ -15,6 +15,7 @@ import net.minecraft.text.Text import moe.nea.firmament.apis.UrsaManager import moe.nea.firmament.events.CommandEvent import moe.nea.firmament.features.inventory.buttons.InventoryButtons +import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen import moe.nea.firmament.features.inventory.storageoverlay.StorageOverviewScreen import moe.nea.firmament.features.world.FairySouls import moe.nea.firmament.gui.config.AllConfigsGui @@ -105,12 +106,18 @@ fun firmamentCommand() = literal("firmament") { } } } - thenLiteral("storage") { + thenLiteral("storageoverview") { thenExecute { ScreenUtil.setScreenLater(StorageOverviewScreen()) MC.player?.networkHandler?.sendChatCommand("storage") } } + thenLiteral("storage") { + thenExecute { + ScreenUtil.setScreenLater(StorageOverlayScreen()) + MC.player?.networkHandler?.sendChatCommand("storage") + } + } thenLiteral("repo") { thenLiteral("reload") { thenLiteral("fetch") { diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlay.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlay.kt index f3a0f47..777cbe9 100644 --- a/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlay.kt +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlay.kt @@ -9,14 +9,19 @@ package moe.nea.firmament.features.inventory.storageoverlay import java.util.SortedMap import kotlinx.serialization.serializer -import net.minecraft.client.gui.screen.Screen import net.minecraft.client.gui.screen.ingame.GenericContainerScreen import net.minecraft.client.gui.screen.ingame.HandledScreen +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.item.Items +import net.minecraft.network.packet.c2s.play.CloseHandledScreenC2SPacket +import net.minecraft.text.Text import moe.nea.firmament.annotations.Subscribe import moe.nea.firmament.events.ScreenChangeEvent +import moe.nea.firmament.events.SlotClickEvent import moe.nea.firmament.events.TickEvent import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.gui.config.ManagedConfig +import moe.nea.firmament.util.MC import moe.nea.firmament.util.customgui.customGui import moe.nea.firmament.util.data.ProfileSpecificDataHolder @@ -43,7 +48,8 @@ object StorageOverlay : FirmamentFeature { override val config: TConfig get() = TConfig - var lastStorageOverlay: Screen? = null + var lastStorageOverlay: StorageOverviewScreen? = null + var skipNextStorageOverlayBackflip = false var currentHandler: StorageBackingHandle? = null @Subscribe @@ -51,23 +57,59 @@ object StorageOverlay : FirmamentFeature { rememberContent(currentHandler ?: return) } + @Subscribe + fun onClick(event: SlotClickEvent) { + if (lastStorageOverlay != null && event.slot.inventory !is PlayerInventory && event.slot.index < 9 + && event.stack.item != Items.BLACK_STAINED_GLASS_PANE + ) { + skipNextStorageOverlayBackflip = true + } + } + @Subscribe fun onScreenChange(it: ScreenChangeEvent) { + if (it.old == null && it.new == null) return val storageOverlayScreen = it.old as? StorageOverlayScreen ?: ((it.old as? HandledScreen<*>)?.customGui as? StorageOverlayCustom)?.overview + var storageOverviewScreen = it.old as? StorageOverviewScreen + val screen = it.new as? GenericContainerScreen + val oldHandler = currentHandler + currentHandler = StorageBackingHandle.fromScreen(screen) + rememberContent(currentHandler) + if (storageOverviewScreen != null && oldHandler is StorageBackingHandle.HasBackingScreen) { + val player = MC.player + assert(player != null) + player?.networkHandler?.sendPacket(CloseHandledScreenC2SPacket(oldHandler.handler.syncId)) + if (player?.currentScreenHandler === oldHandler.handler) { + player.currentScreenHandler = player.playerScreenHandler + } + } + storageOverviewScreen = storageOverviewScreen ?: lastStorageOverlay if (it.new == null && storageOverlayScreen != null && !storageOverlayScreen.isExiting) { it.overrideScreen = storageOverlayScreen return } - val screen = it.new as? GenericContainerScreen ?: return - currentHandler = StorageBackingHandle.fromScreen(screen) + if (storageOverviewScreen != null + && !storageOverviewScreen.isClosing + && (currentHandler is StorageBackingHandle.Overview || currentHandler == null) + ) { + if (skipNextStorageOverlayBackflip) { + skipNextStorageOverlayBackflip = false + } else { + it.overrideScreen = storageOverviewScreen + lastStorageOverlay = null + } + return + } + screen ?: return screen.customGui = StorageOverlayCustom( - currentHandler as? StorageBackingHandle.Page ?: return, + currentHandler ?: return, screen, storageOverlayScreen ?: return) } - fun rememberContent(handler: StorageBackingHandle) { + fun rememberContent(handler: StorageBackingHandle?) { + handler ?: return // TODO: Make all of these functions work on deltas / updates instead of the entire contents val data = Data.data?.storageInventories ?: return when (handler) { diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlayCustom.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlayCustom.kt index d1cdef2..a349c0f 100644 --- a/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlayCustom.kt +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlayCustom.kt @@ -17,7 +17,7 @@ import moe.nea.firmament.mixins.accessor.AccessorHandledScreen import moe.nea.firmament.util.customgui.CustomGui class StorageOverlayCustom( - val handler: StorageBackingHandle.Page, + val handler: StorageBackingHandle, val screen: GenericContainerScreen, val overview: StorageOverlayScreen, ) : CustomGui() { @@ -59,7 +59,7 @@ class StorageOverlayCustom( } override fun mouseClick(mouseX: Double, mouseY: Double, button: Int): Boolean { - return overview.mouseClicked(mouseX, mouseY, button, handler.storagePageSlot) + return overview.mouseClicked(mouseX, mouseY, button, (handler as? StorageBackingHandle.Page)?.storagePageSlot) } override fun render(drawContext: DrawContext, delta: Float, mouseX: Int, mouseY: Int) { @@ -68,7 +68,7 @@ class StorageOverlayCustom( mouseX, mouseY, delta, - handler.storagePageSlot, + (handler as? StorageBackingHandle.Page)?.storagePageSlot, screen.screenHandler.slots.take(screen.screenHandler.rows * 9).drop(9), Point((screen as AccessorHandledScreen).x_Firmament, screen.y_Firmament)) overview.drawScrollBar(drawContext) diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverviewScreen.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverviewScreen.kt index 22b612b..dc2bd48 100644 --- a/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverviewScreen.kt +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverviewScreen.kt @@ -7,6 +7,7 @@ package moe.nea.firmament.features.inventory.storageoverlay +import org.lwjgl.glfw.GLFW import kotlin.math.max import net.minecraft.block.Blocks import net.minecraft.client.gui.DrawContext @@ -119,8 +120,9 @@ class StorageOverviewScreen() : Screen(Text.empty()) { } } - override fun close() { - isClosing = true - super.close() + override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean { + if (keyCode == GLFW.GLFW_KEY_ESCAPE) + isClosing = true + return super.keyPressed(keyCode, scanCode, modifiers) } } diff --git a/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt b/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt index 85efd15..4f897bd 100644 --- a/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt +++ b/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt @@ -13,16 +13,19 @@ import me.shedaniel.rei.api.client.registry.display.DisplayRegistry import me.shedaniel.rei.api.client.registry.entry.CollapsibleEntryRegistry import me.shedaniel.rei.api.client.registry.entry.EntryRegistry import me.shedaniel.rei.api.client.registry.screen.ExclusionZones +import me.shedaniel.rei.api.client.registry.screen.OverlayDecider 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 import net.minecraft.client.gui.screen.ingame.HandledScreen 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 @@ -99,6 +102,15 @@ class FirmamentReiPlugin : REIClientPlugin { } 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) } -- cgit