Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: /shnavigate #2575

Merged
merged 10 commits into from
Sep 24, 2024
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,109 @@
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 {
asyncTest(args)
}
}

private fun asyncTest(args: Array<String>) {
hannibal002 marked this conversation as resolved.
Show resolved Hide resolved
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
if (!node.tags.any { it in allowedTags }) continue
if (name.lowercase().contains(searchTerm)) {
distances[node] = grapth.findShortestDistance(closedNote, node)
}
val remainingTags = node.tags.filter { it in allowedTags }
hannibal002 marked this conversation as resolved.
Show resolved Hide resolved
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
}

}
Loading