From d2f240ff0ca0d27f417f837e706c781a98c31311 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Wed, 28 Aug 2024 19:04:24 +0200 Subject: Refactor source layout Introduce compat source sets and move all kotlin sources to the main directory [no changelog] --- src/main/kotlin/features/world/FairySouls.kt | 131 +++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/main/kotlin/features/world/FairySouls.kt (limited to 'src/main/kotlin/features/world/FairySouls.kt') diff --git a/src/main/kotlin/features/world/FairySouls.kt b/src/main/kotlin/features/world/FairySouls.kt new file mode 100644 index 0000000..8a8291a --- /dev/null +++ b/src/main/kotlin/features/world/FairySouls.kt @@ -0,0 +1,131 @@ + + +package moe.nea.firmament.features.world + +import io.github.moulberry.repo.data.Coordinate +import kotlinx.serialization.Serializable +import kotlinx.serialization.serializer +import net.minecraft.text.Text +import net.minecraft.util.math.Vec3d +import moe.nea.firmament.annotations.Subscribe +import moe.nea.firmament.events.ProcessChatEvent +import moe.nea.firmament.events.SkyblockServerUpdateEvent +import moe.nea.firmament.events.WorldRenderLastEvent +import moe.nea.firmament.features.FirmamentFeature +import moe.nea.firmament.gui.config.ManagedConfig +import moe.nea.firmament.repo.RepoManager +import moe.nea.firmament.util.MC +import moe.nea.firmament.util.SBData +import moe.nea.firmament.util.SkyBlockIsland +import moe.nea.firmament.util.blockPos +import moe.nea.firmament.util.data.ProfileSpecificDataHolder +import moe.nea.firmament.util.render.RenderInWorldContext +import moe.nea.firmament.util.render.RenderInWorldContext.Companion.renderInWorld +import moe.nea.firmament.util.unformattedString + + +object FairySouls : FirmamentFeature { + + + @Serializable + data class Data( + val foundSouls: MutableMap> = mutableMapOf() + ) + + override val config: ManagedConfig + get() = TConfig + + object DConfig : ProfileSpecificDataHolder(serializer(), "found-fairysouls", ::Data) + + + object TConfig : ManagedConfig("fairy-souls") { + val displaySouls by toggle("show") { false } + val resetSouls by button("reset") { + DConfig.data?.foundSouls?.clear() != null + updateMissingSouls() + } + } + + + override val identifier: String get() = "fairy-souls" + + val playerReach = 5 + val playerReachSquared = playerReach * playerReach + + var currentLocationName: SkyBlockIsland? = null + var currentLocationSouls: List = emptyList() + var currentMissingSouls: List = emptyList() + + fun updateMissingSouls() { + currentMissingSouls = emptyList() + val c = DConfig.data ?: return + val fi = c.foundSouls[currentLocationName] ?: setOf() + val cms = currentLocationSouls.toMutableList() + fi.asSequence().sortedDescending().filter { it in cms.indices }.forEach { cms.removeAt(it) } + currentMissingSouls = cms + } + + fun updateWorldSouls() { + currentLocationSouls = emptyList() + val loc = currentLocationName ?: return + currentLocationSouls = RepoManager.neuRepo.constants.fairySouls.soulLocations[loc.locrawMode] ?: return + } + + fun findNearestClickableSoul(): Coordinate? { + val player = MC.player ?: return null + val pos = player.pos + val location = SBData.skyblockLocation ?: return null + val soulLocations: List = + RepoManager.neuRepo.constants.fairySouls.soulLocations[location.locrawMode] ?: return null + return soulLocations + .map { it to it.blockPos.getSquaredDistance(pos) } + .filter { it.second < playerReachSquared } + .minByOrNull { it.second } + ?.first + } + + private fun markNearestSoul() { + val nearestSoul = findNearestClickableSoul() ?: return + val c = DConfig.data ?: return + val loc = currentLocationName ?: return + val idx = currentLocationSouls.indexOf(nearestSoul) + c.foundSouls.computeIfAbsent(loc) { mutableSetOf() }.add(idx) + DConfig.markDirty() + updateMissingSouls() + } + + @Subscribe + fun onWorldRender(it: WorldRenderLastEvent) { + if (!TConfig.displaySouls) return + renderInWorld(it) { + color(1F, 1F, 0F, 0.8F) + currentMissingSouls.forEach { + block(it.blockPos) + } + color(1f, 0f, 1f, 1f) + currentLocationSouls.forEach { + wireframeCube(it.blockPos) + } + } + } + + @Subscribe + fun onProcessChat(it: ProcessChatEvent) { + when (it.text.unformattedString) { + "You have already found that Fairy Soul!" -> { + markNearestSoul() + } + + "SOUL! You found a Fairy Soul!" -> { + markNearestSoul() + } + } + } + + @Subscribe + fun onLocationChange(it: SkyblockServerUpdateEvent) { + currentLocationName = it.newLocraw?.skyblockLocation + updateWorldSouls() + updateMissingSouls() + } +} -- cgit