Skip to content

Commit

Permalink
Feature: /shnavigate (#2575)
Browse files Browse the repository at this point in the history
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
  • Loading branch information
hannibal002 and hannibal002 authored Sep 24, 2024
1 parent 1e9764d commit cc8a3db
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import at.hannibal2.skyhanni.features.misc.TpsCounter
import at.hannibal2.skyhanni.features.misc.discordrpc.DiscordRPCManager
import at.hannibal2.skyhanni.features.misc.limbo.LimboTimeTracker
import at.hannibal2.skyhanni.features.misc.massconfiguration.DefaultConfigFeatures
import at.hannibal2.skyhanni.features.misc.pathfind.NavigationHelper
import at.hannibal2.skyhanni.features.misc.reminders.ReminderManager
import at.hannibal2.skyhanni.features.misc.update.UpdateManager
import at.hannibal2.skyhanni.features.misc.visualwords.VisualWordGui
Expand Down Expand Up @@ -182,6 +183,7 @@ object Commands {
)
registerCommand("shremind", "Set a reminder for yourself") { ReminderManager.command(it) }
registerCommand("shwords", "Opens the config list for modifying visual words") { openVisualWords() }
registerCommand("shnavigate", "Using path finder to go to locatons") { NavigationHelper.onCommand(it) }
}

