aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/diana/AncestralSpadeSolver.kt17
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/diana/DianaWaypoints.kt3
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/WarpUtil.kt77
-rw-r--r--src/main/resources/assets/firmament/lang/en_us.json2
4 files changed, 97 insertions, 2 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/features/diana/AncestralSpadeSolver.kt b/src/main/kotlin/moe/nea/firmament/features/diana/AncestralSpadeSolver.kt
index 459fa3c..442d8cf 100644
--- a/src/main/kotlin/moe/nea/firmament/features/diana/AncestralSpadeSolver.kt
+++ b/src/main/kotlin/moe/nea/firmament/features/diana/AncestralSpadeSolver.kt
@@ -13,9 +13,11 @@ import net.minecraft.sound.SoundEvents
import net.minecraft.util.math.Vec3d
import moe.nea.firmament.events.ParticleSpawnEvent
import moe.nea.firmament.events.SoundReceiveEvent
+import moe.nea.firmament.events.WorldKeyboardEvent
import moe.nea.firmament.events.WorldReadyEvent
import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.util.TimeMark
+import moe.nea.firmament.util.WarpUtil
import moe.nea.firmament.util.render.RenderInWorldContext
object AncestralSpadeSolver {
@@ -26,6 +28,17 @@ object AncestralSpadeSolver {
var nextGuess: Vec3d? = null
private set
+ private var lastTeleportAttempt = TimeMark.farPast()
+
+ fun onKeyBind(event: WorldKeyboardEvent) {
+ if (!DianaWaypoints.TConfig.ancestralSpadeSolver) return
+ if (!event.matches(DianaWaypoints.TConfig.ancestralSpadeTeleport)) return
+
+ if (lastTeleportAttempt.passedTime() < 3.seconds) return
+ WarpUtil.teleportToNearestWarp("hub", nextGuess ?: return)
+ lastTeleportAttempt = TimeMark.now()
+ }
+
fun onParticleSpawn(event: ParticleSpawnEvent) {
if (!DianaWaypoints.TConfig.ancestralSpadeSolver) return
if (event.particleEffect != ParticleTypes.DRIPPING_LAVA) return
@@ -57,7 +70,7 @@ object AncestralSpadeSolver {
}
val averagePitchDelta =
- if (pitches.isEmpty()) 0.0
+ if (pitches.isEmpty()) return
else pitches
.zipWithNext { a, b -> b - a }
.average()
@@ -86,7 +99,7 @@ object AncestralSpadeSolver {
val cameraForward = Vector3f(0f, 0f, 1f).rotate(event.camera.rotation)
line(event.camera.pos.add(Vec3d(cameraForward)), it, lineWidth = 3f)
}
- if (particlePositions.size > 2 && lastDing.passedTime() < 10.seconds) {
+ if (particlePositions.size > 2 && lastDing.passedTime() < 10.seconds && nextGuess != null) {
color(0f, 1f, 0f, 0.7f)
line(*particlePositions.toTypedArray())
}
diff --git a/src/main/kotlin/moe/nea/firmament/features/diana/DianaWaypoints.kt b/src/main/kotlin/moe/nea/firmament/features/diana/DianaWaypoints.kt
index 9f72967..9102497 100644
--- a/src/main/kotlin/moe/nea/firmament/features/diana/DianaWaypoints.kt
+++ b/src/main/kotlin/moe/nea/firmament/features/diana/DianaWaypoints.kt
@@ -11,6 +11,7 @@ import moe.nea.firmament.events.ParticleSpawnEvent
import moe.nea.firmament.events.ProcessChatEvent
import moe.nea.firmament.events.SoundReceiveEvent
import moe.nea.firmament.events.UseBlockEvent
+import moe.nea.firmament.events.WorldKeyboardEvent
import moe.nea.firmament.events.WorldReadyEvent
import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.features.FirmamentFeature
@@ -22,6 +23,7 @@ object DianaWaypoints : FirmamentFeature {
object TConfig : ManagedConfig(identifier) {
val ancestralSpadeSolver by toggle("ancestral-spade") { true }
+ val ancestralSpadeTeleport by keyBindingWithDefaultUnbound("ancestral-teleport")
val nearbyWaypoints by toggle("nearby-waypoints") { true }
}
@@ -38,6 +40,7 @@ object DianaWaypoints : FirmamentFeature {
ProcessChatEvent.subscribe(NearbyBurrowsSolver::onChatEvent)
+ WorldKeyboardEvent.subscribe(AncestralSpadeSolver::onKeyBind)
ParticleSpawnEvent.subscribe(AncestralSpadeSolver::onParticleSpawn)
SoundReceiveEvent.subscribe(AncestralSpadeSolver::onPlaySound)
WorldRenderLastEvent.subscribe(AncestralSpadeSolver::onWorldRender)
diff --git a/src/main/kotlin/moe/nea/firmament/util/WarpUtil.kt b/src/main/kotlin/moe/nea/firmament/util/WarpUtil.kt
new file mode 100644
index 0000000..25cfdb0
--- /dev/null
+++ b/src/main/kotlin/moe/nea/firmament/util/WarpUtil.kt
@@ -0,0 +1,77 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+package moe.nea.firmament.util
+
+import io.github.moulberry.repo.constants.Islands
+import io.github.moulberry.repo.constants.Islands.Warp
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.serializer
+import kotlin.math.sqrt
+import kotlin.time.Duration.Companion.seconds
+import net.minecraft.text.Text
+import net.minecraft.util.math.Position
+import moe.nea.firmament.events.ProcessChatEvent
+import moe.nea.firmament.repo.RepoManager
+import moe.nea.firmament.util.data.ProfileSpecificDataHolder
+
+object WarpUtil {
+ val warps: List<Islands.Warp> get() = RepoManager.neuRepo.constants.islands.warps
+
+ @Serializable
+ data class Data(
+ val excludedWarps: MutableSet<String> = mutableSetOf(),
+ )
+
+ object DConfig : ProfileSpecificDataHolder<Data>(serializer(), "warp-util", ::Data)
+
+ private var lastAttemptedWarp = ""
+ private var lastWarpAttempt = TimeMark.farPast()
+ fun findNearestWarp(locrawMode: String, pos: Position): Islands.Warp? {
+ return warps.minByOrNull {
+ if (locrawMode != it.mode || (DConfig.data?.excludedWarps?.contains(it.warp) == true)) {
+ return@minByOrNull Double.MAX_VALUE
+ } else {
+ return@minByOrNull squaredDist(pos, it)
+ }
+ }
+ }
+
+ private fun squaredDist(pos: Position, warp: Warp): Double {
+ val dx = pos.x - warp.x
+ val dy = pos.y - warp.y
+ val dz = pos.z - warp.z
+ return dx * dx + dy * dy + dz * dz
+ }
+
+ fun teleportToNearestWarp(locrawMode: String, pos: Position) {
+ val nearestWarp = findNearestWarp(locrawMode, pos) ?: return
+
+ if (locrawMode == SBData.skyblockLocation
+ && sqrt(squaredDist(pos, nearestWarp)) > 1.1 * sqrt(squaredDist((MC.player ?: return).pos, nearestWarp))
+ ) {
+ return
+ }
+ MC.sendServerCommand("warp ${nearestWarp.warp}")
+ }
+
+ init {
+ ProcessChatEvent.subscribe {
+ if (it.unformattedString == "You haven't unlocked this fast travel destination!"
+ && lastWarpAttempt.passedTime() < 2.seconds
+ ) {
+ DConfig.data?.excludedWarps?.add(lastAttemptedWarp)
+ DConfig.markDirty()
+ MC.sendChat(Text.translatable("firmament.warp-util.mark-excluded", lastAttemptedWarp))
+ lastWarpAttempt = TimeMark.farPast()
+ }
+ if (it.unformattedString == "You may now fast travel to") {
+ DConfig.data?.excludedWarps?.clear()
+ DConfig.markDirty()
+ }
+ }
+ }
+}
diff --git a/src/main/resources/assets/firmament/lang/en_us.json b/src/main/resources/assets/firmament/lang/en_us.json
index 2f3f4d9..824a4a0 100644
--- a/src/main/resources/assets/firmament/lang/en_us.json
+++ b/src/main/resources/assets/firmament/lang/en_us.json
@@ -21,6 +21,7 @@
"firmament.tooltip.ah.lowestbin": "Lowest BIN: %d",
"firmament.pv.pets": "Pets",
"firmament.config.diana": "Diana",
+ "firmament.config.diana.ancestral-teleport": "Warp near guess",
"firmament.config.diana.ancestral-spade": "Ancestral Spade Solver",
"firmament.config.diana.nearby-waypoints": "Nearby Waypoints Highlighter",
"firmament.config.pristine-profit": "Pristine Profit Tracker",
@@ -74,6 +75,7 @@
"firmament.inventory-buttons.import-failed": "One of your buttons could only be imported partially",
"firmament.config.inventory-buttons": "Inventory buttons",
"firmament.config.inventory-buttons.open-editor": "Open Editor",
+ "firmament.warp-util.mark-excluded": "Firmament: Tried to warp to %s, but it was not unlocked. I will avoid warping there again.",
"firmament.waypoint.temporary": "Temporary Waypoint: %s",
"firmament.config.waypoints": "Waypoints",
"firmament.config.waypoints.temp-waypoint-duration": "Temporary Waypoint Duration",