aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/test')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt33
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt (renamed from src/main/java/at/hannibal2/skyhanni/test/GraphEditor.kt)39
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditorBugFinder.kt95
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/graph/GraphNodeEditor.kt (renamed from src/main/java/at/hannibal2/skyhanni/test/GraphNodeEditor.kt)68
4 files changed, 194 insertions, 41 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt
index 5b7333189..045ce5bce 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt
@@ -131,36 +131,13 @@ object SkyHanniDebugsAndTests {
}
fun testCommand(args: Array<String>) {
+ SkyHanniMod.coroutineScope.launch {
+ asyncTest()
+ }
+ }
+ private fun asyncTest() {
-// val a = Thread { OSUtils.copyToClipboard("123") }
-// val b = Thread { OSUtils.copyToClipboard("456") }
-// a.start()
-// b.start()
-
-// for ((i, s) in ScoreboardData.siedebarLinesFormatted().withIndex()) {
-// println("$i: '$s'")
-// }
-
-// val name = args[0]
-// val pitch = args[1].toFloat()
-// val sound = SoundUtils.createSound("note.harp", 1.35f)
-// val sound = SoundUtils.createSound("random.orb", 11.2f)
-// SoundUtils.createSound(name, pitch).playSound()
-
-// a = args[0].toDouble()
-// b = args[1].toDouble()
-// c = args[2].toDouble()
-
-// for (line in getPlayerTabOverlay().footer.unformattedText
-// .split("\n")) {
-// println("footer: '$line'")
-// }
-//
-//
-// for (line in TabListUtils.getTabList()) {
-// println("tablist: '$line'")
-// }
}
fun findNullConfig(args: Array<String>) {
diff --git a/src/main/java/at/hannibal2/skyhanni/test/GraphEditor.kt b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt
index d4038162f..1aefeda52 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/GraphEditor.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.test
+package at.hannibal2.skyhanni.test.graph
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.IslandGraphs
@@ -26,6 +26,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.OSUtils
+import at.hannibal2.skyhanni.utils.RaycastUtils
import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine_nea
import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
import at.hannibal2.skyhanni.utils.RenderUtils.drawWaypointFilled
@@ -127,6 +128,7 @@ object GraphEditor {
if (!inEditMode && !inTextMode) {
add("§ePlace: §6${KeyboardManager.getKeyName(config.placeKey)}")
add("§eSelect: §6${KeyboardManager.getKeyName(config.selectKey)}")
+ add("§eSelect (Look): §6${KeyboardManager.getKeyName(config.selectRaycastKey)}")
add("§eConnect: §6${KeyboardManager.getKeyName(config.connectKey)}")
add("§eTest: §6${KeyboardManager.getKeyName(config.dijkstraKey)}")
add("§eVision: §6${KeyboardManager.getKeyName(config.throughBlocksKey)}")
@@ -259,7 +261,9 @@ object GraphEditor {
}
}
- private fun chatAtDisable() = ChatUtils.clickableChat("Graph Editor is now inactive. §lClick to activate.", ::commandIn)
+ private fun chatAtDisable() = ChatUtils.clickableChat("Graph Editor is now inactive. §lClick to activate.",
+ GraphEditor::commandIn
+ )
private fun input() {
if (LorenzUtils.isAnyGuiActive()) return
@@ -346,13 +350,35 @@ object GraphEditor {
closedNode
}
}
+ if (config.selectRaycastKey.isKeyClicked()) {
+ val playerRay = RaycastUtils.createPlayerLookDirectionRay()
+ var minimumDistance = Double.MAX_VALUE
+ var minimumNode: GraphingNode? = null
+ for (node in nodes) {
+ val nodeCenterPosition = node.position.add(0.5, 0.5, 0.5)
+ val distance = RaycastUtils.findDistanceToRay(playerRay, nodeCenterPosition)
+ if (distance > minimumDistance) {
+ continue
+ }
+ if (minimumDistance > 1.0) {
+ minimumNode = node
+ minimumDistance = distance
+ continue
+ }
+ if (minimumNode == null || minimumNode.position.distanceSqToPlayer() > node.position.distanceSqToPlayer()) {
+ minimumNode = node
+ minimumDistance = distance
+ }
+ }
+ activeNode = minimumNode
+ }
if (activeNode != closedNode && config.connectKey.isKeyClicked()) {
val edge = getEdgeIndex(activeNode, closedNode)
if (edge == null) {
addEdge(activeNode, closedNode)
feedBackInTutorial("Added new edge.")
} else {
- this.edges.removeAt(edge)
+ edges.removeAt(edge)
checkDissolve()
selectedEdge = findEdgeBetweenActiveAndClosed()
feedBackInTutorial("Removed edge.")
@@ -405,6 +431,7 @@ object GraphEditor {
val compileGraph = compileGraph()
if (config.useAsIslandArea) {
IslandGraphs.setNewGraph(compileGraph)
+ GraphEditorBugFinder.runTests()
}
val json = compileGraph.toJson()
OSUtils.copyToClipboard(json)
@@ -457,7 +484,7 @@ object GraphEditor {
nodes.remove(closedNode)
edges.removeIf { it.isInEdge(closedNode) }
if (closedNode == activeNode) activeNode = null
- this.closedNode = null
+ GraphEditor.closedNode = null
return
}
}
@@ -505,7 +532,7 @@ object GraphEditor {
prune()
val indexedTable = nodes.mapIndexed { index, node -> node.id to index }.toMap()
val nodes = nodes.mapIndexed { index, it -> GraphNode(index, it.position, it.name, it.tags.mapNotNull { it.internalName }) }
- val neighbours = this.nodes.map { node ->
+ val neighbours = GraphEditor.nodes.map { node ->
edges.filter { it.isInEdge(node) }.map { edge ->
val otherNode = if (node == edge.node1) edge.node2 else edge.node1
nodes[indexedTable[otherNode.id]!!] to node.position.distance(otherNode.position)
@@ -523,7 +550,7 @@ object GraphEditor {
it.id,
it.position,
it.name,
- it.tagNames?.mapNotNull { GraphNodeTag.byId(it) }?.toMutableList() ?: mutableListOf(),
+ it.tagNames.mapNotNull { tag -> GraphNodeTag.byId(tag) }.toMutableList(),
)
},
)
diff --git a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditorBugFinder.kt b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditorBugFinder.kt
new file mode 100644
index 000000000..aee75ec5f
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditorBugFinder.kt
@@ -0,0 +1,95 @@
+package at.hannibal2.skyhanni.test.graph
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.IslandGraphs
+import at.hannibal2.skyhanni.data.model.GraphNode
+import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
+import at.hannibal2.skyhanni.features.misc.IslandAreas.getAreaTag
+import at.hannibal2.skyhanni.test.graph.GraphEditor.distanceSqToPlayer
+import at.hannibal2.skyhanni.utils.GraphUtils
+import at.hannibal2.skyhanni.utils.LorenzVec
+import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
+import kotlinx.coroutines.launch
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import java.awt.Color
+
+// Trying to find errors in Area Graph for the current graph editor instance
+object GraphEditorBugFinder {
+ private var errorsInWorld = emptyMap<LorenzVec, String>()
+
+ fun runTests() {
+ SkyHanniMod.coroutineScope.launch {
+ asyncTest()
+ }
+ }
+
+ private fun asyncTest() {
+ val graph = IslandGraphs.currentIslandGraph ?: return
+ val errorsInWorld: MutableMap<LorenzVec, String> = mutableMapOf()
+ val nodes = graph.nodes
+
+ val nearestArea = mutableMapOf<GraphNode, GraphNode>()
+ for (node in nodes) {
+ val pathToNearestArea = GraphUtils.findFastestPath(graph, node) { it.getAreaTag(ignoreConfig = true) != null }?.first
+ if (pathToNearestArea == null) {
+ continue
+ }
+ val areaNode = pathToNearestArea.lastOrNull() ?: error("Empty path to nearest area")
+ nearestArea[node] = areaNode
+ }
+ var bugs = 0
+ for (node in nodes) {
+ val areaNode = nearestArea[node]?.name ?: continue
+ for (neighbour in node.neighbours.keys) {
+ val neighbouringAreaNode = nearestArea[neighbour]?.name ?: continue
+ if (neighbouringAreaNode == areaNode) continue
+ if ((null == node.getAreaTag(ignoreConfig = true))) {
+ bugs++
+ errorsInWorld[node.position] = "§cConflicting areas $areaNode and $neighbouringAreaNode"
+ }
+ }
+ }
+ for (node in nodes) {
+ val nameNull = node.name.isNullOrBlank()
+ val tagsEmpty = node.tags.isEmpty()
+ if (nameNull > tagsEmpty) {
+ errorsInWorld[node.position] = "§cMissing name despite having tags"
+ bugs++
+ }
+ if (tagsEmpty > nameNull) {
+ errorsInWorld[node.position] = "§cMissing tags despite having name"
+ bugs++
+ }
+ }
+
+ val clusters = GraphUtils.findDisjointClusters(graph)
+ if (clusters.size > 1) {
+ val closestCluster = clusters.minBy { it.minOf { it.position.distanceSqToPlayer() } }
+ val foreignClusters = clusters.filter { it !== closestCluster }
+ val closestForeignNodes = foreignClusters.map { network -> network.minBy { it.position.distanceSqToPlayer() } }
+ closestForeignNodes.forEach {
+ errorsInWorld[it.position] = "§cDisjoint node network"
+ bugs++
+ }
+ val closestForeignNode = closestForeignNodes.minBy { it.position.distanceSqToPlayer() }
+ val closestNodeToForeignNode = closestCluster.minBy { it.position.distanceSq(closestForeignNode.position) }
+ IslandGraphs.pathFind(closestNodeToForeignNode.position, Color.RED)
+ }
+
+ println("found $bugs bugs!")
+ this.errorsInWorld = errorsInWorld
+ if (clusters.size <= 1) {
+ IslandGraphs.pathFind(errorsInWorld.keys.minByOrNull { it.distanceSqToPlayer() } ?: return, Color.RED)
+ }
+ }
+
+ @SubscribeEvent
+ fun onRenderWorld(event: LorenzRenderWorldEvent) {
+ if (!isEnabled()) return
+
+ for ((location, text) in errorsInWorld) {
+ event.drawDynamicText(location, text, 1.5)
+ }
+ }
+ fun isEnabled() = GraphEditor.isEnabled()
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/GraphNodeEditor.kt b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphNodeEditor.kt
index f541b16e3..e6c4536d8 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/GraphNodeEditor.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphNodeEditor.kt
@@ -1,10 +1,10 @@
-package at.hannibal2.skyhanni.test
+package at.hannibal2.skyhanni.test.graph
import at.hannibal2.skyhanni.data.model.GraphNodeTag
import at.hannibal2.skyhanni.data.model.TextInput
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
-import at.hannibal2.skyhanni.test.GraphEditor.distanceSqToPlayer
+import at.hannibal2.skyhanni.test.graph.GraphEditor.distanceSqToPlayer
import at.hannibal2.skyhanni.utils.CollectionUtils.addString
import at.hannibal2.skyhanni.utils.KeyboardManager
import at.hannibal2.skyhanni.utils.LorenzUtils
@@ -29,12 +29,12 @@ object GraphNodeEditor {
private val textInput = TextInput()
private var nodesDisplay = emptyList<Renderable>()
private var lastUpdate = SimpleTimeMark.farPast()
+ private val tagsToShow: MutableList<GraphNodeTag> = GraphNodeTag.entries.toMutableList()
@SubscribeEvent
fun onGuiRender(event: GuiRenderEvent) {
if (!isEnabled()) return
-
config.namedNodesList.renderRenderables(
getNodeNames(),
posLabel = "Graph Nodes List",
@@ -52,15 +52,66 @@ object GraphNodeEditor {
lastUpdate = SimpleTimeMark.now()
nodesDisplay = buildList {
val list = drawNodeNames()
- val size = list.size
- addString("§eGraph Nodes: $size")
- val height = (size * 10).coerceAtMost(250)
+ val total = GraphEditor.nodes.count { it.name?.isNotBlank() ?: false }
+ val shown = list.size
+ add(
+ Renderable.clickAndHover(
+ "§eGraph Nodes: $shown/$total",
+ listOf("§eClick to toggle node tags!"),
+ onClick = {
+ updateToggleTags()
+ },
+ ),
+ )
+ val height = (shown * 10).coerceAtMost(250)
if (list.isNotEmpty()) {
add(list.buildSearchableScrollable(height, textInput, scrollValueNodes, velocity = 10.0))
}
}
}
+ private fun updateToggleTags() {
+ lastUpdate = SimpleTimeMark.now() + 60.seconds
+ nodesDisplay = buildList {
+ addString("§eToggle Visible Tags")
+ for (tag in GraphNodeTag.entries) {
+ val isVisible = tag in tagsToShow
+ val nodes = GraphEditor.nodes.count { tag in it.tags }
+ val visibilityText = if (isVisible) " §aVisible" else " §7Invisible"
+ val name = " - ${tag.displayName} §8($nodes nodes) $visibilityText"
+ add(
+ Renderable.clickAndHover(
+ name,
+ listOf("§eClick to " + (if (isVisible) "hide" else "show") + " nodes with this tag!"),
+ onClick = {
+ toggleTag(tag)
+ updateToggleTags()
+ },
+ ),
+ )
+ }
+ addString("")
+ add(
+ Renderable.clickAndHover(
+ "§cGo Back!",
+ tips = listOf("§eClick to go back to the node list!"),
+ onClick = {
+ updateNodeNames()
+ },
+ ),
+ )
+ }
+
+ }
+
+ private fun toggleTag(tag: GraphNodeTag) {
+ if (tag in tagsToShow) {
+ tagsToShow.remove(tag)
+ } else {
+ tagsToShow.add(tag)
+ }
+ }
+
private fun updateTagView(node: GraphingNode) {
lastUpdate = SimpleTimeMark.now() + 60.seconds
nodesDisplay = buildList {
@@ -123,7 +174,10 @@ object GraphNodeEditor {
private fun drawNodeNames(): List<Searchable> = buildList {
for ((node, distance: Double) in GraphEditor.nodes.map { it to it.position.distanceSqToPlayer() }.sortedBy { it.second }) {
- val name = node.name?.takeIf { !it.isBlank() } ?: continue
+ if (node.tags.isNotEmpty()) {
+ if (!node.tags.any { it in tagsToShow }) continue
+ }
+ val name = node.name?.takeIf { it.isNotBlank() } ?: continue
val color = if (node == GraphEditor.activeNode) "§a" else "§7"
val distanceFormat = sqrt(distance).toInt().addSeparators()
val tagText = node.tags.let { tags ->