diff options
| author | Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> | 2024-05-07 22:43:17 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-07 22:43:17 +0200 |
| commit | d0345f39230e4f07f061b6c82a381c863e9787d8 (patch) | |
| tree | beaf9d162d1ee0b891fefefeb1fb4815d9adb89b /src/main/java/at/hannibal2/skyhanni/data | |
| parent | 912c8d8a8c9ad412b2f94827e09a9cf262e5b69a (diff) | |
| download | skyhanni-d0345f39230e4f07f061b6c82a381c863e9787d8.tar.gz skyhanni-d0345f39230e4f07f061b6c82a381c863e9787d8.tar.bz2 skyhanni-d0345f39230e4f07f061b6c82a381c863e9787d8.zip | |
Feature: Tunnels maps (#1546)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/data')
| -rw-r--r-- | src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt | 23 | ||||
| -rw-r--r-- | src/main/java/at/hannibal2/skyhanni/data/model/Graph.kt | 180 |
2 files changed, 203 insertions, 0 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt b/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt index ae5a03878..97039022a 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt @@ -1,11 +1,16 @@ package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.events.EntityMoveEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzTickEvent +import at.hannibal2.skyhanni.events.LorenzWarpEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent +import at.hannibal2.skyhanni.utils.DelayedRun import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzVec +import at.hannibal2.skyhanni.utils.StringUtils.matches import at.hannibal2.skyhanni.utils.getLorenzVec +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import net.minecraft.client.Minecraft import net.minecraft.entity.Entity import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -41,6 +46,24 @@ class EntityMovementData { } } + private val warpingPattern by RepoPattern.pattern( + "warping", + "§7Warping...|" + + "§7Warping you to your SkyBlock island...|" + + "§7Warping using transfer token...|" + + "§7Finding player...|" + + "§7Sending a visit request..." + ) + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!warpingPattern.matches(event.message)) return + DelayedRun.runNextTick { + LorenzWarpEvent().postAndCatch() + } + } + @SubscribeEvent fun onWorldChange(event: LorenzWorldChangeEvent) { entityLocation.clear() diff --git a/src/main/java/at/hannibal2/skyhanni/data/model/Graph.kt b/src/main/java/at/hannibal2/skyhanni/data/model/Graph.kt new file mode 100644 index 000000000..b6e6f7b8e --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/model/Graph.kt @@ -0,0 +1,180 @@ +package at.hannibal2.skyhanni.data.model + +import at.hannibal2.skyhanni.config.ConfigManager.Companion.registerTypeAdapter +import at.hannibal2.skyhanni.utils.LorenzVec +import at.hannibal2.skyhanni.utils.fromJson +import com.google.gson.GsonBuilder +import com.google.gson.JsonElement +import com.google.gson.annotations.Expose +import java.util.PriorityQueue + +@JvmInline +value class Graph( + @Expose + val graph: List<GraphNode>, +) : List<GraphNode> { + override val size + get() = graph.size + + override fun contains(element: GraphNode) = graph.contains(element) + + override fun containsAll(elements: Collection<GraphNode>) = graph.containsAll(elements) + + override fun get(index: Int) = graph.get(index) + + override fun isEmpty() = graph.isEmpty() + + override fun indexOf(element: GraphNode) = graph.indexOf(element) + + override fun iterator(): Iterator<GraphNode> = graph.iterator() + override fun listIterator() = graph.listIterator() + + override fun listIterator(index: Int) = graph.listIterator(index) + + override fun subList(fromIndex: Int, toIndex: Int) = graph.subList(fromIndex, toIndex) + + override fun lastIndexOf(element: GraphNode) = graph.lastIndexOf(element) + + companion object { + val gson = GsonBuilder().setPrettyPrinting() + /* ConfigManager.createBaseGsonBuilder() */.registerTypeAdapter<Graph>({ out, value -> + out.beginObject() + value.forEach { + out.name(it.id.toString()).beginObject() + out.name("Position").value(with(it.position) { "$x:$y:$z" }) + if (it.name != null) { + out.name("Name").value(it.name) + } + out.name("Neighbours") + out.beginObject() + it.neighbours.forEach { (node, weight) -> + val id = node.id.toString() + out.name(id).value(weight) + } + out.endObject() + out.endObject() + } + out.endObject() + }, { reader -> + reader.beginObject() + val list = mutableListOf<GraphNode>() + val neigbourMap = mutableMapOf<GraphNode, List<Pair<Int, Double>>>() + while (reader.hasNext()) { + val id = reader.nextName().toInt() + reader.beginObject() + var position: LorenzVec? = null + var name: String? = null + var neighbors = mutableListOf<Pair<Int, Double>>() + while (reader.hasNext()) { + when (reader.nextName()) { + "Position" -> { + position = reader.nextString().split(":").let { parts -> + LorenzVec(parts[0].toDouble(), parts[1].toDouble(), parts[2].toDouble()) + } + } + + "Neighbours" -> { + reader.beginObject() + while (reader.hasNext()) { + val nId = reader.nextName().toInt() + val distance = reader.nextDouble() + neighbors.add(nId to distance) + } + reader.endObject() + } + + "Name" -> { + name = reader.nextString() + } + + } + } + val node = GraphNode(id, position!!, name) + list.add(node) + neigbourMap[node] = neighbors + reader.endObject() + } + neigbourMap.forEach { (node, edge) -> + node.neighbours = edge.associate { (id, distance) -> + list.first { it.id == id } to distance + } + } + reader.endObject() + Graph(list) + }).create() + + fun fromJson(json: String): Graph = gson.fromJson<Graph>(json) + fun fromJson(json: JsonElement): Graph = gson.fromJson<Graph>(json) + } +} + +class GraphNode(val id: Int, val position: LorenzVec, val name: String? = null) { + + /** Keys are the neighbours and value the edge weight (e.g. Distance) */ + lateinit var neighbours: Map<GraphNode, Double> + + override fun hashCode(): Int { + return id + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as GraphNode + + if (id != other.id) return false + + return true + } +} + +fun Graph.findShortestPathAsGraph(start: GraphNode, end: GraphNode): Graph = + this.findShortestPathAsGraphWithDistance(start, end).first + +fun Graph.findShortestPathAsGraphWithDistance(start: GraphNode, end: GraphNode): Pair<Graph, Double> { + val distances = mutableMapOf<GraphNode, Double>() + val previous = mutableMapOf<GraphNode, GraphNode>() + val visited = mutableSetOf<GraphNode>() + val queue = PriorityQueue<GraphNode>(compareBy { distances.getOrDefault(it, Double.MAX_VALUE) }) + + distances[start] = 0.0 + queue.add(start) + + while (queue.isNotEmpty()) { + val current = queue.poll() + if (current == end) break + + visited.add(current) + + current.neighbours.forEach { (neighbour, weight) -> + if (neighbour !in visited) { + val newDistance = distances.getValue(current) + weight + if (newDistance < distances.getOrDefault(neighbour, Double.MAX_VALUE)) { + distances[neighbour] = newDistance + previous[neighbour] = current + queue.add(neighbour) + } + } + } + } + + return Graph(buildList { + var current = end + while (current != start) { + add(current) + current = previous[current] ?: return Graph(emptyList()) to 0.0 + } + add(start) + }.reversed()) to distances[end]!! +} + +fun Graph.findShortestPath(start: GraphNode, end: GraphNode): List<LorenzVec> = + this.findShortestPathAsGraph(start, end).toPositionsList() + +fun Graph.findShortestDistance(start: GraphNode, end: GraphNode): Double = + this.findShortestPathAsGraphWithDistance(start, end).second + +fun Graph.toPositionsList() = this.map { it.position } + +fun Graph.toJson(): String = Graph.gson.toJson(this) |
