From 478e5c6ac5f587dbf5f6f45f6489cbe37b05fd2f Mon Sep 17 00:00:00 2001
From: hannibal2 <24389977+hannibal002@users.noreply.github.com>
Date: Mon, 23 Sep 2024 15:10:19 +0200
Subject: Improvement: Glacite Tunnels Area Navigation (#2544)

Co-authored-by: nea <nea@nea.moe>
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
---
 .../hannibal2/skyhanni/api/event/SkyHanniEvent.kt  |  3 +
 .../at/hannibal2/skyhanni/data/IslandGraphs.kt     | 77 ++++++++++++++++++++--
 .../at/hannibal2/skyhanni/events/LorenzEvent.kt    |  5 ++
 .../skyhanni/features/mining/TunnelsMaps.kt        | 10 ++-
 .../skyhanni/features/misc/IslandAreas.kt          |  4 +-
 5 files changed, 89 insertions(+), 10 deletions(-)

diff --git a/src/main/java/at/hannibal2/skyhanni/api/event/SkyHanniEvent.kt b/src/main/java/at/hannibal2/skyhanni/api/event/SkyHanniEvent.kt
index 4f3685c8b..c05b438cd 100644
--- a/src/main/java/at/hannibal2/skyhanni/api/event/SkyHanniEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/api/event/SkyHanniEvent.kt
@@ -1,5 +1,8 @@
 package at.hannibal2.skyhanni.api.event
 
+/**
+ * Use @[HandleEvent]
+ */
 abstract class SkyHanniEvent protected constructor() {
 
     var isCancelled: Boolean = false
diff --git a/src/main/java/at/hannibal2/skyhanni/data/IslandGraphs.kt b/src/main/java/at/hannibal2/skyhanni/data/IslandGraphs.kt
index ca3143b95..9e4639454 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/IslandGraphs.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/IslandGraphs.kt
@@ -1,6 +1,7 @@
 package at.hannibal2.skyhanni.data
 
 import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.api.event.HandleEvent
 import at.hannibal2.skyhanni.data.model.Graph
 import at.hannibal2.skyhanni.data.model.GraphNode
 import at.hannibal2.skyhanni.data.model.findShortestPathAsGraphWithDistance
@@ -10,23 +11,29 @@ import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
 import at.hannibal2.skyhanni.events.LorenzTickEvent
 import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
 import at.hannibal2.skyhanni.events.RepositoryReloadEvent
+import at.hannibal2.skyhanni.events.skyblock.ScoreboardAreaChangeEvent
 import at.hannibal2.skyhanni.features.misc.IslandAreas
 import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
 import at.hannibal2.skyhanni.test.SkyHanniDebugsAndTests
+import at.hannibal2.skyhanni.utils.DelayedRun
 import at.hannibal2.skyhanni.utils.LocationUtils
 import at.hannibal2.skyhanni.utils.LocationUtils.canBeSeen
 import at.hannibal2.skyhanni.utils.LocationUtils.distanceSqToPlayer
 import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer
 import at.hannibal2.skyhanni.utils.LorenzColor
 import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
 import at.hannibal2.skyhanni.utils.LorenzVec
+import at.hannibal2.skyhanni.utils.RegexUtils.matches
 import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine
 import at.hannibal2.skyhanni.utils.RenderUtils.draw3DPathWithWaypoint
 import at.hannibal2.skyhanni.utils.RenderUtils.drawWaypointFilled
+import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
 import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
 import java.awt.Color
 import java.io.File
 import kotlin.math.abs
+import kotlin.time.Duration.Companion.milliseconds
 
 /**
  * TODO
@@ -101,26 +108,73 @@ object IslandGraphs {
 
     private var fastestPath: Graph? = null
     private var condition: () -> Boolean = { true }
+    private var inGlaciteTunnels: Boolean? = null
+
+    private val patternGroup = RepoPattern.group("data.island.navigation")
+
+    /**
+     * REGEX-TEST: Dwarven Base Camp
+     * REGEX-TEST: Forge
+     * REGEX-TEST: Fossil Research Center
+     */
+    private val glaciteTunnelsPattern by patternGroup.pattern(
+        "glacitetunnels",
+        "(Glacite Tunnels|Dwarven Base Camp|Great Glacite Lake|Fossil Research Center)",
+    )
 
     @SubscribeEvent
     fun onRepoReload(event: RepositoryReloadEvent) {
         if (!LorenzUtils.inSkyBlock) return
 
-        reloadFromJson(LorenzUtils.skyBlockIsland)
+        loadIsland(LorenzUtils.skyBlockIsland)
     }
 
     @SubscribeEvent
     fun onIslandChange(event: IslandChangeEvent) {
-        reloadFromJson(event.newIsland)
+        if (currentIslandGraph != null) return
+        if (event.newIsland == IslandType.NONE) return
+        loadIsland(event.newIsland)
     }
 
     @SubscribeEvent
     fun onWorldChange(event: LorenzWorldChangeEvent) {
+        currentIslandGraph = null
         reset()
     }
 
-    private fun reloadFromJson(newIsland: IslandType) {
-        val islandName = newIsland.name
+    fun isGlaciteTunnelsArea(area: String?): Boolean = glaciteTunnelsPattern.matches(area)
+
+    @HandleEvent
+    fun onAreaChange(event: ScoreboardAreaChangeEvent) {
+        if (!IslandType.DWARVEN_MINES.isInIsland()) {
+            inGlaciteTunnels = null
+            return
+        }
+
+        val now = isGlaciteTunnelsArea(LorenzUtils.skyBlockArea)
+        if (inGlaciteTunnels != now) {
+            inGlaciteTunnels = now
+            loadDwarvenMines()
+        }
+    }
+
+    private fun loadDwarvenMines() {
+        if (isGlaciteTunnelsArea(LorenzUtils.skyBlockArea)) {
+            reloadFromJson("GLACITE_TUNNELS")
+        } else {
+            reloadFromJson("DWARVEN_MINES")
+        }
+    }
+
+    private fun loadIsland(newIsland: IslandType) {
+        if (newIsland == IslandType.DWARVEN_MINES) {
+            loadDwarvenMines()
+        } else {
+            reloadFromJson(newIsland.name)
+        }
+    }
+
+    private fun reloadFromJson(islandName: String) {
         val constant = "island_graphs/$islandName"
         val name = "constants/$constant.json"
         val jsonFile = File(SkyHanniMod.repo.repoLocation, name)
@@ -136,6 +190,13 @@ object IslandGraphs {
     fun setNewGraph(graph: Graph) {
         reset()
         currentIslandGraph = graph
+
+        // calling various update functions to make swtiching between deep caverns and glacite tunnels bareable
+        handleTick()
+        IslandAreas.noteMoved()
+        DelayedRun.runDelayed(150.milliseconds) {
+            IslandAreas.updatePosition()
+        }
     }
 
     private fun reset() {
@@ -143,11 +204,16 @@ object IslandGraphs {
         currentTarget = null
         goal = null
         fastestPath = null
+        IslandAreas.display = null
     }
 
     @SubscribeEvent
     fun onTick(event: LorenzTickEvent) {
         if (!LorenzUtils.inSkyBlock) return
+        handleTick()
+    }
+
+    private fun handleTick() {
         val prevClosed = closedNote
 
         val graph = currentIslandGraph ?: return
@@ -294,8 +360,7 @@ object IslandGraphs {
 
         val nodes = graph.nodes
         val potentialSkip =
-            nodes.lastOrNull { it.position.canBeSeen(maxSkipDistance, -1.0) && abs(it.position.y - playerY) <= 2 }
-                ?: return null
+            nodes.lastOrNull { it.position.canBeSeen(maxSkipDistance, -1.0) && abs(it.position.y - playerY) <= 2 } ?: return null
 
         val angleSkip = if (potentialSkip == nodes.first()) {
             false
diff --git a/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt
index c895b1058..4a294a677 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt
@@ -12,6 +12,11 @@ import at.hannibal2.skyhanni.utils.system.PlatformUtils
 import net.minecraftforge.common.MinecraftForge
 import net.minecraftforge.fml.common.eventhandler.Event
 import net.minecraftforge.fml.common.eventhandler.IEventListener
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+/**
+ * Use @[SubscribeEvent]
+ */
 
 @Deprecated("Use SkyHanniEvent instead")
 abstract class LorenzEvent : Event() {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/TunnelsMaps.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/TunnelsMaps.kt
index 847a3673f..5214ff162 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/mining/TunnelsMaps.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/mining/TunnelsMaps.kt
@@ -81,6 +81,7 @@ object TunnelsMaps {
     private var active: String = ""
 
     private lateinit var fairySouls: Map<String, GraphNode>
+    // TODO what is this? why is there a difference? can this be replaced with GraphNodeTag.GRIND_ORES?
     private lateinit var newGemstones: Map<String, List<GraphNode>>
     private lateinit var oldGemstones: Map<String, List<GraphNode>>
     private lateinit var normalLocations: Map<String, List<GraphNode>>
@@ -221,7 +222,7 @@ object TunnelsMaps {
 
     @SubscribeEvent
     fun onRepoReload(event: RepositoryReloadEvent) {
-        graph = event.getConstant<Graph>("TunnelsGraph", gson = Graph.gson)
+        graph = event.getConstant<Graph>("island_graphs/GLACITE_TUNNELS", gson = Graph.gson)
         possibleLocations = graph.groupBy { it.name }.filterNotNullKeys().mapValues { (_, value) ->
             value
         }
@@ -235,7 +236,12 @@ object TunnelsMaps {
                 key.contains("Fairy") -> fairy[key] = value.first()
                 newGemstonePattern.matches(key) -> newGemstone[key] = value
                 oldGemstonePattern.matches(key) -> oldGemstone[key] = value
-                else -> other[key] = value
+                else -> {
+                    // ignore node names without color codes
+                    if (key.removeColor() != key) {
+                        other[key] = value
+                    }
+                }
             }
         }
         fairySouls = fairy
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/IslandAreas.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/IslandAreas.kt
index 311af056e..d5e57d513 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/IslandAreas.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/IslandAreas.kt
@@ -41,7 +41,7 @@ object IslandAreas {
 
     private var nodes = mapOf<GraphNode, Double>()
     private var paths = mapOf<GraphNode, Graph>()
-    private var display: Renderable? = null
+    var display: Renderable? = null
     private var targetNode: GraphNode? = null
     private var currentAreaName = ""
     private val textInput = TextInput()
@@ -103,7 +103,7 @@ object IslandAreas {
         }
     }
 
-    private fun updatePosition() {
+    fun updatePosition() {
         display = buildDisplay().buildSearchBox(textInput)
     }
 
-- 
cgit