From bf1a7394e6c1c1df404bf305286ead60585dd142 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 23 Aug 2022 21:05:39 +0700 Subject: [PATCH] Highlight paths in research tree --- .../mc/otm/client/render/RenderHelper.kt | 4 +- .../otm/client/screen/AndroidStationScreen.kt | 144 +++++++++++++----- .../otm/client/screen/panels/EditablePanel.kt | 19 ++- .../ru/dbotthepony/mc/otm/core/RGBAColor.kt | 3 + 4 files changed, 124 insertions(+), 46 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt index ece72d1f2..3d69060bd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt @@ -374,12 +374,12 @@ fun drawLine( val y3 = -width builder.vertex(matrix, - startX + y0 * sin, + startX - y0 * sin, startY + y0 * cos, zLevel).color(drawColor).endVertex() builder.vertex(matrix, - startX + y1 * sin, + startX - y1 * sin, startY + y1 * cos, zLevel).color(drawColor).endVertex() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/AndroidStationScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/AndroidStationScreen.kt index 5ef46ae56..74bde26ee 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/AndroidStationScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/AndroidStationScreen.kt @@ -79,6 +79,8 @@ private fun isTree(root: AndroidResearchType<*>): Boolean { return true } +typealias LinePos = Pair, Pair> + private class Tree(val node: AndroidResearchType<*>) : Iterable { val subtrees = ArrayList() @@ -159,37 +161,25 @@ private class Tree(val node: AndroidResearchType<*>) : Iterable { ): Pair { val totalWidth = width * 24f - val lines = ArrayList, Pair>>() - - val button = object : AndroidResearchButton(rows[node.researchTreeDepth], capability.getResearch(node)) { - override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) { - super.innerRender(stack, mouse_x, mouse_y, flag) - - drawColor = RGBAColor.WHITE - RGBAColor.WHITE.setShaderColor() - - for (line in lines) { - val (pos1, pos2) = line - val (x1, y1) = pos1 - val (x2, y2) = pos2 - - drawLine(stack, x1, y1, x2, y2, 0.5f) - } - } - } + val lines = ArrayList() + val linesToResearch = IdentityHashMap, ArrayList>() + val button = AndroidResearchButton(rows[node.researchTreeDepth], capability.getResearch(node), lines, linesToResearch) button.x = left + totalWidth / 2f - button.width / 2f @Suppress("name_shadowing") var left = left - val widths = FloatArrayList() + var busLine: LinePos? = null if (subtrees.size > 1) { - lines.add( - ((button.width / 2f) to button.y + button.height) to - ((button.width / 2f) to button.y + button.height + 3f) - ) + val x = button.width / 2f + val y = button.y + button.height + + busLine = (x to y) to + (x to y + 3f) + + lines.add(busLine) } var minX = Float.MAX_VALUE @@ -197,25 +187,51 @@ private class Tree(val node: AndroidResearchType<*>) : Iterable { for (subtree in this) { val (btn, move) = subtree.put(rows, left, capability) - widths.add(move) left += move + val line: LinePos + if (subtrees.size == 1) { - lines.add( - ((button.width / 2f) to button.y + button.height) to - ((btn.width / 2f) to button.y + button.height + 6f) - ) + val x = (button.width / 2f) + val y = button.y + button.height + + line = (x to y) to + (x to y + 6f) } else { val x = btn.x + btn.width / 2f - button.x val y = button.y + button.height + 3f - lines.add( - (x to y) to - (x to y + 3f) - ) + line = (x to y) to + (x to y + 3f) minX = minX.coerceAtMost(x) maxX = maxX.coerceAtLeast(x) + + val highlightLine = + ((button.width / 2f) to y) to + (x to y) + + linesToResearch.computeIfAbsent(subtree.node) { ArrayList() }.add(highlightLine) + + for (children in subtree.node.allUnlocks) { + linesToResearch.computeIfAbsent(children) { ArrayList() }.add(highlightLine) + } + } + + lines.add(line) + + linesToResearch.computeIfAbsent(subtree.node) { ArrayList() }.add(line) + + for (children in subtree.node.allUnlocks) { + linesToResearch.computeIfAbsent(children) { ArrayList() }.add(line) + } + + if (busLine != null) { + linesToResearch.computeIfAbsent(subtree.node) { ArrayList() }.add(busLine) + + for (children in subtree.node.allUnlocks) { + linesToResearch.computeIfAbsent(children) { ArrayList() }.add(busLine) + } } } @@ -232,19 +248,38 @@ private class Tree(val node: AndroidResearchType<*>) : Iterable { } } -private open class AndroidResearchButton(parent: EditablePanel, private val node: AndroidResearch) : - EditablePanel( - parent.screen, - parent, - 0f, - 0f, - AndroidStationScreen.BUTTON_SIZE.toFloat(), - AndroidStationScreen.BUTTON_SIZE.toFloat() - ) { +private open class AndroidResearchButton( + parent: EditablePanel, + private val node: AndroidResearch, + private val lines: List, + private val highlightLines: Map, List> +) :EditablePanel( + parent.screen, + parent, + 0f, + 0f, + AndroidStationScreen.BUTTON_SIZE.toFloat(), + AndroidStationScreen.BUTTON_SIZE.toFloat() +) { + init { setDockMargin(2f, 2f, 2f, 2f) } + override fun onHovered() { + super.onHovered() + + (screen as AndroidStationScreen).hoveredResearch = node + } + + override fun onUnHovered() { + super.onUnHovered() + + if ((screen as AndroidStationScreen).hoveredResearch == node) { + screen.hoveredResearch = null + } + } + override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) { minecraft.player?.getCapability(MatteryCapability.ANDROID)?.ifPresentK { if (node.isResearched) { @@ -269,6 +304,30 @@ private open class AndroidResearchButton(parent: EditablePanel, private val node font.drawShadow(stack, text, width - font.width(text), height - font.lineHeight, -0x1) } } + + drawColor = RGBAColor.WHITE + RGBAColor.WHITE.setShaderColor() + + for (line in lines) { + val (pos1, pos2) = line + val (x1, y1) = pos1 + val (x2, y2) = pos2 + + drawLine(stack, x1, y1, x2, y2, 0.5f) + } + + val hovered = (screen as AndroidStationScreen).hoveredResearch ?: return + val lines = highlightLines[hovered.type] ?: return + + drawColor = RGBAColor.LIGHT_GREEN + + for (line in lines) { + val (pos1, pos2) = line + val (x1, y1) = pos1 + val (x2, y2) = pos2 + + drawLine(stack, x1, y1, x2, y2, 0.5f) + } } override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean { @@ -307,6 +366,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I private var canvas: DraggableCanvasPanel? = null private var research: FramePanel? = null + var hoveredResearch: AndroidResearch? = null private fun openResearchTree() { val window = minecraft!!.window @@ -352,7 +412,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I } }) - val button = AndroidResearchButton(row, it.getResearch(research)) + val button = AndroidResearchButton(row, it.getResearch(research), emptyList(), emptyMap()) val width = rowWidths[research.researchTreeDepth] button.setPos(totalWidth + width, 0f) rowWidths[research.researchTreeDepth] += 22f diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt index b01b5005b..fd4784655 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt @@ -23,7 +23,7 @@ enum class Dock { } open class EditablePanel @JvmOverloads constructor( - @JvmField val screen: MatteryScreen<*>, + val screen: MatteryScreen<*>, parent: EditablePanel?, // относительно родителя @@ -176,12 +176,27 @@ open class EditablePanel @JvmOverloads constructor( private set var isHovered = false - private set + private set(value) { + if (value == field) { + return + } + + field = value + + if (value) { + onHovered() + } else { + onUnHovered() + } + } fun unsetHovered() { isHovered = false } + open fun onHovered() {} + open fun onUnHovered() {} + var isFocused = false set(value) { if (field != value) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/RGBAColor.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/RGBAColor.kt index ee948f8ae..c4b1b7458 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/RGBAColor.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/RGBAColor.kt @@ -5,6 +5,7 @@ import com.mojang.blaze3d.systems.RenderSystem data class RGBAColor(val red: Float, val green: Float, val blue: Float, val alpha: Float = 1f) { constructor(r: Int, g: Int, b: Int) : this((r / 255f), (g / 255f), (b / 255f), 1f) constructor(r: Int, g: Int, b: Int, a: Int) : this((r / 255f), (g / 255f), (b / 255f), (a / 255f)) + constructor(r: Int, g: Int, b: Int, a: Float) : this((r / 255f), (g / 255f), (b / 255f), a) constructor(color: Long) : this( (((color and -0x1000000) ushr 24) / 255f), @@ -52,6 +53,8 @@ data class RGBAColor(val red: Float, val green: Float, val blue: Float, val alph companion object { val BLACK = RGBAColor(0f, 0f, 0f, 1f) val WHITE = RGBAColor(1f, 1f, 1f, 1f) + val GREEN = RGBAColor(0f, 1f, 0f, 1f) + val LIGHT_GREEN = RGBAColor(136, 255, 124) val SLATE_GRAY = RGBAColor(64, 64, 64) val GRAY = RGBAColor(0x2C2C2CFFL)