Skip to content

Commit

Permalink
Add Ancestral Spade solver
Browse files Browse the repository at this point in the history
  • Loading branch information
nea89o committed Jan 18, 2024
1 parent ac151c8 commit c769265
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 2 deletions.
35 changes: 35 additions & 0 deletions src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* SPDX-FileCopyrightText: 2024 Linnea Gräf <[email protected]>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/

package moe.nea.firmament.mixins;

import moe.nea.firmament.events.SoundReceiveEvent;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket;
import net.minecraft.util.math.Vec3d;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ClientPlayNetworkHandler.class)
public class SoundReceiveEventPatch {
@Inject(method = "onPlaySound", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;playSound(Lnet/minecraft/entity/player/PlayerEntity;DDDLnet/minecraft/registry/entry/RegistryEntry;Lnet/minecraft/sound/SoundCategory;FFJ)V"), cancellable = true)
private void postEventWhenSoundIsPlayed(PlaySoundS2CPacket packet, CallbackInfo ci) {
var event = new SoundReceiveEvent(
packet.getSound(),
packet.getCategory(),
new Vec3d(packet.getX(), packet.getY(), packet.getZ()),
packet.getPitch(),
packet.getVolume(),
packet.getSeed()
);
SoundReceiveEvent.Companion.publish(event);
if (event.getCancelled()) {
ci.cancel();
}
}
}
23 changes: 23 additions & 0 deletions src/main/kotlin/moe/nea/firmament/events/SoundReceiveEvent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* SPDX-FileCopyrightText: 2024 Linnea Gräf <[email protected]>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/

package moe.nea.firmament.events

import net.minecraft.registry.entry.RegistryEntry
import net.minecraft.sound.SoundCategory
import net.minecraft.sound.SoundEvent
import net.minecraft.util.math.Vec3d

data class SoundReceiveEvent(
val sound: RegistryEntry<SoundEvent>,
val category: SoundCategory,
val position: Vec3d,
val pitch: Float,
val volume: Float,
val seed: Long
) : FirmamentEvent.Cancellable() {
companion object : FirmamentEventBus<SoundReceiveEvent>()
}
2 changes: 2 additions & 0 deletions src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import moe.nea.firmament.features.debug.DebugView
import moe.nea.firmament.features.debug.DeveloperFeatures
import moe.nea.firmament.features.debug.MinorTrolling
import moe.nea.firmament.features.debug.PowerUserTools
import moe.nea.firmament.features.diana.DianaWaypoints
import moe.nea.firmament.features.fixes.CompatibliltyFeatures
import moe.nea.firmament.features.fixes.Fixes
import moe.nea.firmament.features.inventory.CraftingOverlay
Expand Down Expand Up @@ -68,6 +69,7 @@ object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "feature
loadFeature(CustomSkyBlockTextures)
loadFeature(PriceData)
loadFeature(Fixes)
loadFeature(DianaWaypoints)
loadFeature(ItemRarityCosmetics)
if (Firmament.DEBUG) {
loadFeature(DeveloperFeatures)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* SPDX-FileCopyrightText: 2024 Linnea Gräf <[email protected]>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/

package moe.nea.firmament.features.diana

import org.joml.Vector3f
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.events.ParticleSpawnEvent
import moe.nea.firmament.events.SoundReceiveEvent
import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.util.TimeMark
import moe.nea.firmament.util.render.RenderInWorldContext

object AncestralSpadeSolver {
var lastDing = TimeMark.farPast()
private set
private val pitches = mutableListOf<Float>()
val particlePositions = mutableListOf<Vec3d>()
var nextGuess: Vec3d? = null
private set

fun onParticleSpawn(event: ParticleSpawnEvent) {
if (!DianaWaypoints.TConfig.ancestralSpadeSolver) return
if (event.particleEffect != ParticleTypes.DRIPPING_LAVA) return
particlePositions.add(event.position)
if (particlePositions.size > 20) {
particlePositions.removeFirst()
}
}

fun onPlaySound(event: SoundReceiveEvent) {
if (!DianaWaypoints.TConfig.ancestralSpadeSolver) 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()) 0.0
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))
}

fun onWorldRender(event: WorldRenderLastEvent) {
if (!DianaWaypoints.TConfig.ancestralSpadeSolver) return
RenderInWorldContext.renderInWorld(event) {
nextGuess?.let {
color(1f, 1f, 0f, 0.5f)
tinyBlock(it, 1f)
color(1f, 1f, 0f, 1f)
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) {
color(0f, 1f, 0f, 0.7f)
line(*particlePositions.toTypedArray())
}
}
}

}
32 changes: 32 additions & 0 deletions src/main/kotlin/moe/nea/firmament/features/diana/DianaWaypoints.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: 2024 Linnea Gräf <[email protected]>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/

package moe.nea.firmament.features.diana

import moe.nea.firmament.events.ParticleSpawnEvent
import moe.nea.firmament.events.SoundReceiveEvent
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: String
get() = "diana-waypoints"
override val config: ManagedConfig?
get() = TConfig

object TConfig : ManagedConfig(identifier) {
val ancestralSpadeSolver by toggle("ancestral-spade") { false }
}

override fun onLoad() {
ParticleSpawnEvent.subscribe(AncestralSpadeSolver::onParticleSpawn)
SoundReceiveEvent.subscribe(AncestralSpadeSolver::onPlaySound)
WorldRenderLastEvent.subscribe(AncestralSpadeSolver::onWorldRender)
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,16 @@ class RenderInWorldContext private constructor(
}

fun line(vararg points: Vec3d, lineWidth: Float = 10F) {
line(points.toList(), lineWidth)
}

fun line(points: List<Vec3d>, lineWidth: Float = 10F) {
RenderSystem.setShader(GameRenderer::getRenderTypeLinesProgram)
RenderSystem.lineWidth(lineWidth / pow(camera.pos.squaredDistanceTo(points.first()), 0.25).toFloat())
buffer.begin(VertexFormat.DrawMode.LINES, VertexFormats.LINES)
buffer.fixedColor(255, 255, 255, 255)

points.toList().zipWithNext().forEach { (a, b) ->
points.zipWithNext().forEach { (a, b) ->
doLine(matrixStack.peek(), buffer, a.x, a.y, a.z, b.x, b.y, b.z)
}
buffer.unfixColor()
Expand All @@ -173,7 +177,7 @@ class RenderInWorldContext private constructor(
) {
val normal = Vector3f(x.toFloat(), y.toFloat(), z.toFloat())
.sub(i.toFloat(), j.toFloat(), k.toFloat())
.mul(-1F)
.normalize()
buf.vertex(matrix.positionMatrix, i.toFloat(), j.toFloat(), k.toFloat())
.normal(matrix.normalMatrix, normal.x, normal.y, normal.z).next()
buf.vertex(matrix.positionMatrix, x.toFloat(), y.toFloat(), z.toFloat())
Expand Down

0 comments on commit c769265

Please sign in to comment.