diff options
| author | nea <nea@nea.moe> | 2023-07-11 21:01:58 +0200 |
|---|---|---|
| committer | nea <nea@nea.moe> | 2023-07-11 21:01:58 +0200 |
| commit | 4d93f475aadc42c4bf83c3a0749af41659235c71 (patch) | |
| tree | c8e01710defe66e06c50fa962c72fdac66a35a1f /src/main/kotlin | |
| parent | 4444fcca44d9a53c8162d69e0e9f19fd214c2f54 (diff) | |
| download | Firmament-4d93f475aadc42c4bf83c3a0749af41659235c71.tar.gz Firmament-4d93f475aadc42c4bf83c3a0749af41659235c71.tar.bz2 Firmament-4d93f475aadc42c4bf83c3a0749af41659235c71.zip | |
Bulk commit
Diffstat (limited to 'src/main/kotlin')
33 files changed, 884 insertions, 31 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/Firmament.kt b/src/main/kotlin/moe/nea/firmament/Firmament.kt index 2e1cd05..46329f1 100644 --- a/src/main/kotlin/moe/nea/firmament/Firmament.kt +++ b/src/main/kotlin/moe/nea/firmament/Firmament.kt @@ -19,13 +19,15 @@ package moe.nea.firmament import com.mojang.brigadier.CommandDispatcher -import io.ktor.client.* -import io.ktor.client.plugins.* -import io.ktor.client.plugins.cache.* -import io.ktor.client.plugins.compression.* -import io.ktor.client.plugins.contentnegotiation.* -import io.ktor.client.plugins.logging.* -import io.ktor.serialization.kotlinx.json.* +import dev.architectury.event.events.client.ClientTickEvent +import io.ktor.client.HttpClient +import io.ktor.client.plugins.UserAgent +import io.ktor.client.plugins.cache.HttpCache +import io.ktor.client.plugins.compression.ContentEncoding +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.plugins.logging.LogLevel +import io.ktor.client.plugins.logging.Logging +import io.ktor.serialization.kotlinx.json.json import java.nio.file.Files import java.nio.file.Path import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback @@ -49,6 +51,7 @@ import net.minecraft.command.CommandRegistryAccess import net.minecraft.util.Identifier import moe.nea.firmament.commands.registerFirmamentCommand import moe.nea.firmament.dbus.FirmamentDbusObject +import moe.nea.firmament.events.TickEvent import moe.nea.firmament.features.FeatureManager import moe.nea.firmament.repo.HypixelStaticData import moe.nea.firmament.repo.RepoManager @@ -114,6 +117,10 @@ object Firmament { @JvmStatic fun onClientInitialize() { dbusConnection.requestBusName("moe.nea.firmament") + var tick = 0 + ClientTickEvent.CLIENT_POST.register(ClientTickEvent.Client { instance -> + TickEvent.publish(TickEvent(tick++)) + }) dbusConnection.exportObject(FirmamentDbusObject) IDataHolder.registerEvents() RepoManager.initialize() diff --git a/src/main/kotlin/moe/nea/firmament/commands/rome.kt b/src/main/kotlin/moe/nea/firmament/commands/rome.kt index 2237abd..11aaf17 100644 --- a/src/main/kotlin/moe/nea/firmament/commands/rome.kt +++ b/src/main/kotlin/moe/nea/firmament/commands/rome.kt @@ -22,6 +22,7 @@ import com.mojang.brigadier.CommandDispatcher import com.mojang.brigadier.arguments.StringArgumentType.string import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource import net.minecraft.text.Text +import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen import moe.nea.firmament.features.world.FairySouls import moe.nea.firmament.gui.config.AllConfigsGui import moe.nea.firmament.gui.profileviewer.ProfileViewer @@ -30,6 +31,7 @@ import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.util.FirmFormatters import moe.nea.firmament.util.MC import moe.nea.firmament.util.SBData +import moe.nea.firmament.util.ScreenUtil import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.unformattedString @@ -40,6 +42,12 @@ fun firmamentCommand() = literal("firmament") { AllConfigsGui.showAllGuis() } } + thenLiteral("storage") { + thenExecute { + ScreenUtil.setScreenLater(StorageOverlayScreen()) + MC.player?.networkHandler?.sendChatCommand("ec") + } + } thenLiteral("repo") { thenLiteral("reload") { thenLiteral("fetch") { diff --git a/src/main/kotlin/moe/nea/firmament/events/TickEvent.kt b/src/main/kotlin/moe/nea/firmament/events/TickEvent.kt new file mode 100644 index 0000000..5d9b0ce --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/events/TickEvent.kt @@ -0,0 +1,5 @@ +package moe.nea.firmament.events + +data class TickEvent(val tickCount: Int) : FirmamentEvent() { + companion object : FirmamentEventBus<TickEvent>() +} diff --git a/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt b/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt index e465349..0f0a166 100644 --- a/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt +++ b/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt @@ -21,10 +21,13 @@ package moe.nea.firmament.features import kotlinx.serialization.Serializable import kotlinx.serialization.serializer import moe.nea.firmament.Firmament +import moe.nea.firmament.features.debug.DebugView import moe.nea.firmament.features.debug.DeveloperFeatures import moe.nea.firmament.features.fishing.FishingWarning import moe.nea.firmament.features.inventory.CraftingOverlay +import moe.nea.firmament.features.inventory.SaveCursorPosition import moe.nea.firmament.features.inventory.SlotLocking +import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlay import moe.nea.firmament.features.world.FairySouls import moe.nea.firmament.util.data.DataHolder @@ -50,9 +53,13 @@ object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "feature loadFeature(FairySouls) loadFeature(FishingWarning) loadFeature(SlotLocking) + loadFeature(StorageOverlay) loadFeature(CraftingOverlay) - if (Firmament.DEBUG) + loadFeature(SaveCursorPosition) + if (Firmament.DEBUG) { loadFeature(DeveloperFeatures) + loadFeature(DebugView) + } hasAutoloaded = true } } diff --git a/src/main/kotlin/moe/nea/firmament/features/FirmamentFeature.kt b/src/main/kotlin/moe/nea/firmament/features/FirmamentFeature.kt index e394fb7..94b69f1 100644 --- a/src/main/kotlin/moe/nea/firmament/features/FirmamentFeature.kt +++ b/src/main/kotlin/moe/nea/firmament/features/FirmamentFeature.kt @@ -21,7 +21,6 @@ package moe.nea.firmament.features import moe.nea.firmament.gui.config.ManagedConfig interface FirmamentFeature { - val name: String val identifier: String val defaultEnabled: Boolean get() = true diff --git a/src/main/kotlin/moe/nea/firmament/features/debug/DebugView.kt b/src/main/kotlin/moe/nea/firmament/features/debug/DebugView.kt new file mode 100644 index 0000000..e8c85d8 --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/features/debug/DebugView.kt @@ -0,0 +1,53 @@ +package moe.nea.firmament.features.debug + +import io.github.cottonmc.cotton.gui.client.CottonHud +import io.github.cottonmc.cotton.gui.widget.WBox +import io.github.cottonmc.cotton.gui.widget.data.Axis +import java.util.Optional +import kotlin.time.Duration.Companion.seconds +import net.minecraft.scoreboard.Scoreboard +import net.minecraft.scoreboard.Team +import net.minecraft.text.StringVisitable +import net.minecraft.text.Style +import net.minecraft.text.Text +import net.minecraft.util.Formatting +import moe.nea.firmament.Firmament +import moe.nea.firmament.events.TickEvent +import moe.nea.firmament.features.FirmamentFeature +import moe.nea.firmament.util.MC +import moe.nea.firmament.util.TimeMark + +object DebugView : FirmamentFeature { + private data class StoredVariable<T>( + val obj: T, + val timer: TimeMark, + ) + + private val storedVariables: MutableMap<String, StoredVariable<*>> = mutableMapOf() + override val identifier: String + get() = "debug-view" + override val defaultEnabled: Boolean + get() = Firmament.DEBUG + + fun <T : Any?> showVariable(label: String, obj: T) { + synchronized(this) { + storedVariables[label] = StoredVariable(obj, TimeMark.now()) + } + } + + val debugWidget = WBox(Axis.VERTICAL) + + + override fun onLoad() { + TickEvent.subscribe { + synchronized(this) { + storedVariables.entries.removeIf { it.value.timer.passedTime() > 1.seconds } + if (storedVariables.isEmpty()) { + CottonHud.add(debugWidget, 20, 20) + } else { + CottonHud.remove(debugWidget) + } + } + } + } +} diff --git a/src/main/kotlin/moe/nea/firmament/features/debug/DeveloperFeatures.kt b/src/main/kotlin/moe/nea/firmament/features/debug/DeveloperFeatures.kt index e89ee6f..253bc0d 100644 --- a/src/main/kotlin/moe/nea/firmament/features/debug/DeveloperFeatures.kt +++ b/src/main/kotlin/moe/nea/firmament/features/debug/DeveloperFeatures.kt @@ -14,8 +14,6 @@ import moe.nea.firmament.util.TimeMark import moe.nea.firmament.util.iterate object DeveloperFeatures : FirmamentFeature { - override val name: String - get() = "developer" override val identifier: String get() = "developer" override val config: TConfig diff --git a/src/main/kotlin/moe/nea/firmament/features/debug/ObjectRenderer.kt b/src/main/kotlin/moe/nea/firmament/features/debug/ObjectRenderer.kt new file mode 100644 index 0000000..f5185cd --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/features/debug/ObjectRenderer.kt @@ -0,0 +1,52 @@ +package moe.nea.firmament.features.debug + +import io.github.cottonmc.cotton.gui.widget.WBox +import io.github.cottonmc.cotton.gui.widget.WLabel +import io.github.cottonmc.cotton.gui.widget.WWidget +import io.github.cottonmc.cotton.gui.widget.data.Axis +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import kotlin.reflect.KProperty1 +import net.minecraft.text.Text +import moe.nea.firmament.gui.WSpacer + +class ObjectRenderer(val box: WBox) { + var indent = 0 + + fun beginObject() { + indent++ + } + + fun endObject() { + indent-- + } + + fun emit(label: String, widget: WWidget) { + WSpacer(WBox(Axis.VERTICAL).also { + it.add(WWidget()) + it.add(widget) + }, indent * 18) + } + + fun <T : Any?> getDebuggingView(label: String, obj: T) { + if (obj == null) { + emit(label, WLabel(Text.literal("§cnull"))) + return + } + if (obj is String) { + emit(label, WLabel(Text.literal(Json.encodeToString(obj)))) + } + getObject(label, obj) + } + + fun <T : Any> getObject(label: String, obj: T) { + emit(label, WLabel(Text.literal(obj::class.simpleName ?: "<unknown>"))) + beginObject() + for (prop in obj::class.members.filterIsInstance<KProperty1<T, *>>()) { + val child = prop.get(obj) + getDebuggingView(prop.name, child) + } + endObject() + } + +} diff --git a/src/main/kotlin/moe/nea/firmament/features/fishing/FishingWarning.kt b/src/main/kotlin/moe/nea/firmament/features/fishing/FishingWarning.kt index fa8d779..4c20450 100644 --- a/src/main/kotlin/moe/nea/firmament/features/fishing/FishingWarning.kt +++ b/src/main/kotlin/moe/nea/firmament/features/fishing/FishingWarning.kt @@ -38,8 +38,6 @@ import moe.nea.firmament.util.TimeMark import moe.nea.firmament.util.render.RenderInWorldContext.Companion.renderInWorld object FishingWarning : FirmamentFeature { - override val name: String - get() = "Fishing Warning" override val identifier: String get() = "fishing-warning" @@ -137,7 +135,7 @@ object FishingWarning : FirmamentFeature { WorldRenderLastEvent.subscribe { recentParticles.removeIf { it.second.passedTime() > 5.seconds } recentCandidates.removeIf { it.timeMark.passedTime() > 5.seconds } - renderInWorld(it.matrices, it.camera) { + renderInWorld(it) { color(0f, 0f, 1f, 1f) recentParticles.forEach { tinyBlock(it.first, 0.1F) diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/CraftingOverlay.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/CraftingOverlay.kt index 31d2b23..bb73513 100644 --- a/src/main/kotlin/moe/nea/firmament/features/inventory/CraftingOverlay.kt +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/CraftingOverlay.kt @@ -26,8 +26,6 @@ object CraftingOverlay : FirmamentFeature { this.recipe = recipe } - override val name: String - get() = "Crafting Overlay" override val identifier: String get() = "crafting-overlay" diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/SaveCursorPosition.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/SaveCursorPosition.kt new file mode 100644 index 0000000..577f19b --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/SaveCursorPosition.kt @@ -0,0 +1,67 @@ +package moe.nea.firmament.features.inventory + +import kotlin.math.absoluteValue +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds +import net.minecraft.client.util.InputUtil +import moe.nea.firmament.features.FirmamentFeature +import moe.nea.firmament.gui.config.ManagedConfig +import moe.nea.firmament.util.MC +import moe.nea.firmament.util.TimeMark +import moe.nea.firmament.util.assertNotNullOr + +object SaveCursorPosition : FirmamentFeature { + override val identifier: String + get() = "save-cursor-position" + + object TConfig : ManagedConfig(identifier) { + val enable by toggle("enable") { true } + val tolerance by duration("tolerance", 10.milliseconds, 5000.milliseconds) { 500.milliseconds } + } + + override val config: TConfig + get() = TConfig + + override fun onLoad() { + + } + + var savedPositionedP1: Pair<Double, Double>? = null + var savedPosition: SavedPosition? = null + + data class SavedPosition( + val middle: Pair<Double, Double>, + val cursor: Pair<Double, Double>, + val savedAt: TimeMark = TimeMark.now() + ) + + @JvmStatic + fun saveCursorOriginal(positionedX: Double, positionedY: Double) { + savedPositionedP1 = Pair(positionedX, positionedY) + } + + @JvmStatic + fun loadCursor(middleX: Double, middleY: Double): Pair<Double, Double>? { + val lastPosition = savedPosition?.takeIf { it.savedAt.passedTime() < 1.seconds } + savedPosition = null + if (lastPosition != null && + (lastPosition.middle.first - middleX).absoluteValue < 1 && + (lastPosition.middle.second - middleY).absoluteValue < 1 + ) { + InputUtil.setCursorParameters( + MC.window.handle, + InputUtil.GLFW_CURSOR_NORMAL, + lastPosition.cursor.first, + lastPosition.cursor.second + ) + return lastPosition.cursor + } + return null + } + + @JvmStatic + fun saveCursorMiddle(middleX: Double, middleY: Double) { + val cursorPos = assertNotNullOr(savedPositionedP1) { return } + savedPosition = SavedPosition(Pair(middleX, middleY), cursorPos) + } +} diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/SlotLocking.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/SlotLocking.kt index eab0da0..a601489 100644 --- a/src/main/kotlin/moe/nea/firmament/features/inventory/SlotLocking.kt +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/SlotLocking.kt @@ -33,8 +33,6 @@ import moe.nea.firmament.util.MC import moe.nea.firmament.util.data.ProfileSpecificDataHolder object SlotLocking : FirmamentFeature { - override val name: String - get() = "Slot Locking" override val identifier: String get() = "slot-locking" diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageBackingHandle.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageBackingHandle.kt new file mode 100644 index 0000000..5802cb7 --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageBackingHandle.kt @@ -0,0 +1,56 @@ +package moe.nea.firmament.features.inventory.storageoverlay + +import net.minecraft.client.gui.screen.Screen +import net.minecraft.client.gui.screen.ingame.GenericContainerScreen +import net.minecraft.screen.GenericContainerScreenHandler +import moe.nea.firmament.util.ifMatches +import moe.nea.firmament.util.unformattedString + +/** + * A handle representing the state of the "server side" screens. + */ +sealed interface StorageBackingHandle { + + sealed interface HasBackingScreen { + val handler: GenericContainerScreenHandler + } + + /** + * No open "server side" screen. + */ + object None : StorageBackingHandle + + /** + * The main storage overview is open. Clicking on a slot will open that page. This page is accessible via `/storage` + */ + data class Overview(override val handler: GenericContainerScreenHandler) : StorageBackingHandle, HasBackingScreen + + /** + * An individual storage page is open. This may be a backpack or an enderchest page. This page is accessible via + * the [Overview] or via `/ec <index + 1>` for enderchest pages. + */ + data class Page(override val handler: GenericContainerScreenHandler, val storagePageSlot: StoragePageSlot) : + StorageBackingHandle, HasBackingScreen + + companion object { + private val enderChestName = "^Ender Chest \\(([1-9])/[1-9]\\)$".toRegex() + private val backPackName = "^.+Backpack \\(Slot #([0-9]+)\\)$".toRegex() + + /** + * Parse a screen into a [StorageBackingHandle]. If this returns null it means that the screen is not + * representable as a [StorageBackingHandle], meaning another screen is open, for example the enderchest icon + * selection screen. + */ + fun fromScreen(screen: Screen?): StorageBackingHandle? { + if (screen == null) return None + if (screen !is GenericContainerScreen) return null + val title = screen.title.unformattedString + if (title == "Storage") return Overview(screen.screenHandler) + return title.ifMatches(enderChestName) { + Page(screen.screenHandler, StoragePageSlot.ofEnderChestPage(it.groupValues[1].toInt())) + } ?: title.ifMatches(backPackName) { + Page(screen.screenHandler, StoragePageSlot.ofBackPackPage(it.groupValues[1].toInt())) + } + } + } +} diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageData.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageData.kt new file mode 100644 index 0000000..1c2ac08 --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageData.kt @@ -0,0 +1,16 @@ +package moe.nea.firmament.features.inventory.storageoverlay + +import java.util.SortedMap +import kotlinx.serialization.Serializable + +@Serializable +data class StorageData( + val storageInventories: SortedMap<StoragePageSlot, StorageInventory> = sortedMapOf() +) { + @Serializable + data class StorageInventory( + var title: String, + val slot: StoragePageSlot, + var inventory: VirtualInventory?, + ) +} 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 new file mode 100644 index 0000000..fae3867 --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlay.kt @@ -0,0 +1,94 @@ +package moe.nea.firmament.features.inventory.storageoverlay + +import java.util.* +import kotlinx.serialization.serializer +import moe.nea.firmament.events.ScreenOpenEvent +import moe.nea.firmament.events.TickEvent +import moe.nea.firmament.features.FirmamentFeature +import moe.nea.firmament.gui.config.ManagedConfig +import moe.nea.firmament.util.data.ProfileSpecificDataHolder + +object StorageOverlay : FirmamentFeature { + + + object Data : ProfileSpecificDataHolder<StorageData>(serializer(), "storage-data", ::StorageData) + + override val identifier: String + get() = "storage-overlay" + + object TConfig : ManagedConfig(identifier) { + val rows by integer("rows", 1, 5) { 3 } + val scrollSpeed by integer("scroll-speed", 1, 50) { 10 } + val inverseScroll by toggle("inverse-scroll") { false } + val padding by integer("padding", 1, 20) { 5 } + val margin by integer("margin", 1, 60) { 20 } + } + + override val config: TConfig + get() = TConfig + + var currentHandler: StorageBackingHandle? = StorageBackingHandle.None + + override fun onLoad() { + ScreenOpenEvent.subscribe { event -> + currentHandler = StorageBackingHandle.fromScreen(event.new) + if (event.old is StorageOverlayScreen && !event.old.isClosing) { + event.old.setHandler(currentHandler) + if (currentHandler != null) + // TODO: Consider instead only replacing rendering? might make a lot of stack handling easier + event.cancel() + } + } + TickEvent.subscribe { + rememberContent(currentHandler ?: return@subscribe) + } + } + + private fun rememberContent(handler: StorageBackingHandle) { + // TODO: Make all of these functions work on deltas / updates instead of the entire contents + val data = Data.data?.storageInventories ?: return + when (handler) { + StorageBackingHandle.None -> {} + is StorageBackingHandle.Overview -> rememberStorageOverview(handler, data) + is StorageBackingHandle.Page -> rememberPage(handler, data) + } + } + + private fun rememberStorageOverview( + handler: StorageBackingHandle.Overview, + data: SortedMap<StoragePageSlot, StorageData.StorageInventory> + ) { + for ((index, stack) in handler.handler.stacks.withIndex()) { + // Ignore unloaded item stacks + if (stack.isEmpty) continue + val slot = StoragePageSlot.fromOverviewSlotIndex(index) ?: continue + val isEmpty = stack.item in StorageOverlayScreen.emptyStorageSlotItems + if (slot in data) { + if (isEmpty) + data.remove(slot) + continue + } + if (!isEmpty) { + data[slot] = StorageData.StorageInventory(slot.defaultName(), slot, null) + } + } + } + + private fun rememberPage( + handler: StorageBackingHandle.Page, + data: SortedMap<StoragePageSlot, StorageData.StorageInventory> + ) { + // TODO: FIXME: FIXME NOW: Definitely don't copy all of this every tick into persistence + val newStacks = + VirtualInventory(handler.handler.stacks.take(handler.handler.rows * 9).drop(9).map { it.copy() }) + data.compute(handler.storagePageSlot) { slot, existingInventory -> + (existingInventory ?: StorageData.StorageInventory( + slot.defaultName(), + slot, + null + )).also { + it.inventory = newStacks + } + } + } +} diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlayScreen.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlayScreen.kt new file mode 100644 index 0000000..1c896db --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/storageoverlay/StorageOverlayScreen.kt @@ -0,0 +1,135 @@ +package moe.nea.firmament.features.inventory.storageoverlay + +import moe.nea.firmament.util.MC +import moe.nea.firmament.util.assertNotNullOr +import moe.nea.firmament.util.toShedaniel +import net.minecraft.block.Blocks +import net.minecraft.client.gui.DrawContext +import net.minecraft.client.gui.screen.Screen +import net.minecraft.item.Item +import net.minecraft.item.Items +import net.minecraft.network.packet.c2s.play.CloseHandledScreenC2SPacket +import net.minecraft.text.Text +import net.minecraft.util.DyeColor +import kotlin.math.max + +class StorageOverlayScreen() : Screen(Text.empty()) { + companion object { + val emptyStorageSlotItems = listOf<Item>( + Blocks.RED_STAINED_GLASS_PANE.asItem(), + Blocks.BROWN_STAINED_GLASS_PANE.asItem(), + Items.GRAY_DYE + ) + val pageWidth get() = 19 * 9 + } + + private var handler: StorageBackingHandle = StorageBackingHandle.None + val content = StorageOverlay.Data.data ?: StorageData() + var isClosing = false + + private fun discardOldHandle() { + val player = assertNotNullOr(MC.player) { return } + val handle = this.handler + if (handle is StorageBackingHandle.HasBackingScreen) { + player.networkHandler.sendPacket(CloseHandledScreenC2SPacket(handle.handler.syncId)) + if (player.currentScreenHandler === handle.handler) { + player.currentScreenHandler = player.playerScreenHandler + } + } + } + + fun setHandler(handler: StorageBackingHandle?) { + discardOldHandle() + if (handler != null) + this.handler = handler + } |
