diff --git a/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp b/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp index cdf24de9be6..295a53237d7 100644 --- a/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp +++ b/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp @@ -398,6 +398,20 @@ bool CClientPlayerVoice::IsFxEffectEnabled(uint uiFxEffect) return m_EnabledEffects[uiFxEffect] ? true : false; } +bool CClientPlayerVoice::SetFxEffectParameters(std::uint32_t uiFxEffect, void* params) +{ + if (IsFxEffectEnabled(uiFxEffect)) + return BASS_FXSetParameters(m_FxEffects[uiFxEffect], params); + return false; +} + +bool CClientPlayerVoice::GetFxEffectParameters(std::uint32_t uiFxEffect, void* params) +{ + if (IsFxEffectEnabled(uiFxEffect)) + return BASS_FXGetParameters(m_FxEffects[uiFxEffect], params); + return false; +} + bool CClientPlayerVoice::GetPan(float& fPan) { fPan = 0.0f; diff --git a/Client/mods/deathmatch/logic/CClientPlayerVoice.h b/Client/mods/deathmatch/logic/CClientPlayerVoice.h index 67c88be508d..8ce78bd5aaa 100644 --- a/Client/mods/deathmatch/logic/CClientPlayerVoice.h +++ b/Client/mods/deathmatch/logic/CClientPlayerVoice.h @@ -73,6 +73,9 @@ class CClientPlayerVoice bool SetFxEffect(uint uiFxEffect, bool bEnable); bool IsFxEffectEnabled(uint uiFxEffect); + bool SetFxEffectParameters(std::uint32_t uiFxEffect, void* params); + bool GetFxEffectParameters(std::uint32_t uiFxEffect, void* params); + bool IsActive() { return m_bVoiceActive; } private: diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp index d796377ccd7..6684e6e697d 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp @@ -1393,28 +1393,41 @@ int CLuaAudioDefs::GetSoundEffects(lua_State* luaVM) return 1; } -int CLuaAudioDefs::SetSoundEffectParameter(lua_State* luaVM) +// This wrapper eliminates the need in additional methods inside CClientPlayer. +// It doesn't look right to put them there. +struct SPlayerVoiceWrapper { - // bool setSoundEffectParameter ( sound sound, string effectName, string effectParameter, var effectParameterValue ) - CClientSound* pSound = nullptr; - SoundEffectType eEffectType; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pSound); - argStream.ReadEnumString(eEffectType); + CClientPlayer* pPlayer{}; - if (argStream.HasErrors()) + bool IsFxEffectEnabled(std::uint32_t uiFxEffect) { - return luaL_error(luaVM, argStream.GetFullErrorMessage()); + CClientPlayerVoice* pVoice = pPlayer->GetVoice(); + return pVoice ? pVoice->IsFxEffectEnabled(uiFxEffect) : false; } - if (!pSound->IsFxEffectEnabled((uint)eEffectType)) + bool SetFxEffectParameters(std::uint32_t uiFxEffect, void* params) { - return luaL_error(luaVM, "Effect's parameters can't be set unless it's enabled"); + CClientPlayerVoice* pVoice = pPlayer->GetVoice(); + return pVoice ? pVoice->SetFxEffectParameters(uiFxEffect, params) : false; } + bool GetFxEffectParameters(std::uint32_t uiFxEffect, void* params) + { + CClientPlayerVoice* pVoice = pPlayer->GetVoice(); + return pVoice ? pVoice->GetFxEffectParameters(uiFxEffect, params) : false; + } +}; + +int CLuaAudioDefs::SetSoundEffectParameter(lua_State* luaVM) +{ + // bool setSoundEffectParameter ( sound/player sound, string effectName, string effectParameter, var effectParameterValue ) + CClientSound* pSound{}; + SPlayerVoiceWrapper playerVoice; + SoundEffectType eEffectType; + + CScriptArgReader argStream(luaVM); // Call `SetFxEffectParameters` and log errors if any - const auto SetParamWithErrorLog = [&](auto effectParam, auto& params) { + const auto SetParamWithErrorLog = [luaVM, &eEffectType](auto* pSound, auto effectParam, auto& params) { // Try setting parameter if (pSound->SetFxEffectParameters((uint)eEffectType, ¶ms)) { @@ -1438,431 +1451,461 @@ int CLuaAudioDefs::SetSoundEffectParameter(lua_State* luaVM) return 1; }; - using namespace eSoundEffectParams; - switch (eEffectType) - { - case SoundEffectType::FX_DX8_CHORUS: - { - BASS_DX8_CHORUS params; - pSound->GetFxEffectParameters((uint)eEffectType, ¶ms); + const auto ProcessSoundParams = [&eEffectType, luaVM, &argStream, &SetParamWithErrorLog](auto* pSound) { + if (!pSound->IsFxEffectEnabled((std::uint32_t)eEffectType)) + return luaL_error(luaVM, "Effect's parameters can't be set unless it's enabled"); - Chorus eEffectParameter; - argStream.ReadEnumString(eEffectParameter); - switch (eEffectParameter) + using namespace eSoundEffectParams; + switch (eEffectType) + { + case SoundEffectType::FX_DX8_CHORUS: { - case Chorus::WET_DRY_MIX: - { - argStream.ReadNumber(params.fWetDryMix); - break; - } - case Chorus::DEPTH: - { - argStream.ReadNumber(params.fDepth); - break; - } - case Chorus::FEEDBACK: - { - argStream.ReadNumber(params.fFeedback); - break; - } - case Chorus::FREQUENCY: - { - argStream.ReadNumber(params.fFrequency); - break; - } - case Chorus::WAVEFORM: - { - argStream.ReadNumber(params.lWaveform); - break; - } - case Chorus::DELAY: - { - argStream.ReadNumber(params.fDelay); - break; - } - case Chorus::PHASE: + BASS_DX8_CHORUS params; + pSound->GetFxEffectParameters((std::uint32_t)eEffectType, ¶ms); + + Chorus eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) { - argStream.ReadNumber(params.lPhase); - break; + case Chorus::WET_DRY_MIX: + { + argStream.ReadNumber(params.fWetDryMix); + break; + } + case Chorus::DEPTH: + { + argStream.ReadNumber(params.fDepth); + break; + } + case Chorus::FEEDBACK: + { + argStream.ReadNumber(params.fFeedback); + break; + } + case Chorus::FREQUENCY: + { + argStream.ReadNumber(params.fFrequency); + break; + } + case Chorus::WAVEFORM: + { + argStream.ReadNumber(params.lWaveform); + break; + } + case Chorus::DELAY: + { + argStream.ReadNumber(params.fDelay); + break; + } + case Chorus::PHASE: + { + argStream.ReadNumber(params.lPhase); + break; + } } - } - if (argStream.HasErrors()) - break; - - return SetParamWithErrorLog(eEffectParameter, params); - } - case SoundEffectType::FX_DX8_COMPRESSOR: - { - BASS_DX8_COMPRESSOR params; - pSound->GetFxEffectParameters((uint)eEffectType, ¶ms); + if (argStream.HasErrors()) + break; - Compressor eEffectParameter; - argStream.ReadEnumString(eEffectParameter); - switch (eEffectParameter) + return SetParamWithErrorLog(pSound, eEffectParameter, params); + } + case SoundEffectType::FX_DX8_COMPRESSOR: { - case Compressor::GAIN: - { - argStream.ReadNumber(params.fGain); - break; - } - case Compressor::ATTACK: - { - argStream.ReadNumber(params.fAttack); - break; - } - case Compressor::RELEASE: - { - argStream.ReadNumber(params.fRelease); - break; - } - case Compressor::THRESHOLD: - { - argStream.ReadNumber(params.fThreshold); - break; - } - case Compressor::RATIO: - { - argStream.ReadNumber(params.fRatio); - break; - } - case Compressor::PREDELAY: + BASS_DX8_COMPRESSOR params; + pSound->GetFxEffectParameters((std::uint32_t)eEffectType, ¶ms); + + Compressor eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) { - argStream.ReadNumber(params.fPredelay); - break; + case Compressor::GAIN: + { + argStream.ReadNumber(params.fGain); + break; + } + case Compressor::ATTACK: + { + argStream.ReadNumber(params.fAttack); + break; + } + case Compressor::RELEASE: + { + argStream.ReadNumber(params.fRelease); + break; + } + case Compressor::THRESHOLD: + { + argStream.ReadNumber(params.fThreshold); + break; + } + case Compressor::RATIO: + { + argStream.ReadNumber(params.fRatio); + break; + } + case Compressor::PREDELAY: + { + argStream.ReadNumber(params.fPredelay); + break; + } } - } - - if (argStream.HasErrors()) - break; - return SetParamWithErrorLog(eEffectParameter, params); - } - case SoundEffectType::FX_DX8_DISTORTION: - { - BASS_DX8_DISTORTION params; - pSound->GetFxEffectParameters((uint)eEffectType, ¶ms); + if (argStream.HasErrors()) + break; - Distortion eEffectParameter; - argStream.ReadEnumString(eEffectParameter); - switch (eEffectParameter) + return SetParamWithErrorLog(pSound, eEffectParameter, params); + } + case SoundEffectType::FX_DX8_DISTORTION: { - case Distortion::GAIN: - { - argStream.ReadNumber(params.fGain); - break; - } - case Distortion::EDGE: - { - argStream.ReadNumber(params.fEdge); - break; - } - case Distortion::POST_EQ_CENTER_FREQUENCY: - { - argStream.ReadNumber(params.fPostEQCenterFrequency); - break; - } - case Distortion::POST_EQ_BANDWIDTH: - { - argStream.ReadNumber(params.fPostEQBandwidth); - break; - } - case Distortion::PRE_LOWPASS_CUTOFF: + BASS_DX8_DISTORTION params; + pSound->GetFxEffectParameters((std::uint32_t)eEffectType, ¶ms); + + Distortion eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) { - argStream.ReadNumber(params.fPreLowpassCutoff); - break; + case Distortion::GAIN: + { + argStream.ReadNumber(params.fGain); + break; + } + case Distortion::EDGE: + { + argStream.ReadNumber(params.fEdge); + break; + } + case Distortion::POST_EQ_CENTER_FREQUENCY: + { + argStream.ReadNumber(params.fPostEQCenterFrequency); + break; + } + case Distortion::POST_EQ_BANDWIDTH: + { + argStream.ReadNumber(params.fPostEQBandwidth); + break; + } + case Distortion::PRE_LOWPASS_CUTOFF: + { + argStream.ReadNumber(params.fPreLowpassCutoff); + break; + } } - } - - if (argStream.HasErrors()) - break; - return SetParamWithErrorLog(eEffectParameter, params); - } - case SoundEffectType::FX_DX8_ECHO: - { - BASS_DX8_ECHO params; - pSound->GetFxEffectParameters((uint)eEffectType, ¶ms); + if (argStream.HasErrors()) + break; - Echo eEffectParameter; - argStream.ReadEnumString(eEffectParameter); - switch (eEffectParameter) + return SetParamWithErrorLog(pSound, eEffectParameter, params); + } + case SoundEffectType::FX_DX8_ECHO: { - case Echo::WET_DRY_MIX: - { - argStream.ReadNumber(params.fWetDryMix); - break; - } - case Echo::FEEDBACK: - { - argStream.ReadNumber(params.fFeedback); - break; - } - case Echo::LEFT_DELAY: - { - argStream.ReadNumber(params.fLeftDelay); - break; - } - case Echo::RIGHT_DELAY: - { - argStream.ReadNumber(params.fRightDelay); - break; - } - case Echo::PAN_DELAY: + BASS_DX8_ECHO params; + pSound->GetFxEffectParameters((std::uint32_t)eEffectType, ¶ms); + + Echo eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) { - bool bPanDelay; - argStream.ReadBool(bPanDelay); - params.lPanDelay = bPanDelay; - break; + case Echo::WET_DRY_MIX: + { + argStream.ReadNumber(params.fWetDryMix); + break; + } + case Echo::FEEDBACK: + { + argStream.ReadNumber(params.fFeedback); + break; + } + case Echo::LEFT_DELAY: + { + argStream.ReadNumber(params.fLeftDelay); + break; + } + case Echo::RIGHT_DELAY: + { + argStream.ReadNumber(params.fRightDelay); + break; + } + case Echo::PAN_DELAY: + { + bool bPanDelay; + argStream.ReadBool(bPanDelay); + params.lPanDelay = bPanDelay; + break; + } } - } - - if (argStream.HasErrors()) - break; - return SetParamWithErrorLog(eEffectParameter, params); - } - case SoundEffectType::FX_DX8_FLANGER: - { - BASS_DX8_FLANGER params; - pSound->GetFxEffectParameters((uint)eEffectType, ¶ms); + if (argStream.HasErrors()) + break; - Flanger eEffectParameter; - argStream.ReadEnumString(eEffectParameter); - switch (eEffectParameter) + return SetParamWithErrorLog(pSound, eEffectParameter, params); + } + case SoundEffectType::FX_DX8_FLANGER: { - case Flanger::WET_DRY_MIX: - { - argStream.ReadNumber(params.fWetDryMix); - break; - } - case Flanger::DEPTH: - { - argStream.ReadNumber(params.fDepth); - break; - } - case Flanger::FEEDBACK: - { - argStream.ReadNumber(params.fFeedback); - break; - } - case Flanger::FREQUENCY: - { - argStream.ReadNumber(params.fFrequency); - break; - } - case Flanger::WAVEFORM: - { - argStream.ReadNumber(params.lWaveform); - break; - } - case Flanger::DELAY: - { - argStream.ReadNumber(params.fDelay); - break; - } - case Flanger::PHASE: + BASS_DX8_FLANGER params; + pSound->GetFxEffectParameters((std::uint32_t)eEffectType, ¶ms); + + Flanger eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) { - argStream.ReadNumber(params.lPhase); - break; + case Flanger::WET_DRY_MIX: + { + argStream.ReadNumber(params.fWetDryMix); + break; + } + case Flanger::DEPTH: + { + argStream.ReadNumber(params.fDepth); + break; + } + case Flanger::FEEDBACK: + { + argStream.ReadNumber(params.fFeedback); + break; + } + case Flanger::FREQUENCY: + { + argStream.ReadNumber(params.fFrequency); + break; + } + case Flanger::WAVEFORM: + { + argStream.ReadNumber(params.lWaveform); + break; + } + case Flanger::DELAY: + { + argStream.ReadNumber(params.fDelay); + break; + } + case Flanger::PHASE: + { + argStream.ReadNumber(params.lPhase); + break; + } } - } - - if (argStream.HasErrors()) - break; - return SetParamWithErrorLog(eEffectParameter, params); - } - case SoundEffectType::FX_DX8_GARGLE: - { - BASS_DX8_GARGLE params; - pSound->GetFxEffectParameters((uint)eEffectType, ¶ms); + if (argStream.HasErrors()) + break; - Gargle eEffectParameter; - argStream.ReadEnumString(eEffectParameter); - switch (eEffectParameter) + return SetParamWithErrorLog(pSound, eEffectParameter, params); + } + case SoundEffectType::FX_DX8_GARGLE: { - case Gargle::RATE_HZ: - { - argStream.ReadNumber(params.dwRateHz); - break; - } - case Gargle::WAVE_SHAPE: + BASS_DX8_GARGLE params; + pSound->GetFxEffectParameters((std::uint32_t)eEffectType, ¶ms); + + Gargle eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) { - argStream.ReadNumber(params.dwWaveShape); - break; + case Gargle::RATE_HZ: + { + argStream.ReadNumber(params.dwRateHz); + break; + } + case Gargle::WAVE_SHAPE: + { + argStream.ReadNumber(params.dwWaveShape); + break; + } } - } - - if (argStream.HasErrors()) - break; - return SetParamWithErrorLog(eEffectParameter, params); - } - case SoundEffectType::FX_DX8_I3DL2REVERB: - { - BASS_DX8_I3DL2REVERB params; - pSound->GetFxEffectParameters((uint)eEffectType, ¶ms); + if (argStream.HasErrors()) + break; - I3DL2Reverb eEffectParameter; - argStream.ReadEnumString(eEffectParameter); - switch (eEffectParameter) + return SetParamWithErrorLog(pSound, eEffectParameter, params); + } + case SoundEffectType::FX_DX8_I3DL2REVERB: { - case I3DL2Reverb::ROOM: - { - argStream.ReadNumber(params.lRoom); - break; - } - case I3DL2Reverb::ROOM_HF: - { - argStream.ReadNumber(params.lRoomHF); - break; - } - case I3DL2Reverb::ROOM_ROLLOFF_FACTOR: - { - argStream.ReadNumber(params.flRoomRolloffFactor); - break; - } - case I3DL2Reverb::DECAY_TIME: - { - argStream.ReadNumber(params.flDecayTime); - break; - } - case I3DL2Reverb::DECAY_HF_RATIO: - { - argStream.ReadNumber(params.flDecayHFRatio); - break; - } - case I3DL2Reverb::REFLECTIONS: - { - argStream.ReadNumber(params.lReflections); - break; - } - case I3DL2Reverb::REFLECTIONS_DELAY: - { - argStream.ReadNumber(params.flReflectionsDelay); - break; - } - case I3DL2Reverb::REVERB: - { - argStream.ReadNumber(params.lReverb); - break; - } - case I3DL2Reverb::REVERB_DELAY: - { - argStream.ReadNumber(params.flReverbDelay); - break; - } - case I3DL2Reverb::DIFFUSION: - { - argStream.ReadNumber(params.flDiffusion); - break; - } - case I3DL2Reverb::DENSITY: - { - argStream.ReadNumber(params.flDensity); - break; - } - case I3DL2Reverb::HF_REFERENCE: + BASS_DX8_I3DL2REVERB params; + pSound->GetFxEffectParameters((std::uint32_t)eEffectType, ¶ms); + + I3DL2Reverb eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) { - argStream.ReadNumber(params.flHFReference); - break; + case I3DL2Reverb::ROOM: + { + argStream.ReadNumber(params.lRoom); + break; + } + case I3DL2Reverb::ROOM_HF: + { + argStream.ReadNumber(params.lRoomHF); + break; + } + case I3DL2Reverb::ROOM_ROLLOFF_FACTOR: + { + argStream.ReadNumber(params.flRoomRolloffFactor); + break; + } + case I3DL2Reverb::DECAY_TIME: + { + argStream.ReadNumber(params.flDecayTime); + break; + } + case I3DL2Reverb::DECAY_HF_RATIO: + { + argStream.ReadNumber(params.flDecayHFRatio); + break; + } + case I3DL2Reverb::REFLECTIONS: + { + argStream.ReadNumber(params.lReflections); + break; + } + case I3DL2Reverb::REFLECTIONS_DELAY: + { + argStream.ReadNumber(params.flReflectionsDelay); + break; + } + case I3DL2Reverb::REVERB: + { + argStream.ReadNumber(params.lReverb); + break; + } + case I3DL2Reverb::REVERB_DELAY: + { + argStream.ReadNumber(params.flReverbDelay); + break; + } + case I3DL2Reverb::DIFFUSION: + { + argStream.ReadNumber(params.flDiffusion); + break; + } + case I3DL2Reverb::DENSITY: + { + argStream.ReadNumber(params.flDensity); + break; + } + case I3DL2Reverb::HF_REFERENCE: + { + argStream.ReadNumber(params.flHFReference); + break; + } } - } - - if (argStream.HasErrors()) - break; - return SetParamWithErrorLog(eEffectParameter, params); - } - case SoundEffectType::FX_DX8_PARAMEQ: - { - BASS_DX8_PARAMEQ params; - pSound->GetFxEffectParameters((uint)eEffectType, ¶ms); + if (argStream.HasErrors()) + break; - ParamEq eEffectParameter; - argStream.ReadEnumString(eEffectParameter); - switch (eEffectParameter) + return SetParamWithErrorLog(pSound, eEffectParameter, params); + } + case SoundEffectType::FX_DX8_PARAMEQ: { - case ParamEq::CENTER: - { - argStream.ReadNumber(params.fCenter); - break; - } - case ParamEq::BANDWIDTH: - { - argStream.ReadNumber(params.fBandwidth); - break; - } - case ParamEq::GAIN: + BASS_DX8_PARAMEQ params; + pSound->GetFxEffectParameters((std::uint32_t)eEffectType, ¶ms); + + ParamEq eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) { - argStream.ReadNumber(params.fGain); - break; + case ParamEq::CENTER: + { + argStream.ReadNumber(params.fCenter); + break; + } + case ParamEq::BANDWIDTH: + { + argStream.ReadNumber(params.fBandwidth); + break; + } + case ParamEq::GAIN: + { + argStream.ReadNumber(params.fGain); + break; + } } - } - - if (argStream.HasErrors()) - break; - return SetParamWithErrorLog(eEffectParameter, params); - } - case SoundEffectType::FX_DX8_REVERB: - { - BASS_DX8_REVERB params; - pSound->GetFxEffectParameters((uint)eEffectType, ¶ms); + if (argStream.HasErrors()) + break; - Reverb eEffectParameter; - argStream.ReadEnumString(eEffectParameter); - switch (eEffectParameter) + return SetParamWithErrorLog(pSound, eEffectParameter, params); + } + case SoundEffectType::FX_DX8_REVERB: { - case Reverb::IN_GAIN: - { - argStream.ReadNumber(params.fInGain); - break; - } - case Reverb::REVERB_MIX: - { - argStream.ReadNumber(params.fReverbMix); - break; - } - case Reverb::REVERB_TIME: + BASS_DX8_REVERB params; + pSound->GetFxEffectParameters((std::uint32_t)eEffectType, ¶ms); + + Reverb eEffectParameter; + argStream.ReadEnumString(eEffectParameter); + switch (eEffectParameter) { - argStream.ReadNumber(params.fReverbTime); - break; + case Reverb::IN_GAIN: + { + argStream.ReadNumber(params.fInGain); + break; + } + case Reverb::REVERB_MIX: + { + argStream.ReadNumber(params.fReverbMix); + break; + } + case Reverb::REVERB_TIME: + { + argStream.ReadNumber(params.fReverbTime); + break; + } + case Reverb::HIGH_FREQ_RT_RATIO: + { + argStream.ReadNumber(params.fHighFreqRTRatio); + break; + } } - case Reverb::HIGH_FREQ_RT_RATIO: - { - argStream.ReadNumber(params.fHighFreqRTRatio); + + if (argStream.HasErrors()) break; - } + + return SetParamWithErrorLog(pSound, eEffectParameter, params); } + } - if (argStream.HasErrors()) - break; + lua_pushboolean(luaVM, false); + return 1; + }; + + if (argStream.NextIsUserDataOfType()) + argStream.ReadUserData(pSound); + else if (argStream.NextIsUserDataOfType()) + argStream.ReadUserData(playerVoice.pPlayer); + else + { + m_pScriptDebugging->LogBadPointer(luaVM, "sound/player", 1); + lua_pushboolean(luaVM, false); + return false; + } + argStream.ReadEnumString(eEffectType); - return SetParamWithErrorLog(eEffectParameter, params); - } + if (!argStream.HasErrors()) + { + if (pSound) + return ProcessSoundParams(pSound); + else if (playerVoice.pPlayer) + return ProcessSoundParams(&playerVoice); + else + assert(nullptr && "Unreachable"); } - // Only ever reaches this point if there's an error - return luaL_error(luaVM, argStream.GetFullErrorMessage()); + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; } int CLuaAudioDefs::GetSoundEffectParameters(lua_State* luaVM) { - // table getSoundEffectParameters ( sound sound, string effectName ) - CClientSound* pSound = nullptr; + // table getSoundEffectParameters ( sound/player sound, string effectName ) + CClientSound* pSound{}; + SPlayerVoiceWrapper playerVoice; SoundEffectType eEffectType; CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pSound); - argStream.ReadEnumString(eEffectType); - if (argStream.HasErrors()) - return luaL_error(luaVM, argStream.GetFullErrorMessage()); + const auto ProcessSoundParams = [luaVM, &eEffectType](auto* pSound) { + if (!pSound->IsFxEffectEnabled((std::uint32_t)eEffectType)) + return luaL_error(luaVM, "Effect's parameters can't be set unless it's enabled"); - if (pSound->IsFxEffectEnabled((uint)eEffectType)) - { using namespace eSoundEffectParams; switch (eEffectType) { @@ -2110,7 +2153,34 @@ int CLuaAudioDefs::GetSoundEffectParameters(lua_State* luaVM) break; } } + + lua_pushboolean(luaVM, false); + return 1; + }; + + if (argStream.NextIsUserDataOfType()) + argStream.ReadUserData(pSound); + else if (argStream.NextIsUserDataOfType()) + argStream.ReadUserData(playerVoice.pPlayer); + else + { + m_pScriptDebugging->LogBadPointer(luaVM, "sound/player", 1); + lua_pushboolean(luaVM, false); + return false; } + argStream.ReadEnumString(eEffectType); + + if (!argStream.HasErrors()) + { + if (pSound) + return ProcessSoundParams(pSound); + else if (playerVoice.pPlayer) + return ProcessSoundParams(&playerVoice); + else + assert(nullptr && "Unreachable"); + } + + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); lua_pushboolean(luaVM, false); return 1;