private fun usersNormal() {
Expand Down
28 changes: 23 additions & 5 deletions src/main/java/at/hannibal2/skyhanni/data/model/GraphNodeTag.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import at.hannibal2.skyhanni.utils.LorenzColor
enum class GraphNodeTag(
val internalName: String,
val color: LorenzColor,
cleanName: String,
val cleanName: String,
val description: String,
val onlyIsland: IslandType? = null,
) {
Expand All @@ -17,7 +17,7 @@ enum class GraphNodeTag(
AREA("area", LorenzColor.DARK_GREEN, "Area", "A big SkyBlock area."),
SMALL_AREA("small_area", LorenzColor.GREEN, "Small Area", "A small SkyBlock area, e.g. a house."),
POI("poi", LorenzColor.WHITE, "Point of Interest", "A relevant spot or a landmark on the map."),
// LAUNCH_PAD("launch", LorenzColor.WHITE, "Launch Pad", "Slime blocks sending you to another server."),
// LAUNCH_PAD("launch", LorenzColor.WHITE, "Launch Pad", "Slime blocks sending you to another server."),
TELEPORT("teleport", LorenzColor.BLUE, "Teleport", "A spot from/to teleport."),

// on multiple islands
Expand All @@ -43,18 +43,36 @@ enum class GraphNodeTag(
// Rift
RIFT_ENIGMA("rift_enigma", LorenzColor.DARK_PURPLE, "Enigma Soul", "Enigma Souls in the Rift.", onlyIsland = IslandType.THE_RIFT),
RIFT_EYE("rift_eye", LorenzColor.DARK_RED, "Rift Eye", "An Eye in the Rift to teleport to.", onlyIsland = IslandType.THE_RIFT),
RIFT_MONTEZUMA("rift_montezuma", LorenzColor.GRAY, "Montezuma Soul Piece", "A piece of the Montezuma Soul.", onlyIsland = IslandType.THE_RIFT),
RIFT_MONTEZUMA(
"rift_montezuma",
LorenzColor.GRAY,
"Montezuma Soul Piece",
"A piece of the Montezuma Soul.",
onlyIsland = IslandType.THE_RIFT,
),
RIFT_EFFIGY("rift_effigy", LorenzColor.RED, "Blood Effigies", "Locations of the Blood Effigies.", onlyIsland = IslandType.THE_RIFT),

// Spider's Den
SPIDER_RELIC("SPIDER_RELIC", LorenzColor.DARK_PURPLE, "Spider's Relic", "An relic in the Spider's Den.", onlyIsland = IslandType.SPIDER_DEN),
SPIDER_RELIC(
"SPIDER_RELIC",
LorenzColor.DARK_PURPLE,
"Spider's Relic",
"An relic in the Spider's Den.",
onlyIsland = IslandType.SPIDER_DEN,
),

// Dwarven Mines
MINES_EMISSARY("mines_emissary", LorenzColor.GOLD, "Mines Emissary", "An Emissary to the king.", onlyIsland = IslandType.DWARVEN_MINES),
// commission areas

// Crimson Isles
CRIMSON_MINIBOSS("crimson_miniboss", LorenzColor.RED, "Crimson Miniboss", "A Miniboss in the Crimson Isle.", onlyIsland = IslandType.CRIMSON_ISLE),
CRIMSON_MINIBOSS(
"crimson_miniboss",
LorenzColor.RED,
"Crimson Miniboss",
"A Miniboss in the Crimson Isle.",
onlyIsland = IslandType.CRIMSON_ISLE,
),

// The End
END_GOLEM("end_golem", LorenzColor.RED, "Golem Spawn", "A spot where the golem can spawn in the End.", onlyIsland = IslandType.THE_END),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@ import at.hannibal2.skyhanni.utils.StringUtils.splitLines
import at.hannibal2.skyhanni.utils.chat.Text
import at.hannibal2.skyhanni.utils.chat.Text.asComponent
import at.hannibal2.skyhanni.utils.chat.Text.center
import at.hannibal2.skyhanni.utils.chat.Text.fitToChat
import at.hannibal2.skyhanni.utils.chat.Text.hover
import at.hannibal2.skyhanni.utils.chat.Text.onClick
import at.hannibal2.skyhanni.utils.chat.Text.send
import at.hannibal2.skyhanni.utils.chat.Text.style
import at.hannibal2.skyhanni.utils.chat.Text.suggest
import net.minecraft.util.EnumChatFormatting
import net.minecraft.util.IChatComponent
import kotlin.math.ceil

Expand All @@ -20,11 +17,6 @@ object HelpCommand {
private const val COMMANDS_PER_PAGE = 15
private const val HELP_ID = -6457563

private fun createDivider() = Text.HYPHEN.fitToChat().style {
strikethrough = true
color = EnumChatFormatting.BLUE
}

private fun createCommandEntry(command: Commands.CommandInfo): IChatComponent {
val category = command.category
val color = category.color
Expand Down Expand Up @@ -60,7 +52,7 @@ object HelpCommand {

val text = mutableListOf<IChatComponent>()

text.add(createDivider())
text.add(Text.createDivider())
text.add(title.asComponent().center())
text.add(
Text.join(
Expand All @@ -77,7 +69,7 @@ object HelpCommand {
} else null,
).center(),
)
text.add(createDivider())
text.add(Text.createDivider())

if (filtered.isEmpty()) {
text.add(Text.EMPTY)
Expand All @@ -91,7 +83,7 @@ object HelpCommand {
}
}

text.add(createDivider())
text.add(Text.createDivider())

Text.multiline(text).send(HELP_ID)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package at.hannibal2.skyhanni.features.misc.pathfind

import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.IslandGraphs
import at.hannibal2.skyhanni.data.model.GraphNode
import at.hannibal2.skyhanni.data.model.GraphNodeTag
import at.hannibal2.skyhanni.data.model.findShortestDistance
import at.hannibal2.skyhanni.utils.CollectionUtils.sorted
import at.hannibal2.skyhanni.utils.LorenzUtils.round
import at.hannibal2.skyhanni.utils.chat.Text
import at.hannibal2.skyhanni.utils.chat.Text.asComponent
import at.hannibal2.skyhanni.utils.chat.Text.center
import at.hannibal2.skyhanni.utils.chat.Text.hover
import at.hannibal2.skyhanni.utils.chat.Text.onClick
import at.hannibal2.skyhanni.utils.chat.Text.send
import kotlinx.coroutines.launch
import net.minecraft.util.IChatComponent

object NavigationHelper {
private val NAVIGATION_CHAT_ID = -6457562

val allowedTags = listOf(
GraphNodeTag.NPC,
GraphNodeTag.AREA,
GraphNodeTag.SMALL_AREA,
GraphNodeTag.POI,
GraphNodeTag.SLAYER,
GraphNodeTag.GRIND_MOBS,
GraphNodeTag.GRIND_ORES,
GraphNodeTag.GRIND_CROPS,
GraphNodeTag.MINES_EMISSARY,
GraphNodeTag.CRIMSON_MINIBOSS,
)

fun onCommand(args: Array<String>) {
SkyHanniMod.coroutineScope.launch {
doCommandAsync(args)
}
}

private fun doCommandAsync(args: Array<String>) {
val searchTerm = args.joinToString(" ").lowercase()
val distances = calculateDistances(searchTerm)
val names = calculateNames(distances)

val text = mutableListOf<IChatComponent>()
text.add(Text.createDivider())
text.add("§7Found ${names.size} locations ($searchTerm)".asComponent().center())
val goBack = {
onCommand(searchTerm.split(" ").toTypedArray())
IslandGraphs.stop()
}
// TODO dont show a too long list, add pages
for ((name, node) in names) {
val distance = distances[node]!!.round(1)
val component = "$name §e$distance".asComponent()
component.onClick {
IslandGraphs.pathFind(node.position)
sendNavigateMessage(name, goBack)
}
val tag = node.tags.first { it in allowedTags }
// TODO include most closest area, if this is no area (type in area = forger in forge)
component.hover =
("§eClick to start navigating to\n" + "§7Type: §r${tag.displayName}\n" + "§7Distance: §e$distance blocks").asComponent()
text.add(component)
}
text.add(Text.createDivider())
Text.multiline(text).send(NAVIGATION_CHAT_ID)
}

private fun sendNavigateMessage(name: String, goBack: () -> Unit) {
val componentText = "§7Navigating to §r$name".asComponent()
componentText.onClick(onClick = goBack)
componentText.send(NAVIGATION_CHAT_ID)
}

private fun calculateNames(distances: Map<GraphNode, Double>): MutableMap<String, GraphNode> {
val names = mutableMapOf<String, GraphNode>()
for (node in distances.sorted().keys) {
val tag = node.tags.first { it in allowedTags }
val name = "${node.name} §7(${tag.displayName}§7)"
if (name in names) continue
names[name] = node
}
return names
}

private fun calculateDistances(
searchTerm: String,
): Map<GraphNode, Double> {
val grapth = IslandGraphs.currentIslandGraph ?: return emptyMap()
val closedNote = IslandGraphs.closedNote ?: return emptyMap()

val nodes = grapth.nodes
val distances = mutableMapOf<GraphNode, Double>()
for (node in nodes) {
val name = node.name ?: continue
val remainingTags = node.tags.filter { it in allowedTags }
if (remainingTags.isEmpty()) continue
if (name.lowercase().contains(searchTerm)) {
distances[node] = grapth.findShortestDistance(closedNote, node)
}
if (remainingTags.size != 1) {
println("found node with invalid amount of tags: ${node.name} (${remainingTags.map { it.cleanName }}")
}
}
return distances
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,10 @@ import at.hannibal2.skyhanni.utils.chat.Text
import at.hannibal2.skyhanni.utils.chat.Text.asComponent
import at.hannibal2.skyhanni.utils.chat.Text.center
import at.hannibal2.skyhanni.utils.chat.Text.command
import at.hannibal2.skyhanni.utils.chat.Text.fitToChat
import at.hannibal2.skyhanni.utils.chat.Text.hover
import at.hannibal2.skyhanni.utils.chat.Text.send
import at.hannibal2.skyhanni.utils.chat.Text.style
import at.hannibal2.skyhanni.utils.chat.Text.suggest
import at.hannibal2.skyhanni.utils.chat.Text.wrap
import net.minecraft.util.EnumChatFormatting
import net.minecraft.util.IChatComponent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration
Expand All @@ -44,11 +41,6 @@ object ReminderManager {

private fun sendMessage(message: String) = Text.join("§e[Reminder]", " ", message).send(REMINDERS_ACTION_ID)

private fun createDivider() = Text.HYPHEN.fitToChat().style {
strikethrough = true
color = EnumChatFormatting.BLUE
}

private fun parseDuration(text: String): Duration? = try {
val duration = TimeUtils.getDuration(text)
if (duration <= 1.seconds) null else duration
Expand All @@ -64,7 +56,7 @@ object ReminderManager {

val text: MutableList<IChatComponent> = mutableListOf()

text.add(createDivider())
text.add(Text.createDivider())

text.add(
Text.join(
Expand Down Expand Up @@ -113,7 +105,7 @@ object ReminderManager {
text.add(Text.EMPTY)
}

text.add(createDivider())
text.add(Text.createDivider())

Text.join(*text.toTypedArray(), separator = Text.NEWLINE).send(REMINDERS_LIST_ID)
}
Expand Down Expand Up @@ -183,15 +175,15 @@ object ReminderManager {
}

private fun help() {
createDivider().send()
Text.createDivider().send()
"§6SkyHanni Reminder Commands:".asComponent().send()
"§e/shremind <time> <reminder> - §bCreates a new reminder".asComponent().send()
"§e/shremind list <page> - §bLists all reminders".asComponent().send()
"§e/shremind remove <id> - §bRemoves a reminder".asComponent().send()
"§e/shremind edit <id> <reminder> - §bEdits a reminder".asComponent().send()
"§e/shremind move <id> <time> - §bMoves a reminder".asComponent().send()
"§e/shremind help - §bShows this help message".asComponent().send()
createDivider().send()
Text.createDivider().send()
}

@SubscribeEvent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ object SkyHanniDebugsAndTests {

fun testCommand(args: Array<String>) {
SkyHanniMod.coroutineScope.launch {
asyncTest()
asyncTest(args)
}
}

private fun asyncTest() {
private fun asyncTest(args: Array<String>) {

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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.features.misc.pathfind.NavigationHelper
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.test.graph.GraphEditor.distanceSqToPlayer
import at.hannibal2.skyhanni.utils.GraphUtils
Expand All @@ -30,6 +31,15 @@ object GraphEditorBugFinder {
val errorsInWorld: MutableMap<LorenzVec, String> = mutableMapOf()
val nodes = graph.nodes

for (node in nodes) {
if (node.tags.any { it in NavigationHelper.allowedTags }) {
val remainingTags = node.tags.filter { it in NavigationHelper.allowedTags }
if (remainingTags.size != 1) {
errorsInWorld[node.position] = "§cConflicting tags: $remainingTags"
}
}
}

val nearestArea = mutableMapOf<GraphNode, GraphNode>()
for (node in nodes) {
val pathToNearestArea = GraphUtils.findFastestPath(graph, node) { it.getAreaTag(ignoreConfig = true) != null }?.first
Expand Down Expand Up @@ -93,5 +103,6 @@ object GraphEditorBugFinder {
event.drawDynamicText(location, text, 1.5)
}
}

fun isEnabled() = GraphEditor.isEnabled()
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.test.graph.GraphEditor.distanceSqToPlayer
import at.hannibal2.skyhanni.utils.CollectionUtils.addString
import at.hannibal2.skyhanni.utils.CollectionUtils.sortedDesc
import at.hannibal2.skyhanni.utils.KeyboardManager
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
Expand Down Expand Up @@ -74,7 +75,12 @@ object GraphNodeEditor {
lastUpdate = SimpleTimeMark.now() + 60.seconds
nodesDisplay = buildList {
addString("§eToggle Visible Tags")
val map = mutableMapOf<GraphNodeTag, Int>()
for (tag in GraphNodeTag.entries) {
val nodes = GraphEditor.nodes.count { tag in it.tags }
map[tag] = nodes
}
for (tag in map.sortedDesc().keys) {
val isVisible = tag in tagsToShow
val nodes = GraphEditor.nodes.count { tag in it.tags }
val visibilityText = if (isVisible) " §aVisible" else " §7Invisible"
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/at/hannibal2/skyhanni/utils/chat/Text.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import net.minecraft.event.ClickEvent
import net.minecraft.event.HoverEvent
import net.minecraft.util.ChatComponentText
import net.minecraft.util.ChatStyle
import net.minecraft.util.EnumChatFormatting
import net.minecraft.util.IChatComponent

object Text {
Expand Down Expand Up @@ -97,5 +98,11 @@ object Text {
val token = ChatClickActionManager.createAction(onClick, expiresAt, oneTime)
this.command = "/shaction $token"
}


fun createDivider() = Text.HYPHEN.fitToChat().style {
strikethrough = true
color = EnumChatFormatting.BLUE
}

}

0 comments on commit cc8a3db

Please sign in to comment.