mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 11:04:05 +09:00
fix: explosion cuts off randomly
This commit is contained in:
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/explosion/fuse.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/explosion/fuse.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/explosion/fuse_continue.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/explosion/fuse_continue.ogg
LFS
Normal file
Binary file not shown.
@@ -340,10 +340,11 @@ Sound from <https://freesound.org/people/DrinkingWindGames>
|
|||||||
℗ 2019 Richwise
|
℗ 2019 Richwise
|
||||||
Sound from <https://freesound.org/people/richwise>
|
Sound from <https://freesound.org/people/richwise>
|
||||||
|
|
||||||
- effects/explosion/bang_small.ogg
|
- effects/explosion/fuse.ogg
|
||||||
|
- effects/explosion/fuse_continue.ogg
|
||||||
℗ 2009 Superex1110
|
|
||||||
Sound from <https://freesound.org/people/Superex1110/>
|
℗ 2012, 2015 j1987 and ScouseMouseJB
|
||||||
|
Sound from <https://freesound.org/people/j1987> and <https://freesound.org/people/ScouseMouseJB>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -453,9 +453,9 @@ class AudioMixer : Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun startAmb(song: MusicContainer) {
|
fun startAmb(song: MusicContainer) {
|
||||||
val ambientTrack = if (!ambientTrack1.streamPlaying)
|
val ambientTrack = if (!ambientTrack1.streamPlaying.get())
|
||||||
ambientTrack1
|
ambientTrack1
|
||||||
else if (!ambientTrack2.streamPlaying)
|
else if (!ambientTrack2.streamPlaying.get())
|
||||||
ambientTrack2
|
ambientTrack2
|
||||||
else if (ambientTrack1.playStartedTime < ambientTrack2.playStartedTime)
|
else if (ambientTrack1.playStartedTime < ambientTrack2.playStartedTime)
|
||||||
ambientTrack1
|
ambientTrack1
|
||||||
|
|||||||
@@ -181,8 +181,15 @@ class MixerTrackProcessor(bufferSize: Int, val rate: Int, val track: TerrarumAud
|
|||||||
|
|
||||||
|
|
||||||
// fetch deviceBufferSize amount of sample from the disk
|
// fetch deviceBufferSize amount of sample from the disk
|
||||||
if (track.trackType != TrackType.MASTER && track.trackType != TrackType.BUS && track.streamPlaying) {
|
if (track.playRequested.get()) {
|
||||||
if (streamBuf == null && track.currentTrack != null) allocateStreamBuf(track)
|
track.play()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (track.trackType != TrackType.MASTER && track.trackType != TrackType.BUS && track.streamPlaying.get()) {
|
||||||
|
if (streamBuf == null && track.currentTrack != null) {
|
||||||
|
allocateStreamBuf(track)
|
||||||
|
}
|
||||||
|
|
||||||
streamBuf!!.fetchBytes()
|
streamBuf!!.fetchBytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +215,7 @@ class MixerTrackProcessor(bufferSize: Int, val rate: Int, val track: TerrarumAud
|
|||||||
}
|
}
|
||||||
// source channel: skip processing if there's no active input
|
// source channel: skip processing if there's no active input
|
||||||
// else if (track.getSidechains().any { it != null && !it.isBus && !it.isMaster && !it.streamPlaying } && !track.streamPlaying) {
|
// else if (track.getSidechains().any { it != null && !it.isBus && !it.isMaster && !it.streamPlaying } && !track.streamPlaying) {
|
||||||
else if (!track.streamPlaying || streamBuf == null || streamBuf!!.validSamplesInBuf < App.audioBufferSize) {
|
else if (!track.streamPlaying.get() || streamBuf == null || streamBuf!!.validSamplesInBuf < App.audioBufferSize) {
|
||||||
samplesL1 = emptyBuf
|
samplesL1 = emptyBuf
|
||||||
samplesR1 = emptyBuf
|
samplesR1 = emptyBuf
|
||||||
|
|
||||||
|
|||||||
@@ -41,13 +41,13 @@ data class MusicContainer(
|
|||||||
is Wav.Music -> {
|
is Wav.Music -> {
|
||||||
val rate = gdxMusic.extortField<Wav.WavInputStream>("input")!!.sampleRate
|
val rate = gdxMusic.extortField<Wav.WavInputStream>("input")!!.sampleRate
|
||||||
|
|
||||||
App.printdbg(this, "music $name is WAV; rate = $rate")
|
// App.printdbg(this, "music $name is WAV; rate = $rate")
|
||||||
rate
|
rate
|
||||||
}
|
}
|
||||||
is Ogg.Music -> {
|
is Ogg.Music -> {
|
||||||
val rate = gdxMusic.extortField<OggInputStream>("input")!!.sampleRate
|
val rate = gdxMusic.extortField<OggInputStream>("input")!!.sampleRate
|
||||||
|
|
||||||
App.printdbg(this, "music $name is OGG; rate = $rate")
|
// App.printdbg(this, "music $name is OGG; rate = $rate")
|
||||||
rate
|
rate
|
||||||
}
|
}
|
||||||
is Mp3.Music -> {
|
is Mp3.Music -> {
|
||||||
@@ -62,11 +62,11 @@ data class MusicContainer(
|
|||||||
// val rate = header.sampleRate
|
// val rate = header.sampleRate
|
||||||
// gdxMusic.reset()
|
// gdxMusic.reset()
|
||||||
|
|
||||||
App.printdbg(this, "music $name is MP3; rate = $rate")
|
// App.printdbg(this, "music $name is MP3; rate = $rate")
|
||||||
rate
|
rate
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
App.printdbg(this, "music $name is ${gdxMusic::class.qualifiedName}; rate = default")
|
// App.printdbg(this, "music $name is ${gdxMusic::class.qualifiedName}; rate = default")
|
||||||
TerrarumAudioMixerTrack.SAMPLING_RATE
|
TerrarumAudioMixerTrack.SAMPLING_RATE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,14 @@ import com.badlogic.gdx.backends.lwjgl3.audio.OpenALLwjgl3Audio
|
|||||||
import com.badlogic.gdx.utils.Disposable
|
import com.badlogic.gdx.utils.Disposable
|
||||||
import com.badlogic.gdx.utils.Queue
|
import com.badlogic.gdx.utils.Queue
|
||||||
import net.torvald.terrarum.App
|
import net.torvald.terrarum.App
|
||||||
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.audio.dsp.NullFilter
|
import net.torvald.terrarum.audio.dsp.NullFilter
|
||||||
import net.torvald.terrarum.audio.dsp.TerrarumAudioFilter
|
import net.torvald.terrarum.audio.dsp.TerrarumAudioFilter
|
||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
import net.torvald.terrarum.getHashStr
|
import net.torvald.terrarum.getHashStr
|
||||||
import net.torvald.terrarum.hashStrMap
|
import net.torvald.terrarum.hashStrMap
|
||||||
|
import net.torvald.terrarum.printStackTrace
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import kotlin.math.log10
|
import kotlin.math.log10
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
@@ -60,7 +63,7 @@ class TerrarumAudioMixerTrack(
|
|||||||
|
|
||||||
var trackingTarget: Actor? = null
|
var trackingTarget: Actor? = null
|
||||||
|
|
||||||
internal var streamPlaying = false
|
internal val streamPlaying = AtomicBoolean(false)
|
||||||
var playStartedTime = 0L; internal set
|
var playStartedTime = 0L; internal set
|
||||||
|
|
||||||
|
|
||||||
@@ -70,7 +73,7 @@ class TerrarumAudioMixerTrack(
|
|||||||
other.nextTrack = this.nextTrack
|
other.nextTrack = this.nextTrack
|
||||||
other.volume = this.volume
|
other.volume = this.volume
|
||||||
other.trackingTarget = this.trackingTarget
|
other.trackingTarget = this.trackingTarget
|
||||||
other.streamPlaying = this.streamPlaying
|
other.streamPlaying.set(this.streamPlaying.get())
|
||||||
other.playStartedTime = this.playStartedTime
|
other.playStartedTime = this.playStartedTime
|
||||||
filters.indices.forEach { i ->
|
filters.indices.forEach { i ->
|
||||||
other.filters[i].copyParamsFrom(this.filters[i])
|
other.filters[i].copyParamsFrom(this.filters[i])
|
||||||
@@ -133,15 +136,18 @@ class TerrarumAudioMixerTrack(
|
|||||||
nextTrack = nextNext
|
nextTrack = nextNext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val playRequested = AtomicBoolean(false)
|
||||||
|
|
||||||
|
|
||||||
fun play() {
|
fun play() {
|
||||||
playStartedTime = System.nanoTime()
|
playStartedTime = System.nanoTime()
|
||||||
streamPlaying = true
|
streamPlaying.set(true)
|
||||||
|
playRequested.set(false)
|
||||||
// currentTrack?.gdxMusic?.play()
|
// currentTrack?.gdxMusic?.play()
|
||||||
}
|
}
|
||||||
|
|
||||||
val isPlaying: Boolean
|
val isPlaying: Boolean
|
||||||
get() = streamPlaying//currentTrack?.gdxMusic?.isPlaying
|
get() = streamPlaying.get()//currentTrack?.gdxMusic?.isPlaying
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
/*if (isMaster) { // uncomment to multithread
|
/*if (isMaster) { // uncomment to multithread
|
||||||
@@ -158,7 +164,7 @@ class TerrarumAudioMixerTrack(
|
|||||||
fun stop() {
|
fun stop() {
|
||||||
currentTrack?.reset()
|
currentTrack?.reset()
|
||||||
|
|
||||||
streamPlaying = false
|
streamPlaying.set(false)
|
||||||
// playStartedTime = 0L
|
// playStartedTime = 0L
|
||||||
|
|
||||||
if (trackingTarget != null && currentTrack != null) {
|
if (trackingTarget != null && currentTrack != null) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.gameactors
|
|||||||
|
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.App
|
import net.torvald.terrarum.App
|
||||||
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.INGAME
|
import net.torvald.terrarum.INGAME
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.audio.MusicContainer
|
import net.torvald.terrarum.audio.MusicContainer
|
||||||
@@ -12,6 +13,9 @@ import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
|||||||
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
||||||
import net.torvald.terrarum.savegame.toBigEndian
|
import net.torvald.terrarum.savegame.toBigEndian
|
||||||
import net.torvald.terrarum.utils.PasswordBase32
|
import net.torvald.terrarum.utils.PasswordBase32
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
import kotlin.collections.HashMap
|
||||||
|
|
||||||
|
|
||||||
typealias ActorID = Int
|
typealias ActorID = Int
|
||||||
@@ -72,6 +76,8 @@ abstract class Actor : Comparable<Actor>, Runnable {
|
|||||||
@Transient open val canBeDespawned = true
|
@Transient open val canBeDespawned = true
|
||||||
@Volatile internal var despawned = false
|
@Volatile internal var despawned = false
|
||||||
|
|
||||||
|
@Transient open val stopMusicOnDespawn = true
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other == null) return false
|
if (other == null) return false
|
||||||
|
|
||||||
@@ -105,8 +111,12 @@ abstract class Actor : Comparable<Actor>, Runnable {
|
|||||||
musicTracks1.forEach { name ->
|
musicTracks1.forEach { name ->
|
||||||
val it = App.audioMixer.dynamicTracks[name.substring(2).toInt() - 1]
|
val it = App.audioMixer.dynamicTracks[name.substring(2).toInt() - 1]
|
||||||
|
|
||||||
println("stop track $name")
|
printdbg(this, "stop track $name")
|
||||||
it.stop()
|
|
||||||
|
if (stopMusicOnDespawn) {
|
||||||
|
it.stop()
|
||||||
|
}
|
||||||
|
|
||||||
it.filters[0] = NullFilter
|
it.filters[0] = NullFilter
|
||||||
it.filters[1] = NullFilter
|
it.filters[1] = NullFilter
|
||||||
it.processor.streamBuf?.pitch = 1f
|
it.processor.streamBuf?.pitch = 1f
|
||||||
@@ -149,6 +159,7 @@ abstract class Actor : Comparable<Actor>, Runnable {
|
|||||||
if (track != null) {
|
if (track != null) {
|
||||||
musicTracks[music] = track
|
musicTracks[music] = track
|
||||||
musicTracks1.add(track.name)
|
musicTracks1.add(track.name)
|
||||||
|
track.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,14 +172,20 @@ abstract class Actor : Comparable<Actor>, Runnable {
|
|||||||
* To loop the audio, set `music.gdxMusic.isLooping` to `true`
|
* To loop the audio, set `music.gdxMusic.isLooping` to `true`
|
||||||
*/
|
*/
|
||||||
open fun startAudio(music: MusicContainer, volume: TrackVolume = 1.0, doSomethingWithTrack: (TerrarumAudioMixerTrack) -> Unit = {}) {
|
open fun startAudio(music: MusicContainer, volume: TrackVolume = 1.0, doSomethingWithTrack: (TerrarumAudioMixerTrack) -> Unit = {}) {
|
||||||
getTrackByAudio(music)?.let {
|
getTrackByAudio(music).let {
|
||||||
it.stop()
|
if (it == null) {
|
||||||
it.trackingTarget = this
|
printdbg(this, "cannot startAudio $music")
|
||||||
it.currentTrack = music
|
}
|
||||||
it.maxVolumeFun = { volume }
|
else {
|
||||||
it.volume = volume
|
printdbg(this, "startAudio $music")
|
||||||
doSomethingWithTrack(it)
|
it.trackingTarget = this
|
||||||
it.play()
|
it.currentTrack = music
|
||||||
|
it.maxVolumeFun = { volume }
|
||||||
|
it.volume = volume
|
||||||
|
doSomethingWithTrack(it)
|
||||||
|
// it.play()
|
||||||
|
it.playRequested.set(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,9 +194,15 @@ abstract class Actor : Comparable<Actor>, Runnable {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
open fun stopAudio(music: MusicContainer, doSomethingWithTrack: (TerrarumAudioMixerTrack) -> Unit = {}) {
|
open fun stopAudio(music: MusicContainer, doSomethingWithTrack: (TerrarumAudioMixerTrack) -> Unit = {}) {
|
||||||
musicTracks[music]?.let {
|
musicTracks[music].let {
|
||||||
doSomethingWithTrack(it)
|
if (it == null) {
|
||||||
it.stop()
|
// printdbg(this, "cannot stopAudio $music")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// printdbg(this, "stopAudio $music")
|
||||||
|
doSomethingWithTrack(it)
|
||||||
|
it.stop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,14 +54,14 @@ object ExplosionManager {
|
|||||||
Thread {
|
Thread {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
val job = runners.first { !it.executed }
|
runners.toList().firstOrNull { !it.executed }?.let { job ->
|
||||||
val executor = Executors.newSingleThreadExecutor()
|
val executor = Executors.newSingleThreadExecutor()
|
||||||
executor.submit(job.runner).get(500L, TimeUnit.MILLISECONDS)
|
executor.submit(job.runner).get(500L, TimeUnit.MILLISECONDS)
|
||||||
executor.shutdownNow()
|
executor.shutdownNow()
|
||||||
job.executed = true
|
job.executed = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (_: TimeoutException) { }
|
catch (_: TimeoutException) { }
|
||||||
catch (_: NoSuchElementException) { }
|
|
||||||
|
|
||||||
Thread.sleep(50L)
|
Thread.sleep(50L)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,36 @@ open class ActorPrimedBomb(
|
|||||||
) {
|
) {
|
||||||
this.flagDespawn()
|
this.flagDespawn()
|
||||||
}
|
}
|
||||||
|
@Transient private val fuseSound = MusicContainer(
|
||||||
|
"fuse", ModMgr.getFile("basegame", "audio/effects/explosion/fuse.ogg")
|
||||||
|
) {
|
||||||
|
this.flagDespawn()
|
||||||
|
}
|
||||||
|
@Transient private val fuseSoundCont = MusicContainer(
|
||||||
|
"fuse_continue", ModMgr.getFile("basegame", "audio/effects/explosion/fuse_continue.ogg")
|
||||||
|
) {
|
||||||
|
this.flagDespawn()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var fuseSoundStatus = 0 // this value must be stored into the savegame
|
||||||
|
@Transient private var fuseSoundFired = false
|
||||||
|
|
||||||
|
override val stopMusicOnDespawn: Boolean
|
||||||
|
get() = this.isVisible
|
||||||
|
|
||||||
override fun updateImpl(delta: Float) {
|
override fun updateImpl(delta: Float) {
|
||||||
super.updateImpl(delta)
|
super.updateImpl(delta)
|
||||||
|
|
||||||
|
if (!fuseSoundFired && fuse > 0f) {
|
||||||
|
fuseSoundFired = true
|
||||||
|
if (fuseSoundStatus == 0) {
|
||||||
|
startAudio(fuseSound, 2.0)
|
||||||
|
fuseSoundStatus = 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
startAudio(fuseSoundCont, 2.0)
|
||||||
|
}
|
||||||
|
|
||||||
fuse -= delta
|
fuse -= delta
|
||||||
|
|
||||||
if (fuse <= 0f && !explosionCalled) {
|
if (fuse <= 0f && !explosionCalled) {
|
||||||
@@ -57,6 +83,7 @@ open class ActorPrimedBomb(
|
|||||||
) {
|
) {
|
||||||
physProp.usePhysics = false
|
physProp.usePhysics = false
|
||||||
this.isVisible = false // or play explosion anim
|
this.isVisible = false // or play explosion anim
|
||||||
|
stopAudio(fuseSound)
|
||||||
startAudio(boomSound, 10.0)
|
startAudio(boomSound, 10.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,6 +92,8 @@ open class ActorPrimedBomb(
|
|||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
super.dispose()
|
super.dispose()
|
||||||
boomSound.dispose()
|
boomSound.dispose()
|
||||||
|
fuseSound.dispose()
|
||||||
|
fuseSoundCont.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -805,7 +805,7 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
drawFaderHandle(batch, sliderX.toFloat(), faderY + 18f + meterHeight - faderKnobDbFs * meterHeight)
|
drawFaderHandle(batch, sliderX.toFloat(), faderY + 18f + meterHeight - faderKnobDbFs * meterHeight)
|
||||||
|
|
||||||
// currently streaming
|
// currently streaming
|
||||||
if (track.streamPlaying) {
|
if (track.streamPlaying.get()) {
|
||||||
batch.color = ICON_GREEN
|
batch.color = ICON_GREEN
|
||||||
App.fontSmallNumbers.draw(batch, "\u00C0", x + 17f, faderY + 1f)
|
App.fontSmallNumbers.draw(batch, "\u00C0", x + 17f, faderY + 1f)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user