diff --git a/Client/game_sa/CAEVehicleAudioEntitySA.h b/Client/game_sa/CAEVehicleAudioEntitySA.h index 08098481f8..5294597b02 100644 --- a/Client/game_sa/CAEVehicleAudioEntitySA.h +++ b/Client/game_sa/CAEVehicleAudioEntitySA.h @@ -11,6 +11,7 @@ #pragma once +#include "CVehicleAudioSettingsEntrySA.h" #include #include "CAudioEngineSA.h" @@ -20,28 +21,7 @@ #define FUNC_CAEVehicleAudioEntity__ProcessAIProp 0x4FDFD0 #define FUNC_CAEVehicleAudioEntity__ProcessAIHeli 0x4FEE20 -struct tVehicleAudioSettings -{ - char m_nVehicleSoundType; - char unk1; - short m_wEngineOnSoundBankId; - short m_wEngineOffSoundBankId; - char m_nStereo; - char unk2; - int unk3; - int unk4; - char m_bHornTon; - char unk5[3]; - float m_fHornHigh; - char m_nDoorSound; - char unk6; - char m_nRadioNum; - char m_nRadioType; - char unk7; - char unk8[3]; - float m_fHornVolumeDelta; -}; -static_assert(sizeof(tVehicleAudioSettings) == 0x24, "Invalid size for tVehicleAudioSettings"); +class CVehicleSAInterface; struct tVehicleSound { @@ -73,9 +53,13 @@ static_assert(sizeof(CAETwinLoopSoundEntity) == 0xA8, "Invalid size for CAETwinL class CAEVehicleAudioEntitySAInterface : public CAEAudioEntity { public: - void AddAudioEvent(int eventId, float volume) + void AddAudioEvent(int eventId, float volume) { ((void(__thiscall*)(CAEVehicleAudioEntitySAInterface*, int, float))0x4F6420)(this, eventId, volume); } + bool TerminateAudio() { return ((bool(__thiscall*)(CAEVehicleAudioEntitySAInterface*))0x4FB8C0)(this); } + bool SoundJoin() { return ((bool(__thiscall*)(CAEVehicleAudioEntitySAInterface*))0x4F5700)(this); } + + int16_t InitAudio(CVehicleSAInterface* vehicle) { - ((void(__thiscall*)(CAEVehicleAudioEntitySAInterface*, int, float))0x4F6420)(this, eventId, volume); + return ((int16_t(__thiscall*)(CAEVehicleAudioEntitySAInterface*, CVehicleSAInterface*))0x4F7670)(this, vehicle); } short unk1; // +124 @@ -157,6 +141,7 @@ class CAEVehicleAudioEntitySA : public CAEVehicleAudioEntity void JustGotOutOfVehicleAsDriver(); void TurnOnRadioForVehicle(); void StopVehicleEngineSound(unsigned char ucSlot); + CAEVehicleAudioEntitySAInterface* GetInterface() { return m_pInterface; }; private: CAEVehicleAudioEntitySAInterface* m_pInterface; diff --git a/Client/game_sa/CGameSA.cpp b/Client/game_sa/CGameSA.cpp index 9c52c90b8a..274237592b 100644 --- a/Client/game_sa/CGameSA.cpp +++ b/Client/game_sa/CGameSA.cpp @@ -147,6 +147,7 @@ CGameSA::CGameSA() m_pCoverManager = new CCoverManagerSA(); m_pPlantManager = new CPlantManagerSA(); m_pBuildingRemoval = new CBuildingRemovalSA(); + m_pVehicleAudioSettingsManager = std::make_unique(); m_pRenderer = std::make_unique(); @@ -247,6 +248,7 @@ CGameSA::CGameSA() CCheckpointSA::StaticSetHooks(); CHudSA::StaticSetHooks(); CPtrNodeSingleLinkPoolSA::StaticSetHooks(); + CVehicleAudioSettingsManagerSA::StaticSetHooks(); } catch (const std::bad_alloc& e) { diff --git a/Client/game_sa/CGameSA.h b/Client/game_sa/CGameSA.h index 3703a1ad35..c366dddd8f 100644 --- a/Client/game_sa/CGameSA.h +++ b/Client/game_sa/CGameSA.h @@ -18,6 +18,7 @@ #include "CCoverManagerSA.h" #include "CPlantManagerSA.h" #include "CRendererSA.h" +#include "CVehicleAudioSettingsManagerSA.h" class CAnimBlendClumpDataSAInterface; class CObjectGroupPhysicalPropertiesSA; @@ -174,7 +175,12 @@ class CGameSA : public CGame CPlantManagerSA* GetPlantManager() const noexcept { return m_pPlantManager; }; CBuildingRemoval* GetBuildingRemoval() { return m_pBuildingRemoval; } CRenderer* GetRenderer() const noexcept override { return m_pRenderer.get(); } - + + CVehicleAudioSettingsManager* GetVehicleAudioSettingsManager() const noexcept override + { + return m_pVehicleAudioSettingsManager.get(); + } + CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD); CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false); CObjectGroupPhysicalProperties* GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup); @@ -351,6 +357,8 @@ class CGameSA : public CGame CPlantManagerSA* m_pPlantManager; CBuildingRemoval* m_pBuildingRemoval; + std::unique_ptr m_pVehicleAudioSettingsManager; + std::unique_ptr m_pRenderer; CPad* m_pPad; diff --git a/Client/game_sa/CVehicleAudioSettingsEntrySA.h b/Client/game_sa/CVehicleAudioSettingsEntrySA.h new file mode 100644 index 0000000000..9d69058646 --- /dev/null +++ b/Client/game_sa/CVehicleAudioSettingsEntrySA.h @@ -0,0 +1,81 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CVehicleAudioSettingsEntrySA.h + * PURPOSE: Header file for vehicle audio settings entry class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include "game/CVehicleAudioSettingsEntry.h" +#include + +// SA interface +struct tVehicleAudioSettings +{ + eVehicleSoundType m_eVehicleSoundType; + int16 m_nEngineOnSoundBankId; + int16 m_nEngineOffSoundBankId; + int8 m_nBassSetting; // 0 or 1 or 2 + float m_fBassEq; + float field_C; + int8 m_nHornToneSoundInBank; + float m_fHornHigh; + char m_nDoorSound; + char m_EngineUpgrade; + char m_nRadioID; + char m_nRadioType; + char m_nVehTypeForAudio; + float m_fHornVolumeDelta; +}; +static_assert(sizeof(tVehicleAudioSettings) == 0x24, "Invalid size for tVehicleAudioSettings"); + +class CVehicleAudioSettingsEntrySA final : public CVehicleAudioSettingsEntry +{ +public: + CVehicleAudioSettingsEntrySA(): m_Settings{} {}; + CVehicleAudioSettingsEntrySA(tVehicleAudioSettings* pSettings) { m_Settings = *pSettings; }; + ~CVehicleAudioSettingsEntrySA() = default; + + const tVehicleAudioSettings& GetInterface() const noexcept { return m_Settings; }; + + void Assign(const tVehicleAudioSettings& settings) noexcept { m_Settings = settings; } + void Assign(const CVehicleAudioSettingsEntry& settings) noexcept { m_Settings = static_cast(settings).GetInterface(); }; + + eVehicleSoundType GetSoundType() const noexcept override { return m_Settings.m_eVehicleSoundType; }; + short GetEngineOnSoundBankID() const noexcept override { return m_Settings.m_nEngineOnSoundBankId; }; + short GetEngineOffSoundBankID() const noexcept override { return m_Settings.m_nEngineOffSoundBankId; }; + char GetBassSetting() const noexcept override { return m_Settings.m_nBassSetting; }; + float GetBassEq() const noexcept override { return m_Settings.m_fBassEq; }; + float GetFieldC() const noexcept override { return m_Settings.field_C; }; + char GetHornTon() const noexcept override { return m_Settings.m_nHornToneSoundInBank; }; + float GetHornHign() const noexcept override { return m_Settings.m_fHornHigh; }; + char GetEngineUpgrade() const noexcept override { return m_Settings.m_EngineUpgrade; }; + char GetDoorSound() const noexcept override { return m_Settings.m_nDoorSound; }; + char GetRadioNum() const noexcept override { return m_Settings.m_nRadioID; }; + char GetRadioType() const noexcept override { return m_Settings.m_nRadioType; }; + char GetVehicleTypeForAudio() const noexcept override { return m_Settings.m_nVehTypeForAudio; }; + float GetHornVolumeDelta() const noexcept override { return m_Settings.m_fHornVolumeDelta; }; + + void SetSoundType(eVehicleSoundType value) noexcept override { m_Settings.m_eVehicleSoundType = value; }; + void SetEngineOnSoundBankID(short value) noexcept override { m_Settings.m_nEngineOnSoundBankId = value; }; + void SetEngineOffSoundBankID(short value) noexcept override { m_Settings.m_nEngineOffSoundBankId = value; }; + void SetBassSetting(char value) noexcept override { m_Settings.m_nBassSetting = value; }; + void SetBassEq(float value) noexcept override { m_Settings.m_fBassEq = value; }; + void SetFieldC(float value) noexcept override { m_Settings.field_C = value; }; + void SetHornTon(char value) noexcept override { m_Settings.m_nHornToneSoundInBank = value; }; + void SetHornHign(float value) noexcept override { m_Settings.m_fHornHigh = value; }; + void SetEngineUpgrade(char value) noexcept override { m_Settings.m_EngineUpgrade = value; }; + void SetDoorSound(char value) noexcept override { m_Settings.m_nDoorSound = value; }; + void SetRadioNum(char value) noexcept override { m_Settings.m_nRadioID = value; }; + void SetRadioType(char value) noexcept override { m_Settings.m_nRadioType = value; }; + void SetVehicleTypeForAudio(char value) noexcept override { m_Settings.m_nVehTypeForAudio = value; }; + void SetHornVolumeDelta(float value) noexcept override { m_Settings.m_fHornVolumeDelta = value; }; + +private: + tVehicleAudioSettings m_Settings; +}; diff --git a/Client/game_sa/CVehicleAudioSettingsManagerSA.cpp b/Client/game_sa/CVehicleAudioSettingsManagerSA.cpp new file mode 100644 index 0000000000..a47cdeed00 --- /dev/null +++ b/Client/game_sa/CVehicleAudioSettingsManagerSA.cpp @@ -0,0 +1,68 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CVehicleAudioSettingsEntry.cpp + * PURPOSE: Implementation file for vehicle audio settings manager class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "CVehicleAudioSettingsManagerSA.h" +#include + +const auto (&ORIGINAL_AUDIO_SETTINGS)[VEHICLES_COUNT] = *reinterpret_cast(0x860AF0); +tVehicleAudioSettings const * pNextVehicleAudioSettings = nullptr; + +CVehicleAudioSettingsManagerSA::CVehicleAudioSettingsManagerSA() +{ + ResetAudioSettingsData(); +} + +std::unique_ptr CVehicleAudioSettingsManagerSA::CreateVehicleAudioSettingsData(uint32_t modelId) +{ + auto settings = std::make_unique(); + const auto& fromSetting = GetVehicleModelAudioSettingsData(modelId); + settings->Assign(fromSetting); + return settings; +} + +CVehicleAudioSettingsEntry& CVehicleAudioSettingsManagerSA::GetVehicleModelAudioSettingsData(uint32_t modelId) noexcept +{ + return m_modelEntrys[GetVehicleModelAudioSettingsID(modelId)]; +} + +void CVehicleAudioSettingsManagerSA::SetNextSettings(CVehicleAudioSettingsEntry const* pSettings) noexcept +{ + pNextVehicleAudioSettings = &static_cast(pSettings)->GetInterface(); +} + +void CVehicleAudioSettingsManagerSA::SetNextSettings(uint32_t modelId) noexcept +{ + pNextVehicleAudioSettings = &m_modelEntrys[GetVehicleModelAudioSettingsID(modelId)].GetInterface(); +} + +void CVehicleAudioSettingsManagerSA::ResetModelSettings(uint32_t modelId) noexcept +{ + size_t index = GetVehicleModelAudioSettingsID(modelId); + m_modelEntrys[index].Assign(ORIGINAL_AUDIO_SETTINGS[index]); +} + +void CVehicleAudioSettingsManagerSA::ResetAudioSettingsData() noexcept +{ + for (size_t i = 0; i < VEHICLES_COUNT; i++) + m_modelEntrys[i].Assign(ORIGINAL_AUDIO_SETTINGS[i]); +} + +void CVehicleAudioSettingsManagerSA::StaticSetHooks() noexcept +{ + // Replace + // 8D 34 B5 F0 0A 86 00 ; lea esi, _VehicleAudioProperties.m_eVehicleSoundType[esi*4] + // to + // 8b 35 XX XX XX XX ; mov esi, [pNextVehicleAudioSettings] + // 90 ; nop + MemCpy((void*)0x4F77CA, "\x8B\x35\x00\x00\x00\x00\x90", 7); + MemPut(0x4F77CA + 2, (std::uint32_t)&pNextVehicleAudioSettings); +} diff --git a/Client/game_sa/CVehicleAudioSettingsManagerSA.h b/Client/game_sa/CVehicleAudioSettingsManagerSA.h new file mode 100644 index 0000000000..ddd1514095 --- /dev/null +++ b/Client/game_sa/CVehicleAudioSettingsManagerSA.h @@ -0,0 +1,43 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CVehicleAudioSettingsManagerSA.h + * PURPOSE: Header file for vehicle audio settings manager class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include "CVehicleAudioSettingsEntrySA.h" +#include "CAEVehicleAudioEntitySA.h" +#include + +constexpr size_t VEHICLES_COUNT = 212; + +class CVehicleAudioSettingsManagerSA final : public CVehicleAudioSettingsManager +{ +public: + CVehicleAudioSettingsManagerSA(); + + std::unique_ptr CreateVehicleAudioSettingsData(uint32_t modelId) override; + CVehicleAudioSettingsEntry& GetVehicleModelAudioSettingsData(uint32_t modelId) noexcept override; + + void ResetModelSettings(uint32_t modelId) noexcept override; + void ResetAudioSettingsData() noexcept override; + + void SetNextSettings(CVehicleAudioSettingsEntry const* pSettings) noexcept override; + void SetNextSettings(uint32_t modelId) noexcept override; + + static void StaticSetHooks() noexcept; + +private: + size_t GetVehicleModelAudioSettingsID(uint32_t modelId) const noexcept { return modelId - 400; }; + +private: + // Array with the model audio settings entries + std::array m_modelEntrys; +}; diff --git a/Client/game_sa/CVehicleSA.cpp b/Client/game_sa/CVehicleSA.cpp index 1d656c5374..b43292b69f 100644 --- a/Client/game_sa/CVehicleSA.cpp +++ b/Client/game_sa/CVehicleSA.cpp @@ -2381,3 +2381,16 @@ bool CVehicleSA::SetWindowOpenFlagState(unsigned char ucWindow, bool bState) } return bReturn; } + +void CVehicleSA::ReinitAudio() +{ + auto* audioInterface = m_pVehicleAudioEntity->GetInterface(); + + audioInterface->TerminateAudio(); + audioInterface->InitAudio(GetVehicleInterface()); + + CPed* pLocalPlayer = pGame->GetPedContext(); + + if (IsPassenger(pLocalPlayer) || GetDriver() == pLocalPlayer) + audioInterface->SoundJoin(); +} diff --git a/Client/game_sa/CVehicleSA.h b/Client/game_sa/CVehicleSA.h index 784c5e4abe..8186d261c8 100644 --- a/Client/game_sa/CVehicleSA.h +++ b/Client/game_sa/CVehicleSA.h @@ -17,6 +17,7 @@ #include "CPhysicalSA.h" #include "CPoolsSA.h" #include "CHandlingManagerSA.h" +#include "CVehicleAudioSettingsManagerSA.h" #include "CDamageManagerSA.h" #include "CDoorSA.h" #include "CColPointSA.h" @@ -35,6 +36,7 @@ struct RwTexture; #define FUNC_CVehicle_GetBaseVehicleType 0x411D50 #define FUNC_CVehicle_IsUpsideDown 0x6D1D90 #define FUNC_CVehicle_SetEngineOn 0x41BDD0 +#define FUNC_CVehicle_IsPassenger 0x6D1BD0 #define FUNC_CTrain_FindPositionOnTrackFromCoors 0x6F6CC0 #define FUNC_CVehicle_QueryPickedUpEntityWithWinch 0x6d3cf0 @@ -282,6 +284,10 @@ class CVehicleSAInterface : public CPhysicalSAInterface ((void(__thiscall*)(CVehicleSAInterface*, RwFrame*, std::uint32_t))0x6D2700)(this, component, state); } + bool IsPassenger(CPedSAInterface* ped) const noexcept { + return ((bool(__thiscall*)(CVehicleSAInterface const*, CPedSAInterface*))0x6D1BD0)(this, ped); + } + CAEVehicleAudioEntitySAInterface m_VehicleAudioEntity; // 312 tHandlingDataSA* pHandlingData; // +900 @@ -477,6 +483,7 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA void SetRailTrack(BYTE ucTrackID); float GetTrainPosition(); void SetTrainPosition(float fPosition, bool bRecalcOnRailDistance = true); + bool IsPassenger(CPed* pPed) noexcept { return GetVehicleInterface()->IsPassenger(pPed->GetPedInterface()); }; void AddVehicleUpgrade(DWORD dwModelID); void RemoveVehicleUpgrade(DWORD dwModelID); @@ -691,6 +698,7 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA bool SetWindowOpenFlagState(unsigned char ucWindow, bool bState); float GetWheelScale() override { return GetVehicleInterface()->m_fWheelScale; } void SetWheelScale(float fWheelScale) override { GetVehicleInterface()->m_fWheelScale = fWheelScale; } + void ReinitAudio(); void UpdateLandingGearPosition(); diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index dc32b143e4..de8b0f242c 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -35,6 +35,7 @@ #include #include "game/CClock.h" #include +#include #include #include "CServerInfo.h" @@ -3490,6 +3491,8 @@ void CClientGame::Event_OnIngame() // Make sure we never get tired g_pGame->GetPlayerInfo()->SetDoesNotGetTired(true); + g_pGame->GetVehicleAudioSettingsManager()->ResetAudioSettingsData(); + // Tell doggy we got the game running WatchDogCompletedSection("L1"); } diff --git a/Client/mods/deathmatch/logic/CClientVehicle.cpp b/Client/mods/deathmatch/logic/CClientVehicle.cpp index 50793fef2d..41d8cfd869 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.cpp +++ b/Client/mods/deathmatch/logic/CClientVehicle.cpp @@ -19,6 +19,7 @@ #include #include #include +#include using std::list; @@ -209,6 +210,8 @@ CClientVehicle::CClientVehicle(CClientManager* pManager, ElementID ID, unsigned // We've not changed the wheel scale m_bWheelScaleChanged = false; m_clientModel = pManager->GetModelManager()->FindModelByID(usModel); + + m_pSoundSettingsEntry = nullptr; } CClientVehicle::~CClientVehicle() @@ -2489,6 +2492,18 @@ void CClientVehicle::Create() if (!m_strRegPlate.empty()) m_pModelInfo->SetCustomCarPlateText(m_strRegPlate.c_str()); + // Prepare audio settings + if (m_pSoundSettingsEntry) + g_pGame->GetVehicleAudioSettingsManager()->SetNextSettings(m_pSoundSettingsEntry.get()); + else + { + uint32_t modelId = m_usModel; + if (!CClientVehicleManager::IsStandardModel(modelId)) + modelId = g_pGame->GetModelInfo(m_usModel)->GetParentID(); + + g_pGame->GetVehicleAudioSettingsManager()->SetNextSettings(m_usModel); + } + // Create the vehicle if (CClientVehicleManager::IsTrainModel(m_usModel)) { @@ -4903,6 +4918,23 @@ bool CClientVehicle::OnVehicleFallThroughMap() return false; } +const CVehicleAudioSettingsEntry& CClientVehicle::GetAudioSettings() const noexcept +{ + if (m_pSoundSettingsEntry) + return *m_pSoundSettingsEntry.get(); + else + return g_pGame->GetVehicleAudioSettingsManager()->GetVehicleModelAudioSettingsData(m_usModel); +} + +CVehicleAudioSettingsEntry& CClientVehicle::GetOrCreateAudioSettings() +{ + if (!m_pSoundSettingsEntry) + m_pSoundSettingsEntry = g_pGame->GetVehicleAudioSettingsManager()->CreateVehicleAudioSettingsData(m_usModel); + + return *m_pSoundSettingsEntry.get(); +} + + bool CClientVehicle::GetDummyPosition(eVehicleDummies dummy, CVector& position) const { if (dummy >= 0 && dummy < VEHICLE_DUMMY_COUNT) @@ -5071,3 +5103,19 @@ CVector CClientVehicle::GetEntryPoint(std::uint32_t entryPointIndex) return entryPoint; } + +void CClientVehicle::ApplyAudioSettings() +{ + if (!m_pVehicle) + return; + + g_pGame->GetVehicleAudioSettingsManager()->SetNextSettings(&GetAudioSettings()); + m_pVehicle->ReinitAudio(); +} + +void CClientVehicle::ResetAudioSettings() +{ + m_pSoundSettingsEntry = nullptr; + ApplyAudioSettings(); +} + diff --git a/Client/mods/deathmatch/logic/CClientVehicle.h b/Client/mods/deathmatch/logic/CClientVehicle.h index a316425b1d..de78ed24ee 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.h +++ b/Client/mods/deathmatch/logic/CClientVehicle.h @@ -16,6 +16,7 @@ class CClientVehicle; #include #include #include +#include #include "CClientCommon.h" #include "CClientCamera.h" @@ -540,6 +541,11 @@ class CClientVehicle : public CClientStreamElement void ResetWheelScale(); bool OnVehicleFallThroughMap(); + const CVehicleAudioSettingsEntry& GetAudioSettings() const noexcept; + CVehicleAudioSettingsEntry& GetOrCreateAudioSettings(); + + void ApplyAudioSettings(); + void ResetAudioSettings(); bool GetDummyPosition(eVehicleDummies dummy, CVector& position) const; bool SetDummyPosition(eVehicleDummies dummy, const CVector& position); @@ -668,6 +674,7 @@ class CClientVehicle : public CClientStreamElement float m_fNitroLevel; char m_cNitroCount; float m_fWheelScale; + std::unique_ptr m_pSoundSettingsEntry; bool m_bChainEngine; bool m_bIsDerailed; diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index d465350561..8a222cda1d 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -959,6 +959,25 @@ ADD_ENUM(ENTITY_TYPE_DUMMY, "dummy") ADD_ENUM(ENTITY_TYPE_NOTINPOOLS, "unknown") IMPLEMENT_ENUM_END("entity-type") + +IMPLEMENT_ENUM_CLASS_BEGIN(eVehicleAudioSettingProperty) +ADD_ENUM(eVehicleAudioSettingProperty::DOOR_SOUND, "door-sound") +ADD_ENUM(eVehicleAudioSettingProperty::ENGINE_OFF_SOUND_BANK_ID, "engine-off-soundbank-id") +ADD_ENUM(eVehicleAudioSettingProperty::ENGINE_ON_SOUND_BANK_ID, "engine-on-soundbank-id") +ADD_ENUM(eVehicleAudioSettingProperty::HORN_HIGH, "horn-high") +ADD_ENUM(eVehicleAudioSettingProperty::HORN_TON, "horn-ton") +ADD_ENUM(eVehicleAudioSettingProperty::HORN_VOLUME_DELTA, "horn-volume-delta") +ADD_ENUM(eVehicleAudioSettingProperty::RADIO_NUM, "radion-num") +ADD_ENUM(eVehicleAudioSettingProperty::RADIO_TYPE, "radio-type") +ADD_ENUM(eVehicleAudioSettingProperty::SOUND_TYPE, "sound-type") +ADD_ENUM(eVehicleAudioSettingProperty::BASS_SETTING, "bass-setting") +ADD_ENUM(eVehicleAudioSettingProperty::BASS_EQ, "bass-eq") +ADD_ENUM(eVehicleAudioSettingProperty::FIELD_C, "field-c") +ADD_ENUM(eVehicleAudioSettingProperty::ENGINE_UPGRADE, "engine-upgrade") +ADD_ENUM(eVehicleAudioSettingProperty::VEHICLE_TYPE_FOR_AUDIO, "vehicle-type-for-audio") +IMPLEMENT_ENUM_CLASS_END("vehicle-audio-setting") + + // // CResource from userdata // diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index 4fbb4fd53f..f7e111d2d5 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -90,7 +90,7 @@ DECLARE_ENUM_CLASS(eModelLoadState); DECLARE_ENUM_CLASS(PreloadAreaOption); DECLARE_ENUM_CLASS(taskType); DECLARE_ENUM(eEntityType); - +DECLARE_ENUM_CLASS(eVehicleAudioSettingProperty); class CRemoteCall; @@ -517,6 +517,11 @@ inline SString GetClassTypeName(CClientVectorGraphic*) return "svg"; } +inline SString GetClassByTypeName(eVehicleAudioSettingProperty) +{ + return "vehicle-audio-setting"; +} + // // CResource from userdata // diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp index f3069f6546..4020a1d5eb 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp @@ -12,6 +12,7 @@ #include "StdInc.h" #include #include +#include #include "lua/CLuaFunctionParser.h" #include @@ -95,6 +96,8 @@ void CLuaVehicleDefs::LoadFunctions() {"getVehicleEntryPoints", ArgumentParser}, {"isVehicleSmokeTrailEnabled", ArgumentParser}, {"getVehicleRotorState", ArgumentParser}, + {"getVehicleModelAudioSettings", ArgumentParser}, + {"getVehicleAudioSettings", ArgumentParser}, // Vehicle set funcs {"createVehicle", CreateVehicle}, @@ -163,6 +166,10 @@ void CLuaVehicleDefs::LoadFunctions() {"spawnVehicleFlyingComponent", ArgumentParser}, {"setVehicleSmokeTrailEnabled", ArgumentParser}, {"setVehicleRotorState", ArgumentParser}, + {"setVehicleModelAudioSetting", ArgumentParser}, + {"resetVehicleModelAudioSettings", ArgumentParser}, + {"setVehicleAudioSetting", ArgumentParser}, + {"resetVehicleAudioSettings", ArgumentParser}, }; // Add functions @@ -303,6 +310,8 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setModelWheelSize", "setVehicleModelWheelSize"); lua_classfunction(luaVM, "setSmokeTrailEnabled", "setVehicleSmokeTrailEnabled"); lua_classfunction(luaVM, "setRotorState", "setVehicleRotorState"); + lua_classfunction(luaVM, "resetAudioSettings", "resetVehicleAudioSettings"); + lua_classfunction(luaVM, "setAudioSetting", "setVehicleAudioSetting"); lua_classfunction(luaVM, "resetComponentPosition", "resetVehicleComponentPosition"); lua_classfunction(luaVM, "resetComponentRotation", "resetVehicleComponentRotation"); @@ -362,6 +371,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classvariable(luaVM, "turnVelocity", SetVehicleTurnVelocity, OOP_GetVehicleTurnVelocity); lua_classvariable(luaVM, "wheelScale", "setVehicleWheelScale", "getVehicleWheelScale"); lua_classvariable(luaVM, "rotorState", "setVehicleRotorState", "getVehicleRotorState"); + lua_classvariable(luaVM, "audioSettings", nullptr, "getVehicleAudioSettings"); lua_registerclass(luaVM, "Vehicle", "Element"); } @@ -4257,7 +4267,7 @@ bool CLuaVehicleDefs::BlowVehicle(CClientEntity* entity, std::optional wit { return CStaticFunctionDefinitions::BlowVehicle(*entity, withExplosion); } - + std::variant, 4>> CLuaVehicleDefs::GetVehicleEntryPoints(CClientVehicle* vehicle) { auto entryPointVectors = OOP_GetVehicleEntryPoints(vehicle); @@ -4362,7 +4372,8 @@ bool CLuaVehicleDefs::SpawnVehicleFlyingComponent(CClientVehicle* const vehicle, return vehicle->SpawnFlyingComponent(partNodeIndex, collisionType, removalTime.value_or(-1)); } -bool CLuaVehicleDefs::AddVehicleSirens(CClientVehicle* vehicle, std::uint8_t sirenType, std::uint8_t sirenCount, std::optional enable360, std::optional enableLOSCheck, std::optional enableRandomiser, std::optional enableSilent) noexcept +bool CLuaVehicleDefs::AddVehicleSirens(CClientVehicle* vehicle, std::uint8_t sirenType, std::uint8_t sirenCount, std::optional enable360, + std::optional enableLOSCheck, std::optional enableRandomiser, std::optional enableSilent) noexcept { eClientVehicleType vehicleType = vehicle->GetVehicleType(); @@ -4391,7 +4402,7 @@ bool CLuaVehicleDefs::SetSmokeTrailEnabled(CClientVehicle* vehicle, bool state) std::uint16_t model = vehicle->GetModel(); if (model != 512 && model != 513) throw LuaFunctionError("Invaild model ID"); - + vehicle->SetSmokeTrailEnabled(state); return true; } @@ -4414,3 +4425,194 @@ bool CLuaVehicleDefs::GetVehicleRotorState(CClientVehicle* vehicle) noexcept { return vehicle->GetVehicleRotorState(); } + +bool CLuaVehicleDefs::SetVehicleModelAudioSetting(const uint32_t uiModel, const eVehicleAudioSettingProperty eProperty, float varValue) +{ + if (!CClientVehicleManager::IsStandardModel(uiModel)) + throw std::invalid_argument("Cannot change audio setting for allocated vechiles"); + + CVehicleAudioSettingsEntry& pModelSettings = g_pGame->GetVehicleAudioSettingsManager()->GetVehicleModelAudioSettingsData(uiModel); + + switch (eProperty) + { + case eVehicleAudioSettingProperty::DOOR_SOUND: + pModelSettings.SetDoorSound(varValue); + break; + case eVehicleAudioSettingProperty::ENGINE_OFF_SOUND_BANK_ID: + pModelSettings.SetEngineOffSoundBankID(varValue); + break; + case eVehicleAudioSettingProperty::ENGINE_ON_SOUND_BANK_ID: + pModelSettings.SetEngineOnSoundBankID(varValue); + break; + case eVehicleAudioSettingProperty::HORN_HIGH: + pModelSettings.SetHornHign(varValue); + break; + case eVehicleAudioSettingProperty::HORN_TON: + pModelSettings.SetHornTon(varValue); + break; + case eVehicleAudioSettingProperty::HORN_VOLUME_DELTA: + pModelSettings.SetHornVolumeDelta(varValue); + break; + case eVehicleAudioSettingProperty::RADIO_NUM: + pModelSettings.SetRadioNum(varValue); + break; + case eVehicleAudioSettingProperty::RADIO_TYPE: + pModelSettings.SetRadioType(varValue); + break; + case eVehicleAudioSettingProperty::SOUND_TYPE: + pModelSettings.SetSoundType((eVehicleSoundType)(int)(varValue)); + break; + case eVehicleAudioSettingProperty::BASS_SETTING: + pModelSettings.SetBassSetting(varValue); + break; + case eVehicleAudioSettingProperty::BASS_EQ: + pModelSettings.SetBassEq(varValue); + break; + case eVehicleAudioSettingProperty::FIELD_C: + pModelSettings.SetFieldC(varValue); + break; + case eVehicleAudioSettingProperty::ENGINE_UPGRADE: + pModelSettings.SetEngineUpgrade(varValue); + break; + case eVehicleAudioSettingProperty::VEHICLE_TYPE_FOR_AUDIO: + pModelSettings.SetVehicleTypeForAudio(varValue); + break; + default: + return false; + } + + return true; +} + +bool CLuaVehicleDefs::ResetVehicleModelAudioSettings(const uint32_t uiModel) +{ + if (!CClientVehicleManager::IsStandardModel(uiModel)) + throw std::invalid_argument("Cannot change audio setting for allocated vechiles"); + + g_pGame->GetVehicleAudioSettingsManager()->ResetModelSettings(uiModel); +} + +bool CLuaVehicleDefs::SetVehicleAudioSetting(CClientVehicle* pVehicle, const eVehicleAudioSettingProperty eProperty, float varValue) +{ + CVehicleAudioSettingsEntry& pModelSettings = pVehicle->GetOrCreateAudioSettings(); + + switch (eProperty) + { + case eVehicleAudioSettingProperty::DOOR_SOUND: + pModelSettings.SetDoorSound(varValue); + break; + case eVehicleAudioSettingProperty::ENGINE_OFF_SOUND_BANK_ID: + pModelSettings.SetEngineOffSoundBankID(varValue); + break; + case eVehicleAudioSettingProperty::ENGINE_ON_SOUND_BANK_ID: + pModelSettings.SetEngineOnSoundBankID(varValue); + break; + case eVehicleAudioSettingProperty::HORN_HIGH: + pModelSettings.SetHornHign(varValue); + break; + case eVehicleAudioSettingProperty::HORN_TON: + pModelSettings.SetHornTon(varValue); + break; + case eVehicleAudioSettingProperty::HORN_VOLUME_DELTA: + pModelSettings.SetHornVolumeDelta(varValue); + break; + case eVehicleAudioSettingProperty::RADIO_NUM: + pModelSettings.SetRadioNum(varValue); + break; + case eVehicleAudioSettingProperty::RADIO_TYPE: + pModelSettings.SetRadioType(varValue); + break; + case eVehicleAudioSettingProperty::SOUND_TYPE: + pModelSettings.SetSoundType((eVehicleSoundType)(int)(varValue)); + break; + case eVehicleAudioSettingProperty::BASS_SETTING: + pModelSettings.SetBassSetting(varValue); + break; + case eVehicleAudioSettingProperty::BASS_EQ: + pModelSettings.SetBassEq(varValue); + break; + case eVehicleAudioSettingProperty::FIELD_C: + pModelSettings.SetFieldC(varValue); + break; + case eVehicleAudioSettingProperty::ENGINE_UPGRADE: + pModelSettings.SetEngineUpgrade(varValue); + break; + case eVehicleAudioSettingProperty::VEHICLE_TYPE_FOR_AUDIO: + pModelSettings.SetVehicleTypeForAudio(varValue); + break; + default: + return false; + } + + pVehicle->ApplyAudioSettings(); + + return true; +} + +bool CLuaVehicleDefs::ResetVehicleAudioSettings(CClientVehicle* pVehicle) +{ + pVehicle->ResetAudioSettings(); + return true; +} + +std::unordered_map CLuaVehicleDefs::GetVehicleModelAudioSettings(uint32_t uiModel) +{ + if (!CClientVehicleManager::IsStandardModel(uiModel)) + { + auto* modelInfo = g_pGame->GetModelInfo(uiModel); + + if (!modelInfo) + throw std::invalid_argument("Invalid model id"); + + uiModel = modelInfo->GetParentID(); + + if (!CClientVehicleManager::IsStandardModel(uiModel)) + throw std::invalid_argument("Invalid model id"); + } + + CVehicleAudioSettingsEntry& pEntry = g_pGame->GetVehicleAudioSettingsManager()->GetVehicleModelAudioSettingsData(uiModel); + + std::unordered_map output; + + output["sound-type"] = (int)pEntry.GetSoundType(); + output["engine-on-soundbank-id"] = pEntry.GetEngineOnSoundBankID(); + output["engine-off-soundbank-id"] = pEntry.GetEngineOffSoundBankID(); + output["bass-setting"] = pEntry.GetBassSetting(); + output["bass-eq"] = pEntry.GetBassEq(); + output["field-c"] = pEntry.GetFieldC(); + output["horn-ton"] = pEntry.GetHornTon(); + output["horn-high"] = pEntry.GetHornHign(); + output["engine-upgrade"] = pEntry.GetEngineUpgrade(); + output["door-sound"] = pEntry.GetDoorSound(); + output["radio-num"] = pEntry.GetRadioNum(); + output["radio-type"] = pEntry.GetRadioType(); + output["vehicle-type-for-audio"] = pEntry.GetVehicleTypeForAudio(); + output["horn-volume-delta"] = pEntry.GetHornVolumeDelta(); + + return output; +} + +std::unordered_map CLuaVehicleDefs::GetVehicleAudioSettings(CClientVehicle* pVehicle) +{ + const CVehicleAudioSettingsEntry& pEntry = pVehicle->GetAudioSettings(); + + std::unordered_map output; + + output["sound-type"] = (int)pEntry.GetSoundType(); + output["engine-on-soundbank-id"] = pEntry.GetEngineOnSoundBankID(); + output["engine-off-soundbank-id"] = pEntry.GetEngineOffSoundBankID(); + output["bass-setting"] = pEntry.GetBassSetting(); + output["bass-eq"] = pEntry.GetBassEq(); + output["field-c"] = pEntry.GetFieldC(); + output["horn-ton"] = pEntry.GetHornTon(); + output["horn-high"] = pEntry.GetHornHign(); + output["engine-upgrade"] = pEntry.GetEngineUpgrade(); + output["door-sound"] = pEntry.GetDoorSound(); + output["radio-num"] = pEntry.GetRadioNum(); + output["radio-type"] = pEntry.GetRadioType(); + output["vehicle-type-for-audio"] = pEntry.GetVehicleTypeForAudio(); + output["horn-volume-delta"] = pEntry.GetHornVolumeDelta(); + + return output; +} + diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h index cf113ca8c6..346ebd5739 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h @@ -171,6 +171,13 @@ class CLuaVehicleDefs : public CLuaDefs static bool AddVehicleSirens(CClientVehicle* vehicle, std::uint8_t sirenType, std::uint8_t sirenCount, std::optional enable360, std::optional enableLOSCheck, std::optional enableRandomiser, std::optional enableSilent) noexcept; static bool RemoveVehicleSirens(CClientVehicle* vehicle) noexcept; + + static bool SetVehicleModelAudioSetting(const uint32_t uiModel, const eVehicleAudioSettingProperty eProperty, float varValue); + static bool ResetVehicleModelAudioSettings(const uint32_t uiModel); + static bool SetVehicleAudioSetting(CClientVehicle* pVehicle, const eVehicleAudioSettingProperty eProperty, float varValue); + static bool ResetVehicleAudioSettings(CClientVehicle* pVehicle); + static std::unordered_map GetVehicleModelAudioSettings(uint32_t uiModel); + static std::unordered_map GetVehicleAudioSettings(CClientVehicle* pVehicle); // Components LUA_DECLARE(SetVehicleComponentPosition); diff --git a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp index 88b0b11eb8..dc9eaa887c 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp @@ -58,55 +58,6 @@ static void _declspec(naked) HOOK_CDamageManager__ProgressDoorDamage() } } -////////////////////////////////////////////////////////////////////////////////////////// -// -// CAEVehicleAudioEntity::Initialise -// -// This hook setup a audio interfeace for custom vehicles -// -////////////////////////////////////////////////////////////////////////////////////////// -// 0x4F77C1 | 8D 34 C0 | lea esi, [eax + eax * 8] -// 0x4F77C4 | 8D BD 80 00 00 00 | lea edi, [ebp + 80h] -// 0x4F77CA | 8D 34 B5 F0 0A 86 00 | lea esi, _VehicleAudioProperties.m_eVehicleSoundType[esi * 4] -// 0x4F77D1 | B9 09 00 00 00 | mov ecx,9 -// 0x4F77D6 | F3 A5 | rep movsd -// 0x4F77D8 | 8B CA | mov ecx, edx; - -static CVehicleSAInterface* pRequestSoundSettingsVehicle = 0; -tVehicleAudioSettings* pVehicleAudioSettings = nullptr; - -static tVehicleAudioSettings* __fastcall getVehicleSoundSettings() -{ - ushort usModel = pRequestSoundSettingsVehicle->m_nModelIndex; - // Check if it is a custom model - if (usModel < VT_LANDSTAL || usModel >= VT_MAX) - usModel = pGameInterface->GetModelInfo(usModel)->GetParentID(); - return (tVehicleAudioSettings*)0x860AF0 + (usModel - VT_LANDSTAL); -} - -#define HOOKPOS_CAEVehicleAudioEntity__Initialise 0x4F77C1 -#define HOOKSIZE_CAEVehicleAudioEntity__Initialise 0x10 -static DWORD CONTINUE_CAEVehicleAudioEntity__Initialise = 0x4F77D1; - -static void _declspec(naked) HOOK_CAEVehicleAudioEntity__Initialise() -{ - _asm - { - pushad - mov pRequestSoundSettingsVehicle, edx - } - - pVehicleAudioSettings = getVehicleSoundSettings(); - - _asm - { - popad - lea edi, [ebp + 80h] - mov esi, pVehicleAudioSettings - jmp CONTINUE_CAEVehicleAudioEntity__Initialise - } -} - ////////////////////////////////////////////////////////////////////////////////////////// // // CMultiplayerSA::InitHooks_Vehicles @@ -117,5 +68,4 @@ static void _declspec(naked) HOOK_CAEVehicleAudioEntity__Initialise() void CMultiplayerSA::InitHooks_Vehicles() { EZHookInstall(CDamageManager__ProgressDoorDamage); - EZHookInstall(CAEVehicleAudioEntity__Initialise); } diff --git a/Client/sdk/game/CGame.h b/Client/sdk/game/CGame.h index 33c6c7b25c..6ff324df86 100644 --- a/Client/sdk/game/CGame.h +++ b/Client/sdk/game/CGame.h @@ -69,6 +69,7 @@ class CWorld; class CIplStore; class CBuildingRemoval; class CRenderer; +class CVehicleAudioSettingsManager; enum eEntityType; enum ePedPieceTypes; @@ -152,6 +153,8 @@ class __declspec(novtable) CGame virtual CBuildingRemoval* GetBuildingRemoval() = 0; virtual CRenderer* GetRenderer() const noexcept = 0; + virtual CVehicleAudioSettingsManager* GetVehicleAudioSettingsManager() const noexcept = 0; + virtual CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD) = 0; virtual CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false) = 0; diff --git a/Client/sdk/game/CVehicle.h b/Client/sdk/game/CVehicle.h index c01518b1f3..43f0345ae8 100644 --- a/Client/sdk/game/CVehicle.h +++ b/Client/sdk/game/CVehicle.h @@ -327,5 +327,5 @@ class CVehicle : public virtual CPhysical virtual bool SetDummyPosition(eVehicleDummies dummy, const CVector& position) = 0; virtual const CVector* GetDummyPositions() const = 0; - + virtual void ReinitAudio() = 0; }; diff --git a/Client/sdk/game/CVehicleAudioSettingsEntry.h b/Client/sdk/game/CVehicleAudioSettingsEntry.h new file mode 100644 index 0000000000..e740667a3e --- /dev/null +++ b/Client/sdk/game/CVehicleAudioSettingsEntry.h @@ -0,0 +1,53 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/game/CHandlingEntry.h + * PURPOSE: Vehicle handling entry interface + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include "Common.h" + +class CVehicleAudioSettingsEntry +{ +public: + // Destructor + virtual ~CVehicleAudioSettingsEntry(){} + + // Get + virtual eVehicleSoundType GetSoundType() const noexcept = 0; + virtual short GetEngineOnSoundBankID() const noexcept = 0; + virtual short GetEngineOffSoundBankID() const noexcept = 0; + virtual char GetBassSetting() const noexcept = 0; + virtual float GetBassEq() const noexcept = 0; + virtual float GetFieldC() const noexcept = 0; + virtual char GetHornTon() const noexcept = 0; + virtual float GetHornHign() const noexcept = 0; + virtual char GetEngineUpgrade() const noexcept = 0; + virtual char GetDoorSound() const noexcept = 0; + virtual char GetRadioNum() const noexcept = 0; + virtual char GetRadioType() const noexcept = 0; + virtual char GetVehicleTypeForAudio() const noexcept = 0; + virtual float GetHornVolumeDelta() const noexcept = 0; + + // Set + virtual void SetSoundType(eVehicleSoundType value) noexcept = 0; + virtual void SetEngineOnSoundBankID(short value) noexcept = 0; + virtual void SetEngineOffSoundBankID(short value) noexcept = 0; + virtual void SetBassSetting(char value) noexcept = 0; + virtual void SetBassEq(float value) noexcept = 0; + virtual void SetFieldC(float value) noexcept = 0; + virtual void SetHornTon(char value) noexcept = 0; + virtual void SetHornHign(float value) noexcept = 0; + virtual void SetEngineUpgrade(char value) noexcept = 0; + virtual void SetDoorSound(char value) noexcept = 0; + virtual void SetRadioNum(char value) noexcept = 0; + virtual void SetRadioType(char value) noexcept = 0; + virtual void SetVehicleTypeForAudio(char value) noexcept = 0; + virtual void SetHornVolumeDelta(float value) noexcept = 0; +}; diff --git a/Client/sdk/game/CVehicleAudioSettingsManager.h b/Client/sdk/game/CVehicleAudioSettingsManager.h new file mode 100644 index 0000000000..a34864cb99 --- /dev/null +++ b/Client/sdk/game/CVehicleAudioSettingsManager.h @@ -0,0 +1,26 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/game/CVehicleAudioSettingsManager.h + * PURPOSE: Vehicle audio manager interface + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include "CVehicleAudioSettingsEntry.h" + +class CVehicleAudioSettingsManager +{ +public: + virtual std::unique_ptr CreateVehicleAudioSettingsData(uint32_t modelId) = 0; + virtual CVehicleAudioSettingsEntry& GetVehicleModelAudioSettingsData(uint32_t modelId) noexcept = 0; + + virtual void ResetModelSettings(uint32_t modelId) noexcept = 0; + virtual void ResetAudioSettingsData() noexcept = 0; + virtual void SetNextSettings(CVehicleAudioSettingsEntry const* pSettings) noexcept = 0; + virtual void SetNextSettings(uint32_t modelId) noexcept = 0; +}; diff --git a/Client/sdk/game/Common.h b/Client/sdk/game/Common.h index be4d18a643..82e6e499b7 100644 --- a/Client/sdk/game/Common.h +++ b/Client/sdk/game/Common.h @@ -1443,6 +1443,37 @@ enum eObjectProperty OBJECT_PROPERTY_MAX, }; +enum class eVehicleSoundType : char +{ + CAR = 0, + MOTORCYCLE, + BICYCLE, + BOAT, + HELI, + PLANE, + TRAIN = 8, + TRAILLER, + SPECIAL, +}; + +enum class eVehicleAudioSettingProperty +{ + SOUND_TYPE, + ENGINE_ON_SOUND_BANK_ID, + ENGINE_OFF_SOUND_BANK_ID, + BASS_SETTING, + BASS_EQ, + FIELD_C, + HORN_TON, + ENGINE_UPGRADE, + DOOR_SOUND, + RADIO_NUM, + RADIO_TYPE, + VEHICLE_TYPE_FOR_AUDIO, + HORN_VOLUME_DELTA, + HORN_HIGH, +}; + namespace eObjectGroup { enum Modifiable diff --git a/Server/mods/deathmatch/logic/CGame.h b/Server/mods/deathmatch/logic/CGame.h index a911a5fea9..dd02c44f3e 100644 --- a/Server/mods/deathmatch/logic/CGame.h +++ b/Server/mods/deathmatch/logic/CGame.h @@ -105,6 +105,7 @@ class CWaterManager; class CTrainTrackManager; class CWeaponStatManager; class CBuildingRemovalManager; +class CVehicleSoundSettingsManager; class CCustomWeaponManager; class COpenPortsTester;