From 96f858fa518844316a3d4025410a03abf071350b Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 13 Jul 2024 19:15:04 +0900 Subject: [PATCH] item throwing sounds and better linter --- .../effects/throwing/throw_low_short.wav | Bin 0 -> 32812 bytes src/net/torvald/terrarum/QuickDirtyLint.kt | 128 +++++++++++++----- src/net/torvald/terrarum/audio/AudioBank.kt | 2 +- .../torvald/terrarum/audio/AudioProcessBuf.kt | 24 +++- .../audio/audiobank/MusicContainer.kt | 39 +++++- .../audio/audiobank/AudioBankMusicBox.kt | 2 +- .../modulebasegame/gameactors/ActorLobbed.kt | 51 +++++-- .../modulebasegame/gameactors/Cultivable.kt | 2 + .../modulebasegame/gameactors/DroppedItem.kt | 6 +- .../modulebasegame/gameitems/ItemThrowable.kt | 5 +- 10 files changed, 193 insertions(+), 66 deletions(-) create mode 100644 assets/mods/basegame/audio/effects/throwing/throw_low_short.wav diff --git a/assets/mods/basegame/audio/effects/throwing/throw_low_short.wav b/assets/mods/basegame/audio/effects/throwing/throw_low_short.wav new file mode 100644 index 0000000000000000000000000000000000000000..e7e094f5e52e427bf13cf75981478f2269d805f9 GIT binary patch literal 32812 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 z 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 - val offendingFields = scan.allClasses.filter { classinfo -> - superClasses.any { classinfo.extendsSuperclass(it) || classinfo.name == it.canonicalName } && - !classaNonGrata.contains(classinfo.name) - }.flatMap { clazz -> - clazz.declaredFieldInfo.filter { field -> - !field.isTransient && - !field.isEnum && - !serialisablePrimitives.contains(field.typeSignatureOrTypeDescriptorStr) && - serialisableTypes.none { field.typeSignatureOrTypeDescriptorStr.startsWith(it) } + fun checkForNonSerialisableFields(): Int { + val superClasses = listOf( + Actor::class.java, + GameItem::class.java + ) + + var retcode = 0 + + classGraph.let { scan -> + val offendingFields = scan.allClasses.filter { classinfo -> + superClasses.any { classinfo.extendsSuperclass(it) || classinfo.name == it.canonicalName } && + !classaNonGrata.contains(classinfo.name) + }.flatMap { clazz -> + clazz.declaredFieldInfo.filter { field -> + !field.isTransient && + !field.isEnum && + !serialisablePrimitives.contains(field.typeSignatureOrTypeDescriptorStr) && + serialisableTypes.none { field.typeSignatureOrTypeDescriptorStr.startsWith(it) } + } + }.filter { + !classaNomenNonGrata.contains(it.name) && !it.name.startsWith("this") && !it.name.contains("\$delegate") + } + + if (offendingFields.isNotEmpty()) { + println("$csiBold$csiR= Classes with non-@Transient fields =$csi0\n") + } + + offendingFields.forEach { + println("$csiBold${it.name}$csi0\n" + + "\t${csiG}from: ${csi0}${it.className}\n" + + "\t${csiG}type: ${csi0}${it.typeSignatureOrTypeDescriptorStr}\n" + + "\t${csiG}remarks: ${csi0}${ + remarks.keys.filter { key -> + it.typeSignatureOrTypeDescriptorStr.startsWith( + key + ) + }.map { remarks[it] }.joinToString(" ") + }" + ) + retcode = 1 } - }.filter { - !classaNomenNonGrata.contains(it.name) && !it.name.startsWith("this") && !it.name.contains("\$delegate") } -// println(offendingFields) - - offendingFields.forEach { - println("\u001B[1m${it.name}\u001B[m\n" + - "\t${csiG}from: ${csi0}${it.className}\n" + - "\t${csiG}type: ${csi0}${it.typeSignatureOrTypeDescriptorStr}\n" + - "\t${csiG}remarks: ${csi0}${remarks.keys.filter { key -> it.typeSignatureOrTypeDescriptorStr.startsWith(key) }.map { remarks[it] }.joinToString(" ")}") - retcode = 1 + if (retcode != 0) { + println("\n${csiR}Having above classes as non-@Transient may cause savegame to not load!$csi0") } + + return retcode } - if (retcode != 0) { - println("\n${csiR}Having above classes as non-@Transient may cause savegame to not load!$csi0") + fun checkForNoZeroArgConstructor(): Int { + val superClasses = listOf( + Actor::class.java + ) + + var retcode = 0 + + classGraph.let { scan -> + val offendingClasses = scan.allClasses.filter { classinfo -> + superClasses.any { classinfo.extendsSuperclass(it) || classinfo.name == it.canonicalName } && + !classaNonGrata.contains(classinfo.name) + }.filter { + !classaNomenNonGrata.contains(it.name) && !it.name.startsWith("this") && !it.name.contains("\$delegate") && + !it.name.endsWith("$1") && !it.name.endsWith("$2") && !it.name.endsWith("$3") && + !it.name.endsWith("$4") && !it.name.endsWith("$5") && !it.name.endsWith("$6") + }.filter { + it.declaredConstructorInfo.none { it.parameterInfo.isEmpty() } + } + + if (offendingClasses.isNotEmpty()) { + println("$csiBold$csiR= Classes with no-zero-arg constructors =$csi0\n") + } + + offendingClasses.forEach { + println("$csiBold${it.name}$csi0\n") + retcode = 1 + } + } + + if (retcode != 0) { + println("\n${csiR}Having no zero-arg constructors for above classes will cause savegame to not load!$csi0") + } + + return retcode } - exitProcess(retcode) + fun main() { + val nonSerialisable = checkForNonSerialisableFields() + val noZeroArgConstructor = checkForNoZeroArgConstructor() + + exitProcess(nonSerialisable or noZeroArgConstructor) + } +} + +fun main() { + QuickDirtyLint().main() } \ No newline at end of file diff --git a/src/net/torvald/terrarum/audio/AudioBank.kt b/src/net/torvald/terrarum/audio/AudioBank.kt index f269c4487..d998a660a 100644 --- a/src/net/torvald/terrarum/audio/AudioBank.kt +++ b/src/net/torvald/terrarum/audio/AudioBank.kt @@ -19,7 +19,7 @@ abstract class AudioBank : Disposable { abstract val name: String - abstract val samplingRate: Int + abstract val samplingRate: Float abstract val channels: Int abstract val totalSizeInSamples: Long abstract fun currentPositionInSamples(): Long diff --git a/src/net/torvald/terrarum/audio/AudioProcessBuf.kt b/src/net/torvald/terrarum/audio/AudioProcessBuf.kt index e61b4bb31..38ac968eb 100644 --- a/src/net/torvald/terrarum/audio/AudioProcessBuf.kt +++ b/src/net/torvald/terrarum/audio/AudioProcessBuf.kt @@ -4,6 +4,7 @@ import com.jme3.math.FastMath import net.torvald.terrarum.App import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE +import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATEF import net.torvald.terrarum.ceilToInt import net.torvald.terrarum.floorToInt import net.torvald.terrarum.serialise.toUint @@ -25,7 +26,7 @@ private data class Frac(var nom: Int, val denom: Int) { * * Created by minjaesong on 2023-11-17. */ -class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (FloatArray, FloatArray) -> Int?, val onAudioFinished: () -> Unit) { +class AudioProcessBuf(val inputSamplingRate: Float, val audioReadFun: (FloatArray, FloatArray) -> Int?, val onAudioFinished: () -> Unit) { var pitch: Float = 1f var playbackSpeed = 1f @@ -48,6 +49,10 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (FloatArray, else 1f / (1f - this) } + /** + * PlayRate is varying value for simulation of Doppler Shift, etc., if all you want is to just change + * the pitch of the entire audio, override the sampling rate of the [MusicContainer]. + */ internal val playRate: Float get() = (playbackSpeed * pitch).coerceIn(0.5f, 2f)/*(playbackSpeed * when (jitterMode) { // disabled until arraycopy negative length bug is resolved 1 -> jitterMode1(totalSamplesPlayed.toFloat()) @@ -58,7 +63,7 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (FloatArray, get() = inputSamplingRate * playRate private val doResample - get() = !(inputSamplingRate == SAMPLING_RATE && (playRate - 1f).absoluteValue < (1f / 1024f)) + get() = !(inputSamplingRate == SAMPLING_RATEF && (playRate - 1f).absoluteValue < (1f / 1024f)) companion object { private val RPM = 45f @@ -90,6 +95,8 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (FloatArray, private val bufLut = HashMap, Int>() + private val bufferRates = arrayOf(48000,44100,32768,32000,24000,22050,16384,16000,12000,11025,8192,8000) + init { val bl = arrayOf( 1152,1380,1814,1792,2304,2634,3502,3456,4608,5141,6874,6912, @@ -99,14 +106,17 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (FloatArray, 4096,4554,5421,5376,6144,7056,8796,8704,10240,12078,15544,15360 ) - arrayOf(48000,44100,32768,32000,24000,22050,16384,16000,12000,11025,8192,8000).forEachIndexed { ri, r -> + bufferRates.forEachIndexed { ri, r -> arrayOf(128,256,512,1024,2048).forEachIndexed { bi, b -> - bufLut[b to r] = bl[bi * 12 + ri] * 2 + bufLut[b to r] = (bl[bi * 12 + ri] * 1.05).ceilToInt() * 2 } } } - private fun getOptimalBufferSize(rate: Int) = bufLut[App.audioBufferSize to rate]!! + private fun getOptimalBufferSize(rate: Float): Int { + val validRate = bufferRates.map { (rate - it) to it }.first { it.first >= 0 }.second + return bufLut[App.audioBufferSize to validRate]!! + } } private val q @@ -146,8 +156,8 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (FloatArray, private val finL = FloatArray(fetchSize + 2 * PADSIZE) private val finR = FloatArray(fetchSize + 2 * PADSIZE) - private val fmidL = FloatArray((fetchSize * 2 + 1.0).toInt()) - private val fmidR = FloatArray((fetchSize * 2 + 1.0).toInt()) + private val fmidL = FloatArray(fetchSize * 4) + private val fmidR = FloatArray(fetchSize * 4) private val foutL = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4 private val foutR = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4 private val readBufL = FloatArray(fetchSize) diff --git a/src/net/torvald/terrarum/audio/audiobank/MusicContainer.kt b/src/net/torvald/terrarum/audio/audiobank/MusicContainer.kt index 9dc550692..60ed56eb5 100644 --- a/src/net/torvald/terrarum/audio/audiobank/MusicContainer.kt +++ b/src/net/torvald/terrarum/audio/audiobank/MusicContainer.kt @@ -14,6 +14,7 @@ import net.torvald.reflection.forceInvoke import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.audio.AudioBank import net.torvald.terrarum.audio.TerrarumAudioMixerTrack +import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATEF import net.torvald.terrarum.serialise.toUint import net.torvald.unsafe.UnsafeHelper import net.torvald.unsafe.UnsafePtr @@ -26,12 +27,36 @@ class MusicContainer( val file: File, val looping: Boolean = false, val toRAM: Boolean = false, + val samplingRateOverride: Float?, // this is FIXED sampling rate override var songFinishedHook: (AudioBank) -> Unit = {} ): AudioBank() { - override val samplingRate: Int + override val samplingRate: Float override val channels: Int val codec: String + // make Java code shorter + constructor( + name: String, + file: File, + looping: Boolean = false, + toRAM: Boolean = false, + songFinishedHook: (AudioBank) -> Unit = {} + ) : this(name, file, looping, toRAM, null, songFinishedHook) + // make Java code shorter + constructor( + name: String, + file: File, + looping: Boolean = false, + songFinishedHook: (AudioBank) -> Unit = {} + ) : this(name, file, looping, false, null, songFinishedHook) + // make Java code shorter + constructor( + name: String, + file: File, + songFinishedHook: (AudioBank) -> Unit = {} + ) : this(name, file, false, false, null, songFinishedHook) + + var samplesReadCount = 0L; internal set override val totalSizeInSamples: Long private val totalSizeInBytes: Long @@ -55,18 +80,18 @@ class MusicContainer( bytesPerSample = 2 * channels - samplingRate = when (gdxMusic) { + samplingRate = samplingRateOverride ?: when (gdxMusic) { is Wav.Music -> { val rate = gdxMusic.extortField("input")!!.sampleRate // App.printdbg(this, "music $name is WAV; rate = $rate") - rate + rate.toFloat() } is Ogg.Music -> { val rate = gdxMusic.extortField("input")!!.sampleRate // App.printdbg(this, "music $name is OGG; rate = $rate") - rate + rate.toFloat() } is Mp3.Music -> { val tempMusic = Gdx.audio.newMusic(Gdx.files.absolute(file.absolutePath)) @@ -81,11 +106,11 @@ class MusicContainer( // gdxMusic.reset() // App.printdbg(this, "music $name is MP3; rate = $rate") - rate + rate.toFloat() } else -> { // App.printdbg(this, "music $name is ${gdxMusic::class.qualifiedName}; rate = default") - TerrarumAudioMixerTrack.SAMPLING_RATE + TerrarumAudioMixerTrack.SAMPLING_RATEF } } @@ -315,7 +340,7 @@ class MusicContainer( } override fun makeCopy(): AudioBank { - val new = MusicContainer(name, file, looping, false, songFinishedHook) + val new = MusicContainer(name, file, looping, false, samplingRateOverride, songFinishedHook) synchronized(this) { if (this.toRAM) { diff --git a/src/net/torvald/terrarum/modulebasegame/audio/audiobank/AudioBankMusicBox.kt b/src/net/torvald/terrarum/modulebasegame/audio/audiobank/AudioBankMusicBox.kt index 005b35df1..534ab418e 100644 --- a/src/net/torvald/terrarum/modulebasegame/audio/audiobank/AudioBankMusicBox.kt +++ b/src/net/torvald/terrarum/modulebasegame/audio/audiobank/AudioBankMusicBox.kt @@ -19,7 +19,7 @@ class AudioBankMusicBox(override var songFinishedHook: (AudioBank) -> Unit = {}) } override val name = "spieluhr" - override val samplingRate = 48000 // 122880 // use 122880 to make each tick is 2048 samples + override val samplingRate = 48000f // 122880 // use 122880 to make each tick is 2048 samples override val channels = 1 private val getSample = // usage: getSample(noteNum 0..60) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorLobbed.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorLobbed.kt index d3bcb2d5f..5e69424ed 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorLobbed.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorLobbed.kt @@ -16,29 +16,46 @@ import kotlin.math.log10 /** * Created by minjaesong on 2024-07-12. */ -open class ActorLobbed : ActorWithBody() +open class ActorLobbed(throwPitch: Float) : ActorWithBody() { + + protected constructor() : this(1f) + + @Transient private val whooshSound = MusicContainer( + "throw_low_short", ModMgr.getFile("basegame", "audio/effects/throwing/throw_low_short.wav"), + toRAM = true, + samplingRateOverride = 48000f * throwPitch.coerceIn(0.5f, 2f) + ) + + init { + renderOrder = RenderOrder.FRONT + physProp = PhysProperties.PHYSICS_OBJECT() + elasticity = 0.34 + } + + private var soundFired = false + + override fun updateImpl(delta: Float) { + super.updateImpl(delta) + if (!soundFired) { + soundFired = true + startAudio(whooshSound, 1.0) + } + } +} /** * Created by minjaesong on 2024-02-13. */ open class ActorPrimedBomb( + throwPitch: Float, @Transient private var explosionPower: Float = 1f, private var fuse: Second = 1f, @Transient private var dropProbNonOre: Float = 0.25f, @Transient private var dropProbOre: Float = 0.75f -) : ActorLobbed() { +) : ActorLobbed(throwPitch) { - init { - renderOrder = RenderOrder.MIDTOP - physProp = PhysProperties.PHYSICS_OBJECT() - elasticity = 0.34 - } - - protected constructor() : this(1f, 1f) { - renderOrder = RenderOrder.MIDTOP - physProp = PhysProperties.PHYSICS_OBJECT() - } + protected constructor() : this(1f, 1f, 1f) private var explosionCalled = false @@ -110,7 +127,10 @@ open class ActorPrimedBomb( /** * Created by minjaesong on 2024-02-14. */ -class ActorCherryBomb : ActorPrimedBomb(14f, 4.5f) { // 14 is the intended value; 32 is for testing +class ActorCherryBomb(throwPitch: Float) : ActorPrimedBomb(throwPitch, 14f, 4.5f) { // 14 is the intended value; 32 is for testing + + private constructor() : this(1f) + init { val itemImage = CommonResourcePool.getAsItemSheet("basegame.items").get(0,13) @@ -126,7 +146,10 @@ class ActorCherryBomb : ActorPrimedBomb(14f, 4.5f) { // 14 is the intended value /** * Created by minjaesong on 2024-07-12. */ -class ActorGlowOrb : ActorLobbed() { +class ActorGlowOrb(throwPitch: Float) : ActorLobbed(throwPitch) { + + private constructor() : this(1f) + val spawnTime = INGAME.world.worldTime.TIME_T init { diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/Cultivable.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/Cultivable.kt index 7c58a2bc2..bbcaad70e 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/Cultivable.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/Cultivable.kt @@ -51,6 +51,8 @@ open class Cultivable: FixtureBase { * Created by minjaesong on 2024-02-03. */ open class SaplingBase(val species: Int) : Cultivable(72000) { + private constructor() : this(0) + private val variant = (0..3).random() init { CommonResourcePool.addToLoadingList("basegame/sprites/saplings.tga") { diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt index 8a3d48059..3276b8de2 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt @@ -16,13 +16,17 @@ import org.dyn4j.geometry.Vector2 /** * Created by minjaesong on 2016-03-15. */ -open class DroppedItem : ActorWithBody { +class DroppedItem : ActorWithBody { companion object { const val NO_PICKUP_TIME = 1f const val MERGER_RANGE = 8.0 * TILE_SIZED // the wanted distance, squared } + init { + renderOrder = RenderOrder.FRONT + } + var itemID: ItemID = ""; private set @Transient private var visualItemID = "" diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemThrowable.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemThrowable.kt index f8fc98937..c2305f8e6 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemThrowable.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemThrowable.kt @@ -33,7 +33,10 @@ open class ItemThrowable(originalID: ItemID, private val throwableActorClassName override fun startPrimaryUse(actor: ActorWithBody, delta: Float): Long = mouseInInteractableRange(actor) { mx, my, mtx, mty -> val (throwPos, throwForce) = getThrowPosAndVector(actor) - val lobbed = Class.forName(throwableActorClassName).getDeclaredConstructor().newInstance() as ActorWithBody + val magnRel = throwForce.magnitude / actor.avStrength * 1000.0 + val pitch = (magnRel * 0.2).sqrt().toFloat() + + val lobbed = Class.forName(throwableActorClassName).getDeclaredConstructor(pitch.javaClass).newInstance(pitch) as ActorWithBody lobbed.setPositionFromCentrePoint(throwPos) lobbed.externalV.set(throwForce) setupLobbedActor(lobbed)