Highlight paths in research tree
This commit is contained in:
parent
14e57cd4d1
commit
bf1a7394e6
@ -374,12 +374,12 @@ fun drawLine(
|
|||||||
val y3 = -width
|
val y3 = -width
|
||||||
|
|
||||||
builder.vertex(matrix,
|
builder.vertex(matrix,
|
||||||
startX + y0 * sin,
|
startX - y0 * sin,
|
||||||
startY + y0 * cos,
|
startY + y0 * cos,
|
||||||
zLevel).color(drawColor).endVertex()
|
zLevel).color(drawColor).endVertex()
|
||||||
|
|
||||||
builder.vertex(matrix,
|
builder.vertex(matrix,
|
||||||
startX + y1 * sin,
|
startX - y1 * sin,
|
||||||
startY + y1 * cos,
|
startY + y1 * cos,
|
||||||
zLevel).color(drawColor).endVertex()
|
zLevel).color(drawColor).endVertex()
|
||||||
|
|
||||||
|
@ -79,6 +79,8 @@ private fun isTree(root: AndroidResearchType<*>): Boolean {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typealias LinePos = Pair<Pair<Float, Float>, Pair<Float, Float>>
|
||||||
|
|
||||||
private class Tree(val node: AndroidResearchType<*>) : Iterable<Tree> {
|
private class Tree(val node: AndroidResearchType<*>) : Iterable<Tree> {
|
||||||
val subtrees = ArrayList<Tree>()
|
val subtrees = ArrayList<Tree>()
|
||||||
|
|
||||||
@ -159,37 +161,25 @@ private class Tree(val node: AndroidResearchType<*>) : Iterable<Tree> {
|
|||||||
): Pair<AndroidResearchButton, Float> {
|
): Pair<AndroidResearchButton, Float> {
|
||||||
val totalWidth = width * 24f
|
val totalWidth = width * 24f
|
||||||
|
|
||||||
val lines = ArrayList<Pair<Pair<Float, Float>, Pair<Float, Float>>>()
|
val lines = ArrayList<LinePos>()
|
||||||
|
val linesToResearch = IdentityHashMap<AndroidResearchType<*>, ArrayList<LinePos>>()
|
||||||
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 button = AndroidResearchButton(rows[node.researchTreeDepth], capability.getResearch(node), lines, linesToResearch)
|
||||||
button.x = left + totalWidth / 2f - button.width / 2f
|
button.x = left + totalWidth / 2f - button.width / 2f
|
||||||
|
|
||||||
@Suppress("name_shadowing")
|
@Suppress("name_shadowing")
|
||||||
var left = left
|
var left = left
|
||||||
|
|
||||||
val widths = FloatArrayList()
|
var busLine: LinePos? = null
|
||||||
|
|
||||||
if (subtrees.size > 1) {
|
if (subtrees.size > 1) {
|
||||||
lines.add(
|
val x = button.width / 2f
|
||||||
((button.width / 2f) to button.y + button.height) to
|
val y = button.y + button.height
|
||||||
((button.width / 2f) to button.y + button.height + 3f)
|
|
||||||
)
|
busLine = (x to y) to
|
||||||
|
(x to y + 3f)
|
||||||
|
|
||||||
|
lines.add(busLine)
|
||||||
}
|
}
|
||||||
|
|
||||||
var minX = Float.MAX_VALUE
|
var minX = Float.MAX_VALUE
|
||||||
@ -197,25 +187,51 @@ private class Tree(val node: AndroidResearchType<*>) : Iterable<Tree> {
|
|||||||
|
|
||||||
for (subtree in this) {
|
for (subtree in this) {
|
||||||
val (btn, move) = subtree.put(rows, left, capability)
|
val (btn, move) = subtree.put(rows, left, capability)
|
||||||
widths.add(move)
|
|
||||||
left += move
|
left += move
|
||||||
|
|
||||||
|
val line: LinePos
|
||||||
|
|
||||||
if (subtrees.size == 1) {
|
if (subtrees.size == 1) {
|
||||||
lines.add(
|
val x = (button.width / 2f)
|
||||||
((button.width / 2f) to button.y + button.height) to
|
val y = button.y + button.height
|
||||||
((btn.width / 2f) to button.y + button.height + 6f)
|
|
||||||
)
|
line = (x to y) to
|
||||||
|
(x to y + 6f)
|
||||||
} else {
|
} else {
|
||||||
val x = btn.x + btn.width / 2f - button.x
|
val x = btn.x + btn.width / 2f - button.x
|
||||||
val y = button.y + button.height + 3f
|
val y = button.y + button.height + 3f
|
||||||
|
|
||||||
lines.add(
|
line = (x to y) to
|
||||||
(x to y) to
|
|
||||||
(x to y + 3f)
|
(x to y + 3f)
|
||||||
)
|
|
||||||
|
|
||||||
minX = minX.coerceAtMost(x)
|
minX = minX.coerceAtMost(x)
|
||||||
maxX = maxX.coerceAtLeast(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) :
|
private open class AndroidResearchButton(
|
||||||
EditablePanel(
|
parent: EditablePanel,
|
||||||
|
private val node: AndroidResearch,
|
||||||
|
private val lines: List<LinePos>,
|
||||||
|
private val highlightLines: Map<AndroidResearchType<*>, List<LinePos>>
|
||||||
|
) :EditablePanel(
|
||||||
parent.screen,
|
parent.screen,
|
||||||
parent,
|
parent,
|
||||||
0f,
|
0f,
|
||||||
@ -241,10 +261,25 @@ private open class AndroidResearchButton(parent: EditablePanel, private val node
|
|||||||
AndroidStationScreen.BUTTON_SIZE.toFloat(),
|
AndroidStationScreen.BUTTON_SIZE.toFloat(),
|
||||||
AndroidStationScreen.BUTTON_SIZE.toFloat()
|
AndroidStationScreen.BUTTON_SIZE.toFloat()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setDockMargin(2f, 2f, 2f, 2f)
|
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) {
|
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
|
||||||
minecraft.player?.getCapability(MatteryCapability.ANDROID)?.ifPresentK {
|
minecraft.player?.getCapability(MatteryCapability.ANDROID)?.ifPresentK {
|
||||||
if (node.isResearched) {
|
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)
|
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 {
|
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 canvas: DraggableCanvasPanel? = null
|
||||||
private var research: FramePanel? = null
|
private var research: FramePanel? = null
|
||||||
|
var hoveredResearch: AndroidResearch? = null
|
||||||
|
|
||||||
private fun openResearchTree() {
|
private fun openResearchTree() {
|
||||||
val window = minecraft!!.window
|
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]
|
val width = rowWidths[research.researchTreeDepth]
|
||||||
button.setPos(totalWidth + width, 0f)
|
button.setPos(totalWidth + width, 0f)
|
||||||
rowWidths[research.researchTreeDepth] += 22f
|
rowWidths[research.researchTreeDepth] += 22f
|
||||||
|
@ -23,7 +23,7 @@ enum class Dock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open class EditablePanel @JvmOverloads constructor(
|
open class EditablePanel @JvmOverloads constructor(
|
||||||
@JvmField val screen: MatteryScreen<*>,
|
val screen: MatteryScreen<*>,
|
||||||
parent: EditablePanel?,
|
parent: EditablePanel?,
|
||||||
|
|
||||||
// относительно родителя
|
// относительно родителя
|
||||||
@ -176,12 +176,27 @@ open class EditablePanel @JvmOverloads constructor(
|
|||||||
private set
|
private set
|
||||||
|
|
||||||
var isHovered = false
|
var isHovered = false
|
||||||
private set
|
private set(value) {
|
||||||
|
if (value == field) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
field = value
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
onHovered()
|
||||||
|
} else {
|
||||||
|
onUnHovered()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun unsetHovered() {
|
fun unsetHovered() {
|
||||||
isHovered = false
|
isHovered = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun onHovered() {}
|
||||||
|
open fun onUnHovered() {}
|
||||||
|
|
||||||
var isFocused = false
|
var isFocused = false
|
||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (field != value) {
|
||||||
|
@ -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) {
|
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) : 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: 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(
|
constructor(color: Long) : this(
|
||||||
(((color and -0x1000000) ushr 24) / 255f),
|
(((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 {
|
companion object {
|
||||||
val BLACK = RGBAColor(0f, 0f, 0f, 1f)
|
val BLACK = RGBAColor(0f, 0f, 0f, 1f)
|
||||||
val WHITE = RGBAColor(1f, 1f, 1f, 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 SLATE_GRAY = RGBAColor(64, 64, 64)
|
||||||
val GRAY = RGBAColor(0x2C2C2CFFL)
|
val GRAY = RGBAColor(0x2C2C2CFFL)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user