-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
191 additions
and
2 deletions.
There are no files selected for viewing
35 changes: 35 additions & 0 deletions
35
src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
23
src/main/kotlin/moe/nea/firmament/events/SoundReceiveEvent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
src/main/kotlin/moe/nea/firmament/features/diana/AncestralSpadeSolver.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
32
src/main/kotlin/moe/nea/firmament/features/diana/DianaWaypoints.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters