Highlight paths in research tree

This commit is contained in:
DBotThePony 2022-08-23 21:05:39 +07:00
parent 14e57cd4d1
commit bf1a7394e6
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 124 additions and 46 deletions

View File

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

View File

@ -79,6 +79,8 @@ private fun isTree(root: AndroidResearchType<*>): Boolean {
return true
}
typealias LinePos = Pair<Pair<Float, Float>, Pair<Float, Float>>
private class Tree(val node: AndroidResearchType<*>) : Iterable<Tree> {
val subtrees = ArrayList<Tree>()
@ -159,37 +161,25 @@ private class Tree(val node: AndroidResearchType<*>) : Iterable<Tree> {
): Pair<AndroidResearchButton, Float> {
val totalWidth = width * 24f
val lines = ArrayList<Pair<Pair<Float, Float>, Pair<Float, Float>>>()
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<LinePos>()
val linesToResearch = IdentityHashMap<AndroidResearchType<*>, ArrayList<LinePos>>()
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<Tree> {
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
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,8 +248,12 @@ private class Tree(val node: AndroidResearchType<*>) : Iterable<Tree> {
}
}
private open class AndroidResearchButton(parent: EditablePanel, private val node: AndroidResearch) :
EditablePanel(
private open class AndroidResearchButton(
parent: EditablePanel,
private val node: AndroidResearch,
private val lines: List<LinePos>,
private val highlightLines: Map<AndroidResearchType<*>, List<LinePos>>
) :EditablePanel(
parent.screen,
parent,
0f,
@ -241,10 +261,25 @@ private open class AndroidResearchButton(parent: EditablePanel, private val node
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

View File

@ -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) {

View File

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