Refactor source layout

Introduce compat source sets and move all kotlin sources to the main directory

[no changelog]
This commit is contained in:
Linnea Gräf
2024-08-28 19:04:24 +02:00
parent a690630816
commit d2f240ff0c
251 changed files with 295 additions and 38 deletions

View File

@@ -0,0 +1,131 @@
package moe.nea.firmament.features.diana
import kotlin.time.Duration.Companion.seconds
import net.minecraft.particle.ParticleTypes
import net.minecraft.sound.SoundEvents
import net.minecraft.util.math.Vec3d
import moe.nea.firmament.annotations.Subscribe
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.events.subscription.SubscriptionOwner
import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SBData
import moe.nea.firmament.util.SkyBlockIsland
import moe.nea.firmament.util.SkyblockId
import moe.nea.firmament.util.TimeMark
import moe.nea.firmament.util.WarpUtil
import moe.nea.firmament.util.render.RenderInWorldContext
import moe.nea.firmament.util.skyBlockId
object AncestralSpadeSolver : SubscriptionOwner {
var lastDing = TimeMark.farPast()
private set
private val pitches = mutableListOf<Float>()
val particlePositions = mutableListOf<Vec3d>()
var nextGuess: Vec3d? = null
private set
val ancestralSpadeId = SkyblockId("ANCESTRAL_SPADE")
private var lastTeleportAttempt = TimeMark.farPast()
fun isEnabled() =
DianaWaypoints.TConfig.ancestralSpadeSolver
&& SBData.skyblockLocation == SkyBlockIsland.HUB
&& MC.player?.inventory?.containsAny { it.skyBlockId == ancestralSpadeId } == true // TODO: add a reactive property here
@Subscribe
fun onKeyBind(event: WorldKeyboardEvent) {
if (!isEnabled()) return
if (!event.matches(DianaWaypoints.TConfig.ancestralSpadeTeleport)) return
if (lastTeleportAttempt.passedTime() < 3.seconds) return
WarpUtil.teleportToNearestWarp(SkyBlockIsland.HUB, nextGuess ?: return)
lastTeleportAttempt = TimeMark.now()
}
@Subscribe
fun onParticleSpawn(event: ParticleSpawnEvent) {
if (!isEnabled()) return
if (event.particleEffect != ParticleTypes.DRIPPING_LAVA) return
if (event.offset.x != 0.0F || event.offset.y != 0F || event.offset.z != 0F)
return
particlePositions.add(event.position)
if (particlePositions.size > 20) {
particlePositions.removeFirst()
}
}
@Subscribe
fun onPlaySound(event: SoundReceiveEvent) {
if (!isEnabled()) return
if (!SoundEvents.BLOCK_NOTE_BLOCK_HARP.matchesId(event.sound.value().id)) return
if (lastDing.passedTime() > 1.seconds) {
particlePositions.clear()
pitches.clear()
}
lastDing = TimeMark.now()
pitches.add(event.pitch)
if (pitches.size > 20) {
pitches.removeFirst()
}
if (particlePositions.size < 3) {
return
}
val averagePitchDelta =
if (pitches.isEmpty()) return
else pitches
.zipWithNext { a, b -> b - a }
.average()
val soundDistanceEstimate = (Math.E / averagePitchDelta) - particlePositions.first().distanceTo(event.position)
if (soundDistanceEstimate > 1000) {
return
}
val lastParticleDirection = particlePositions
.takeLast(3)
.let { (a, _, b) -> b.subtract(a) }
.normalize()
nextGuess = event.position.add(lastParticleDirection.multiply(soundDistanceEstimate))
}
@Subscribe
fun onWorldRender(event: WorldRenderLastEvent) {
if (!isEnabled()) return
RenderInWorldContext.renderInWorld(event) {
nextGuess?.let {
color(1f, 1f, 0f, 0.5f)
tinyBlock(it, 1f)
color(1f, 1f, 0f, 1f)
tracer(it, lineWidth = 3f)
}
if (particlePositions.size > 2 && lastDing.passedTime() < 10.seconds && nextGuess != null) {
color(0f, 1f, 0f, 0.7f)
line(particlePositions)
}
}
}
@Subscribe
fun onSwapWorld(event: WorldReadyEvent) {
nextGuess = null
particlePositions.clear()
pitches.clear()
lastDing = TimeMark.farPast()
}
override val delegateFeature: FirmamentFeature
get() = DianaWaypoints
}

View File

@@ -0,0 +1,35 @@
package moe.nea.firmament.features.diana
import moe.nea.firmament.events.AttackBlockEvent
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
import moe.nea.firmament.gui.config.ManagedConfig
object DianaWaypoints : FirmamentFeature {
override val identifier get() = "diana"
override val config get() = TConfig
object TConfig : ManagedConfig(identifier) {
val ancestralSpadeSolver by toggle("ancestral-spade") { true }
val ancestralSpadeTeleport by keyBindingWithDefaultUnbound("ancestral-teleport")
val nearbyWaypoints by toggle("nearby-waypoints") { true }
}
override fun onLoad() {
UseBlockEvent.subscribe {
NearbyBurrowsSolver.onBlockClick(it.hitResult.blockPos)
}
AttackBlockEvent.subscribe {
NearbyBurrowsSolver.onBlockClick(it.blockPos)
}
}
}

