From dcb769967dce8c4e98f035c23f5167553750a94a Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Fri, 19 Jan 2024 00:25:02 +0100 Subject: Add warp to diana guess keybind --- .../features/diana/AncestralSpadeSolver.kt | 17 ++++- .../nea/firmament/features/diana/DianaWaypoints.kt | 3 + src/main/kotlin/moe/nea/firmament/util/WarpUtil.kt | 77 ++++++++++++++++++++++ 3 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/moe/nea/firmament/util/WarpUtil.kt (limited to 'src/main/kotlin') 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 + * + * 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 get() = RepoManager.neuRepo.constants.islands.warps + + @Serializable + data class Data( + val excludedWarps: MutableSet = mutableSetOf(), + ) + + object DConfig : ProfileSpecificDataHolder(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() + } + } + } +} -- cgit