aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/features/inventory/storageoverlay/StorageOverviewScreen.kt
blob: 3462d3d6a42c2eeb08babac6cfd131fc24babef7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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
import net.minecraft.client.gui.screen.Screen
import net.minecraft.item.Item
import net.minecraft.item.Items
import net.minecraft.text.Text
import net.minecraft.util.DyeColor
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.toShedaniel

class StorageOverviewScreen() : 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

		var scroll = 0
		var lastRenderedHeight = 0
    }

    val content = StorageOverlay.Data.data ?: StorageData()
    var isClosing = false

	override fun init() {
		super.init()
		scroll = scroll.coerceAtMost(getMaxScroll()).coerceAtLeast(0)
	}

	override fun close() {
		if (!StorageOverlay.TConfig.retainScroll) scroll = 0
		super.close()
	}

    override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
        super.render(context, mouseX, mouseY, delta)
        context.fill(0, 0, width, height, 0x90000000.toInt())
        layoutedForEach { (key, value), offsetX, offsetY ->
            context.matrices.push()
            context.matrices.translate(offsetX.toFloat(), offsetY.toFloat(), 0F)
            renderStoragePage(context, value, mouseX - offsetX, mouseY - offsetY)
            context.matrices.pop()
        }
    }

    inline fun layoutedForEach(onEach: (data: Pair<StoragePageSlot, StorageData.StorageInventory>, offsetX: Int, offsetY: Int) -> Unit) {
        var offsetY = 0
        var currentMaxHeight = StorageOverlay.config.margin - StorageOverlay.config.padding - scroll
        var totalHeight = -currentMaxHeight
        content.storageInventories.onEachIndexed { index, (key, value) ->
            val pageX = (index % StorageOverlay.config.columns)
            if (pageX == 0) {
                currentMaxHeight += StorageOverlay.config.padding
                offsetY += currentMaxHeight
                totalHeight += currentMaxHeight
                currentMaxHeight = 0
            }
            val xPosition =
                width / 2 - (StorageOverlay.config.columns * (pageWidth + StorageOverlay.config.padding) - StorageOverlay.config.padding) / 2 + pageX * (pageWidth + StorageOverlay.config.padding)
            onEach(Pair(key, value), xPosition, offsetY)
            val height = getStorePageHeight(value)
            currentMaxHeight = max(currentMaxHeight, height)
        }
        lastRenderedHeight = totalHeight + currentMaxHeight
    }

    override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
        layoutedForEach { (k, p), x, y ->
            val rx = mouseX - x
            val ry = mouseY - y
            if (rx in (0.0..pageWidth.toDouble()) && ry in (0.0..getStorePageHeight(p).toDouble())) {
                close()
                StorageOverlay.lastStorageOverlay = this
                k.navigateTo()
                return true
            }
        }
        return super.mouseClicked(mouseX, mouseY, button)
    }

    fun getStorePageHeight(page: StorageData.StorageInventory): Int {
        return page.inventory?.rows?.let { it * 19 + MC.font.fontHeight + 2 } ?: 60
    }

    override fun mouseScrolled(
        mouseX: Double,
        mouseY: Double,
        horizontalAmount: Double,
        verticalAmount: Double
    ): Boolean {
        scroll =
            (scroll + StorageOverlay.adjustScrollSpeed(verticalAmount)).toInt()
                .coerceAtMost(getMaxScroll()).coerceAtLeast(0)
        return true
    }

	private fun getMaxScroll() = lastRenderedHeight - height + 2 * StorageOverlay.config.margin

    private fun renderStoragePage(context: DrawContext, page: StorageData.StorageInventory, mouseX: Int, mouseY: Int) {
        context.drawText(MC.font, page.title, 2, 2, -1, true)
        val inventory = page.inventory
        if (inventory == null) {
            // TODO: Missing texture
            context.fill(0, 0, pageWidth, 60, DyeColor.RED.toShedaniel().darker(4.0).color)
            context.drawCenteredTextWithShadow(MC.font, Text.literal("Not loaded yet"), pageWidth / 2, 30, -1)
            return
        }

        for ((index, stack) in inventory.stacks.withIndex()) {
            val x = (index % 9) * 19
            val y = (index / 9) * 19 + MC.font.fontHeight + 2
            if (((mouseX - x) in 0 until 18) && ((mouseY - y) in 0 until 18)) {
                context.fill(x, y, x + 18, y + 18, 0x80808080.toInt())
            } else {
                context.fill(x, y, x + 18, y + 18, 0x40808080.toInt())
            }
            context.drawItem(stack, x + 1, y + 1)
            context.drawStackOverlay(MC.font, stack, x + 1, y + 1)
        }
    }

    override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
        if (keyCode == GLFW.GLFW_KEY_ESCAPE)
            isClosing = true
        return super.keyPressed(keyCode, scanCode, modifiers)
    }
}