View File

@@ -0,0 +1,144 @@
package moe.nea.firmament.features.diana
import kotlin.time.Duration.Companion.seconds
import net.minecraft.particle.ParticleTypes
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.MathHelper
import net.minecraft.util.math.Position
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.ParticleSpawnEvent
import moe.nea.firmament.events.ProcessChatEvent
import moe.nea.firmament.events.WorldReadyEvent
import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.events.subscription.SubscriptionOwner
import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.util.TimeMark
import moe.nea.firmament.util.mutableMapWithMaxSize
import moe.nea.firmament.util.render.RenderInWorldContext.Companion.renderInWorld
object NearbyBurrowsSolver : SubscriptionOwner {
private val recentlyDugBurrows: MutableMap<BlockPos, TimeMark> = mutableMapWithMaxSize(20)
private val recentEnchantParticles: MutableMap<BlockPos, TimeMark> = mutableMapWithMaxSize(500)
private var lastBlockClick: BlockPos? = null
enum class BurrowType {
START, MOB, TREASURE
}
val burrows = mutableMapOf<BlockPos, BurrowType>()
@Subscribe
fun onChatEvent(event: ProcessChatEvent) {
val lastClickedBurrow = lastBlockClick ?: return
if (event.unformattedString.startsWith("You dug out a Griffin Burrow!") ||
event.unformattedString.startsWith(" ☠ You were killed by") ||
event.unformattedString.startsWith("You finished the Griffin burrow chain!")
) {
markAsDug(lastClickedBurrow)
burrows.remove(lastClickedBurrow)
}
}
fun wasRecentlyDug(blockPos: BlockPos): Boolean {
val lastDigTime = recentlyDugBurrows[blockPos] ?: TimeMark.farPast()
return lastDigTime.passedTime() < 10.seconds
}
fun markAsDug(blockPos: BlockPos) {
recentlyDugBurrows[blockPos] = TimeMark.now()
}
fun wasRecentlyEnchanted(blockPos: BlockPos): Boolean {
val lastEnchantTime = recentEnchantParticles[blockPos] ?: TimeMark.farPast()
return lastEnchantTime.passedTime() < 4.seconds
}
fun markAsEnchanted(blockPos: BlockPos) {
recentEnchantParticles[blockPos] = TimeMark.now()
}
@Subscribe
fun onParticles(event: ParticleSpawnEvent) {
if (!DianaWaypoints.TConfig.nearbyWaypoints) return
val position: BlockPos = event.position.toBlockPos().down()
if (wasRecentlyDug(position)) return
val isEven50Spread = (event.offset.x == 0.5f && event.offset.z == 0.5f)
if (event.particleEffect.type == ParticleTypes.ENCHANT) {
if (event.count == 5 && event.speed == 0.05F && event.offset.y == 0.4F && isEven50Spread) {
markAsEnchanted(position)
}
return
}
if (!wasRecentlyEnchanted(position)) return
if (event.particleEffect.type == ParticleTypes.ENCHANTED_HIT
&& event.count == 4
&& event.speed == 0.01F
&& event.offset.y == 0.1f
&& isEven50Spread
) {
burrows[position] = BurrowType.START
}
if (event.particleEffect.type == ParticleTypes.CRIT
&& event.count == 3
&& event.speed == 0.01F
&& event.offset.y == 0.1F
&& isEven50Spread
) {
burrows[position] = BurrowType.MOB
}
if (event.particleEffect.type == ParticleTypes.DRIPPING_LAVA
&& event.count == 2
&& event.speed == 0.01F
&& event.offset.y == 0.1F
&& event.offset.x == 0.35F && event.offset.z == 0.35f
) {
burrows[position] = BurrowType.TREASURE
}
}
@Subscribe
fun onRender(event: WorldRenderLastEvent) {
if (!DianaWaypoints.TConfig.nearbyWaypoints) return
renderInWorld(event) {
for ((location, burrow) in burrows) {
when (burrow) {
BurrowType.START -> color(.2f, .8f, .2f, 0.4f)
BurrowType.MOB -> color(0.3f, 0.4f, 0.9f, 0.4f)
BurrowType.TREASURE -> color(1f, 0.7f, 0.2f, 0.4f)
}
block(location)
}
}
}
@Subscribe
fun onSwapWorld(worldReadyEvent: WorldReadyEvent) {
burrows.clear()
recentEnchantParticles.clear()
recentlyDugBurrows.clear()
lastBlockClick = null
}
fun onBlockClick(blockPos: BlockPos) {
if (!DianaWaypoints.TConfig.nearbyWaypoints) return
burrows.remove(blockPos)
lastBlockClick = blockPos
}
override val delegateFeature: FirmamentFeature
get() = DianaWaypoints
}
fun Position.toBlockPos(): BlockPos {
return BlockPos(MathHelper.floor(x), MathHelper.floor(y), MathHelper.floor(z))
}