`CAEVehicleAudioEntity` (#892)

* `CAEVehicleAudioEntity`
* Refactor `CAESound`
* Refactor some other audio stuff
This commit is contained in:
Pirulax 2025-06-01 13:39:11 +02:00 committed by GitHub
parent f9147b8f4d
commit cb7301b575
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
137 changed files with 9754 additions and 4776 deletions

View File

@ -3,7 +3,7 @@ AlignAfterOpenBracket: BlockIndent
AlignArrayOfStructures: Left
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: false
AcrossEmptyLines: true
AcrossComments: false
AlignCompound: false
PadOperators: false

View File

@ -194,6 +194,24 @@ void SAFE_RELEASE(T*& ptr) { // DirectX stuff `Release()`
}
}
// std::format support for enums
// either using `EnumToString`, or using the enum name and value as a fallback
template<typename Enum>
requires std::is_enum_v<Enum>
struct std::formatter<Enum> : std::formatter<std::string> {
auto format(Enum e, format_context& ctx) const {
if constexpr (requires { EnumToString(e); }) {
if (const auto name = EnumToString(e)) {
return formatter<string>::format(*name, ctx);
}
}
return formatter<string>::format(
std::format("{} ({})", typeid(Enum).name(), static_cast<std::underlying_type_t<Enum>>(e)),
ctx
);
}
};
#define _IGNORED_
#define _CAN_BE_NULL_

View File

@ -52,9 +52,11 @@ endif()
add_library(${RE_PROJECT_LIB_NAME} MODULE ${SOURCE_FILES_LIST})
target_link_options(${RE_PROJECT_LIB_NAME} PRIVATE
"$<$<CXX_COMPILER_ID:MSVC>:/INCREMENTAL>"
)
target_compile_options(${RE_PROJECT_LIB_NAME} PRIVATE
"$<$<CXX_COMPILER_ID:MSVC>:/MP;/Zc:preprocessor;/W3;/wd4251;/wd4275;/wd4996;/wd26495;/wd26812;/wd28159>"
"$<$<CXX_COMPILER_ID:MSVC>:/MP;/Zc:preprocessor;/ZI;/W3;/wd4251;/wd4275;/wd4996;/wd26495;/wd26812;/wd28159>"
"$<$<OR:$<CXX_COMPILER_ID:Clang,GCC>,$<CXX_COMPILER_ID:GNU>>:-Wall;>"
)
set_target_properties(${RE_PROJECT_LIB_NAME}

View File

@ -424,9 +424,10 @@
#include "Entity/Vehicle/Train.h"
#include "Entity/Vehicle/Vehicle.h"
#include "Audio/config/eAudioBank.h"
#include "Audio/config/eAudioSlot.h"
#include "Audio/config/eSFX.h"
#include "Fx\eFxInfoType.h"
#include "Fx\FxManager.h"
#include "Fx\FxPrtMult.h"
#include "Fx\Fx.h"
#include "Fx/eFxInfoType.h"
#include "Fx/FxManager.h"

View File

@ -13,6 +13,9 @@
#include "platform/win/WinPlatform.h"
#include "Enums/eGameState.h"
#include "Base.h"
void AppInjectHooks() {
RH_ScopedCategory("App");
RH_ScopedNamespaceName("App");
@ -32,6 +35,13 @@ void AppInjectHooks() {
AppLightInjectHooks();
}
void ChangeGameStateTo(eGameState newgs) {
if (gGameState != newgs) {
//NOTSA_LOG_DEBUG("GS Change: `{}` to `{}`", (eGameState)(gGameState), (eGameState)(newgs)); // doesn't compile???
gGameState = newgs;
}
};
// 0x53D690
bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha) {
RwRGBA TopColor{ (uint8)TopRed, (uint8)TopGreen, (uint8)TopBlue, (uint8)Alpha };

View File

@ -19,12 +19,7 @@ void AppInjectHooks();
static inline int32& gGameState = *(int32*)0xC8D4C0;
//! NOTSA (We wanna have this wrapper for debugging)
inline void ChangeGameStateTo(eGameState newgs) {
if (gGameState != newgs) {
NOTSA_LOG_DEBUG("GS Change: `{}` to `{}`", EnumToString((eGameState)gGameState), EnumToString(newgs));
gGameState = newgs;
}
};
void ChangeGameStateTo(eGameState newgs);
static inline bool& ForegroundApp = *(bool*)0x8D621C;

View File

@ -14,6 +14,7 @@ public:
//! Construct from a pre-compressed value
//! Be (very) careful when using this constructor, as mixing up this and the float version will cause bugs...
// TODO: Maybe use tag-based constructors, because this is kinda bug-prone....
template<std::integral Y>
explicit constexpr FixedFloat(Y x) : value(x) {}

View File

@ -4,34 +4,52 @@
#include <cstdint>
namespace notsa {
//! Store enums (of type `Enum`) in a given integral type.
//! Useful in cases where the class originally used a width
//! different to the enums underlaying type.
//! WEnum just sounded like a cool name... Venom.. WEnum, idk
/*!
* Store enums (of type `Enum`) in a given integral type.
* Useful in cases where the class originally used a width
* different to the enums underlaying type.
* WEnum just sounded like a cool name... Venom.. WEnum, idk
*/
template<typename Enum, typename StoreAs>
requires(std::is_integral_v<StoreAs>)
struct WEnum {
StoreAs m_Value;
//! Implicitly convert from the enum value
WEnum(Enum e = {}) : m_Value{static_cast<StoreAs>(e)} { }
constexpr WEnum(Enum e = {}) noexcept : m_Value{static_cast<StoreAs>(e)} { }
//! Implicitly convert from another WEnum for the same enum
template<typename Y>
WEnum(WEnum<Enum, Y> other) : WEnum{static_cast<Enum>(other)} { }
constexpr WEnum(WEnum<Enum, Y> other) noexcept : WEnum{static_cast<Enum>(other)} { }
//! Implicitly convert back to the underlaying `Enum` type
operator Enum() const { return static_cast<Enum>(m_Value); }
constexpr operator Enum() const noexcept { return static_cast<Enum>(m_Value); }
//! Implicitly cast to underlaying type ref, pointer
explicit operator StoreAs*() { return &m_Value; }
explicit operator StoreAs&() { return m_Value; }
constexpr explicit operator StoreAs*() noexcept { return &m_Value; }
constexpr explicit operator StoreAs&() noexcept { return m_Value; }
//! Use this in cases you want to cast to an int (for cout or something)
Enum get() const { return static_cast<Enum>(m_Value); }
constexpr Enum get() const noexcept { return static_cast<Enum>(m_Value); }
//! Get the underlaying value
StoreAs get_underlying() const { return m_Value; }
constexpr StoreAs get_underlying() const noexcept { return m_Value; }
//! Get underlaying value as a reference
constexpr StoreAs& get_underlying_ref() noexcept { return m_Value; }
};
// std::format support for `WEnum`
template<typename Enum, typename StoreAs>
struct std::formatter<WEnum<Enum, StoreAs>> : std::formatter<std::string> {
auto format(auto e, format_context& ctx) const {
if constexpr (requires { EnumToString(e.get()); }) {
if (const auto name = EnumToString(e.get())) {
return formatter<string>::format(*name, ctx);
}
}
return formatter<string>::format(std::format("{} ({})", typeid(Enum).name(), e.get_underlying()), ctx);
}
};
template<typename E>

View File

@ -5,6 +5,7 @@
#include <Vector.h>
#include <unordered_map>
#include "Base.h"
#include <game_sa/Timer.h>
namespace notsa {
//template<typename TChar, size_t N>
@ -401,4 +402,45 @@ F wrap(F x, F min, F max) {
}
return (x < 0 ? max : min) + std::fmod(x, max - min);
}
template<std::floating_point F>
F step_up_to(F x, F to, F step, bool useTimeStep = false) {
return std::min<F>(to, x + (useTimeStep ? std::pow(step, CTimer::GetTimeStep()) : step));
}
template<std::floating_point F>
F step_down_to(F x, F to, F step, bool useTimeStep = false) {
return std::max<F>(to, x - (useTimeStep ? std::pow(step, CTimer::GetTimeStep()) : step));
}
/*!
* @brief Step `x` towards `to` in steps
* @brief This function is useful for interpolating changing values
* @arg stepUp The step size when `x` is less than `to`
* @arg stepDown The step size when `x` is greater than `to`
* @arg useTimeStep Whether to use timestep for calculating the correct step size (Avoids FPS related issues somewhat)
*********/
template<std::floating_point F>
F step_to(F x, F to, F stepUp, F stepDown, bool useTimeStep = false) {
assert(stepDown > 0.f);
assert(stepUp > 0.f);
if (x == to) {
return to;
}
return x < to
? step_up_to<F>(x, to, stepUp, useTimeStep)
: step_down_to<F>(x, to, stepUp, useTimeStep);
}
// Step `x` towards `to` in steps
template<std::floating_point F>
F step_to(F x, F to, F step, bool useTimeStep = false) {
return step_to<F>(x, to, step, step, useTimeStep);
}
//! Range of a specific type
//! See: https://stackoverflow.com/a/64228354/15363969
template <typename R, typename T>
concept range_of = rng::range<R> && std::same_as<rng::range_value_t<R>, T>;
};

View File

@ -21,7 +21,7 @@ public:
float m_fBlendAmount;
float m_fBlendDelta;
float m_fCurrentTime;
float m_fSpeed;
float m_Speed;
float fTimeStep;
int16 m_nAnimId;
uint16 m_nFlags;

View File

@ -47,22 +47,28 @@ float CAEAudioEnvironment::GetDistanceAttenuation(float dist) {
// 0x4D7F60
float CAEAudioEnvironment::GetDirectionalMikeAttenuation(const CVector& soundDir) {
// https://en.wikipedia.org/wiki/Cutoff_frequency
static constexpr float fCutoffFrequency = 0.70710678118F; // sqrt(0.5F);
static constexpr float fAttenuationMult = -6.0F;
static constexpr float CUT_OFF_FREQ = 0.70710678118F; // sqrt(0.5F);
static constexpr float ATTENUATION_FACTOR = -6.0F;
CVector vecDir = soundDir;
vecDir.Normalise();
// BUG? Seems weird that it uses just single axis,
// seems like it should be normalized dot product
// with for example Camera direction,
// to work the same way regardless of direction
const auto freq = soundDir.Dot({ 0.f, 1.f, 0.f });
// BUG? Seems weird that it uses just single axis, seems like it should be normalized Dot product with for example Camera direction, to work the same way regardless of
// direction
const auto freq = vecDir.y; // (vecDir.x + vecDir.z) * 0.0F + vecDir.y
if (fCutoffFrequency == -1.0F || freq >= fCutoffFrequency)
if (CUT_OFF_FREQ == -1.0F) {
return 0.0F;
}
if (freq <= -fCutoffFrequency)
return fAttenuationMult;
if (freq >= CUT_OFF_FREQ) {
return 0.f;
}
return (1.0F - invLerp(-fCutoffFrequency, fCutoffFrequency, freq)) * fAttenuationMult;
if (freq <= -CUT_OFF_FREQ) {
return ATTENUATION_FACTOR;
}
return (1.0f - invLerp(-CUT_OFF_FREQ, CUT_OFF_FREQ, freq)) * ATTENUATION_FACTOR;
}
// 0x4D8010

View File

@ -66,13 +66,16 @@ bool CAEAudioUtility::ResolveProbability(float p) {
}
// 0x4d9d90
float CAEAudioUtility::GetPiecewiseLinear(float x, int16 dataCount, float (*data)[2]) {
if (x >= data[dataCount - 1][0])
float CAEAudioUtility::GetPiecewiseLinear(float x, int16 dataCount, const float (*data)[2]) {
assert(dataCount >= 1);
if (x >= data[dataCount - 1][0]) {
return data[dataCount - 1][1];
if (x <= data[0][0])
}
if (x <= data[0][0]) {
return data[0][1];
}
assert(dataCount >= 2);
int32 i = 0;
for (; i < dataCount; i++) {
if (data[i][0] >= x)

View File

@ -30,8 +30,10 @@ public:
static uint32 ConvertFromBytesToMS(uint32 lengthInBytes, uint32 sampleRate, uint16 numChannels);
static uint32 ConvertFromMSToBytes(uint32 a, uint32 frequency, uint16 frequencyMult);
static bool GetBankAndSoundFromScriptSlotAudioEvent(const eAudioEvents& ae, eSoundBankS32& outBankID, int32& outSoundID, int32 slot);
static float GetPiecewiseLinear(float x, int16 dataCount, float (*data)[2]);
static bool GetBankAndSoundFromScriptSlotAudioEvent(const eAudioEvents& scriptID, eSoundBankS32& outBankID, int32& outSoundID, int32 slot);
static float GetPiecewiseLinear(float x, int16 dataCount, const float (*data)[2]);
template<int16 DataCnt>
static float GetPiecewiseLinearT(float x, const float (&points)[DataCnt][2]) { return GetPiecewiseLinear(x, DataCnt, points); }
static uint64 GetCurrentTimeInMS();
// NOTSA

View File

@ -13,9 +13,6 @@
#include "AEAudioHardware.h"
#include "AEAudioUtility.h"
//TODO: Remove once the cause of occasional nan here is found
#define NANCHECK() if (isnan(m_vecCurrPosn.x)) { assert(false); }
void CAESound::InjectHooks() {
RH_ScopedClass(CAESound);
RH_ScopedCategory("Audio");
@ -23,14 +20,14 @@ void CAESound::InjectHooks() {
RH_ScopedInstall(operator=, 0x4EF680);
RH_ScopedInstall(UnregisterWithPhysicalEntity, 0x4EF1A0);
RH_ScopedInstall(StopSound, 0x4EF1C0);
RH_ScopedInstall(SetIndividualEnvironment, 0x4EF2B0);
RH_ScopedInstall(SetFlags, 0x4EF2B0);
RH_ScopedInstall(UpdatePlayTime, 0x4EF2E0);
RH_ScopedOverloadedInstall(GetRelativePosition, "orginal", 0x4EF350, void(CAESound::*)(CVector*) const);
RH_ScopedInstall(CalculateFrequency, 0x4EF390);
RH_ScopedInstall(UpdateFrequency, 0x4EF3E0);
RH_ScopedInstall(GetRelativePlaybackFrequencyWithDoppler, 0x4EF400);
RH_ScopedInstall(GetSlowMoFrequencyScalingFactor, 0x4EF440);
RH_ScopedInstall(NewVPSLentry, 0x4EF7A0);
RH_ScopedInstall(NewVPSLEntry, 0x4EF7A0);
RH_ScopedInstall(RegisterWithPhysicalEntity, 0x4EF820);
RH_ScopedInstall(StopSoundAndForget, 0x4EF850);
RH_ScopedInstall(SetPosition, 0x4EF880);
@ -40,161 +37,117 @@ void CAESound::InjectHooks() {
RH_ScopedInstall(SoundHasFinished, 0x4EFFD0);
}
CAESound::CAESound(CAESound& sound) {
m_nBankSlotId = sound.m_nBankSlotId;
m_nSoundIdInSlot = sound.m_nSoundIdInSlot;
m_pBaseAudio = sound.m_pBaseAudio;
m_nEvent = sound.m_nEvent;
m_ClientVariable = sound.m_ClientVariable;
m_fVolume = sound.m_fVolume;
m_fSoundDistance = sound.m_fSoundDistance;
m_fSpeed = sound.m_fSpeed;
m_fSpeedVariability = sound.m_fSpeedVariability;
m_vecCurrPosn = sound.m_vecCurrPosn;
m_vecPrevPosn = sound.m_vecPrevPosn;
m_nLastFrameUpdate = sound.m_nLastFrameUpdate;
m_nCurrTimeUpdate = sound.m_nCurrTimeUpdate;
m_nPrevTimeUpdate = sound.m_nPrevTimeUpdate;
m_fCurrCamDist = sound.m_fCurrCamDist;
m_fPrevCamDist = sound.m_fPrevCamDist;
m_fTimeScale = sound.m_fTimeScale;
m_FrameDelay = sound.m_FrameDelay;
m_nEnvironmentFlags = sound.m_nEnvironmentFlags;
m_nIsUsed = sound.m_nIsUsed;
m_nCurrentPlayPosition = sound.m_nCurrentPlayPosition;
m_IsPhysicallyPlaying = sound.m_IsPhysicallyPlaying;
m_ListenerVolume = sound.m_ListenerVolume;
m_fFrequency = sound.m_fFrequency;
m_nPlayingState = sound.m_nPlayingState;
m_fSoundHeadRoom = sound.m_fSoundHeadRoom;
m_nSoundLength = sound.m_nSoundLength;
m_pPhysicalEntity = nullptr;
CAESound::CAESound(
eSoundBankSlot bankSlot,
eSoundID sfxId,
CAEAudioEntity* audioEntity,
CVector pos,
float volume,
float rollOff,
float speed,
float doppler,
uint8 frameDelay,
uint16 flags,
float speedVariance
) :
m_BankSlot{ bankSlot },
m_SoundID{ sfxId },
m_AudioEntity{ audioEntity },
m_Volume{ volume },
m_RollOffFactor{ rollOff },
m_Speed{ speed },
m_Doppler{ doppler },
m_FrameDelay{ frameDelay },
m_Flags{ flags },
m_SpeedVariance{ speedVariance }
{
assert((!(flags & SOUND_REQUEST_UPDATES) || audioEntity) && "SOUND_REQUEST_UPDATES flag requires `audioEntity` to be set!");
if (sound.m_pPhysicalEntity) {
m_pPhysicalEntity = sound.m_pPhysicalEntity;
m_pPhysicalEntity->RegisterReference(&m_pPhysicalEntity);
}
NANCHECK()
}
CAESound::CAESound(int16 bankSlotId, int16 sfxId, CAEAudioEntity* baseAudio, CVector posn, float volume, float fDistance, float speed, float timeScale,
uint8 ignoredServiceCycles, eSoundEnvironment environmentFlags, float speedVariability) {
m_nBankSlotId = bankSlotId;
m_nSoundIdInSlot = sfxId;
m_pBaseAudio = baseAudio;
m_vecPrevPosn = CVector(0.0f, 0.0f, 0.0f);
m_pPhysicalEntity = nullptr;
m_ClientVariable = -1.0F;
m_nEvent = AE_UNDEFINED;
m_nLastFrameUpdate = 0;
SetPosition(posn);
m_fVolume = volume;
m_fSoundDistance = fDistance;
m_fSpeed = speed;
m_fTimeScale = timeScale;
m_FrameDelay = ignoredServiceCycles;
m_nEnvironmentFlags = environmentFlags;
m_IsPhysicallyPlaying = 0;
m_nCurrentPlayPosition = 0;
m_fSoundHeadRoom = 0.0F;
m_fSpeedVariability = speedVariability;
m_nIsUsed = 1;
m_ListenerVolume = -100.0F;
m_fFrequency = 1.0F;
m_nSoundLength = -1;
SetPosition(pos);
}
CAESound::~CAESound() {
UnregisterWithPhysicalEntity();
}
// 0x4EF680
CAESound& CAESound::operator=(const CAESound& sound) {
if (this == &sound)
return *this;
CAESound::UnregisterWithPhysicalEntity();
m_nBankSlotId = sound.m_nBankSlotId;
m_nSoundIdInSlot = sound.m_nSoundIdInSlot;
m_pBaseAudio = sound.m_pBaseAudio;
m_nEvent = sound.m_nEvent;
m_ClientVariable = sound.m_ClientVariable;
m_fVolume = sound.m_fVolume;
m_fSoundDistance = sound.m_fSoundDistance;
m_fSpeed = sound.m_fSpeed;
m_fSpeedVariability = sound.m_fSpeedVariability;
m_vecCurrPosn = sound.m_vecCurrPosn;
m_vecPrevPosn = sound.m_vecPrevPosn;
m_nLastFrameUpdate = sound.m_nLastFrameUpdate;
m_nCurrTimeUpdate = sound.m_nCurrTimeUpdate;
m_nPrevTimeUpdate = sound.m_nPrevTimeUpdate;
m_fCurrCamDist = sound.m_fCurrCamDist;
m_fPrevCamDist = sound.m_fPrevCamDist;
m_fTimeScale = sound.m_fTimeScale;
m_FrameDelay = sound.m_FrameDelay;
m_nEnvironmentFlags = sound.m_nEnvironmentFlags;
m_nIsUsed = sound.m_nIsUsed;
m_nCurrentPlayPosition = sound.m_nCurrentPlayPosition;
m_IsPhysicallyPlaying = sound.m_IsPhysicallyPlaying;
m_ListenerVolume = sound.m_ListenerVolume;
m_fFrequency = sound.m_fFrequency;
m_nPlayingState = sound.m_nPlayingState;
m_fSoundHeadRoom = sound.m_fSoundHeadRoom;
m_nSoundLength = sound.m_nSoundLength;
m_pPhysicalEntity = nullptr;
RegisterWithPhysicalEntity(sound.m_pPhysicalEntity);
NANCHECK()
return *this;
// 0x4EFE50
void CAESound::Initialise(
eSoundBankSlot bankSlot,
eSoundID sfxId,
CAEAudioEntity* audioEntity,
CVector pos,
float volume,
float rollOff,
float speed,
float doppler,
uint8 frameDelay,
uint16 flags,
float speedVariance,
int16 playTime
) {
*this = CAESound{
bankSlot,
sfxId,
audioEntity,
pos,
volume,
rollOff,
speed,
doppler,
frameDelay,
(eSoundEnvironment)(flags),
speedVariance,
};
m_PlayTime = playTime;
}
// 0x4EF1A0
void CAESound::UnregisterWithPhysicalEntity() {
CEntity::ClearReference(m_pPhysicalEntity);
m_PhysicalEntity = nullptr;
}
// 0x4EF1C0
void CAESound::StopSound() {
m_nPlayingState = eSoundState::SOUND_STOPPED;
m_HasRequestedStopped = true;
UnregisterWithPhysicalEntity();
}
// 0x4EF2B0
void CAESound::SetIndividualEnvironment(uint16 envFlag, uint16 bEnabled) {
void CAESound::SetFlags(uint16 envFlag, uint16 bEnabled) {
if (bEnabled)
m_nEnvironmentFlags |= envFlag;
m_Flags |= envFlag;
else
m_nEnvironmentFlags &= ~envFlag;
m_Flags &= ~envFlag;
}
// 0x4EF2E0
void CAESound::UpdatePlayTime(int16 soundLength, int16 loopStartTime, int16 playProgress) {
m_nSoundLength = soundLength;
if (m_IsPhysicallyPlaying)
return;
m_Length = soundLength;
if (m_nPlayingState != eSoundState::SOUND_ACTIVE) {
m_nCurrentPlayPosition = -1;
if (m_IsPhysicallyPlaying) {
return;
}
m_nCurrentPlayPosition += static_cast<int16>(static_cast<float>(playProgress) * m_fFrequency);
if (m_nCurrentPlayPosition < soundLength)
if (m_HasRequestedStopped) {
m_PlayTime = -1;
return;
}
m_PlayTime += static_cast<int16>(static_cast<float>(playProgress) * m_ListenerSpeed);
if (m_PlayTime < soundLength) {
return;
}
if (loopStartTime == -1) {
m_nCurrentPlayPosition = -1;
m_PlayTime = -1;
return;
}
// Avoid division by 0
// This seems to have been fixed the same way in Android
// The cause is/can be missing audio files, but I'm lazy to fix it, so this is gonna be fine for now
m_nCurrentPlayPosition = !notsa::bugfixes::AESound_UpdatePlayTime_DivisionByZero || soundLength > 0
? loopStartTime + (m_nCurrentPlayPosition % soundLength)
m_PlayTime = !notsa::bugfixes::AESound_UpdatePlayTime_DivisionByZero || soundLength > 0
? loopStartTime + (m_PlayTime % soundLength)
: loopStartTime;
}
@ -207,46 +160,46 @@ CVector CAESound::GetRelativePosition() const {
// 0x4EF350 - Matches the original calling convention, to be used by reversible hooks, use the version returning CVector instead in our code
void CAESound::GetRelativePosition(CVector* outVec) const {
*outVec = GetFrontEnd()
? m_vecCurrPosn
: CAEAudioEnvironment::GetPositionRelativeToCamera(m_vecCurrPosn);
*outVec = IsFrontEnd()
? m_CurrPos
: CAEAudioEnvironment::GetPositionRelativeToCamera(m_CurrPos);
}
// 0x4EF390
void CAESound::CalculateFrequency() {
m_fFrequency = m_fSpeedVariability <= 0.0F || m_fSpeedVariability >= m_fSpeed
? m_fSpeed
: m_fSpeed + CAEAudioUtility::GetRandomNumberInRange(-m_fSpeedVariability, m_fSpeedVariability);
m_ListenerSpeed = m_SpeedVariance <= 0.f || m_SpeedVariance >= m_Speed
? m_Speed
: m_Speed + CAEAudioUtility::GetRandomNumberInRange(-m_SpeedVariance, m_SpeedVariance);
}
// 0x4EF3E0
void CAESound::UpdateFrequency() {
if (m_fSpeedVariability == 0.0F) {
m_fFrequency = m_fSpeed;
if (m_SpeedVariance == 0.f) {
m_ListenerSpeed = m_Speed;
}
}
// 0x4EF400
float CAESound::GetRelativePlaybackFrequencyWithDoppler() const {
return GetFrontEnd()
? m_fFrequency
: m_fFrequency * CAEAudioEnvironment::GetDopplerRelativeFrequency(m_fPrevCamDist, m_fCurrCamDist, m_nPrevTimeUpdate, m_nCurrTimeUpdate, m_fTimeScale);
return IsFrontEnd()
? m_ListenerSpeed
: m_ListenerSpeed * CAEAudioEnvironment::GetDopplerRelativeFrequency(m_PrevCamDist, m_CurrCamDist, m_PrevTimeUpdateMs, m_CurrTimeUpdateMs, m_Doppler);
}
// 0x4EF440
float CAESound::GetSlowMoFrequencyScalingFactor() const {
return GetUnpausable() || !CTimer::GetIsSlowMotionActive() || CCamera::GetActiveCamera().m_nMode == eCamMode::MODE_CAMERA
return IsUnpausable() || !CTimer::GetIsSlowMotionActive() || CCamera::GetActiveCamera().m_nMode == eCamMode::MODE_CAMERA
? 1.f
: fSlowMoFrequencyScalingFactor;
}
// 0x4EF7A0
void CAESound::NewVPSLentry() {
m_IsPhysicallyPlaying = 0;
m_nPlayingState = eSoundState::SOUND_ACTIVE;
m_bWasServiced = 0;
m_nIsUsed = 1;
m_fSoundHeadRoom = AEAudioHardware.GetSoundHeadroom(m_nSoundIdInSlot, m_nBankSlotId);
void CAESound::NewVPSLEntry() {
m_IsPhysicallyPlaying = true;
m_HasRequestedStopped = false;
m_IsAudioHardwareAware = false;
m_IsInUse = true;
m_Headroom = AEAudioHardware.GetSoundHeadroom(m_SoundID, m_BankSlot);
CalculateFrequency();
}
@ -254,107 +207,60 @@ void CAESound::NewVPSLentry() {
void CAESound::RegisterWithPhysicalEntity(CEntity* entity) {
CAESound::UnregisterWithPhysicalEntity();
if (entity) {
m_pPhysicalEntity = entity;
entity->RegisterReference(&m_pPhysicalEntity);
m_PhysicalEntity = entity;
}
}
// 0x4EF850
void CAESound::StopSoundAndForget() {
m_bRequestUpdates = false;
m_pBaseAudio = nullptr;
m_RequestUpdates = false;
m_AudioEntity = nullptr;
StopSound();
}
// 0x4EF880
void CAESound::SetPosition(CVector pos) {
if (!m_nLastFrameUpdate) {
m_vecPrevPosn = pos;
m_vecCurrPosn = pos;
auto const fCamDist = DistanceBetweenPoints(pos, TheCamera.GetPosition());
m_fCurrCamDist = fCamDist;
m_fPrevCamDist = fCamDist;
m_nLastFrameUpdate = CTimer::GetFrameCounter();
m_nCurrTimeUpdate = CTimer::GetTimeInMS();
m_nPrevTimeUpdate = CTimer::GetTimeInMS();
} else if (m_nLastFrameUpdate == CTimer::GetFrameCounter()) {
m_vecCurrPosn = pos;
m_fCurrCamDist = DistanceBetweenPoints(pos, TheCamera.GetPosition());
m_nCurrTimeUpdate = CTimer::GetTimeInMS();
} else {
m_vecPrevPosn = m_vecCurrPosn;
m_fPrevCamDist = m_fCurrCamDist;
m_nPrevTimeUpdate = m_nCurrTimeUpdate;
m_vecCurrPosn = pos;
m_fCurrCamDist = DistanceBetweenPoints(pos, TheCamera.GetPosition());
m_nCurrTimeUpdate = CTimer::GetTimeInMS();
m_nLastFrameUpdate = CTimer::GetFrameCounter();
const auto dist = DistanceBetweenPoints(pos, TheCamera.GetPosition());
if (!m_LastFrameUpdatedAt) { // 0x4EF898
m_PrevCamDist = dist;
m_PrevPos = pos;
m_PrevTimeUpdateMs = CTimer::GetTimeInMS();
} else if (m_LastFrameUpdatedAt != CTimer::GetFrameCounter()) {
m_PrevPos = m_CurrPos;
m_PrevCamDist = m_CurrCamDist;
m_PrevTimeUpdateMs = m_CurrTimeUpdateMs;
}
NANCHECK()
m_LastFrameUpdatedAt = CTimer::GetFrameCounter();
m_CurrCamDist = dist;
m_CurrPos = pos;
m_CurrTimeUpdateMs = CTimer::GetTimeInMS();
}
// 0x4EFA10
void CAESound::CalculateVolume() {
if (GetFrontEnd())
m_ListenerVolume = m_fVolume - m_fSoundHeadRoom;
else {
const auto relativeToCamPos = CAEAudioEnvironment::GetPositionRelativeToCamera(m_vecCurrPosn);
const auto attenuation = CAEAudioEnvironment::GetDistanceAttenuation(relativeToCamPos.Magnitude() / m_fSoundDistance);
m_ListenerVolume = CAEAudioEnvironment::GetDirectionalMikeAttenuation(relativeToCamPos) + attenuation + m_fVolume - m_fSoundHeadRoom;
m_ListenerVolume = m_Volume - m_Headroom;
if (!IsFrontEnd()) {
m_ListenerVolume += CAEAudioEnvironment::GetDirectionalMikeAttenuation(CAEAudioEnvironment::GetPositionRelativeToCamera(m_CurrPos))
+ CAEAudioEnvironment::GetDistanceAttenuation(CAEAudioEnvironment::GetPositionRelativeToCamera(m_CurrPos).Magnitude() / m_RollOffFactor);
}
}
// 0x4EFE50
void CAESound::Initialise(
int16 bankSlotId, int16 soundID, CAEAudioEntity* audioEntity, CVector pos, float volume, float rollOffFactor, float relativeFrequency, float doppler,
uint8 frameDelay, uint32 flags, float frequencyVariance, int16 playTime)
{
UnregisterWithPhysicalEntity();
m_nSoundIdInSlot = soundID;
m_nBankSlotId = bankSlotId;
m_pBaseAudio = audioEntity;
m_fVolume = volume;
m_fSoundDistance = rollOffFactor;
m_fSpeed = relativeFrequency;
m_fSpeedVariability = frequencyVariance;
m_vecPrevPosn .Set(0.0F, 0.0F, 0.0F);
m_nEvent = AE_UNDEFINED;
m_ClientVariable = -1.0F;
m_nLastFrameUpdate = 0;
SetPosition(pos);
m_fTimeScale = doppler;
m_nSoundLength = -1;
m_IsPhysicallyPlaying = 0;
m_nPlayingState = eSoundState::SOUND_ACTIVE;
m_fSoundHeadRoom = 0.0F;
m_FrameDelay = frameDelay;
m_nEnvironmentFlags = flags;
m_nIsUsed = 1;
m_nCurrentPlayPosition = playTime;
m_ListenerVolume = -100.0F;
m_fFrequency = 1.0F;
}
// 0x4EFF50
void CAESound::UpdateParameters(int16 curPlayPos) {
if (GetLifespanTiedToPhysicalEntity()) {
if (!m_pPhysicalEntity)
m_nPlayingState = eSoundState::SOUND_STOPPED;
else
SetPosition(m_pPhysicalEntity->GetPosition());
if (IsLifespanTiedToPhysicalEntity()) {
if (m_PhysicalEntity) {
SetPosition(m_PhysicalEntity->GetPosition());
} else {
m_HasRequestedStopped = true;
}
}
if (GetRequestUpdates() && m_pBaseAudio) {
m_pBaseAudio->UpdateParameters(this, curPlayPos);
if (m_fSpeedVariability == 0.0F)
m_fFrequency = m_fSpeed;
if (GetRequestUpdates()) {
if (m_AudioEntity) { // NB: References are clearable, so must check!
m_AudioEntity->UpdateParameters(this, curPlayPos);
if (m_SpeedVariance == 0.0F) {
m_ListenerSpeed = m_Speed;
}
}
}
}
@ -362,7 +268,7 @@ void CAESound::UpdateParameters(int16 curPlayPos) {
void CAESound::SoundHasFinished() {
UpdateParameters(-1);
UnregisterWithPhysicalEntity();
m_nIsUsed = 0;
m_IsPhysicallyPlaying = 0;
m_nCurrentPlayPosition = 0;
m_IsInUse = false;
m_IsPhysicallyPlaying = false;
m_PlayTime = 0;
}

View File

@ -7,130 +7,70 @@
#pragma once
#include "Vector.h"
#include "Enums/eSoundBankSlot.h"
#include "Enums/SoundIDs.h"
#include "Enums/eAudioEvents.h"
#include <extensions/EntityRef.hpp>
class CAEAudioEntity;
class CEntity;
using eSoundID = int16;
enum eSoundEnvironment : uint16 {
SOUND_DEFAULT = 0x0,
SOUND_FRONT_END = 0x1,
SOUND_UNCANCELLABLE = 0x2,
SOUND_IS_CANCELLABLE = 0x2,
SOUND_REQUEST_UPDATES = 0x4,
SOUND_PLAY_PHYSICALLY = 0x8,
SOUND_UNPAUSABLE = 0x10,
SOUND_IS_PAUSABLE = 0x10,
SOUND_START_PERCENTAGE = 0x20,
SOUND_MUSIC_MASTERED = 0x40,
SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY = 0x80,
SOUND_UNDUCKABLE = 0x100,
SOUND_UNCOMPRESSABLE = 0x200,
SOUND_IS_DUCKABLE = 0x100,
SOUND_IS_COMPRESSABLE = 0x200,
SOUND_ROLLED_OFF = 0x400,
SOUND_SMOOTH_DUCKING = 0x800,
SOUND_FORCED_FRONT = 0x1000
};
enum eSoundState : int16 {
SOUND_ACTIVE = 0,
SOUND_STOPPED = 1,
};
class CAESound {
public:
int16 m_nBankSlotId;
int16 m_nSoundIdInSlot;
CAEAudioEntity* m_pBaseAudio;
CEntity* m_pPhysicalEntity;
int32 m_nEvent; // Not necessarily `eAudioEvents`, for ex. see `CAEWeaponAudioEntity`
float m_ClientVariable;
float m_fVolume;
float m_fSoundDistance;
float m_fSpeed;
float m_fSpeedVariability;
CVector m_vecCurrPosn;
CVector m_vecPrevPosn;
int32 m_nLastFrameUpdate;
int32 m_nCurrTimeUpdate;
int32 m_nPrevTimeUpdate;
float m_fCurrCamDist;
float m_fPrevCamDist;
float m_fTimeScale;
uint8 m_FrameDelay; // Seemingly never used, but CAESoundManager::Service still checks for that
char field_55;
union {
uint16 m_nEnvironmentFlags;
struct {
uint16 m_bFrontEnd : 1;
uint16 m_bUncancellable : 1;
uint16 m_bRequestUpdates : 1;
uint16 m_bPlayPhysically : 1;
uint16 m_bUnpausable : 1;
uint16 m_bStartPercentage : 1;
uint16 m_bMusicMastered : 1;
uint16 m_bLifespanTiedToPhysicalEntity : 1;
uint16 m_bUnduckable : 1;
uint16 m_bUncompressable : 1;
uint16 m_bRolledOff : 1;
uint16 m_bSmoothDucking : 1;
uint16 m_bForcedFront : 1;
};
};
uint16 m_nIsUsed;
int16 m_bWasServiced;
int16 m_nCurrentPlayPosition;
int16 m_IsPhysicallyPlaying;
float m_ListenerVolume;
float m_fFrequency;
int16 m_nPlayingState; // see eSoundState
char field_6A[2];
float m_fSoundHeadRoom;
int16 m_nSoundLength;
int16 field_72;
static constexpr float fSlowMoFrequencyScalingFactor = 0.5F;
public:
static void InjectHooks();
CAESound() { m_pPhysicalEntity = nullptr; }
CAESound(CAESound& sound);
CAESound(int16 bankSlotId, int16 sfxId, CAEAudioEntity* baseAudio, CVector posn, float volume, float fDistance, float speed, float timeScale, uint8 ignoredServiceCycles, eSoundEnvironment environmentFlags, float speedVariability);
~CAESound();
CAESound& operator=(const CAESound& sound);
void Initialise(
int16 bankSlotId,
int16 soundID,
CAESound() = default;
CAESound(
eSoundBankSlot bankSlot,
eSoundID sfxId,
CAEAudioEntity* audioEntity,
CVector pos,
float volume,
float rollOffFactor = 1.f,
float relativeFrequency = 1.f, // Speed
float doppler = 1.f,
uint8 frameDelay = 0,
uint32 flags = 0,
float frequencyVariance = 0.f,
int16 playTime = 0
float rollOff,
float speed,
float doppler,
uint8 frameDelay,
uint16 flags,
float speedVariance
);
~CAESound();
void Initialise(
eSoundBankSlot bankSlot,
eSoundID sfxId,
CAEAudioEntity* audioEntity,
CVector pos,
float volume,
float rollOff = 1.f,
float speed = 1.f,
float doppler = 1.f,
uint8 frameDelay = 0,
uint16 flags = 0,
float speedVariance = 0.f,
int16 playTime = 0
);
void UnregisterWithPhysicalEntity();
void StopSound();
bool GetUncancellable() const { return m_bUncancellable; }
bool GetFrontEnd() const { return m_bFrontEnd; }
bool GetRequestUpdates() const { return m_bRequestUpdates; }
bool GetUnpausable() const { return m_bUnpausable; }
bool GetPlayPhysically() const { return m_bPlayPhysically; };
bool GetStartPercentage() const { return m_bStartPercentage; }
bool GetMusicMastered() const { return m_bMusicMastered; }
bool GetLifespanTiedToPhysicalEntity() const { return m_bLifespanTiedToPhysicalEntity; }
bool GetUnduckable() const { return m_bUnduckable; }
bool GetUncompressable() const { return m_bUncompressable; }
bool GetRolledOff() const { return m_bRolledOff; }
bool GetSmoothDucking() const { return m_bSmoothDucking; }
bool GetForcedFront() const { return m_bForcedFront; }
void SetIndividualEnvironment(uint16 envFlag, uint16 bEnabled); // pass eSoundEnvironment as envFlag
void SetFlags(uint16 envFlag, uint16 bEnabled); // pass eSoundEnvironment as envFlag
void UpdatePlayTime(int16 soundLength, int16 loopStartTime, int16 playProgress);
CVector GetRelativePosition() const;
void GetRelativePosition(CVector* outVec) const;
@ -138,18 +78,87 @@ public:
void UpdateFrequency();
float GetRelativePlaybackFrequencyWithDoppler() const;
float GetSlowMoFrequencyScalingFactor() const;
void NewVPSLentry();
void NewVPSLEntry();
void RegisterWithPhysicalEntity(CEntity* entity);
void StopSoundAndForget();
void SetPosition(CVector vecPos);
void CalculateVolume();
void UpdateParameters(int16 curPlayPos);
void SoundHasFinished();
eSoundState GetPlayingState() const { return (eSoundState)(m_nPlayingState); }
void SetSpeed(float s) noexcept { m_Speed = s; }
auto GetSpeed() const noexcept { return m_Speed; }
void SetVolume(float v) noexcept { m_Volume = v; }
auto GetVolume() const noexcept { return m_Volume; }
auto GetSoundLength() const noexcept { return m_Length; }
bool IsFrontEnd() const { return m_IsFrontEnd; }
bool GetRequestUpdates() const { return m_RequestUpdates; }
bool IsUnpausable() const { return m_IsUnpausable; }
bool GetPlayPhysically() const { return m_PlayPhysically; };
bool GetPlayTimeIsPercentage() const { return m_PlayTimeIsPercentage; }
bool IsMusicMastered() const { return m_IsMusicMastered; }
bool IsLifespanTiedToPhysicalEntity() const { return m_IsLifespanTiedToPhysicalEntity; }
bool IsUnduckable() const { return m_IsUnduckable; }
bool IsIncompressible() const { return m_IsIncompressible; }
bool IsUnancellable() const { return m_IsUnancellable; }
bool GetRolledOff() const { return m_IsRolledOff; }
bool GetSmoothDucking() const { return m_HasSmoothDucking; }
bool IsForcedFront() const { return m_IsForcedFront; }
bool IsActive() const { return m_IsInUse; }
bool IsAudioHardwareAware() const { return m_IsAudioHardwareAware; }
bool IsPhysicallyPlaying() const { return m_IsPhysicallyPlaying; }
public:
bool IsUsed() const { return m_nIsUsed; }
bool WasServiced() const { return m_bWasServiced; }
eSoundBankSlot m_BankSlot{}; //!< Slot to use for the sound
eSoundID m_SoundID{}; //!< Sound ID in the bank that's loaded into the slot
CAEAudioEntity* m_AudioEntity{}; //!< The entity that's playing this sound
notsa::EntityRef<> m_PhysicalEntity{}; //!< If set, the sound is tied to this entity
int32 m_Event{ AE_UNDEFINED }; //!< Not necessarily `eAudioEvents`, for ex. see `CAEWeaponAudioEntity`
float m_ClientVariable{ -1.f }; //!< Custom variable set when playing the sound
float m_Volume{}; //!< Volume of the sound (Used to calculate the final volume, `ListenerVolume`)
float m_RollOffFactor{}; //!< Roll-off factor
float m_Speed{}; //!< Speed of the sound (Used to calculate the final frequency, `ListenerSpeed`)
float m_SpeedVariance{}; //!< Speed variability
CVector m_CurrPos{}; //!< Current position of the sound
CVector m_PrevPos{}; //!< Previous position of the sound the last time it was updated
int32 m_LastFrameUpdatedAt{}; //!< Frame count when the sound was last updated (`CTimer::GetFrameCounter()`)
int32 m_CurrTimeUpdateMs{}; //!< Time in milliseconds when the sound was updated (`CTimer::GetTimeInMS()`)
int32 m_PrevTimeUpdateMs{}; //!< Time in milliseconds when the sound was last updated (`CTimer::GetTimeInMS()`)
float m_CurrCamDist{}; //!< Distance to the camera
float m_PrevCamDist{}; //!< Distance to the camera the last time the sound was updated
float m_Doppler{}; //!< Doppler effect
uint8 m_FrameDelay{}; //!< How many frames to delay the sound (0 = play immediately)
char __pad;
union {
uint16 m_Flags{};
struct {
uint16 m_IsFrontEnd : 1;
uint16 m_IsUnancellable : 1;
uint16 m_RequestUpdates : 1;
uint16 m_PlayPhysically : 1;
uint16 m_IsUnpausable : 1;
uint16 m_PlayTimeIsPercentage : 1;
uint16 m_IsMusicMastered : 1;
uint16 m_IsLifespanTiedToPhysicalEntity : 1;
uint16 m_IsUnduckable : 1;
uint16 m_IsIncompressible : 1;
uint16 m_IsRolledOff : 1;
uint16 m_HasSmoothDucking : 1;
uint16 m_IsForcedFront : 1;
};
};
uint16 m_IsInUse{true};
int16 m_IsAudioHardwareAware{};
int16 m_PlayTime{};
int16 m_IsPhysicallyPlaying{};
float m_ListenerVolume{-100.f};
float m_ListenerSpeed{1.f};
int16 m_HasRequestedStopped{};
float m_Headroom{};
int16 m_Length{-1};
};
VALIDATE_SIZE(CAESound, 0x74);

View File

@ -31,8 +31,8 @@ void CAudioEngine::InjectHooks() {
RH_ScopedInstall(IsAmbienceTrackActive, 0x507210);
RH_ScopedInstall(PauseBeatTrack, 0x507200);
RH_ScopedInstall(RetuneRadio, 0x507E10);
RH_ScopedOverloadedInstall(StartRadio, "", 0x507DF0, void (CAudioEngine::*)(tVehicleAudioSettings*));
RH_ScopedOverloadedInstall(StartRadio, "1", 0x507DC0, void (CAudioEngine::*)(eRadioID, int8));
RH_ScopedOverloadedInstall(StartRadio, "", 0x507DF0, void (CAudioEngine::*)(const tVehicleAudioSettings&));
RH_ScopedOverloadedInstall(StartRadio, "1", 0x507DC0, void (CAudioEngine::*)(eRadioID, eBassSetting));
RH_ScopedInstall(ServiceLoadingTune, 0x5078A0);
RH_ScopedInstall(ResumeAllSounds, 0x507440);
RH_ScopedInstall(PauseAllSounds, 0x507430);
@ -173,19 +173,19 @@ void CAudioEngine::InitialisePostLoading() {
m_GlobalWeaponAE = new CAEGlobalWeaponAudioEntity();
m_GlobalWeaponAE->Initialise();
while ( !AEAudioHardware.IsSoundBankLoaded(39, SLOT_LOADING_TUNE_LEFT)
|| !AEAudioHardware.IsSoundBankLoaded(27, 3)
|| !AEAudioHardware.IsSoundBankLoaded(138, 19)
|| !AEAudioHardware.IsSoundBankLoaded(0, 41)
|| !AEAudioHardware.IsSoundBankLoaded(BANK_EXTRAS, SLOT_EXTRAS)
|| !AEAudioHardware.IsSoundBankLoaded(52, 4)
|| !AEAudioHardware.IsSoundBankLoaded(143, SLOT_LOADING_TUNE_RIGHT)
|| !AEAudioHardware.IsSoundBankLoaded(51, 31)
|| !AEAudioHardware.IsSoundBankLoaded(105, 6)
|| !AEAudioHardware.IsSoundBankLoaded(74, 17)
|| !AEAudioHardware.IsSoundBankLoaded(128, 32)
|| !AEAudioHardware.IsSoundBankLoaded(13, 18)
) {
while ( !AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_COLLISIONS, SND_BANK_SLOT_COLLISIONS)
|| !AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_BULLET_HITS, SND_BANK_SLOT_BULLET_HITS)
|| !AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_VEHICLE_GEN, SND_BANK_SLOT_VEHICLE_GEN)
|| !AEAudioHardware.IsSoundBankLoaded(SND_BANK_FEET_GENERIC, SND_BANK_SLOT_FOOTSTEPS_GENERIC)
|| !AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)
|| !AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_EXPLOSIONS, SND_BANK_SLOT_EXPLOSIONS)
|| !AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN)
|| !AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_DOORS, SND_BANK_SLOT_DOORS)
|| !AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_RAIN, SND_BANK_SLOT_WEATHER)
|| !AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_HORN, SND_BANK_SLOT_HORN_AND_SIREN)
|| !AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_SWIMMING, SND_BANK_SLOT_SWIMMING)
|| !AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_APACHE_D, SND_BANK_SLOT_COP_HELI)
) {
AEAudioHardware.Service();
}
}
@ -270,8 +270,7 @@ bool CAudioEngine::IsMissionAudioSampleFinished(uint8 sampleId) {
void CAudioEngine::PreloadBeatTrack(int16 trackId) {
if (AERadioTrackManager.IsRadioOn()) {
m_nCurrentRadioStationId = AERadioTrackManager.GetCurrentRadioStationID();
tVehicleAudioSettings* settings = CAEVehicleAudioEntity::StaticGetPlayerVehicleAudioSettingsForRadio();
AERadioTrackManager.StopRadio(settings, true);
AERadioTrackManager.StopRadio(CAEVehicleAudioEntity::StaticGetPlayerVehicleAudioSettingsForRadio(), true);
m_FrontendAE.AddAudioEvent(AE_FRONTEND_RADIO_RETUNE_STOP);
while (AERadioTrackManager.IsRadioOn()) {
AERadioTrackManager.Service(AEAudioHardware.GetTrackPlayTime());
@ -407,8 +406,7 @@ void CAudioEngine::PlayRadioAnnouncement(uint32 a1) {
void CAudioEngine::PreloadCutsceneTrack(int16 trackId, bool wait) {
if (AERadioTrackManager.IsRadioOn()) {
m_nCurrentRadioStationId = AERadioTrackManager.GetCurrentRadioStationID();
tVehicleAudioSettings* settings = CAEVehicleAudioEntity::StaticGetPlayerVehicleAudioSettingsForRadio();
AERadioTrackManager.StopRadio(settings, true);
AERadioTrackManager.StopRadio(CAEVehicleAudioEntity::StaticGetPlayerVehicleAudioSettingsForRadio(), true);
m_FrontendAE.AddAudioEvent(AE_FRONTEND_RADIO_RETUNE_STOP);
while (AERadioTrackManager.IsRadioOn()) {
AERadioTrackManager.Service(AEAudioHardware.GetTrackPlayTime());
@ -457,16 +455,16 @@ void CAudioEngine::StopCutsceneTrack(bool bWaitForFinish) {
}
if (m_nCurrentRadioStationId < 0) {
if (AERadioTrackManager.IsVehicleRadioActive()) {
tVehicleAudioSettings* settings = CAEVehicleAudioEntity::StaticGetPlayerVehicleAudioSettingsForRadio();
AERadioTrackManager.StartRadio(settings);
AERadioTrackManager.StartRadio(*CAEVehicleAudioEntity::StaticGetPlayerVehicleAudioSettingsForRadio());
m_bPlayingMissionCompleteTrack = false;
return;
}
m_bPlayingMissionCompleteTrack = false;
return;
}
if (AERadioTrackManager.IsVehicleRadioActive())
AERadioTrackManager.StartRadio(m_nCurrentRadioStationId, 0, 0, 0);
if (AERadioTrackManager.IsVehicleRadioActive()) {
AERadioTrackManager.StartRadio(m_nCurrentRadioStationId, eBassSetting::NORMAL, 0.f, false);
}
m_nCurrentRadioStationId = RADIO_INVALID;
m_bPlayingMissionCompleteTrack = false;
}
@ -620,7 +618,7 @@ void CAudioEngine::Service() {
if (trackPlayTime == -6) {
m_bStoppingMissionCompleteTrack = false;
if (CAERadioTrackManager::IsVehicleRadioActive()) {
AERadioTrackManager.StartRadio(CAEVehicleAudioEntity::StaticGetPlayerVehicleAudioSettingsForRadio());
AERadioTrackManager.StartRadio(*CAEVehicleAudioEntity::StaticGetPlayerVehicleAudioSettingsForRadio());
}
}
}
@ -745,15 +743,17 @@ int8 CAudioEngine::GetBeatTrackStatus() {
}
// 0x507DC0
void CAudioEngine::StartRadio(eRadioID id, int8 bassValue) {
if (!GetBeatTrackStatus())
AERadioTrackManager.StartRadio(id, bassValue, 0, 0);
void CAudioEngine::StartRadio(eRadioID id, eBassSetting bassSetting) {
if (!GetBeatTrackStatus()) {
AERadioTrackManager.StartRadio(id, bassSetting, 0.f, false);
}
}
// 0x507DF0
void CAudioEngine::StartRadio(tVehicleAudioSettings* settings) {
if (!GetBeatTrackStatus())
void CAudioEngine::StartRadio(const tVehicleAudioSettings& settings) {
if (!GetBeatTrackStatus()) {
AERadioTrackManager.StartRadio(settings);
}
}
// 0x506F80
@ -767,8 +767,8 @@ void CAudioEngine::SetBassEnhanceOnOff(bool enable) {
}
// 0x506FA0
void CAudioEngine::SetRadioBassSetting(int8 nBassSet) {
AERadioTrackManager.SetBassSetting(nBassSet, 1.0f);
void CAudioEngine::SetRadioBassSetting(eBassSetting bassSetting) {
AERadioTrackManager.SetBassSetting(bassSetting, 1.0f);
}
// 0x506FC0

View File

@ -89,12 +89,12 @@ public:
void ReportFrontendAudioEvent(eAudioEvents eventId, float volumeChange = 0.0f, float speed = 1.0f);
void InitialiseRadioStationID(eRadioID id);
void StartRadio(tVehicleAudioSettings* settings);
void StartRadio(eRadioID id, int8 bassValue);
void StartRadio(const tVehicleAudioSettings& settings);
void StartRadio(eRadioID id, eBassSetting bassSetting);
void StopRadio(tVehicleAudioSettings* settings, bool bDuringPause);
void SetRadioAutoRetuneOnOff(bool);
void SetBassEnhanceOnOff(bool enable);
void SetRadioBassSetting(int8);
void SetRadioBassSetting(eBassSetting bassSetting);
bool HasRadioRetuneJustStarted();
const GxtChar* GetRadioStationName(eRadioID id);
void GetRadioStationNameKey(eRadioID id, char* outStr);

View File

@ -1,96 +1,451 @@
#pragma once
/*
* SfxIDs (Sound IDs) in sound banks
*/
using eSoundID = int16;
enum eGenrlWeaponSoundID : eSoundID { // GENRL_WEAPONS
SND_GENRL_WEAPONS_UNK = -1,
SND_GENRL_WEAPONS_9MM1SHOT_L = 0x0,
SND_GENRL_WEAPONS_9MM1SHOT_R = 0x1,
SND_GENRL_WEAPONS_9MM1TAIL = 0x2,
SND_GENRL_WEAPONS_AK_SHOT_L = 0x3,
SND_GENRL_WEAPONS_AK_SHOT_R = 0x4,
SND_GENRL_WEAPONS_AK_TAIL_L = 0x5,
SND_GENRL_WEAPONS_EAGLE_SHOT_L = 0x6,
SND_GENRL_WEAPONS_EAGLE_SHOT_R = 0x7,
SND_GENRL_WEAPONS_EAGLE_TAIL_L = 0x8,
SND_GENRL_WEAPONS_FIRE_EXT = 0x9,
SND_GENRL_WEAPONS_GAS_LOOP = 0xA,
SND_GENRL_WEAPONS_MINIGUN_SHOT_L = 0xB,
SND_GENRL_WEAPONS_MINIGUN_SHOT_R = 0xC,
SND_GENRL_WEAPONS_MINIGUN_TAIL = 0xD,
SND_GENRL_WEAPONS_MINIGUNEMPTY = 0xE,
SND_GENRL_WEAPONS_MINIGUNHIGHS = 0xF,
SND_GENRL_WEAPONS_MINIGUNLOWS = 0x10,
SND_GENRL_WEAPONS_MP5SHOT_L = 0x11,
SND_GENRL_WEAPONS_MP5SHOT_R = 0x12,
SND_GENRL_WEAPONS_PARACHUTE_WIND_LOOP_A = 0x13,
SND_GENRL_WEAPONS_PARACHUTE_WIND_LOOP_B = 0x14,
SND_GENRL_WEAPONS_SHOTGUN_SHOT_L = 0x15,
SND_GENRL_WEAPONS_SHOTGUN_SHOT_R = 0x16,
SND_GENRL_WEAPONS_SHOTGUN_TAIL_R = 0x17,
SND_GENRL_WEAPONS_SILENCED_SHOT_L = 0x18,
SND_GENRL_WEAPONS_SILENCED_SHOT_R = 0x19,
SND_GENRL_WEAPONS_SNIPER_SHOT_L = 0x1A,
SND_GENRL_WEAPONS_SNIPER_SHOT_R = 0x1B,
SND_GENRL_WEAPONS_SPRAY_PAINT = 0x1C,
SND_GENRL_WEAPONS_9MM1DRY = 0x1D,
SND_GENRL_WEAPONS_9MM1LOWS = 0x1E,
SND_GENRL_WEAPONS_AK_A = 0x1F,
SND_GENRL_WEAPONS_AK_B = 0x20,
SND_GENRL_WEAPONS_AK_DRYFIRE = 0x21,
SND_GENRL_WEAPONS_BASEBALL_BAT = 0x22,
SND_GENRL_WEAPONS_BAT_STRIKE = 0x23,
SND_GENRL_WEAPONS_BODY_PUNCH1 = 0x24,
SND_GENRL_WEAPONS_BODY_PUNCH2 = 0x25,
SND_GENRL_WEAPONS_BODY_PUNCH3 = 0x26,
SND_GENRL_WEAPONS_BODY_PUNCH4 = 0x27,
SND_GENRL_WEAPONS_BOX_FACE1 = 0x28,
SND_GENRL_WEAPONS_BOX_FACE2 = 0x29,
SND_GENRL_WEAPONS_BOX_FACE3 = 0x2A,
SND_GENRL_WEAPONS_BOX_FACE4 = 0x2B,
SND_GENRL_WEAPONS_BRASS_KNUCKLES = 0x2C,
SND_GENRL_WEAPONS_CAMERA = 0x2D,
SND_GENRL_WEAPONS_CANE_STRIKE = 0x2E,
SND_GENRL_WEAPONS_CANE_SWISH = 0x2F,
SND_GENRL_WEAPONS_CLUB_STRIKE = 0x30,
SND_GENRL_WEAPONS_DETONATOR_BEEP = 0x31,
SND_GENRL_WEAPONS_DILDO = 0x32,
SND_GENRL_WEAPONS_EAGLE_B = 0x33,
SND_GENRL_WEAPONS_EAGLE_DRYFIRE = 0x34,
SND_GENRL_WEAPONS_EAGLE_LOWS = 0x35,
SND_GENRL_WEAPONS_FLOWER_STRIKE = 0x36,
SND_GENRL_WEAPONS_HANDGUN_A = 0x37,
SND_GENRL_WEAPONS_KATANA_SWORD = 0x38,
SND_GENRL_WEAPONS_KNIFE = 0x39,
SND_GENRL_WEAPONS_KNUCKLE = 0x3A,
SND_GENRL_WEAPONS_MARTIAL_STRIKE1 = 0x3B,
SND_GENRL_WEAPONS_MARTIAL_STRIKE2 = 0x3C,
SND_GENRL_WEAPONS_MARTIAL_STRIKE3 = 0x3D,
SND_GENRL_WEAPONS_MARTIAL_STRIKE4 = 0x3E,
SND_GENRL_WEAPONS_MINIGUNOFF = 0x3F,
SND_GENRL_WEAPONS_NIGHT_VISION = 0x40,
SND_GENRL_WEAPONS_PARACHUTE_OPEN = 0x41,
SND_GENRL_WEAPONS_PISTOL_B = 0x42,
SND_GENRL_WEAPONS_POOLCUE = 0x43,
SND_GENRL_WEAPONS_ROCKET_LAUNCH = 0x44,
SND_GENRL_WEAPONS_SAWNOFF_A = 0x45,
SND_GENRL_WEAPONS_SAWNOFF_B = 0x46,
SND_GENRL_WEAPONS_SHOTGUN_A = 0x47,
SND_GENRL_WEAPONS_SHOTGUN_B = 0x48,
SND_GENRL_WEAPONS_SHOTGUN_DRYFIRE = 0x49,
SND_GENRL_WEAPONS_SHOTGUN_LOWS = 0x4A,
SND_GENRL_WEAPONS_SHOVEL = 0x4B,
SND_GENRL_WEAPONS_SILENCED_DRYFIRE = 0x4C,
SND_GENRL_WEAPONS_SILENCED_LOWS = 0x4D,
SND_GENRL_WEAPONS_SMACK_1 = 0x4E,
SND_GENRL_WEAPONS_SMACK_2 = 0x4F,
SND_GENRL_WEAPONS_SMACK_3 = 0x50,
SND_GENRL_WEAPONS_STAB = 0x51,
SND_GENRL_WEAPONS_STOMP1 = 0x52,
SND_GENRL_WEAPONS_TRIGGER = 0x53,
SND_GENRL_WEAPONS_UZI_A = 0x54,
SND_GENRL_WEAPONS_UZI_B = 0x55,
SND_GENRL_WEAPONS_WEAPON_SWIPE = 0x56,
SND_GENRL_WEAPONS_WEAPON_SWIPE_FIST = 0x57,
SND_GENRL_WEAPONS_WEAPON_SWIPE_METAL = 0x58,
enum SND_GENRL_WEAPONS : eSoundID { // GENRL_WEAPONS
SND_GENRL_WEAPONS_UNK = -1, // 1
SND_GENRL_WEAPONS_9MM1SHOT_L = 0, // 0x0
SND_GENRL_WEAPONS_9MM1SHOT_R = 1, // 0x1
SND_GENRL_WEAPONS_9MM1TAIL = 2, // 0x2
SND_GENRL_WEAPONS_AK_SHOT_L = 3, // 0x3
SND_GENRL_WEAPONS_AK_SHOT_R = 4, // 0x4
SND_GENRL_WEAPONS_AK_TAIL_L = 5, // 0x5
SND_GENRL_WEAPONS_EAGLE_SHOT_L = 6, // 0x6
SND_GENRL_WEAPONS_EAGLE_SHOT_R = 7, // 0x7
SND_GENRL_WEAPONS_EAGLE_TAIL_L = 8, // 0x8
SND_GENRL_WEAPONS_FIRE_EXT = 9, // 0x9
SND_GENRL_WEAPONS_GAS_LOOP = 10, // 0xA
SND_GENRL_WEAPONS_MINIGUN_SHOT_L = 11, // 0xB
SND_GENRL_WEAPONS_MINIGUN_SHOT_R = 12, // 0xC
SND_GENRL_WEAPONS_MINIGUN_TAIL = 13, // 0xD
SND_GENRL_WEAPONS_MINIGUNEMPTY = 14, // 0xE
SND_GENRL_WEAPONS_MINIGUNHIGHS = 15, // 0xF
SND_GENRL_WEAPONS_MINIGUNLOWS = 16, // 0x10
SND_GENRL_WEAPONS_MP5SHOT_L = 17, // 0x11
SND_GENRL_WEAPONS_MP5SHOT_R = 18, // 0x12
SND_GENRL_WEAPONS_PARACHUTE_WIND_LOOP_A = 19, // 0x13
SND_GENRL_WEAPONS_PARACHUTE_WIND_LOOP_B = 20, // 0x14
SND_GENRL_WEAPONS_SHOTGUN_SHOT_L = 21, // 0x15
SND_GENRL_WEAPONS_SHOTGUN_SHOT_R = 22, // 0x16
SND_GENRL_WEAPONS_SHOTGUN_TAIL_R = 23, // 0x17
SND_GENRL_WEAPONS_SILENCED_SHOT_L = 24, // 0x18
SND_GENRL_WEAPONS_SILENCED_SHOT_R = 25, // 0x19
SND_GENRL_WEAPONS_SNIPER_SHOT_L = 26, // 0x1A
SND_GENRL_WEAPONS_SNIPER_SHOT_R = 27, // 0x1B
SND_GENRL_WEAPONS_SPRAY_PAINT = 28, // 0x1C
SND_GENRL_WEAPONS_9MM1DRY = 29, // 0x1D
SND_GENRL_WEAPONS_9MM1LOWS = 30, // 0x1E
SND_GENRL_WEAPONS_AK_A = 31, // 0x1F
SND_GENRL_WEAPONS_AK_B = 32, // 0x20
SND_GENRL_WEAPONS_AK_DRYFIRE = 33, // 0x21
SND_GENRL_WEAPONS_BASEBALL_BAT = 34, // 0x22
SND_GENRL_WEAPONS_BAT_STRIKE = 35, // 0x23
SND_GENRL_WEAPONS_BODY_PUNCH1 = 36, // 0x24
SND_GENRL_WEAPONS_BODY_PUNCH2 = 37, // 0x25
SND_GENRL_WEAPONS_BODY_PUNCH3 = 38, // 0x26
SND_GENRL_WEAPONS_BODY_PUNCH4 = 39, // 0x27
SND_GENRL_WEAPONS_BOX_FACE1 = 40, // 0x28
SND_GENRL_WEAPONS_BOX_FACE2 = 41, // 0x29
SND_GENRL_WEAPONS_BOX_FACE3 = 42, // 0x2A
SND_GENRL_WEAPONS_BOX_FACE4 = 43, // 0x2B
SND_GENRL_WEAPONS_BRASS_KNUCKLES = 44, // 0x2C
SND_GENRL_WEAPONS_CAMERA = 45, // 0x2D
SND_GENRL_WEAPONS_CANE_STRIKE = 46, // 0x2E
SND_GENRL_WEAPONS_CANE_SWISH = 47, // 0x2F
SND_GENRL_WEAPONS_CLUB_STRIKE = 48, // 0x30
SND_GENRL_WEAPONS_DETONATOR_BEEP = 49, // 0x31
SND_GENRL_WEAPONS_DILDO = 50, // 0x32
SND_GENRL_WEAPONS_EAGLE_B = 51, // 0x33
SND_GENRL_WEAPONS_EAGLE_DRYFIRE = 52, // 0x34
SND_GENRL_WEAPONS_EAGLE_LOWS = 53, // 0x35
SND_GENRL_WEAPONS_FLOWER_STRIKE = 54, // 0x36
SND_GENRL_WEAPONS_HANDGUN_A = 55, // 0x37
SND_GENRL_WEAPONS_KATANA_SWORD = 56, // 0x38
SND_GENRL_WEAPONS_KNIFE = 57, // 0x39
SND_GENRL_WEAPONS_KNUCKLE = 58, // 0x3A
SND_GENRL_WEAPONS_MARTIAL_STRIKE1 = 59, // 0x3B
SND_GENRL_WEAPONS_MARTIAL_STRIKE2 = 60, // 0x3C
SND_GENRL_WEAPONS_MARTIAL_STRIKE3 = 61, // 0x3D
SND_GENRL_WEAPONS_MARTIAL_STRIKE4 = 62, // 0x3E
SND_GENRL_WEAPONS_MINIGUNOFF = 63, // 0x3F
SND_GENRL_WEAPONS_NIGHT_VISION = 64, // 0x40
SND_GENRL_WEAPONS_PARACHUTE_OPEN = 65, // 0x41
SND_GENRL_WEAPONS_PISTOL_B = 66, // 0x42
SND_GENRL_WEAPONS_POOLCUE = 67, // 0x43
SND_GENRL_WEAPONS_ROCKET_LAUNCH = 68, // 0x44
SND_GENRL_WEAPONS_SAWNOFF_A = 69, // 0x45
SND_GENRL_WEAPONS_SAWNOFF_B = 70, // 0x46
SND_GENRL_WEAPONS_SHOTGUN_A = 71, // 0x47
SND_GENRL_WEAPONS_SHOTGUN_B = 72, // 0x48
SND_GENRL_WEAPONS_SHOTGUN_DRYFIRE = 73, // 0x49
SND_GENRL_WEAPONS_SHOTGUN_LOWS = 74, // 0x4A
SND_GENRL_WEAPONS_SHOVEL = 75, // 0x4B
SND_GENRL_WEAPONS_SILENCED_DRYFIRE = 76, // 0x4C
SND_GENRL_WEAPONS_SILENCED_LOWS = 77, // 0x4D
SND_GENRL_WEAPONS_SMACK_1 = 78, // 0x4E
SND_GENRL_WEAPONS_SMACK_2 = 79, // 0x4F
SND_GENRL_WEAPONS_SMACK_3 = 80, // 0x50
SND_GENRL_WEAPONS_STAB = 81, // 0x51
SND_GENRL_WEAPONS_STOMP1 = 82, // 0x52
SND_GENRL_WEAPONS_TRIGGER = 83, // 0x53
SND_GENRL_WEAPONS_UZI_A = 84, // 0x54
SND_GENRL_WEAPONS_UZI_B = 85, // 0x55
SND_GENRL_WEAPONS_WEAPON_SWIPE = 86, // 0x56
SND_GENRL_WEAPONS_WEAPON_SWIPE_FIST = 87, // 0x57
SND_GENRL_WEAPONS_WEAPON_SWIPE_METAL = 88, // 0x58
};
enum SND_GENRL_HORN : eSoundID { // SND_BANK_GENRL_HORN
SND_GENRL_HORN_BIKEBELL = 0, // 0x0
SND_GENRL_HORN_ESCORTHORN = 1, // 0x1
SND_GENRL_HORN_HORN56CHEV = 2, // 0x2
SND_GENRL_HORN_HORNBMW328 = 3, // 0x3
SND_GENRL_HORN_HORNBUS = 4, // 0x4
SND_GENRL_HORN_HORNBUS2 = 5, // 0x5
SND_GENRL_HORN_HORNJEEP = 6, // 0x6
SND_GENRL_HORN_HORNPICKUP = 7, // 0x7
SND_GENRL_HORN_HORNPORSCHE = 8, // 0x8
SND_GENRL_HORN_HORNTRUCK = 9, // 0x9
SND_GENRL_HORN_SIREN_LONG = 10, // 0xA
SND_GENRL_HORN_SIREN_SHORT = 11, // 0xB
SND_GENRL_HORN_FOGHORN = 12, // 0xC
SND_GENRL_HORN_GOODFOGHORN = 13, // 0xD
};
enum SND_GENRL_COLLISIONS : eSoundID {
SND_GENRL_COLLISIONS_GRASS_SKID = 0x0,
SND_GENRL_COLLISIONS_GRAVEL_SKID = 0x1,
SND_GENRL_COLLISIONS_METAL_SCRAPE = 0x2,
SND_GENRL_COLLISIONS_WATER_LOOP = 0x3,
SND_GENRL_COLLISIONS_BARREL_CONE = 0x4,
SND_GENRL_COLLISIONS_BIKE_CRASH1 = 0x5,
SND_GENRL_COLLISIONS_BIKE_CRASH2 = 0x6,
SND_GENRL_COLLISIONS_BIKE_CRASH3 = 0x7,
SND_GENRL_COLLISIONS_BIKE_CRASH4 = 0x8,
SND_GENRL_COLLISIONS_BIKE_CRASH5 = 0x9,
SND_GENRL_COLLISIONS_BIN_BAG = 0xA,
SND_GENRL_COLLISIONS_BOTTLE_SMASH = 0xB,
SND_GENRL_COLLISIONS_CARDBOARD_BOX1 = 0xC,
SND_GENRL_COLLISIONS_CARDBOARD_BOX2 = 0xD,
SND_GENRL_COLLISIONS_CARDBOARD_BOX3 = 0xE,
SND_GENRL_COLLISIONS_COL_GLASS_TINK1 = 0xF,
SND_GENRL_COLLISIONS_COL_GLASS_TINK2 = 0x10,
SND_GENRL_COLLISIONS_COL_GLASS_TINK3 = 0x11,
SND_GENRL_COLLISIONS_COL_GLASS_TINK4 = 0x12,
SND_GENRL_COLLISIONS_COLBENCH1 = 0x13,
SND_GENRL_COLLISIONS_COLCAR01 = 0x14,
SND_GENRL_COLLISIONS_COLCAR03 = 0x15,
SND_GENRL_COLLISIONS_COLCAR04 = 0x16,
SND_GENRL_COLLISIONS_COLCAR05 = 0x17,
SND_GENRL_COLLISIONS_COLCAR06 = 0x18,
SND_GENRL_COLLISIONS_COLCAR08 = 0x19,
SND_GENRL_COLLISIONS_COLCAR09 = 0x1A,
SND_GENRL_COLLISIONS_COLCAR10 = 0x1B,
SND_GENRL_COLLISIONS_COLCAR12 = 0x1C,
SND_GENRL_COLLISIONS_COLCARPED = 0x1D,
SND_GENRL_COLLISIONS_COLCONTAINER = 0x1E,
SND_GENRL_COLLISIONS_COLGRASS = 0x1F,
SND_GENRL_COLLISIONS_COLLAMPPOST = 0x20,
SND_GENRL_COLLISIONS_COLSOLIDWOOD = 0x21,
SND_GENRL_COLLISIONS_CONCRETE = 0x22,
SND_GENRL_COLLISIONS_CRATE1 = 0x23,
SND_GENRL_COLLISIONS_CRATE2 = 0x24,
SND_GENRL_COLLISIONS_CRATE3 = 0x25,
SND_GENRL_COLLISIONS_DISPENSER = 0x26,
SND_GENRL_COLLISIONS_DUMPSTER = 0x27,
SND_GENRL_COLLISIONS_FENCE_HEAVY = 0x28,
SND_GENRL_COLLISIONS_FENCE_PARTICLES1 = 0x29,
SND_GENRL_COLLISIONS_FENCE_PARTICLES2 = 0x2A,
SND_GENRL_COLLISIONS_FENCE_PARTICLES3 = 0x2B,
SND_GENRL_COLLISIONS_FENCE_PARTICLES4 = 0x2C,
SND_GENRL_COLLISIONS_FENCE_THIN = 0x2D,
SND_GENRL_COLLISIONS_GARAGE_DOOR = 0x2E,
SND_GENRL_COLLISIONS_GORE_SPLAT1 = 0x2F,
SND_GENRL_COLLISIONS_GORE_SPLAT2 = 0x30,
SND_GENRL_COLLISIONS_GORE_SPLAT3 = 0x31,
SND_GENRL_COLLISIONS_GRENADE = 0x32,
SND_GENRL_COLLISIONS_HARD_GLASS = 0x33,
SND_GENRL_COLLISIONS_HAY_BALE = 0x34,
SND_GENRL_COLLISIONS_HEADLIGHT = 0x35,
SND_GENRL_COLLISIONS_HYDRANT = 0x36,
SND_GENRL_COLLISIONS_METAL_BARREL = 0x37,
SND_GENRL_COLLISIONS_PANE_BREAK = 0x38,
SND_GENRL_COLLISIONS_RIMHIT = 0x39,
SND_GENRL_COLLISIONS_RIMSCRAPE = 0x3A,
SND_GENRL_COLLISIONS_ROADCONE = 0x3B,
SND_GENRL_COLLISIONS_RUBBER = 0x3C,
SND_GENRL_COLLISIONS_SATCHEL_CHARGE = 0x3D,
SND_GENRL_COLLISIONS_SCAFFOLD_TIGHT = 0x3E,
SND_GENRL_COLLISIONS_SIGN_A = 0x3F,
SND_GENRL_COLLISIONS_SIGN_B = 0x40,
SND_GENRL_COLLISIONS_SOLID_METAL = 0x41,
SND_GENRL_COLLISIONS_SPLASH_END = 0x42,
SND_GENRL_COLLISIONS_SPLASH_START = 0x43,
SND_GENRL_COLLISIONS_WINDSCREEN = 0x44,
SND_GENRL_COLLISIONS_WIRE_FENCE1 = 0x45,
SND_GENRL_COLLISIONS_WIRE_FENCE2 = 0x46,
SND_GENRL_COLLISIONS_WIRE_FENCE3 = 0x47,
};
enum SND_GENRL_BULLET_HITS : eSoundID {
SND_GENRL_BULLET_HITS_BLOWOUT = 0x0,
SND_GENRL_BULLET_HITS_BULDIR01 = 0x1,
SND_GENRL_BULLET_HITS_BULDIR02 = 0x2,
SND_GENRL_BULLET_HITS_BULDIR03 = 0x3,
SND_GENRL_BULLET_HITS_BULIMT1L = 0x4,
SND_GENRL_BULLET_HITS_BULIMT2L = 0x5,
SND_GENRL_BULLET_HITS_BULIMT3L = 0x6,
SND_GENRL_BULLET_HITS_BULPED1L = 0x7,
SND_GENRL_BULLET_HITS_BULPED2L = 0x8,
SND_GENRL_BULLET_HITS_BULPED3L = 0x9,
SND_GENRL_BULLET_HITS_BULRMT1L = 0xA,
SND_GENRL_BULLET_HITS_BULRMT2L = 0xB,
SND_GENRL_BULLET_HITS_BULRMT3L = 0xC,
SND_GENRL_BULLET_HITS_BULWAL1L = 0xD,
SND_GENRL_BULLET_HITS_BULWAL2L = 0xE,
SND_GENRL_BULLET_HITS_BULWAL3L = 0xF,
SND_GENRL_BULLET_HITS_BULWAT01 = 0x10,
SND_GENRL_BULLET_HITS_BULWAT02 = 0x11,
SND_GENRL_BULLET_HITS_BULWAT03 = 0x12,
SND_GENRL_BULLET_HITS_BULWOD1L = 0x13,
SND_GENRL_BULLET_HITS_BULWOD2L = 0x14,
SND_GENRL_BULLET_HITS_BULWOD3L = 0x15,
SND_GENRL_BULLET_HITS_SHELL_TARMAC_1 = 0x16,
SND_GENRL_BULLET_HITS_SHELL_TARMAC_2 = 0x17,
};
enum SND_GENRL_DOORS_GARAG : eSoundID {
SND_GENRL_DOORS_GARAGE_DOOR_LOOP = 0x0,
SND_GENRL_DOORS_DOOR_OPEN = 0x1,
SND_GENRL_DOORS_GARAGE_DOOR_LIMITS = 0x2,
};
enum SND_GENRL_EXPLOSIONS : eSoundID {
SND_GENRL_EXPLOSIONS_FIRE_LOOP = 0x0,
SND_GENRL_EXPLOSIONS_DISTANT_L = 0x1,
SND_GENRL_EXPLOSIONS_LOWBEE_L = 0x2,
SND_GENRL_EXPLOSIONS_MAIN_L = 0x3,
SND_GENRL_EXPLOSIONS_NEAR_L = 0x4,
};
enum SND_GENRL_VEHICLE_GEN : eSoundID {
SND_GENRL_VEHICLE_GEN_BIKE_SKID_A = 0x0,
SND_GENRL_VEHICLE_GEN_BIKE_SKID_B = 0x1,
SND_GENRL_VEHICLE_GEN_BROKEN_ENGINE = 0x2,
SND_GENRL_VEHICLE_GEN_DISTANT = 0x3,
SND_GENRL_VEHICLE_GEN_FLATTIRELP = 0x4,
SND_GENRL_VEHICLE_GEN_FRONT_ROTOR = 0x5,
SND_GENRL_VEHICLE_GEN_GRASS_SKID_A = 0x6,
SND_GENRL_VEHICLE_GEN_GRASS_SKID_B = 0x7,
SND_GENRL_VEHICLE_GEN_GRAVEL_SKID_A = 0x8,
SND_GENRL_VEHICLE_GEN_GRAVEL_SKID_B = 0x9,
SND_GENRL_VEHICLE_GEN_HARRIER_FRONT = 0xA,
SND_GENRL_VEHICLE_GEN_HARRIER_REAR = 0xB,
SND_GENRL_VEHICLE_GEN_HOOD_FLY = 0xC,
SND_GENRL_VEHICLE_GEN_HUMLP = 0xD,
SND_GENRL_VEHICLE_GEN_JET_DIST = 0xE,
SND_GENRL_VEHICLE_GEN_LIFT_LOOP = 0xF,
SND_GENRL_VEHICLE_GEN_PROP_DIST = 0x10,
SND_GENRL_VEHICLE_GEN_PROP_NEAR = 0x11,
SND_GENRL_VEHICLE_GEN_REAR_ROTOR = 0x12,
SND_GENRL_VEHICLE_GEN_REVERSE = 0x13,
SND_GENRL_VEHICLE_GEN_REVERSE2 = 0x14,
SND_GENRL_VEHICLE_GEN_ROAD = 0x15,
SND_GENRL_VEHICLE_GEN_RUMBLE = 0x16,
SND_GENRL_VEHICLE_GEN_TAIL_ROTOR = 0x17,
SND_GENRL_VEHICLE_GEN_TARSKIDTWIN1 = 0x18,
SND_GENRL_VEHICLE_GEN_TARSKIDTWIN2 = 0x19,
SND_GENRL_VEHICLE_GEN_THRUST = 0x1A,
SND_GENRL_VEHICLE_GEN_TURRET_LOOP = 0x1B,
SND_GENRL_VEHICLE_GEN_UNDERWATER_BOAT_LOOP = 0x1C,
SND_GENRL_VEHICLE_GEN_WHINE = 0x1D,
SND_GENRL_VEHICLE_GEN_BLADE = 0x1E,
SND_GENRL_VEHICLE_GEN_BOUNCE_SUSPENSION = 0x1F,
SND_GENRL_VEHICLE_GEN_CLLIGHT = 0x20,
SND_GENRL_VEHICLE_GEN_CLNEW = 0x21,
SND_GENRL_VEHICLE_GEN_CLOLD = 0x22,
SND_GENRL_VEHICLE_GEN_CLVAN = 0x23,
SND_GENRL_VEHICLE_GEN_CTRUCK = 0x24,
SND_GENRL_VEHICLE_GEN_GENERIC_START = 0x25,
SND_GENRL_VEHICLE_GEN_HYDRAULIC_SUSPENSION = 0x26,
SND_GENRL_VEHICLE_GEN_OPLIGHT = 0x27,
SND_GENRL_VEHICLE_GEN_OPNEW = 0x28,
SND_GENRL_VEHICLE_GEN_OPOLD = 0x29,
SND_GENRL_VEHICLE_GEN_OPVAN = 0x2A,
SND_GENRL_VEHICLE_GEN_OTRUCK = 0x2B,
SND_GENRL_VEHICLE_GEN_TRIGGER_SUSPENSION = 0x2C,
};
enum SND_GENRL_FRONTEND_GAME : eSoundID {
SND_GENRL_FRONTEND_GAME_CITY_NOISE_L = 0x0,
SND_GENRL_FRONTEND_GAME_RADIOTUNELONG = 0x1,
SND_GENRL_FRONTEND_GAME_RADIOTUNESHORT = 0x2,
SND_GENRL_FRONTEND_GAME_SCANNER_NOISE_LOOP = 0x3,
SND_GENRL_FRONTEND_GAME_TIMERL = 0x4,
SND_GENRL_FRONTEND_GAME_TIMERR = 0x5,
SND_GENRL_FRONTEND_GAME_321L = 0x6,
SND_GENRL_FRONTEND_GAME_321R = 0x7,
SND_GENRL_FRONTEND_GAME_AMPFIX = 0x8,
SND_GENRL_FRONTEND_GAME_BUYCARMOD = 0x9,
SND_GENRL_FRONTEND_GAME_DRYAK47 = 0xA,
SND_GENRL_FRONTEND_GAME_DRYUZI = 0xB,
SND_GENRL_FRONTEND_GAME_GOL = 0xC,
SND_GENRL_FRONTEND_GAME_GOR = 0xD,
SND_GENRL_FRONTEND_GAME_INFOL = 0xE,
SND_GENRL_FRONTEND_GAME_INFOR = 0xF,
SND_GENRL_FRONTEND_GAME_MONEYL = 0x10,
SND_GENRL_FRONTEND_GAME_MONEYR = 0x11,
SND_GENRL_FRONTEND_GAME_PARTMISSIONL = 0x12,
SND_GENRL_FRONTEND_GAME_PARTMISSIONR = 0x13,
SND_GENRL_FRONTEND_GAME_PICKUP_AMMO1 = 0x14,
SND_GENRL_FRONTEND_GAME_PICKUP_AMMO2 = 0x15,
SND_GENRL_FRONTEND_GAME_PICKUP_AMMO3 = 0x16,
SND_GENRL_FRONTEND_GAME_RADIOCLICK = 0x17,
SND_GENRL_FRONTEND_GAME_SCANNER_CLICK = 0x18,
SND_GENRL_FRONTEND_GAME_STARTL = 0x19,
SND_GENRL_FRONTEND_GAME_STARTR = 0x1A,
SND_GENRL_FRONTEND_GAME_WEAPONL = 0x1B,
SND_GENRL_FRONTEND_GAME_WEAPONR = 0x1C,
SND_GENRL_FRONTEND_GAME_WIND_L = 0x1D,
SND_GENRL_FRONTEND_GAME_WIND_R = 0x1E,
};
enum SND_GENRL_FRONTEND_MENU : eSoundID {
SND_GENRL_FRONTEND_MENU_BACKL = 0x0,
SND_GENRL_FRONTEND_MENU_BACKR = 0x1,
SND_GENRL_FRONTEND_MENU_ERRORL = 0x2,
SND_GENRL_FRONTEND_MENU_ERRORR = 0x3,
SND_GENRL_FRONTEND_MENU_HIGHLIGHTL = 0x4,
SND_GENRL_FRONTEND_MENU_HIGHLIGHTR = 0x5,
SND_GENRL_FRONTEND_MENU_SELECTL = 0x6,
SND_GENRL_FRONTEND_MENU_SELECTR = 0x7,
SND_GENRL_FRONTEND_MENU_VOLTEST = 0x8,
};
enum SND_GENRL_RAIN : eSoundID {
SND_GENRL_RAIN_RAINLONG = 0x0,
SND_GENRL_RAIN_RAINSHORT = 0x1,
SND_GENRL_RAIN_DROP01 = 0x2,
SND_GENRL_RAIN_DROP02 = 0x3,
SND_GENRL_RAIN_DROP03 = 0x4,
SND_GENRL_RAIN_DROP04 = 0x5,
SND_GENRL_RAIN_DROP05 = 0x6,
SND_GENRL_RAIN_DROP06 = 0x7,
SND_GENRL_RAIN_DROP07 = 0x8,
SND_GENRL_RAIN_DROP08 = 0x9,
SND_GENRL_RAIN_DROP09 = 0xA,
SND_GENRL_RAIN_DROP10 = 0xB,
SND_GENRL_RAIN_RAINCAR01 = 0xC,
SND_GENRL_RAIN_RAINCAR02 = 0xD,
SND_GENRL_RAIN_RAINCAR03 = 0xE,
SND_GENRL_RAIN_RAINCAR04 = 0xF,
};
enum SND_GENRL_SWIMMING : eSoundID {
SND_GENRL_SWIMMING_SWIM1 = 0x0,
SND_GENRL_SWIMMING_SWIM2 = 0x1,
SND_GENRL_SWIMMING_SWIM3 = 0x2,
SND_GENRL_SWIMMING_SWIM4 = 0x3,
SND_GENRL_SWIMMING_SWIM5 = 0x4,
};
//
// Vehicle sounds
// - P = Player
// - D = Dummy
//
enum SND_GENRL_CRANE_P : eSoundID {
SND_GENRL_CRANE_P_CRANE_ENGINE = 0x0,
SND_GENRL_CRANE_P_LIFT_LOOP = 0x1,
SND_GENRL_CRANE_P_CRANE_LIMIT = 0x2,
SND_GENRL_CRANE_P_CRANE_OFF = 0x3,
SND_GENRL_CRANE_P_MAGNET_ATTACH = 0x4,
};
enum SND_GENRL_HARVESTER_P : eSoundID {
SND_GENRL_HARVESTER_P_HAR_AC = 0x0,
SND_GENRL_HARVESTER_P_HAR_TCRZ = 0x1,
SND_GENRL_HARVESTER_P_ZHAR_OFF = 0x2,
SND_GENRL_HARVESTER_P_ZZHARVEST_LOOP = 0x3,
SND_GENRL_HARVESTER_P_ZZHARVEST_PED = 0x4,
};
enum SND_GENRL_APACHE_D : eSoundID {
SND_GENRL_APACHE_D_APACHEDISTANT = 0x0,
SND_GENRL_APACHE_D_APACHEDUMMY = 0x1,
};
enum SND_GENRL_SINGLEPROP : eSoundID {
SND_GENRL_SINGLEPROP_SINGLEPROPFRONT = 0x0,
SND_GENRL_SINGLEPROP_SINGLEPROPREAR = 0x1,
};
enum SND_GENRL_BICYCLE_D : eSoundID {
SND_GENRL_BICYCLE_D_BICYCLE_TYRE_LOOP = 0x0,
SND_GENRL_BICYCLE_D_SPROCKET_LOOP_SLOW = 0x1,
};
enum SND_GENRL_ICEVAN_P : eSoundID {
SND_GENRL_ICEVAN_P_ICE_AC = 0x0,
SND_GENRL_ICEVAN_P_ICE_TCRZ = 0x1,
SND_GENRL_ICEVAN_P_ZICE_OFF = 0x2,
SND_GENRL_ICEVAN_P_ZZICE_TUNE = 0x3,
};
enum SND_GENRL_TRAIN_P : eSoundID {
SND_GENRL_TRAIN_P_TRAIN_BRAKES_A = 0x0,
SND_GENRL_TRAIN_P_TRAIN_BRAKES_B = 0x1,
SND_GENRL_TRAIN_P_TRAIN_ENGINE_FAST = 0x2,
SND_GENRL_TRAIN_P_TRAIN_ENGINE_SLOW = 0x3,
SND_GENRL_TRAIN_P_TRAIN_TRACK = 0x4,
SND_GENRL_TRAIN_P_TRACK_JOIN_1 = 0x5,
SND_GENRL_TRAIN_P_TRACK_JOIN_2 = 0x6,
SND_GENRL_TRAIN_P_TRACK_JOIN_3 = 0x7,
SND_GENRL_TRAIN_P_TRACK_JOIN_4 = 0x8,
SND_GENRL_TRAIN_P_TRACK_JOIN_5 = 0x9,
};
enum SND_GENRL_TRAIN_D : eSoundID {
SND_GENRL_TRAIN_D_TRAIN_ENGINE_SLOW = 0x0,
SND_GENRL_TRAIN_D_TRAIN_HORN = 0x1,
SND_GENRL_TRAIN_D_TRAIN_TRACK = 0x2,
SND_GENRL_TRAIN_D_TRACK_JOIN_3 = 0x3,
SND_GENRL_TRAIN_D_TRACK_JOIN_4 = 0x4,
SND_GENRL_TRAIN_D_TRACK_JOIN_5 = 0x5,
};
enum SND_GENRL_RC_PLANE_D : eSoundID {
SND_GENRL_RC_PLANE_D_RC_PLANE_REV = 0x0,
};
enum SND_GENRL_RC_HELI_D : eSoundID {
SND_GENRL_RC_HELI_D_RC_HELI_REV = 0x0,
};
enum SND_GENRL_HOVERCRAFT_D : eSoundID {
SND_GENRL_HOVERCRAFT_D_HOV_CRZ = 0x0,
SND_GENRL_HOVERCRAFT_D_HOV_ID = 0x1,
};
enum SND_GENRL_GOLF_D : eSoundID {
SND_GENRL_GOLF_D_GOL_CRZ = 0x0,
SND_GENRL_GOLF_D_GOL_ID = 0x1,
};
enum SND_GENRL_FORKLIFT_D : eSoundID {
SND_GENRL_FORKLIFT_D_FOR_CRZ = 0x0,
SND_GENRL_FORKLIFT_D_FOR_ID = 0x1,
SND_GENRL_FORKLIFT_D_FOR_LIFT = 0x2,
};
enum SND_GENRL_CHAINSAW_P : eSoundID {
SND_GENRL_CHAINSAW_P_SAW_CRZ = 0x0,
SND_GENRL_CHAINSAW_P_SAW_ID = 0x1,
SND_GENRL_CHAINSAW_P_SAW_OFF = 0x2,
};

View File

@ -0,0 +1,11 @@
#pragma once
#include <Base.h>
enum eAERadioType : int8 {
AE_RT_DISABLED = -1,
AE_RT_CIVILIAN = 0,
AE_RT_SPECIAL = 1,
AE_RT_UNKNOWN = 2,
AE_RT_EMERGENCY = 3,
};

View File

@ -0,0 +1,11 @@
#pragma once
#include <Base.h>
#include <extensions/WEnum.hpp>
enum class eAEVehicleAudioType : int16 {
CAR = 0, // 0x0
BIKE = 1, // 0x1
GENERIC = 2, // 0x2
};
NOTSA_WENUM_DEFS_FOR(eAEVehicleAudioType);

View File

@ -0,0 +1,54 @@
#pragma once
#include <Base.h>
enum eAEVehicleAudioTypeForName : int8 {
AE_VAT_NONE = -1, // 0xFF
AE_VAT_OFFROAD = 0, // 0x0
AE_VAT_TWO_DOOR = 1, // 0x1
AE_VAT_SPORTS_CAR = 2, // 0x2
AE_VAT_RIG = 3, // 0x3
AE_VAT_STATION_WAGON = 4, // 0x4
AE_VAT_SEDAN = 5, // 0x5
AE_VAT_TRUCK = 6, // 0x6
AE_VAT_FIRETRUCK = 7, // 0x7
AE_VAT_GARBAGE_TRUCK = 8, // 0x8
AE_VAT_STRETCH = 9, // 0x9
AE_VAT_LOWRIDER = 10, // 0xA
AE_VAT_VAN = 11, // 0xB
AE_VAT_AMBULANCE = 12, // 0xC
AE_VAT_HELICOPTER = 13, // 0xD
AE_VAT_TAXI = 14, // 0xE
AE_VAT_PICK_UP = 15, // 0xF
AE_VAT_ICE_CREAM_VAN = 16, // 0x10
AE_VAT_BUGGY = 17, // 0x11
AE_VAT_POLICE_VAN = 18, // 0x12
AE_VAT_BOAT = 19, // 0x13
AE_VAT_COACH = 20, // 0x14
AE_VAT_TANK = 21, // 0x15
AE_VAT_CONVERTIBLE = 22, // 0x16
AE_VAT_HEARSE = 23, // 0x17
AE_VAT_MONSTER_TRUCK = 24, // 0x18
AE_VAT_MOPED = 25, // 0x19
AE_VAT_TRAM = 26, // 0x1A
AE_VAT_GOLF_CART = 27, // 0x1B
AE_VAT_PLANE = 28, // 0x1C
AE_VAT_BIKE = 29, // 0x1D
AE_VAT_QUADBIKE = 30, // 0x1E
AE_VAT_COUPE = 31, // 0x1F
AE_VAT_BULLDOZER = 32, // 0x20
AE_VAT_FORKLIFT = 33, // 0x21
AE_VAT_TRACTOR = 34, // 0x22
AE_VAT_COMBINE_HARVESTER = 35, // 0x23
AE_VAT_KART = 36, // 0x24
AE_VAT_MOWER = 37, // 0x25
AE_VAT_POLICE_CAR = 38, // 0x26
AE_VAT_TRAIN = 39, // 0x27
AE_VAT_HOVERCRAFT = 40, // 0x28
AE_VAT_BICYCLE = 41, // 0x29
AE_VAT_SEA_PLANE = 42, // 0x2A
AE_VAT_DINGHY = 43, // 0x2B
AE_VAT_CAMPER_VAN = 44, // 0x2C
AE_VAT_FOUR_DOOR = 45, // 0x2D
AE_VAT_END = 46, // 0x2E
};

View File

@ -0,0 +1,27 @@
#pragma once
#include <optional>
#include <Base.h>
enum class eAEVehicleDoorType : int8 {
UNSET = -1,
LIGHT = 0,
OLD = 1,
NEW = 2,
TRUCK = 3,
VAN = 4,
};
inline std::optional<const char*> EnumToString(eAEVehicleDoorType v) {
#define ENUM_CASE(_e) case _e: #_e
using enum eAEVehicleDoorType;
switch (v) {
ENUM_CASE(UNSET);
ENUM_CASE(LIGHT);
ENUM_CASE(OLD);
ENUM_CASE(NEW);
ENUM_CASE(TRUCK);
ENUM_CASE(VAN);
}
return std::nullopt;
#undef ENUM_CASE
}

View File

@ -0,0 +1,43 @@
#pragma once
#include <optional>
#include <Base.h>
enum class eAEVehicleHornType : int8 {
NONE = -1,
BIKE = SND_GENRL_HORN_BIKEBELL, // 1
ESCORT = SND_GENRL_HORN_ESCORTHORN, // 1
CHEVY56 = SND_GENRL_HORN_HORN56CHEV, // 2
BMW328 = SND_GENRL_HORN_HORNBMW328, // 3
BUS_A = SND_GENRL_HORN_HORNBUS, // 4
BUS_B = SND_GENRL_HORN_HORNBUS2, // 5
JEEP = SND_GENRL_HORN_HORNJEEP, // 6
PICKUP = SND_GENRL_HORN_HORNPICKUP, // 7
PORSCHE = SND_GENRL_HORN_HORNPORSCHE, // 8
TRUCK = SND_GENRL_HORN_HORNTRUCK, // 9
CAR_FIRST = ESCORT, // 1
CAR_LAST = TRUCK, // 9
NUM // 10
};
inline std::optional<const char*> EnumToString(eAEVehicleHornType v) {
#define ENUM_CASE(_e) case _e: #_e
using enum eAEVehicleHornType;
switch (v) {
ENUM_CASE(NONE);
ENUM_CASE(BIKE);
ENUM_CASE(ESCORT);
ENUM_CASE(CHEVY56);
ENUM_CASE(BMW328);
ENUM_CASE(BUS_A);
ENUM_CASE(BUS_B);
ENUM_CASE(JEEP);
ENUM_CASE(PICKUP);
ENUM_CASE(PORSCHE);
ENUM_CASE(TRUCK);
}
return std::nullopt;
#undef ENUM_CASE
}

View File

@ -0,0 +1,17 @@
#pragma once
#include <Base.h>
enum eAEVehicleSoundType : int8 {
AE_CAR = 0, // 0x0
AE_BIKE = 1, // 0x1
AE_BMX = 2, // 0x2
AE_BOAT = 3, // 0x3
AE_AIRCRAFT_HELICOPTER = 4, // 0x4
AE_AIRCRAFT_PLANE = 5, // 0x5
AE_AIRCRAFT_SEAPLANE = 6, // 0x6
AE_ONE_GEAR = 7, // 0x7
AE_TRAIN = 8, // 0x8
AE_SPECIAL = 9, // 0x9
AE_NO_VEHICLE = 10, // 0xA
};

View File

@ -0,0 +1,24 @@
#pragma once
#include <optional>
#include <Base.h>
enum class eBassSetting : int8 {
NORMAL = 0, // 0x0
BOOST = 1, // 0x1
CUT = 2, // 0x2
// Keep at the bottom
NUM,
};
inline std::optional<const char*> EnumToString(eBassSetting v) {
#define ENUM_CASE(_e) case _e: #_e
using enum eBassSetting;
switch (v) {
ENUM_CASE(NORMAL);
ENUM_CASE(BOOST);
ENUM_CASE(CUT);
}
return std::nullopt;
#undef ENUM_CASE
}

View File

@ -5,16 +5,22 @@
// TODO: Make this an enum class
enum eSoundBank : int16 {
SND_BANK_UNK = -1,
SND_BANK_FEET_GENERIC = 0, // 0x0
SND_BANK_FEET_GRASS = 1, // 0x1
SND_BANK_FEET_GRAVEL = 2, // 0x2
SND_BANK_FEET_METAL = 3, // 0x3
SND_BANK_FEET_SAND = 4, // 0x4
SND_BANK_FEET_TILE = 5, // 0x5
SND_BANK_FEET_WOOD = 6, // 0x6
SND_BANK_GENRL_90S_D = 7, // 0x7
SND_BANK_GENRL_90S_P = 8, // 0x8
SND_BANK_GENRL_AIPROP = 9, // 0x9
SND_BANK_FIRST = 0,
/* Feet */
SND_BANK_FEET_GENERIC = SND_BANK_FIRST, // 0x0
SND_BANK_FEET_GRASS = 1, // 0x1
SND_BANK_FEET_GRAVEL = 2, // 0x2
SND_BANK_FEET_METAL = 3, // 0x3
SND_BANK_FEET_SAND = 4, // 0x4
SND_BANK_FEET_TILE = 5, // 0x5
SND_BANK_FEET_WOOD = 6, // 0x6
/* Vehicles and stuff */
SND_BANK_GENRL_90S_D = 7, // 0x7
SND_BANK_GENRL_90S_P = 8, // 0x8
SND_BANK_GENRL_AIPROP = 9, // 0x9
SND_BANK_GENRL_AIRPORT_D = 10, // 0xA
SND_BANK_GENRL_AIRPORT_P = 11, // 0xB
SND_BANK_GENRL_APACHE = 12, // 0xC
@ -33,10 +39,14 @@ enum eSoundBank : int16 {
SND_BANK_GENRL_BUICK_D = 25, // 0x19
SND_BANK_GENRL_BUICK_P = 26, // 0x1A
SND_BANK_GENRL_BULLET_HITS = 27, // 0x1B
SND_BANK_GENRL_BULLET_PASS_1 = 28, // 0x1C
SND_BANK_GENRL_BULLET_PASS_FIRST = 28,
SND_BANK_GENRL_BULLET_PASS_1 = SND_BANK_GENRL_BULLET_PASS_FIRST, // 0x1C
SND_BANK_GENRL_BULLET_PASS_2 = 29, // 0x1D
SND_BANK_GENRL_BULLET_PASS_3 = 30, // 0x1E
SND_BANK_GENRL_BULLET_PASS_4 = 31, // 0x1F
SND_BANK_GENRL_BULLET_PASS_LAST = SND_BANK_GENRL_BULLET_PASS_4,
SND_BANK_GENRL_BUS_D = 32, // 0x20
SND_BANK_GENRL_BUS_P = 33, // 0x21
SND_BANK_GENRL_CADILLAC_D = 34, // 0x22
@ -153,6 +163,7 @@ enum eSoundBank : int16 {
SND_BANK_PAIN_A_FEMALE = 145, // 0x91
SND_BANK_PAIN_A_MALE = 146, // 0x92
/* Script */
SND_BANK_SCRIPT_FIRST = 147, // NOTSA
SND_BANK_SCRIPT_SCANNER_AREAS = SND_BANK_SCRIPT_FIRST, // 0x93
SND_BANK_SCRIPT_SCANNER_COLOURS = 148, // 0x94
@ -372,6 +383,8 @@ enum eSoundBank : int16 {
SND_BANK_SCRIPT_ZER3 = 362, // 0x16A
SND_BANK_SCRIPT_ZER4 = 363, // 0x16B
SND_BANK_SCRIPT_ZEROING_IN = 364, // 0x16C
/* Ped speech */
SND_BANK_SPC_EA_ARMY1 = 365, // 0x16D
SND_BANK_SPC_EA_ARMY2 = 366, // 0x16E
SND_BANK_SPC_EA_ARMY3 = 367, // 0x16F
@ -717,6 +730,729 @@ enum eSoundBank : int16 {
SND_BANK_SPC_PA_WG2 = 707, // 0x2C3
SND_BANK_SPC_PA_WR = 708, // 0x2C4
SND_BANK_SPC_PA_WR2 = 709, // 0x2C5
NUM_SND_BANKS = 710, // 0x2C6
SND_BANK_END = NUM_SND_BANKS
};
NOTSA_WENUM_DEFS_FOR(eSoundBank);
inline std::optional<const char*> EnumToString(eSoundBank v) {
#define ENUM_CASE(_e) \
case _e: return #_e
switch (v) {
ENUM_CASE(SND_BANK_UNK);
ENUM_CASE(SND_BANK_FEET_GENERIC);
ENUM_CASE(SND_BANK_FEET_GRASS);
ENUM_CASE(SND_BANK_FEET_GRAVEL);
ENUM_CASE(SND_BANK_FEET_METAL);
ENUM_CASE(SND_BANK_FEET_SAND);
ENUM_CASE(SND_BANK_FEET_TILE);
ENUM_CASE(SND_BANK_FEET_WOOD);
ENUM_CASE(SND_BANK_GENRL_90S_D);
ENUM_CASE(SND_BANK_GENRL_90S_P);
ENUM_CASE(SND_BANK_GENRL_AIPROP);
ENUM_CASE(SND_BANK_GENRL_AIRPORT_D);
ENUM_CASE(SND_BANK_GENRL_AIRPORT_P);
ENUM_CASE(SND_BANK_GENRL_APACHE);
ENUM_CASE(SND_BANK_GENRL_APACHE_D);
ENUM_CASE(SND_BANK_GENRL_ATV_D);
ENUM_CASE(SND_BANK_GENRL_ATV_P);
ENUM_CASE(SND_BANK_GENRL_BELAIR_D);
ENUM_CASE(SND_BANK_GENRL_BELAIR_P);
ENUM_CASE(SND_BANK_GENRL_BICYCLE_D);
ENUM_CASE(SND_BANK_GENRL_BICYCLE_P);
ENUM_CASE(SND_BANK_GENRL_BOAT_CRUISER_D);
ENUM_CASE(SND_BANK_GENRL_BOAT_INBOARD_D);
ENUM_CASE(SND_BANK_GENRL_BOAT_INBOARD_P);
ENUM_CASE(SND_BANK_GENRL_BOAT_SPEEDBOAT_D);
ENUM_CASE(SND_BANK_GENRL_BOAT_V12_D);
ENUM_CASE(SND_BANK_GENRL_BUICK_D);
ENUM_CASE(SND_BANK_GENRL_BUICK_P);
ENUM_CASE(SND_BANK_GENRL_BULLET_HITS);
ENUM_CASE(SND_BANK_GENRL_BULLET_PASS_1);
ENUM_CASE(SND_BANK_GENRL_BULLET_PASS_2);
ENUM_CASE(SND_BANK_GENRL_BULLET_PASS_3);
ENUM_CASE(SND_BANK_GENRL_BULLET_PASS_4);
ENUM_CASE(SND_BANK_GENRL_BUS_D);
ENUM_CASE(SND_BANK_GENRL_BUS_P);
ENUM_CASE(SND_BANK_GENRL_CADILLAC_D);
ENUM_CASE(SND_BANK_GENRL_CADILLAC_P);
ENUM_CASE(SND_BANK_GENRL_CHAINSAW_P);
ENUM_CASE(SND_BANK_GENRL_COBRA_D);
ENUM_CASE(SND_BANK_GENRL_COBRA_P);
ENUM_CASE(SND_BANK_GENRL_COLLISIONS);
ENUM_CASE(SND_BANK_GENRL_COPBIKE_D);
ENUM_CASE(SND_BANK_GENRL_COPBIKE_P);
ENUM_CASE(SND_BANK_GENRL_COUPE_D);
ENUM_CASE(SND_BANK_GENRL_COUPE_P);
ENUM_CASE(SND_BANK_GENRL_CRANE_P);
ENUM_CASE(SND_BANK_GENRL_CUTLASS_D);
ENUM_CASE(SND_BANK_GENRL_CUTLASS_P);
ENUM_CASE(SND_BANK_GENRL_DIRTBIKE_D);
ENUM_CASE(SND_BANK_GENRL_DIRTBIKE_P);
ENUM_CASE(SND_BANK_GENRL_DODGE_D);
ENUM_CASE(SND_BANK_GENRL_DODGE_P);
ENUM_CASE(SND_BANK_GENRL_DOORS);
ENUM_CASE(SND_BANK_GENRL_EXPLOSIONS);
ENUM_CASE(SND_BANK_GENRL_FASTPROP);
ENUM_CASE(SND_BANK_GENRL_FASTPROP_D);
ENUM_CASE(SND_BANK_GENRL_FORD_T_D);
ENUM_CASE(SND_BANK_GENRL_FORD_T_P);
ENUM_CASE(SND_BANK_GENRL_FORKLIFT_D);
ENUM_CASE(SND_BANK_GENRL_FORKLIFT_P);
ENUM_CASE(SND_BANK_GENRL_FRONTEND_GAME);
ENUM_CASE(SND_BANK_GENRL_FRONTEND_MENU);
ENUM_CASE(SND_BANK_GENRL_GOKART_D);
ENUM_CASE(SND_BANK_GENRL_GOKART_P);
ENUM_CASE(SND_BANK_GENRL_GOLF_D);
ENUM_CASE(SND_BANK_GENRL_GOLF_P);
ENUM_CASE(SND_BANK_GENRL_GOLFCART_P);
ENUM_CASE(SND_BANK_GENRL_HAIRCUT_V1);
ENUM_CASE(SND_BANK_GENRL_HAIRCUT_V2);
ENUM_CASE(SND_BANK_GENRL_HARVESTER_D);
ENUM_CASE(SND_BANK_GENRL_HARVESTER_P);
ENUM_CASE(SND_BANK_GENRL_HEAVY_V8_D);
ENUM_CASE(SND_BANK_GENRL_HEAVY_V8_P);
ENUM_CASE(SND_BANK_GENRL_HONDA_D);
ENUM_CASE(SND_BANK_GENRL_HONDA_P);
ENUM_CASE(SND_BANK_GENRL_HORN);
ENUM_CASE(SND_BANK_GENRL_HOTROD_D);
ENUM_CASE(SND_BANK_GENRL_HOTROD_P);
ENUM_CASE(SND_BANK_GENRL_HOVERCRAFT_D);
ENUM_CASE(SND_BANK_GENRL_HOVERCRAFT_P);
ENUM_CASE(SND_BANK_GENRL_ICEVAN_P);
ENUM_CASE(SND_BANK_GENRL_JALOPY_D);
ENUM_CASE(SND_BANK_GENRL_JALOPY_P);
ENUM_CASE(SND_BANK_GENRL_LOADING);
ENUM_CASE(SND_BANK_GENRL_MACKTRUCK_D);
ENUM_CASE(SND_BANK_GENRL_MACKTRUCK_P);
ENUM_CASE(SND_BANK_GENRL_MAVERICK);
ENUM_CASE(SND_BANK_GENRL_MERC_D);
ENUM_CASE(SND_BANK_GENRL_MERC_P);
ENUM_CASE(SND_BANK_GENRL_MODEL_T_D);
ENUM_CASE(SND_BANK_GENRL_MODEL_T_P);
ENUM_CASE(SND_BANK_GENRL_MONSTER_D);
ENUM_CASE(SND_BANK_GENRL_MONSTER_P);
ENUM_CASE(SND_BANK_GENRL_MUSTANG_D);
ENUM_CASE(SND_BANK_GENRL_MUSTANG_P);
ENUM_CASE(SND_BANK_GENRL_PACARD_D);
ENUM_CASE(SND_BANK_GENRL_PACARD_P);
ENUM_CASE(SND_BANK_GENRL_PADDY_D);
ENUM_CASE(SND_BANK_GENRL_PADDY_P);
ENUM_CASE(SND_BANK_GENRL_PATHFINDER_D);
ENUM_CASE(SND_BANK_GENRL_PATHFINDER_P);
ENUM_CASE(SND_BANK_GENRL_PONTIAC_D);
ENUM_CASE(SND_BANK_GENRL_PONTIAC_P);
ENUM_CASE(SND_BANK_GENRL_PORSCHE_D);
ENUM_CASE(SND_BANK_GENRL_PORSCHE_P);
ENUM_CASE(SND_BANK_GENRL_R22);
ENUM_CASE(SND_BANK_GENRL_RAIN);
ENUM_CASE(SND_BANK_GENRL_RC_CAR_D);
ENUM_CASE(SND_BANK_GENRL_RC_CAR_P);
ENUM_CASE(SND_BANK_GENRL_RC_HELI_D);
ENUM_CASE(SND_BANK_GENRL_RC_HELI_P);
ENUM_CASE(SND_BANK_GENRL_RC_PLANE_D);
ENUM_CASE(SND_BANK_GENRL_RC_PLANE_P);
ENUM_CASE(SND_BANK_GENRL_RC_TANK_D);
ENUM_CASE(SND_BANK_GENRL_RC_TANK_P);
ENUM_CASE(SND_BANK_GENRL_RS427_D);
ENUM_CASE(SND_BANK_GENRL_RS427_P);
ENUM_CASE(SND_BANK_GENRL_SALOON_D);
ENUM_CASE(SND_BANK_GENRL_SALOON_P);
ENUM_CASE(SND_BANK_GENRL_SCOOTER_D);
ENUM_CASE(SND_BANK_GENRL_SCOOTER_P);
ENUM_CASE(SND_BANK_GENRL_SINGLEPROP);
ENUM_CASE(SND_BANK_GENRL_SKATEBOARD_P);
ENUM_CASE(SND_BANK_GENRL_SPORT_D);
ENUM_CASE(SND_BANK_GENRL_SPORT_P);
ENUM_CASE(SND_BANK_GENRL_SPORTSBIKE_D);
ENUM_CASE(SND_BANK_GENRL_SPORTSBIKE_P);
ENUM_CASE(SND_BANK_GENRL_SWEEPER_D);
ENUM_CASE(SND_BANK_GENRL_SWEEPER_P);
ENUM_CASE(SND_BANK_GENRL_SWIMMING);
ENUM_CASE(SND_BANK_GENRL_TEMP_D);
ENUM_CASE(SND_BANK_GENRL_TEMP_P);
ENUM_CASE(SND_BANK_GENRL_TRAIN_D);
ENUM_CASE(SND_BANK_GENRL_TRAIN_P);
ENUM_CASE(SND_BANK_GENRL_TRAM_D);
ENUM_CASE(SND_BANK_GENRL_TWINPROP);
ENUM_CASE(SND_BANK_GENRL_TWINPROP_D);
ENUM_CASE(SND_BANK_GENRL_VAN_D);
ENUM_CASE(SND_BANK_GENRL_VAN_P);
ENUM_CASE(SND_BANK_GENRL_VEHICLE_GEN);
ENUM_CASE(SND_BANK_GENRL_VTWINBIKE_D);
ENUM_CASE(SND_BANK_GENRL_VTWINBIKE_P);
ENUM_CASE(SND_BANK_GENRL_VW_VAN_D);
ENUM_CASE(SND_BANK_GENRL_VW_VAN_P);
ENUM_CASE(SND_BANK_GENRL_WEAPONS);
ENUM_CASE(SND_BANK_PAIN_A_CARL);
ENUM_CASE(SND_BANK_PAIN_A_FEMALE);
ENUM_CASE(SND_BANK_PAIN_A_MALE);
ENUM_CASE(SND_BANK_SCRIPT_SCANNER_AREAS);
ENUM_CASE(SND_BANK_SCRIPT_SCANNER_COLOURS);
ENUM_CASE(SND_BANK_SCRIPT_SCANNER_DIRECTIONS);
ENUM_CASE(SND_BANK_SCRIPT_SCANNER_INSTRUCTIONS);
ENUM_CASE(SND_BANK_SCRIPT_SCANNER_NUMBERS);
ENUM_CASE(SND_BANK_SCRIPT_SCANNER_VEHICLES);
ENUM_CASE(SND_BANK_SCRIPT_AIR_HORN);
ENUM_CASE(SND_BANK_SCRIPT_ARCHITECTURAL_ESPIONAGE);
ENUM_CASE(SND_BANK_SCRIPT_ARE_YOU_GOING_TO_SAN_FIERO);
ENUM_CASE(SND_BANK_SCRIPT_BACK_TO_SCHOOL);
ENUM_CASE(SND_BANK_SCRIPT_BALLA);
ENUM_CASE(SND_BANK_SCRIPT_BANDIT);
ENUM_CASE(SND_BANK_SCRIPT_BARBERS);
ENUM_CASE(SND_BANK_SCRIPT_BASKETBALL);
ENUM_CASE(SND_BANK_SCRIPT_BBOX);
ENUM_CASE(SND_BANK_SCRIPT_BCS5);
ENUM_CASE(SND_BANK_SCRIPT_BEE);
ENUM_CASE(SND_BANK_SCRIPT_BFYCRP_GAMBLING);
ENUM_CASE(SND_BANK_SCRIPT_BIKE_COURIER);
ENUM_CASE(SND_BANK_SCRIPT_BLACKJACK_DEALER);
ENUM_CASE(SND_BANK_SCRIPT_BLACK_PROJECT);
ENUM_CASE(SND_BANK_SCRIPT_BOAT_SCHOOL);
ENUM_CASE(SND_BANK_SCRIPT_BREAKING_THE_BANK);
ENUM_CASE(SND_BANK_SCRIPT_BURNING_DESIRE);
ENUM_CASE(SND_BANK_SCRIPT_CARGO_PLANE);
ENUM_CASE(SND_BANK_SCRIPT_CAS1);
ENUM_CASE(SND_BANK_SCRIPT_CAS11);
ENUM_CASE(SND_BANK_SCRIPT_CAS2);
ENUM_CASE(SND_BANK_SCRIPT_CAS3);
ENUM_CASE(SND_BANK_SCRIPT_CAS4);
ENUM_CASE(SND_BANK_SCRIPT_CAS5);
ENUM_CASE(SND_BANK_SCRIPT_CAS6);
ENUM_CASE(SND_BANK_SCRIPT_CAS9);
ENUM_CASE(SND_BANK_SCRIPT_CAT);
ENUM_CASE(SND_BANK_SCRIPT_CAT1);
ENUM_CASE(SND_BANK_SCRIPT_CAT2);
ENUM_CASE(SND_BANK_SCRIPT_CAT2_BANK);
ENUM_CASE(SND_BANK_SCRIPT_CAT3);
ENUM_CASE(SND_BANK_SCRIPT_CAT4);
ENUM_CASE(SND_BANK_SCRIPT_CATX);
ENUM_CASE(SND_BANK_SCRIPT_CES1);
ENUM_CASE(SND_BANK_SCRIPT_CES2);
ENUM_CASE(SND_BANK_SCRIPT_CESX);
ENUM_CASE(SND_BANK_SCRIPT_CRA1);
ENUM_CASE(SND_BANK_SCRIPT_CRA2);
ENUM_CASE(SND_BANK_SCRIPT_CRA3);
ENUM_CASE(SND_BANK_SCRIPT_DAM_AND_BLAST);
ENUM_CASE(SND_BANK_SCRIPT_DANCE_HIGH);
ENUM_CASE(SND_BANK_SCRIPT_DANCE_LOW);
ENUM_CASE(SND_BANK_SCRIPT_DANCE_MED);
ENUM_CASE(SND_BANK_SCRIPT_DANCE_NOT);
ENUM_CASE(SND_BANK_SCRIPT_DA_NANG);
ENUM_CASE(SND_BANK_SCRIPT_DC2);
ENUM_CASE(SND_BANK_SCRIPT_DECONSTRUCTION);
ENUM_CASE(SND_BANK_SCRIPT_DES1);
ENUM_CASE(SND_BANK_SCRIPT_DES2);
ENUM_CASE(SND_BANK_SCRIPT_DES3);
ENUM_CASE(SND_BANK_SCRIPT_DES6);
ENUM_CASE(SND_BANK_SCRIPT_DES8);
ENUM_CASE(SND_BANK_SCRIPT_DES9);
ENUM_CASE(SND_BANK_SCRIPT_DOGG);
ENUM_CASE(SND_BANK_SCRIPT_DON_PEYOTE);
ENUM_CASE(SND_BANK_SCRIPT_DUALITY);
ENUM_CASE(SND_BANK_SCRIPT_END_OF_THE_LINE);
ENUM_CASE(SND_BANK_SCRIPT_EXPLOSIVE_SITUATION);
ENUM_CASE(SND_BANK_SCRIPT_FAR2);
ENUM_CASE(SND_BANK_SCRIPT_FAR3);
ENUM_CASE(SND_BANK_SCRIPT_FAR4);
ENUM_CASE(SND_BANK_SCRIPT_FAR5);
ENUM_CASE(SND_BANK_SCRIPT_FIN1);
ENUM_CASE(SND_BANK_SCRIPT_FIN2);
ENUM_CASE(SND_BANK_SCRIPT_FREEFALL);
ENUM_CASE(SND_BANK_SCRIPT_GAR1);
ENUM_CASE(SND_BANK_SCRIPT_GAR2);
ENUM_CASE(SND_BANK_SCRIPT_GATE);
ENUM_CASE(SND_BANK_SCRIPT_GOGO);
ENUM_CASE(SND_BANK_SCRIPT_GREY_IMPORTS);
ENUM_CASE(SND_BANK_SCRIPT_GRO1);
ENUM_CASE(SND_BANK_SCRIPT_GRO2);
ENUM_CASE(SND_BANK_SCRIPT_GYM);
ENUM_CASE(SND_BANK_SCRIPT_HE1);
ENUM_CASE(SND_BANK_SCRIPT_HE2);
ENUM_CASE(SND_BANK_SCRIPT_HE3);
ENUM_CASE(SND_BANK_SCRIPT_HE4);
ENUM_CASE(SND_BANK_SCRIPT_HE5);
ENUM_CASE(SND_BANK_SCRIPT_HE8);
ENUM_CASE(SND_BANK_SCRIPT_HEI);
ENUM_CASE(SND_BANK_SCRIPT_HIJACK);
ENUM_CASE(SND_BANK_SCRIPT_HOME_INVASION);
ENUM_CASE(SND_BANK_SCRIPT_HOUSE_PARTY);
ENUM_CASE(SND_BANK_SCRIPT_INT1);
ENUM_CASE(SND_BANK_SCRIPT_INT2);
ENUM_CASE(SND_BANK_SCRIPT_JIZX);
ENUM_CASE(SND_BANK_SCRIPT_JIZZY);
ENUM_CASE(SND_BANK_SCRIPT_KEYCARD_TO_HER_HEART);
ENUM_CASE(SND_BANK_SCRIPT_KEYPAD);
ENUM_CASE(SND_BANK_SCRIPT_KUNG);
ENUM_CASE(SND_BANK_SCRIPT_LIFE_BEACH_CONV);
ENUM_CASE(SND_BANK_SCRIPT_LOC1);
ENUM_CASE(SND_BANK_SCRIPT_LOC2);
ENUM_CASE(SND_BANK_SCRIPT_LOC3);
ENUM_CASE(SND_BANK_SCRIPT_LOC4);
ENUM_CASE(SND_BANK_SCRIPT_LOCX);
ENUM_CASE(SND_BANK_SCRIPT_LOS_SEPULCROS);
ENUM_CASE(SND_BANK_SCRIPT_LOWR);
ENUM_CASE(SND_BANK_SCRIPT_LURE);
ENUM_CASE(SND_BANK_SCRIPT_MACX);
ENUM_CASE(SND_BANK_SCRIPT_MADD_DOG);
ENUM_CASE(SND_BANK_SCRIPT_MAD_DOGGS_RHYMES);
ENUM_CASE(SND_BANK_SCRIPT_MAN1);
ENUM_CASE(SND_BANK_SCRIPT_MAN2);
ENUM_CASE(SND_BANK_SCRIPT_MAN3);
ENUM_CASE(SND_BANK_SCRIPT_MAN5);
ENUM_CASE(SND_BANK_SCRIPT_MANAGEMENT_ISSUES);
ENUM_CASE(SND_BANK_SCRIPT_MBARB);
ENUM_CASE(SND_BANK_SCRIPT_MCAT);
ENUM_CASE(SND_BANK_SCRIPT_MCES);
ENUM_CASE(SND_BANK_SCRIPT_MDEN);
ENUM_CASE(SND_BANK_SCRIPT_MEAT_BUSINESS);
ENUM_CASE(SND_BANK_SCRIPT_MECHANIC);
ENUM_CASE(SND_BANK_SCRIPT_MECHANIC_DIALOGUE);
ENUM_CASE(SND_BANK_SCRIPT_MHEL);
ENUM_CASE(SND_BANK_SCRIPT_MHRZ);
ENUM_CASE(SND_BANK_SCRIPT_MJET);
ENUM_CASE(SND_BANK_SCRIPT_MJIZ);
ENUM_CASE(SND_BANK_SCRIPT_MKND);
ENUM_CASE(SND_BANK_SCRIPT_MKP);
ENUM_CASE(SND_BANK_SCRIPT_MLOC);
ENUM_CASE(SND_BANK_SCRIPT_MMICH);
ENUM_CASE(SND_BANK_SCRIPT_MMILL);
ENUM_CASE(SND_BANK_SCRIPT_MOUNTAIN_CLOUD_BOY);
ENUM_CASE(SND_BANK_SCRIPT_MPUL);
ENUM_CASE(SND_BANK_SCRIPT_MROS);
ENUM_CASE(SND_BANK_SCRIPT_MSAL);
ENUM_CASE(SND_BANK_SCRIPT_MSMK);
ENUM_CASE(SND_BANK_SCRIPT_MSWE);
ENUM_CASE(SND_BANK_SCRIPT_MTEN);
ENUM_CASE(SND_BANK_SCRIPT_MTG);
ENUM_CASE(SND_BANK_SCRIPT_MTOR);
ENUM_CASE(SND_BANK_SCRIPT_MTRU);
ENUM_CASE(SND_BANK_SCRIPT_MWUZ);
ENUM_CASE(SND_BANK_SCRIPT_MZAHN);
ENUM_CASE(SND_BANK_SCRIPT_MZER);
ENUM_CASE(SND_BANK_SCRIPT_NOE);
ENUM_CASE(SND_BANK_SCRIPT_NULL);
ENUM_CASE(SND_BANK_SCRIPT_OGLOC);
ENUM_CASE(SND_BANK_SCRIPT_OTB);
ENUM_CASE(SND_BANK_SCRIPT_PIMPING);
ENUM_CASE(SND_BANK_SCRIPT_POOL);
ENUM_CASE(SND_BANK_SCRIPT_POOL_MINIGAME);
ENUM_CASE(SND_BANK_SCRIPT_PUNCTURE_WOUNDS);
ENUM_CASE(SND_BANK_SCRIPT_RESTAURANT);
ENUM_CASE(SND_BANK_SCRIPT_REUNITING_THE_FAMILIES);
ENUM_CASE(SND_BANK_SCRIPT_ROB_GAS_STATION);
ENUM_CASE(SND_BANK_SCRIPT_ROT1);
ENUM_CASE(SND_BANK_SCRIPT_ROT2);
ENUM_CASE(SND_BANK_SCRIPT_ROT4);
ENUM_CASE(SND_BANK_SCRIPT_ROULETTE);
ENUM_CASE(SND_BANK_SCRIPT_RYD1);
ENUM_CASE(SND_BANK_SCRIPT_RYD2);
ENUM_CASE(SND_BANK_SCRIPT_RYD3);
ENUM_CASE(SND_BANK_SCRIPT_RYDX);
ENUM_CASE(SND_BANK_SCRIPT_SCR1);
ENUM_CASE(SND_BANK_SCRIPT_SHOOTING_RANGE);
ENUM_CASE(SND_BANK_SCRIPT_SHRK);
ENUM_CASE(SND_BANK_SCRIPT_SMO1);
ENUM_CASE(SND_BANK_SCRIPT_SMO2);
ENUM_CASE(SND_BANK_SCRIPT_SMO3);
ENUM_CASE(SND_BANK_SCRIPT_SMO4);
ENUM_CASE(SND_BANK_SCRIPT_SMOX);
ENUM_CASE(SND_BANK_SCRIPT_SOLO);
ENUM_CASE(SND_BANK_SCRIPT_STADIUM_CHEERS);
ENUM_CASE(SND_BANK_SCRIPT_STINGER);
ENUM_CASE(SND_BANK_SCRIPT_STL1);
ENUM_CASE(SND_BANK_SCRIPT_STL2);
ENUM_CASE(SND_BANK_SCRIPT_STL4);
ENUM_CASE(SND_BANK_SCRIPT_STL5);
ENUM_CASE(SND_BANK_SCRIPT_SWE1);
ENUM_CASE(SND_BANK_SCRIPT_SWE2);
ENUM_CASE(SND_BANK_SCRIPT_SWE3);
ENUM_CASE(SND_BANK_SCRIPT_SWE4);
ENUM_CASE(SND_BANK_SCRIPT_SWE5);
ENUM_CASE(SND_BANK_SCRIPT_SWE7);
ENUM_CASE(SND_BANK_SCRIPT_SWEX);
ENUM_CASE(SND_BANK_SCRIPT_SYN1);
ENUM_CASE(SND_BANK_SCRIPT_SYN2);
ENUM_CASE(SND_BANK_SCRIPT_SYN3);
ENUM_CASE(SND_BANK_SCRIPT_SYN4);
ENUM_CASE(SND_BANK_SCRIPT_SYN5);
ENUM_CASE(SND_BANK_SCRIPT_SYN7);
ENUM_CASE(SND_BANK_SCRIPT_TATTOO);
ENUM_CASE(SND_BANK_SCRIPT_TBOX);
ENUM_CASE(SND_BANK_SCRIPT_TEMPEST);
ENUM_CASE(SND_BANK_SCRIPT_THE_JAR_OF_GREEN_GOO);
ENUM_CASE(SND_BANK_SCRIPT_TORX);
ENUM_CASE(SND_BANK_SCRIPT_TRU1);
ENUM_CASE(SND_BANK_SCRIPT_TRU2);
ENUM_CASE(SND_BANK_SCRIPT_TRUX);
ENUM_CASE(SND_BANK_SCRIPT_UNCLE_SAM);
ENUM_CASE(SND_BANK_SCRIPT_UP_UP_AND_AWAY);
ENUM_CASE(SND_BANK_SCRIPT_VALET);
ENUM_CASE(SND_BANK_SCRIPT_VCR1);
ENUM_CASE(SND_BANK_SCRIPT_VCR2);
ENUM_CASE(SND_BANK_SCRIPT_VENDING);
ENUM_CASE(SND_BANK_SCRIPT_VERTICAL_BIRD);
ENUM_CASE(SND_BANK_SCRIPT_VIDEO_POKER);
ENUM_CASE(SND_BANK_SCRIPT_VO);
ENUM_CASE(SND_BANK_SCRIPT_WBOX);
ENUM_CASE(SND_BANK_SCRIPT_WFYCRP_GAMBLING);
ENUM_CASE(SND_BANK_SCRIPT_WUZ1);
ENUM_CASE(SND_BANK_SCRIPT_WUZ2);
ENUM_CASE(SND_BANK_SCRIPT_WUZ4);
ENUM_CASE(SND_BANK_SCRIPT_WUZX);
ENUM_CASE(SND_BANK_SCRIPT_ZER1);
ENUM_CASE(SND_BANK_SCRIPT_ZER2);
ENUM_CASE(SND_BANK_SCRIPT_ZER3);
ENUM_CASE(SND_BANK_SCRIPT_ZER4);
ENUM_CASE(SND_BANK_SCRIPT_ZEROING_IN);
ENUM_CASE(SND_BANK_SPC_EA_ARMY1);
ENUM_CASE(SND_BANK_SPC_EA_ARMY2);
ENUM_CASE(SND_BANK_SPC_EA_ARMY3);
ENUM_CASE(SND_BANK_SPC_EA_EMT1);
ENUM_CASE(SND_BANK_SPC_EA_EMT2);
ENUM_CASE(SND_BANK_SPC_EA_EMT3);
ENUM_CASE(SND_BANK_SPC_EA_EMT4);
ENUM_CASE(SND_BANK_SPC_EA_EMT5);
ENUM_CASE(SND_BANK_SPC_EA_FBI2);
ENUM_CASE(SND_BANK_SPC_EA_FBI3);
ENUM_CASE(SND_BANK_SPC_EA_FBI4);
ENUM_CASE(SND_BANK_SPC_EA_FBI5);
ENUM_CASE(SND_BANK_SPC_EA_FBI6);
ENUM_CASE(SND_BANK_SPC_EA_LAPD1);
ENUM_CASE(SND_BANK_SPC_EA_LAPD2);
ENUM_CASE(SND_BANK_SPC_EA_LAPD3);
ENUM_CASE(SND_BANK_SPC_EA_LAPD4);
ENUM_CASE(SND_BANK_SPC_EA_LAPD5);
ENUM_CASE(SND_BANK_SPC_EA_LAPD6);
ENUM_CASE(SND_BANK_SPC_EA_LAPD7);
ENUM_CASE(SND_BANK_SPC_EA_LAPD8);
ENUM_CASE(SND_BANK_SPC_EA_LVPD1);
ENUM_CASE(SND_BANK_SPC_EA_LVPD2);
ENUM_CASE(SND_BANK_SPC_EA_LVPD3);
ENUM_CASE(SND_BANK_SPC_EA_LVPD4);
ENUM_CASE(SND_BANK_SPC_EA_LVPD5);
ENUM_CASE(SND_BANK_SPC_EA_MCOP1);
ENUM_CASE(SND_BANK_SPC_EA_MCOP2);
ENUM_CASE(SND_BANK_SPC_EA_MCOP3);
ENUM_CASE(SND_BANK_SPC_EA_MCOP4);
ENUM_CASE(SND_BANK_SPC_EA_MCOP5);
ENUM_CASE(SND_BANK_SPC_EA_MCOP6);
ENUM_CASE(SND_BANK_SPC_EA_PULASKI);
ENUM_CASE(SND_BANK_SPC_EA_RCOP1);
ENUM_CASE(SND_BANK_SPC_EA_RCOP2);
ENUM_CASE(SND_BANK_SPC_EA_RCOP3);
ENUM_CASE(SND_BANK_SPC_EA_RCOP4);
ENUM_CASE(SND_BANK_SPC_EA_SFPD1);
ENUM_CASE(SND_BANK_SPC_EA_SFPD2);
ENUM_CASE(SND_BANK_SPC_EA_SFPD3);
ENUM_CASE(SND_BANK_SPC_EA_SFPD4);
ENUM_CASE(SND_BANK_SPC_EA_SFPD5);
ENUM_CASE(SND_BANK_SPC_EA_SWAT1);
ENUM_CASE(SND_BANK_SPC_EA_SWAT2);
ENUM_CASE(SND_BANK_SPC_EA_SWAT4);
ENUM_CASE(SND_BANK_SPC_EA_SWAT6);
ENUM_CASE(SND_BANK_SPC_FA_BARBARA);
ENUM_CASE(SND_BANK_SPC_FA_BMOBAR);
ENUM_CASE(SND_BANK_SPC_FA_BMYBARB);
ENUM_CASE(SND_BANK_SPC_FA_BMYTATT);
ENUM_CASE(SND_BANK_SPC_FA_CATALINA);
ENUM_CASE(SND_BANK_SPC_FA_DENISE);
ENUM_CASE(SND_BANK_SPC_FA_HELENA);
ENUM_CASE(SND_BANK_SPC_FA_KATIE);
ENUM_CASE(SND_BANK_SPC_FA_MICHELLE);
ENUM_CASE(SND_BANK_SPC_FA_MILLIE);
ENUM_CASE(SND_BANK_SPC_FA_POL_ANN);
ENUM_CASE(SND_BANK_SPC_FA_WFYBURG);
ENUM_CASE(SND_BANK_SPC_FA_WFYCLOT);
ENUM_CASE(SND_BANK_SPC_FA_WMYAMMO);
ENUM_CASE(SND_BANK_SPC_FA_WMYBARB);
ENUM_CASE(SND_BANK_SPC_FA_WMYBELL);
ENUM_CASE(SND_BANK_SPC_FA_WMYCLOT);
ENUM_CASE(SND_BANK_SPC_FA_WMYPIZZ);
ENUM_CASE(SND_BANK_SPC_GA_BBDYG1);
ENUM_CASE(SND_BANK_SPC_GA_BBDYG2);
ENUM_CASE(SND_BANK_SPC_GA_BFORI);
ENUM_CASE(SND_BANK_SPC_GA_BFOST);
ENUM_CASE(SND_BANK_SPC_GA_BFYBE);
ENUM_CASE(SND_BANK_SPC_GA_BFYBU);
ENUM_CASE(SND_BANK_SPC_GA_BFYCRP);
ENUM_CASE(SND_BANK_SPC_GA_BFYPRO);
ENUM_CASE(SND_BANK_SPC_GA_BFYRI);
ENUM_CASE(SND_BANK_SPC_GA_BFYST);
ENUM_CASE(SND_BANK_SPC_GA_BIKDRUG);
ENUM_CASE(SND_BANK_SPC_GA_BIKERA);
ENUM_CASE(SND_BANK_SPC_GA_BIKERB);
ENUM_CASE(SND_BANK_SPC_GA_BMOCD);
ENUM_CASE(SND_BANK_SPC_GA_BMORI);
ENUM_CASE(SND_BANK_SPC_GA_BMOSEC);
ENUM_CASE(SND_BANK_SPC_GA_BMOST);
ENUM_CASE(SND_BANK_SPC_GA_BMOTR1);
ENUM_CASE(SND_BANK_SPC_GA_BMYAP);
ENUM_CASE(SND_BANK_SPC_GA_BMYBE);
ENUM_CASE(SND_BANK_SPC_GA_BMYBOUN);
ENUM_CASE(SND_BANK_SPC_GA_BMYBOX);
ENUM_CASE(SND_BANK_SPC_GA_BMYBU);
ENUM_CASE(SND_BANK_SPC_GA_BMYCG);
ENUM_CASE(SND_BANK_SPC_GA_BMYCON);
ENUM_CASE(SND_BANK_SPC_GA_BMYCR);
ENUM_CASE(SND_BANK_SPC_GA_BMYDJ);
ENUM_CASE(SND_BANK_SPC_GA_BMYDRUG);
ENUM_CASE(SND_BANK_SPC_GA_BMYMOUN);
ENUM_CASE(SND_BANK_SPC_GA_BMYPOL1);
ENUM_CASE(SND_BANK_SPC_GA_BMYPOL2);
ENUM_CASE(SND_BANK_SPC_GA_BMYRI);
ENUM_CASE(SND_BANK_SPC_GA_BMYST);
ENUM_CASE(SND_BANK_SPC_GA_BYMPI);
ENUM_CASE(SND_BANK_SPC_GA_CWFOFR);
ENUM_CASE(SND_BANK_SPC_GA_CWFOHB);
ENUM_CASE(SND_BANK_SPC_GA_CWFYFR1);
ENUM_CASE(SND_BANK_SPC_GA_CWFYFR2);
ENUM_CASE(SND_BANK_SPC_GA_CWFYHB1);
ENUM_CASE(SND_BANK_SPC_GA_CWMOFR1);
ENUM_CASE(SND_BANK_SPC_GA_CWMOHB1);
ENUM_CASE(SND_BANK_SPC_GA_CWMOHB2);
ENUM_CASE(SND_BANK_SPC_GA_CWMYFR);
ENUM_CASE(SND_BANK_SPC_GA_CWMYHB1);
ENUM_CASE(SND_BANK_SPC_GA_CWMYHB2);
ENUM_CASE(SND_BANK_SPC_GA_DNFOLC1);
ENUM_CASE(SND_BANK_SPC_GA_DNFOLC2);
ENUM_CASE(SND_BANK_SPC_GA_DNFYLC);
ENUM_CASE(SND_BANK_SPC_GA_DNMOLC1);
ENUM_CASE(SND_BANK_SPC_GA_DNMOLC2);
ENUM_CASE(SND_BANK_SPC_GA_DNMYLC);
ENUM_CASE(SND_BANK_SPC_GA_DWFOLC);
ENUM_CASE(SND_BANK_SPC_GA_DWFYLC1);
ENUM_CASE(SND_BANK_SPC_GA_DWFYLC2);
ENUM_CASE(SND_BANK_SPC_GA_DWMOLC1);
ENUM_CASE(SND_BANK_SPC_GA_DWMOLC2);
ENUM_CASE(SND_BANK_SPC_GA_DWMYLC1);
ENUM_CASE(SND_BANK_SPC_GA_DWMYLC2);
ENUM_CASE(SND_BANK_SPC_GA_HFORI);
ENUM_CASE(SND_BANK_SPC_GA_HFOST);
ENUM_CASE(SND_BANK_SPC_GA_HFYBE);
ENUM_CASE(SND_BANK_SPC_GA_HFYPRO);
ENUM_CASE(SND_BANK_SPC_GA_HFYRI);
ENUM_CASE(SND_BANK_SPC_GA_HFYST);
ENUM_CASE(SND_BANK_SPC_GA_HMORI);
ENUM_CASE(SND_BANK_SPC_GA_HMOST);
ENUM_CASE(SND_BANK_SPC_GA_HMYBE);
ENUM_CASE(SND_BANK_SPC_GA_HMYCM);
ENUM_CASE(SND_BANK_SPC_GA_HMYCR);
ENUM_CASE(SND_BANK_SPC_GA_HMYDRUG);
ENUM_CASE(SND_BANK_SPC_GA_HMYRI);
ENUM_CASE(SND_BANK_SPC_GA_HMYST);
ENUM_CASE(SND_BANK_SPC_GA_IMYST);
ENUM_CASE(SND_BANK_SPC_GA_IRFYST);
ENUM_CASE(SND_BANK_SPC_GA_IRMYST);
ENUM_CASE(SND_BANK_SPC_GA_MAFFA);
ENUM_CASE(SND_BANK_SPC_GA_MAFFB);
ENUM_CASE(SND_BANK_SPC_GA_MALE01);
ENUM_CASE(SND_BANK_SPC_GA_NOVOICE);
ENUM_CASE(SND_BANK_SPC_GA_OFORI);
ENUM_CASE(SND_BANK_SPC_GA_OFOST);
ENUM_CASE(SND_BANK_SPC_GA_OFYRI);
ENUM_CASE(SND_BANK_SPC_GA_OFYST);
ENUM_CASE(SND_BANK_SPC_GA_OMOBOAT);
ENUM_CASE(SND_BANK_SPC_GA_OMOKUNG);
ENUM_CASE(SND_BANK_SPC_GA_OMORI);
ENUM_CASE(SND_BANK_SPC_GA_OMOST);
ENUM_CASE(SND_BANK_SPC_GA_OMYRI);
ENUM_CASE(SND_BANK_SPC_GA_OMYST);
ENUM_CASE(SND_BANK_SPC_GA_SBFORI);
ENUM_CASE(SND_BANK_SPC_GA_SBFOST);
ENUM_CASE(SND_BANK_SPC_GA_SBFYPRO);
ENUM_CASE(SND_BANK_SPC_GA_SBFYRI);
ENUM_CASE(SND_BANK_SPC_GA_SBFYST);
ENUM_CASE(SND_BANK_SPC_GA_SBFYSTR);
ENUM_CASE(SND_BANK_SPC_GA_SBMOCD);
ENUM_CASE(SND_BANK_SPC_GA_SBMORI);
ENUM_CASE(SND_BANK_SPC_GA_SBMOST);
ENUM_CASE(SND_BANK_SPC_GA_SBMOTR1);
ENUM_CASE(SND_BANK_SPC_GA_SBMOTR2);
ENUM_CASE(SND_BANK_SPC_GA_SBMYCR);
ENUM_CASE(SND_BANK_SPC_GA_SBMYRI);
ENUM_CASE(SND_BANK_SPC_GA_SBMYST);
ENUM_CASE(SND_BANK_SPC_GA_SBMYTR3);
ENUM_CASE(SND_BANK_SPC_GA_SFYPRO);
ENUM_CASE(SND_BANK_SPC_GA_SHFYPRO);
ENUM_CASE(SND_BANK_SPC_GA_SHMYCR);
ENUM_CASE(SND_BANK_SPC_GA_SMYST);
ENUM_CASE(SND_BANK_SPC_GA_SMYST2);
ENUM_CASE(SND_BANK_SPC_GA_SOFORI);
ENUM_CASE(SND_BANK_SPC_GA_SOFOST);
ENUM_CASE(SND_BANK_SPC_GA_SOFYBU);
ENUM_CASE(SND_BANK_SPC_GA_SOFYRI);
ENUM_CASE(SND_BANK_SPC_GA_SOFYST);
ENUM_CASE(SND_BANK_SPC_GA_SOMOBU);
ENUM_CASE(SND_BANK_SPC_GA_SOMORI);
ENUM_CASE(SND_BANK_SPC_GA_SOMOST);
ENUM_CASE(SND_BANK_SPC_GA_SOMYAP);
ENUM_CASE(SND_BANK_SPC_GA_SOMYBU);
ENUM_CASE(SND_BANK_SPC_GA_SOMYRI);
ENUM_CASE(SND_BANK_SPC_GA_SOMYST);
ENUM_CASE(SND_BANK_SPC_GA_SWFOPRO);
ENUM_CASE(SND_BANK_SPC_GA_SWFORI);
ENUM_CASE(SND_BANK_SPC_GA_SWFOST);
ENUM_CASE(SND_BANK_SPC_GA_SWFYRI);
ENUM_CASE(SND_BANK_SPC_GA_SWFYST);
ENUM_CASE(SND_BANK_SPC_GA_SWFYSTR);
ENUM_CASE(SND_BANK_SPC_GA_SWMOCD);
ENUM_CASE(SND_BANK_SPC_GA_SWMORI);
ENUM_CASE(SND_BANK_SPC_GA_SWMOST);
ENUM_CASE(SND_BANK_SPC_GA_SWMOTR1);
ENUM_CASE(SND_BANK_SPC_GA_SWMOTR2);
ENUM_CASE(SND_BANK_SPC_GA_SWMOTR3);
ENUM_CASE(SND_BANK_SPC_GA_SWMOTR4);
ENUM_CASE(SND_BANK_SPC_GA_SWMOTR5);
ENUM_CASE(SND_BANK_SPC_GA_SWMYCR);
ENUM_CASE(SND_BANK_SPC_GA_SWMYHP1);
ENUM_CASE(SND_BANK_SPC_GA_SWMYHP2);
ENUM_CASE(SND_BANK_SPC_GA_SWMYRI);
ENUM_CASE(SND_BANK_SPC_GA_SWMYST);
ENUM_CASE(SND_BANK_SPC_GA_VBFYPRO);
ENUM_CASE(SND_BANK_SPC_GA_VBFYST2);
ENUM_CASE(SND_BANK_SPC_GA_VBMOCD);
ENUM_CASE(SND_BANK_SPC_GA_VBMYCR);
ENUM_CASE(SND_BANK_SPC_GA_VBMYELV);
ENUM_CASE(SND_BANK_SPC_GA_VHFYPRO);
ENUM_CASE(SND_BANK_SPC_GA_VHFYST3);
ENUM_CASE(SND_BANK_SPC_GA_VHMYCR);
ENUM_CASE(SND_BANK_SPC_GA_VHMYELV);
ENUM_CASE(SND_BANK_SPC_GA_VIMYELV);
ENUM_CASE(SND_BANK_SPC_GA_VWFYPRO);
ENUM_CASE(SND_BANK_SPC_GA_VWFYST1);
ENUM_CASE(SND_BANK_SPC_GA_VWFYWAI);
ENUM_CASE(SND_BANK_SPC_GA_VWMOTR1);
ENUM_CASE(SND_BANK_SPC_GA_VWMOTR2);
ENUM_CASE(SND_BANK_SPC_GA_VWMYAP);
ENUM_CASE(SND_BANK_SPC_GA_VWMYBJD);
ENUM_CASE(SND_BANK_SPC_GA_VWMYCD);
ENUM_CASE(SND_BANK_SPC_GA_VWMYCR);
ENUM_CASE(SND_BANK_SPC_GA_WFOPJ);
ENUM_CASE(SND_BANK_SPC_GA_WFORI);
ENUM_CASE(SND_BANK_SPC_GA_WFOST);
ENUM_CASE(SND_BANK_SPC_GA_WFYBE);
ENUM_CASE(SND_BANK_SPC_GA_WFYBU);
ENUM_CASE(SND_BANK_SPC_GA_WFYCRK);
ENUM_CASE(SND_BANK_SPC_GA_WFYCRP);
ENUM_CASE(SND_BANK_SPC_GA_WFYJG);
ENUM_CASE(SND_BANK_SPC_GA_WFYLG);
ENUM_CASE(SND_BANK_SPC_GA_WFYPRO);
ENUM_CASE(SND_BANK_SPC_GA_WFYRI);
ENUM_CASE(SND_BANK_SPC_GA_WFYRO);
ENUM_CASE(SND_BANK_SPC_GA_WFYST);
ENUM_CASE(SND_BANK_SPC_GA_WFYSTEW);
ENUM_CASE(SND_BANK_SPC_GA_WMOMIB);
ENUM_CASE(SND_BANK_SPC_GA_WMOPJ);
ENUM_CASE(SND_BANK_SPC_GA_WMOPREA);
ENUM_CASE(SND_BANK_SPC_GA_WMORI);
ENUM_CASE(SND_BANK_SPC_GA_WMOSCI);
ENUM_CASE(SND_BANK_SPC_GA_WMOST);
ENUM_CASE(SND_BANK_SPC_GA_WMOTR1);
ENUM_CASE(SND_BANK_SPC_GA_WMYBE);
ENUM_CASE(SND_BANK_SPC_GA_WMYBMX);
ENUM_CASE(SND_BANK_SPC_GA_WMYBOUN);
ENUM_CASE(SND_BANK_SPC_GA_WMYBOX);
ENUM_CASE(SND_BANK_SPC_GA_WMYBP);
ENUM_CASE(SND_BANK_SPC_GA_WMYBU);
ENUM_CASE(SND_BANK_SPC_GA_WMYCD1);
ENUM_CASE(SND_BANK_SPC_GA_WMYCD2);
ENUM_CASE(SND_BANK_SPC_GA_WMYCH);
ENUM_CASE(SND_BANK_SPC_GA_WMYCON);
ENUM_CASE(SND_BANK_SPC_GA_WMYCONB);
ENUM_CASE(SND_BANK_SPC_GA_WMYCR);
ENUM_CASE(SND_BANK_SPC_GA_WMYDRUG);
ENUM_CASE(SND_BANK_SPC_GA_WMYGAR);
ENUM_CASE(SND_BANK_SPC_GA_WMYGOL1);
ENUM_CASE(SND_BANK_SPC_GA_WMYGOL2);
ENUM_CASE(SND_BANK_SPC_GA_WMYJG);
ENUM_CASE(SND_BANK_SPC_GA_WMYLG);
ENUM_CASE(SND_BANK_SPC_GA_WMYMECH);
ENUM_CASE(SND_BANK_SPC_GA_WMYMOUN);
ENUM_CASE(SND_BANK_SPC_GA_WMYPLT);
ENUM_CASE(SND_BANK_SPC_GA_WMYRI);
ENUM_CASE(SND_BANK_SPC_GA_WMYRO);
ENUM_CASE(SND_BANK_SPC_GA_WMYSGRD);
ENUM_CASE(SND_BANK_SPC_GA_WMYSKAT);
ENUM_CASE(SND_BANK_SPC_GA_WMYST);
ENUM_CASE(SND_BANK_SPC_GA_WMYTX1);
ENUM_CASE(SND_BANK_SPC_GA_WMYTX2);
ENUM_CASE(SND_BANK_SPC_GA_WMYVA);
ENUM_CASE(SND_BANK_SPC_NA_BALLAS1);
ENUM_CASE(SND_BANK_SPC_NA_BALLAS2);
ENUM_CASE(SND_BANK_SPC_NA_BALLAS3);
ENUM_CASE(SND_BANK_SPC_NA_BALLAS4);
ENUM_CASE(SND_BANK_SPC_NA_BALLAS5);
ENUM_CASE(SND_BANK_SPC_NA_BIG_BEAR);
ENUM_CASE(SND_BANK_SPC_NA_CESAR);
ENUM_CASE(SND_BANK_SPC_NA_DNB1);
ENUM_CASE(SND_BANK_SPC_NA_DNB2);
ENUM_CASE(SND_BANK_SPC_NA_DNB3);
ENUM_CASE(SND_BANK_SPC_NA_DNB5);
ENUM_CASE(SND_BANK_SPC_NA_DWAINE);
ENUM_CASE(SND_BANK_SPC_NA_FAM1);
ENUM_CASE(SND_BANK_SPC_NA_FAM2);
ENUM_CASE(SND_BANK_SPC_NA_FAM3);
ENUM_CASE(SND_BANK_SPC_NA_FAM4);
ENUM_CASE(SND_BANK_SPC_NA_FAM5);
ENUM_CASE(SND_BANK_SPC_NA_JIZZY);
ENUM_CASE(SND_BANK_SPC_NA_LSV1);
ENUM_CASE(SND_BANK_SPC_NA_LSV2);
ENUM_CASE(SND_BANK_SPC_NA_LSV3);
ENUM_CASE(SND_BANK_SPC_NA_LSV4);
ENUM_CASE(SND_BANK_SPC_NA_LSV5);
ENUM_CASE(SND_BANK_SPC_NA_MACCER);
ENUM_CASE(SND_BANK_SPC_NA_MAFBOSS);
ENUM_CASE(SND_BANK_SPC_NA_OGLOC);
ENUM_CASE(SND_BANK_SPC_NA_RYDER);
ENUM_CASE(SND_BANK_SPC_NA_SFR1);
ENUM_CASE(SND_BANK_SPC_NA_SFR2);
ENUM_CASE(SND_BANK_SPC_NA_SFR3);
ENUM_CASE(SND_BANK_SPC_NA_SFR4);
ENUM_CASE(SND_BANK_SPC_NA_SFR5);
ENUM_CASE(SND_BANK_SPC_NA_SMOKE);
ENUM_CASE(SND_BANK_SPC_NA_STRI1);
ENUM_CASE(SND_BANK_SPC_NA_STRI2);
ENUM_CASE(SND_BANK_SPC_NA_STRI4);
ENUM_CASE(SND_BANK_SPC_NA_STRI5);
ENUM_CASE(SND_BANK_SPC_NA_SWEET);
ENUM_CASE(SND_BANK_SPC_NA_TBONE);
ENUM_CASE(SND_BANK_SPC_NA_TORENO);
ENUM_CASE(SND_BANK_SPC_NA_TRUTH);
ENUM_CASE(SND_BANK_SPC_NA_VLA1);
ENUM_CASE(SND_BANK_SPC_NA_VLA2);
ENUM_CASE(SND_BANK_SPC_NA_VLA3);
ENUM_CASE(SND_BANK_SPC_NA_VLA4);
ENUM_CASE(SND_BANK_SPC_NA_VLA5);
ENUM_CASE(SND_BANK_SPC_NA_VMAFF1);
ENUM_CASE(SND_BANK_SPC_NA_VMAFF2);
ENUM_CASE(SND_BANK_SPC_NA_VMAFF3);
ENUM_CASE(SND_BANK_SPC_NA_VMAFF4);
ENUM_CASE(SND_BANK_SPC_NA_VMAFF5);
ENUM_CASE(SND_BANK_SPC_NA_WOOZIE);
ENUM_CASE(SND_BANK_SPC_PA_AG);
ENUM_CASE(SND_BANK_SPC_PA_AG2);
ENUM_CASE(SND_BANK_SPC_PA_AR);
ENUM_CASE(SND_BANK_SPC_PA_AR2);
ENUM_CASE(SND_BANK_SPC_PA_CD);
ENUM_CASE(SND_BANK_SPC_PA_CD2);
ENUM_CASE(SND_BANK_SPC_PA_CF);
ENUM_CASE(SND_BANK_SPC_PA_CF2);
ENUM_CASE(SND_BANK_SPC_PA_CG);
ENUM_CASE(SND_BANK_SPC_PA_CG2);
ENUM_CASE(SND_BANK_SPC_PA_CR);
ENUM_CASE(SND_BANK_SPC_PA_CR2);
ENUM_CASE(SND_BANK_SPC_PA_PG);
ENUM_CASE(SND_BANK_SPC_PA_PG2);
ENUM_CASE(SND_BANK_SPC_PA_PR);
ENUM_CASE(SND_BANK_SPC_PA_PR2);
ENUM_CASE(SND_BANK_SPC_PA_WG);
ENUM_CASE(SND_BANK_SPC_PA_WG2);
ENUM_CASE(SND_BANK_SPC_PA_WR);
ENUM_CASE(SND_BANK_SPC_PA_WR2);
}
#undef ENUM_CASE
return std::nullopt;
}

View File

@ -2,48 +2,75 @@
#include <extensions/WEnum.hpp>
/*!
* Theory:
* Bank slots are used to "store" loaded bank sounds.
* So, for example, you could load `SND_BANK_GENRL_HORN` into `SND_BANK_SLOT_HORN_AND_SIREN`
* and then play sounds from that slot.
* But then you could load any other bank into that slot,
* and the sounds played would now be different.
*/
enum eSoundBankSlot : int16 {
SND_BANK_SLOT_UNK = -1,
SND_BANK_SLOT_FRONTEND_GAME = 0, // 0x0
SND_BANK_SLOT_NONE = -1,
SND_BANK_SLOT_FIRST = 0,
SND_BANK_SLOT_FRONTEND_GAME = SND_BANK_SLOT_FIRST, // 0x0
SND_BANK_SLOT_FRONTEND_MENU = 1, // 0x1
SND_BANK_SLOT_COLLISIONS = 2, // 0x2
SND_BANK_SLOT_BULLET_HITS = 3, // 0x3
SND_BANK_SLOT_EXPLOSIONS = 4, // 0x4
SND_BANK_SLOT_WEAPON_GEN = 5, // 0x5
SND_BANK_SLOT_WEATHER = 6, // 0x6
SND_BANK_SLOT_DUMMY_ENGINE_0 = 7, // 0x7
SND_BANK_SLOT_DUMMY_ENGINE_1 = 8, // 0x8
SND_BANK_SLOT_DUMMY_ENGINE_2 = 9, // 0x9
SND_BANK_SLOT_DUMMY_ENGINE_3 = 10, // 0xA
SND_BANK_SLOT_DUMMY_ENGINE_4 = 11, // 0xB
SND_BANK_SLOT_DUMMY_ENGINE_5 = 12, // 0xC
SND_BANK_SLOT_DUMMY_ENGINE_6 = 13, // 0xD
SND_BANK_SLOT_DUMMY_ENGINE_7 = 14, // 0xE
SND_BANK_SLOT_DUMMY_ENGINE_8 = 15, // 0xF
SND_BANK_SLOT_DUMMY_ENGINE_9 = 16, // 0x10
/* Dummy vehicles */
SND_BANK_SLOT_DUMMY_FIRST = 7,
SND_BANK_SLOT_DUMMY_ENGINE_0 = SND_BANK_SLOT_DUMMY_FIRST,
SND_BANK_SLOT_DUMMY_ENGINE_1, // 8 - 0x8
SND_BANK_SLOT_DUMMY_ENGINE_2, // 9 - 0x9
SND_BANK_SLOT_DUMMY_ENGINE_3, // 10 - 0xA
SND_BANK_SLOT_DUMMY_ENGINE_4, // 11 - 0xB
SND_BANK_SLOT_DUMMY_ENGINE_5, // 12 - 0xC
SND_BANK_SLOT_DUMMY_ENGINE_6, // 13 - 0xD
SND_BANK_SLOT_DUMMY_ENGINE_7, // 14 - 0xE
SND_BANK_SLOT_DUMMY_ENGINE_8, // 15 - 0xF
SND_BANK_SLOT_DUMMY_ENGINE_9, // 16 - 0x10
SND_BANK_SLOT_DUMMY_END,
/* Other vehicle related */
SND_BANK_SLOT_HORN_AND_SIREN = 17, // 0x11
SND_BANK_SLOT_COP_HELI = 18, // 0x12
SND_BANK_SLOT_VEHICLE_GEN = 19, // 0x13
SND_BANK_SLOT_SPEECH1 = 20, // 0x14
SND_BANK_SLOT_SPEECH2 = 21, // 0x15
SND_BANK_SLOT_SPEECH3 = 22, // 0x16
SND_BANK_SLOT_SPEECH4 = 23, // 0x17
SND_BANK_SLOT_SPEECH5 = 24, // 0x18
SND_BANK_SLOT_SPEECH6 = 25, // 0x19
/* Ped speech */
SND_BANK_SLOT_SPEECH_FIRST = 20,
SND_BANK_SLOT_SPEECH1 = SND_BANK_SLOT_SPEECH_FIRST, // 20 - 0x14
SND_BANK_SLOT_SPEECH2, // 21 - 0x15
SND_BANK_SLOT_SPEECH3, // 22 - 0x16
SND_BANK_SLOT_SPEECH4, // 23 - 0x17
SND_BANK_SLOT_SPEECH5, // 24 - 0x18
SND_BANK_SLOT_SPEECH6, // 25 - 0x19
SND_BANK_SLOT_SPEECH_END,
/* Missions */
SND_BANK_SLOT_MISSION1 = 26, // 0x1A
SND_BANK_SLOT_MISSION2 = 27, // 0x1B
SND_BANK_SLOT_MISSION3 = 28, // 0x1C
SND_BANK_SLOT_MISSION4 = 29, // 0x1D
SND_BANK_SLOT_FOOTSTEPS_PLAYER = 30, // 0x1E
SND_BANK_SLOT_DOORS = 31, // 0x1F
SND_BANK_SLOT_SWIMMING = 32, // 0x20
SND_BANK_SLOT_SCANNER_INSTRUCTION = 33, // 0x21
SND_BANK_SLOT_SCANNER_NUMBER = 34, // 0x22
SND_BANK_SLOT_SCANNER_DIRECTION1 = 35, // 0x23
SND_BANK_SLOT_SCANNER_DIRECTION2 = 36, // 0x24
SND_BANK_SLOT_SCANNER_AREA = 37, // 0x25
/* Scanners */
SND_BANK_SLOT_SCANNER_FIRST = 33,
SND_BANK_SLOT_SCANNER_INSTRUCTION = SND_BANK_SLOT_SCANNER_FIRST, // 33 - 0x21
SND_BANK_SLOT_SCANNER_NUMBER, // 34 - 0x22
SND_BANK_SLOT_SCANNER_DIRECTION1, // 35 - 0x23
SND_BANK_SLOT_SCANNER_DIRECTION2, // 36 - 0x24
SND_BANK_SLOT_SCANNER_AREA, // 37 - 0x25
SND_BANK_SLOT_SCANNER_END,
/* Misc stuff */
SND_BANK_SLOT_TEST1 = 38, // 0x26
SND_BANK_SLOT_EFFECT1 = 39, // 0x27
SND_BANK_SLOT_PLAYER_ENGINE_P = 40, // 0x28
@ -51,6 +78,62 @@ enum eSoundBankSlot : int16 {
SND_BANK_SLOT_BULLET_PASS = 42, // 0x2A
SND_BANK_SLOT_TEST2 = 43, // 0x2B
SND_BANK_SLOT_EFFECT2 = 44, // 0x2C
NUM_SND_BANK_SLOTS = 45, // 0x2D
SND_BANK_SLOT_END = NUM_SND_BANK_SLOTS
};
NOTSA_WENUM_DEFS_FOR(eSoundBankSlot);
inline std::optional<const char*> EnumToString(eSoundBankSlot v) {
#define ENUM_CASE(_e) case _e: return #_e
switch (v) {
ENUM_CASE(SND_BANK_SLOT_FRONTEND_GAME);
ENUM_CASE(SND_BANK_SLOT_FRONTEND_MENU);
ENUM_CASE(SND_BANK_SLOT_COLLISIONS);
ENUM_CASE(SND_BANK_SLOT_BULLET_HITS);
ENUM_CASE(SND_BANK_SLOT_EXPLOSIONS);
ENUM_CASE(SND_BANK_SLOT_WEAPON_GEN);
ENUM_CASE(SND_BANK_SLOT_WEATHER);
ENUM_CASE(SND_BANK_SLOT_DUMMY_ENGINE_0);
ENUM_CASE(SND_BANK_SLOT_DUMMY_ENGINE_1);
ENUM_CASE(SND_BANK_SLOT_DUMMY_ENGINE_2);
ENUM_CASE(SND_BANK_SLOT_DUMMY_ENGINE_3);
ENUM_CASE(SND_BANK_SLOT_DUMMY_ENGINE_4);
ENUM_CASE(SND_BANK_SLOT_DUMMY_ENGINE_5);
ENUM_CASE(SND_BANK_SLOT_DUMMY_ENGINE_6);
ENUM_CASE(SND_BANK_SLOT_DUMMY_ENGINE_7);
ENUM_CASE(SND_BANK_SLOT_DUMMY_ENGINE_8);
ENUM_CASE(SND_BANK_SLOT_DUMMY_ENGINE_9);
ENUM_CASE(SND_BANK_SLOT_HORN_AND_SIREN);
ENUM_CASE(SND_BANK_SLOT_COP_HELI);
ENUM_CASE(SND_BANK_SLOT_VEHICLE_GEN);
ENUM_CASE(SND_BANK_SLOT_SPEECH1);
ENUM_CASE(SND_BANK_SLOT_SPEECH2);
ENUM_CASE(SND_BANK_SLOT_SPEECH3);
ENUM_CASE(SND_BANK_SLOT_SPEECH4);
ENUM_CASE(SND_BANK_SLOT_SPEECH5);
ENUM_CASE(SND_BANK_SLOT_SPEECH6);
ENUM_CASE(SND_BANK_SLOT_MISSION1);
ENUM_CASE(SND_BANK_SLOT_MISSION2);
ENUM_CASE(SND_BANK_SLOT_MISSION3);
ENUM_CASE(SND_BANK_SLOT_MISSION4);
ENUM_CASE(SND_BANK_SLOT_FOOTSTEPS_PLAYER);
ENUM_CASE(SND_BANK_SLOT_DOORS);
ENUM_CASE(SND_BANK_SLOT_SWIMMING);
ENUM_CASE(SND_BANK_SLOT_SCANNER_INSTRUCTION);
ENUM_CASE(SND_BANK_SLOT_SCANNER_NUMBER);
ENUM_CASE(SND_BANK_SLOT_SCANNER_DIRECTION1);
ENUM_CASE(SND_BANK_SLOT_SCANNER_DIRECTION2);
ENUM_CASE(SND_BANK_SLOT_SCANNER_AREA);
ENUM_CASE(SND_BANK_SLOT_TEST1);
ENUM_CASE(SND_BANK_SLOT_EFFECT1);
ENUM_CASE(SND_BANK_SLOT_PLAYER_ENGINE_P);
ENUM_CASE(SND_BANK_SLOT_FOOTSTEPS_GENERIC);
ENUM_CASE(SND_BANK_SLOT_BULLET_PASS);
ENUM_CASE(SND_BANK_SLOT_TEST2);
ENUM_CASE(SND_BANK_SLOT_EFFECT2);
ENUM_CASE(NUM_SND_BANK_SLOTS);
}
#undef ENUM_CASE
return std::nullopt;
}

View File

@ -1,19 +0,0 @@
#pragma once
/**
* banks IDs are global (in loading order)
*/
enum eAudioBank {
// FEET
BANK_FEET_0 = 0, // 1 ??Individual Footfalls
BANK_FEET_1 = 1, // 2 ??Running on Water or Leaves
// GENRL
BANK_WEAPON_BULLET_SWISH = 28, // 22
BANK_EXTRAS = 59, // 53 manhunt
BANK_FRONTEND = 60, // 54
BANK_HORNS_AND_SIRENS = 74, // 0x4A
BANK_MRWHOOPIE_SOUNDS = 79, // 0x4F
BANK_LOADING_TUNE = 82, // 76
BANK_RAIN_SOUNDS = 105, // 0x69
};

View File

@ -1,14 +0,0 @@
#pragma once
enum eAudioSlot {
SLOT_EXTRAS = 0,
SLOT_FRONTEND = 1,
SLOT_LOADING_TUNE_LEFT = 2,
SLOT_LOADING_TUNE_RIGHT = 5,
SLOT_RAIN_ON_VEHICLE = 6,
SLOT_HORNS_AND_SIRENS = 17,
SLOT_WHEEL_SOUND = 19,
SLOT_SPECIAL_VEHICLE_SOUNDS = 40,
SLOT_FEET_0 = 41,
SLOT_WEAPON_BULLET_SWISH = 42,
};

View File

@ -1,34 +0,0 @@
#pragma once
enum eSFX {
// slot 28
SFX_WEAPON_BULLET_SWISH_1 = 0,
SFX_WEAPON_BULLET_SWISH_2 = 1,
SFX_WEAPON_BULLET_SWISH_3 = 2,
// slot 59
SFX_FRONTEND_SCANNER_NOISE_START = 3,
SFX_FRONTEND_TIMER_COUNT_LEFT = 4,
SFX_FRONTEND_TIMER_COUNT_RIGHT = 5,
SFX_FRONTEND_WAKEUP_AMPLIFIER = 8,
SFX_FRONTEND_BUY_CAR_MOD = 9,
SFX_FRONTEND_DISPLAY_INFO_LEFT = 14, //
SFX_FRONTEND_DISPLAY_INFO_RIGHT = 15, // ?
SFX_FRONTEND_PICKUP_MONEY_LEFT = 16,
SFX_FRONTEND_PICKUP_MONEY_RIGHT = 17,
SFX_FRONTEND_RADIO_CLICK = 23,
SFX_FRONTEND_SCANNER_CLICK = 24,
SFX_FRONTEND_START_LEFT = 25, // ?
SFX_FRONTEND_START_RIGHT = 26, // ?
SFX_FRONTEND_PICKUP_WEAPON_LEFT = 27,
SFX_FRONTEND_PICKUP_WEAPON_RIGHT = 28,
// slot 60
SFX_FRONTEND_BACK_LEFT = 0, // manhunt
SFX_FRONTEND_BACK_RIGHT = 1, // manhunt
SFX_FRONTEND_ERROR_LEFT = 2, //
SFX_FRONTEND_ERROR_RIGHT = 3, //
SFX_FRONTEND_HIGHLIGHT_LEFT = 4, // gta3
SFX_FRONTEND_HIGHLIGHT_RIGHT = 5, // gta3
SFX_FRONTEND_SELECT_LEFT = 6, // manhunt
SFX_FRONTEND_SELECT_RIGHT = 7, // manhunt
SFX_FRONTEND_NOISE_TEST = 8, //
};

View File

@ -8,20 +8,20 @@
#include "StdInc.h"
#include "AEAudioEntity.h"
int8*& CAEAudioEntity::m_pAudioEventVolumes = *reinterpret_cast<int8**>(0xBD00F8);
constexpr auto EVENT_VOLUMES_BUFFER_SIZE = 45401;
CAEAudioEntity::CAEAudioEntity() : m_pEntity(nullptr), m_tempSound() {}
auto& m_pAudioEventVolumes = StaticRef<int8*>(0xBD00F8); // Use `GetDefaultVolume` to access!
// NOTSA | INLINED | REFACTORED
bool CAEAudioEntity::StaticInitialise() {
m_pAudioEventVolumes = new int8[45401];
m_pAudioEventVolumes = new int8[EVENT_VOLUMES_BUFFER_SIZE];
auto file = CFileMgr::OpenFile("AUDIO\\CONFIG\\EVENTVOL.DAT", "r");
if (!file) {
NOTSA_LOG_WARN("[AudioEngine] Failed to open EVENTVOL.DAT");
CFileMgr::CloseFile(file);
return false;
}
if (CFileMgr::Read(file, m_pAudioEventVolumes, 45401) != 45401) {
if (CFileMgr::Read(file, m_pAudioEventVolumes, EVENT_VOLUMES_BUFFER_SIZE) != EVENT_VOLUMES_BUFFER_SIZE) {
NOTSA_LOG_WARN("[AudioEngine] Failed to read EVENTVOL.DAT");
CFileMgr::CloseFile(file);
return false;
@ -32,6 +32,9 @@ bool CAEAudioEntity::StaticInitialise() {
// NOTSA | INLINED | REFACTORED
void CAEAudioEntity::Shutdown() {
delete[] m_pAudioEventVolumes;
m_pAudioEventVolumes = nullptr;
delete[] std::exchange(m_pAudioEventVolumes, nullptr);
}
float CAEAudioEntity::GetDefaultVolume(eAudioEvents event) {
return static_cast<float>(m_pAudioEventVolumes[event]);
}

View File

@ -14,14 +14,11 @@ class CEntity;
class NOTSA_EXPORT_VTABLE CAEAudioEntity {
public:
CEntity* m_pEntity;
CAESound m_tempSound;
private:
static int8*& m_pAudioEventVolumes; // Use `GetDefaultVolume` to access!
CEntity* m_Entity{};
CAESound m_tempSound{};
protected:
CAEAudioEntity();
CAEAudioEntity() = default;
~CAEAudioEntity() = default;
public:
@ -29,7 +26,7 @@ public:
static bool StaticInitialise();
static void Shutdown();
static float GetDefaultVolume(eAudioEvents event) { return static_cast<float>(m_pAudioEventVolumes[event]); }
static float GetDefaultVolume(eAudioEvents event);
};
VALIDATE_SIZE(CAEAudioEntity, 0x7C);

View File

@ -35,8 +35,8 @@ void CAECollisionAudioEntity::Initialise() {
// 0x4DA050
void CAECollisionAudioEntity::InitialisePostLoading() {
AEAudioHardware.LoadSoundBank(39, SLOT_LOADING_TUNE_LEFT);
AEAudioHardware.LoadSoundBank(27, 3);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_COLLISIONS, SND_BANK_SLOT_COLLISIONS);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_BULLET_HITS, SND_BANK_SLOT_BULLET_HITS);
}
// 0x4DA320
@ -160,7 +160,7 @@ void CAECollisionAudioEntity::PlayBulletHitCollisionSound(eSurfaceType surface,
if (iRand >= 0) {
CAESound sound;
sound.Initialise(3, iRand, this, posn, volume, maxDistance, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.02f, 0);
sound.Initialise(SND_BANK_SLOT_BULLET_HITS, iRand, this, posn, volume, maxDistance, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.02f, 0);
AESoundManager.RequestNewSound(&sound);
m_nLastBulletHitSoundID = iRand;
}
@ -194,7 +194,7 @@ void CAECollisionAudioEntity::ReportGlassCollisionEvent(eAudioEvents glassSoundT
return;
m_tempSound.Initialise(
2,
SND_BANK_SLOT_COLLISIONS,
sfxId,
this,
posn,
@ -206,22 +206,19 @@ void CAECollisionAudioEntity::ReportGlassCollisionEvent(eAudioEvents glassSoundT
if (time) {
auto& snd = m_tempSound;
snd.m_ClientVariable = (float)(time + CTimer::GetTimeInMS());
snd.m_nEvent = glassSoundType;
snd.m_bRequestUpdates = true;
snd.m_Event = glassSoundType;
snd.m_RequestUpdates = true;
}
}
// 0x4DA190
void CAECollisionAudioEntity::ReportWaterSplash(CVector posn, float volume) {
if (!AEAudioHardware.IsSoundBankLoaded(39, 2)) {
if (!AudioEngine.IsLoadingTuneActive())
AEAudioHardware.LoadSoundBank(39, 2);
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_COLLISIONS, SND_BANK_SLOT_COLLISIONS, true)) {
return;
}
m_tempSound.Initialise(
2,
SND_BANK_SLOT_COLLISIONS,
67,
this,
posn,
@ -232,11 +229,11 @@ void CAECollisionAudioEntity::ReportWaterSplash(CVector posn, float volume) {
0u,
SOUND_REQUEST_UPDATES
);
m_tempSound.m_nEvent = AE_FRONTEND_SELECT;
m_tempSound.m_Event = AE_FRONTEND_SELECT;
AESoundManager.RequestNewSound(&m_tempSound);
m_tempSound.Initialise(
2,
SND_BANK_SLOT_COLLISIONS,
66,
this,
posn,
@ -247,7 +244,7 @@ void CAECollisionAudioEntity::ReportWaterSplash(CVector posn, float volume) {
0u,
SOUND_REQUEST_UPDATES
);
m_tempSound.m_nEvent = AE_FRONTEND_BACK;
m_tempSound.m_Event = AE_FRONTEND_BACK;
m_tempSound.m_ClientVariable = static_cast<float>(CTimer::GetTimeInMS() + 166);
}
@ -268,10 +265,10 @@ void CAECollisionAudioEntity::ReportCollision(CEntity* entity1, CEntity* entity2
// 0x4DBDF0
void CAECollisionAudioEntity::ReportBulletHit(CEntity* entity, eSurfaceType surface, const CVector& posn, float angleWithColPointNorm) {
if (AEAudioHardware.IsSoundBankLoaded(27, 3)) {
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_BULLET_HITS, SND_BANK_SLOT_BULLET_HITS)) {
if (entity && entity->IsVehicle()) {
surface = entity->AsVehicle()->IsSubBMX()
? eSurfaceType(188) // todo: C* Surface
? (eSurfaceType)(188) // todo: C* Surface
: SURFACE_CAR;
}
PlayBulletHitCollisionSound(surface, posn, angleWithColPointNorm);

View File

@ -14,7 +14,7 @@ CAEDoorAudioEntity::CAEDoorAudioEntity() : CAEAudioEntity() {
// 0x5B9A80
void CAEDoorAudioEntity::StaticInitialise() {
AEAudioHardware.LoadSoundBank(51, 31);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_DOORS, SND_BANK_SLOT_DOORS);
}
// 0x4DC6B0
@ -83,7 +83,7 @@ void CAEDoorAudioEntity::AddAudioEvent(eAudioEvents event, CVector& posn, float
// 0x4DC6D0
void CAEDoorAudioEntity::PlayDoorSound(int16 sfxId, eAudioEvents event, CVector& posn, float volumeDelta, float speed) {
if (AEAudioHardware.IsSoundBankLoaded(51, 31)) {
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_DOORS, SND_BANK_SLOT_DOORS)) {
CVector position;
bool enabled = false;
if (posn.x == -1000.0f && posn.y == -1000.0f && posn.z == -1000.0f || posn.x == 0.0f && posn.y == 0.0f && posn.z == 0.0f) {
@ -96,9 +96,9 @@ void CAEDoorAudioEntity::PlayDoorSound(int16 sfxId, eAudioEvents event, CVector&
const float eventVolume = GetDefaultVolume(event);
const float volume = eventVolume + volumeDelta;
CAESound sound;
sound.Initialise(31, sfxId, this, position, volume, 2.0f, speed, 1.0f, 0, SOUND_REQUEST_UPDATES, 0.0f, 0);
sound.SetIndividualEnvironment(SOUND_FRONT_END, enabled);
sound.m_nEvent = event;
sound.Initialise(SND_BANK_SLOT_DOORS, sfxId, this, position, volume, 2.0f, speed, 1.0f, 0, SOUND_REQUEST_UPDATES, 0.0f, 0);
sound.SetFlags(SOUND_FRONT_END, enabled);
sound.m_Event = event;
AESoundManager.RequestNewSound(&sound);
} else {
StaticInitialise();
@ -136,21 +136,21 @@ void CAEDoorAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
return sound->StopSoundAndForget();
#else
eAudioEvents event;
if (sound->m_nEvent == AE_GARAGE_DOOR_OPENING) {
if (sound->m_Event == AE_GARAGE_DOOR_OPENING) {
event = AE_GARAGE_DOOR_OPENED;
if (CTimer::GetTimeInMS() > (m_nTime + 10000)) {
auto playing = (!AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_GARAGE_DOOR_OPENED, this) &&
AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_GARAGE_DOOR_OPENING, this));
if (playing) {
AESoundManager.CancelSoundsOwnedByAudioEntity(this, 1);
PlayDoorSound(2, AE_GARAGE_DOOR_OPENED, sound->m_vecCurrPosn, 0.0f, 1.0f);
PlayDoorSound(2, AE_GARAGE_DOOR_OPENED, sound->m_CurrPos, 0.0f, 1.0f);
}
m_nTime = CTimer::GetTimeInMS();
sound->StopSoundAndForget();
return;
}
} else {
if (sound->m_nEvent != AE_GARAGE_DOOR_CLOSING)
if (sound->m_Event != AE_GARAGE_DOOR_CLOSING)
return;
event = AE_GARAGE_DOOR_CLOSED;
@ -159,7 +159,7 @@ void CAEDoorAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_GARAGE_DOOR_CLOSING, this));
if (playing) {
AESoundManager.CancelSoundsOwnedByAudioEntity(this, 1);
PlayDoorSound(2, AE_GARAGE_DOOR_CLOSED, sound->m_vecCurrPosn, 0.0f, 0.79f);
PlayDoorSound(2, AE_GARAGE_DOOR_CLOSED, sound->m_CurrPos, 0.0f, 0.79f);
}
m_nTime = CTimer::GetTimeInMS();
sound->StopSoundAndForget();
@ -182,4 +182,4 @@ void CAEDoorAudioEntity::InjectHooks() {
RH_ScopedOverloadedInstall(AddAudioEvent, "2", 0x4DC860, void (CAEDoorAudioEntity::*)(eAudioEvents, CVector&, float, float));
RH_ScopedInstall(PlayDoorSound, 0x4DC6D0);
RH_ScopedVMTInstall(UpdateParameters, 0x4DCA60);
}
}

View File

@ -14,16 +14,16 @@ CAEExplosionAudioEntity::CAEExplosionAudioEntity() {
}
void CAEExplosionAudioEntity::StaticInitialise() {
AEAudioHardware.LoadSoundBank(52, 4);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_EXPLOSIONS, SND_BANK_SLOT_EXPLOSIONS);
}
// 0x4DCBE0
void CAEExplosionAudioEntity::AddAudioEvent(eAudioEvents audioEvent, CVector& posn, float volume) {
if (audioEvent != AE_EXPLOSION)
if (audioEvent != AE_EXPLOSION) {
return;
}
if (!AEAudioHardware.IsSoundBankLoaded(52, 4)) {
AEAudioHardware.LoadSoundBank(52, 4);
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_EXPLOSIONS, SND_BANK_SLOT_EXPLOSIONS)) {
return;
}
@ -32,13 +32,13 @@ void CAEExplosionAudioEntity::AddAudioEvent(eAudioEvents audioEvent, CVector& po
CAESound sound;
sound.Initialise(4, 4, this, posn, vol0, 2.0f, gfExplosionFrequencyVariations[m_Speed], 1.0f, 0, SOUND_REQUEST_UPDATES, 0.06f, 0);
sound.Initialise(SND_BANK_SLOT_EXPLOSIONS, 4, this, posn, vol0, 2.0f, gfExplosionFrequencyVariations[m_Speed], 1.0f, 0, SOUND_REQUEST_UPDATES, 0.06f, 0);
AESoundManager.RequestNewSound(&sound);
sound.Initialise(4, 3, this, posn, vol0, 4.0f, gfExplosionFrequencyVariations[m_Speed], 1.0f, 0, SOUND_REQUEST_UPDATES, 0.06f, 0);
sound.Initialise(SND_BANK_SLOT_EXPLOSIONS, 3, this, posn, vol0, 4.0f, gfExplosionFrequencyVariations[m_Speed], 1.0f, 0, SOUND_REQUEST_UPDATES, 0.06f, 0);
AESoundManager.RequestNewSound(&sound);
sound.Initialise(4, 2, this, posn, vol0, 7.5f, gfExplosionFrequencyVariations[m_Speed], 1.0f, 0, SOUND_REQUEST_UPDATES, 0.06f, 0);
sound.Initialise(SND_BANK_SLOT_EXPLOSIONS, 2, this, posn, vol0, 7.5f, gfExplosionFrequencyVariations[m_Speed], 1.0f, 0, SOUND_REQUEST_UPDATES, 0.06f, 0);
AESoundManager.RequestNewSound(&sound);
float speed_a, speed_b;
@ -53,18 +53,18 @@ void CAEExplosionAudioEntity::AddAudioEvent(eAudioEvents audioEvent, CVector& po
auto vol1 = CAEAudioEnvironment::GetDistanceAttenuation(CAEAudioEnvironment::GetPositionRelativeToCamera(posn).Magnitude() / 12.0f) + vol0 - 3.0f;
auto flags = static_cast<eSoundEnvironment>(SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_REQUEST_UPDATES | SOUND_FRONT_END);
sound.Initialise(4, 1, this, { -1.0f, 0.0f, 0.0f }, vol1, 12.0f, speed_a, 1.0f, 0, flags, 0.0f, 0);
sound.Initialise(SND_BANK_SLOT_EXPLOSIONS, 1, this, { -1.0f, 0.0f, 0.0f }, vol1, 12.0f, speed_a, 1.0f, 0, flags, 0.0f, 0);
AESoundManager.RequestNewSound(&sound);
sound.Initialise(4, 1, this, { 1.0f, 0.0f, 0.0f }, vol1, 12.0f, speed_b, 1.0f, 0, flags, 0.0f, 0);
sound.Initialise(SND_BANK_SLOT_EXPLOSIONS, 1, this, { 1.0f, 0.0f, 0.0f }, vol1, 12.0f, speed_b, 1.0f, 0, flags, 0.0f, 0);
AESoundManager.RequestNewSound(&sound);
}
// 0x4DCB90
void CAEExplosionAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
if (curPlayPos > 0) {
if (sound->m_fVolume > 0.0f) {
sound->m_fVolume = std::max(sound->m_fVolume - 1.0f, 0.0f);
if (sound->m_Volume > 0.0f) {
sound->m_Volume = std::max(sound->m_Volume - 1.0f, 0.0f);
}
}
}

View File

@ -15,7 +15,7 @@ void CAEFireAudioEntity::Initialise(FxSystem_c* system) {
// 0x5B9A90
void CAEFireAudioEntity::StaticInitialise() {
AEAudioHardware.LoadSoundBank(52, 4);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_RAIN, SND_BANK_SLOT_WEATHER);
}
// 0x4DCF40
@ -43,7 +43,7 @@ void CAEFireAudioEntity::PlayFireSounds(eAudioEvents audioId, CVector& posn) {
CAESound sound;
sound.Initialise(
4,
SND_BANK_SLOT_EXPLOSIONS,
0,
this,
posn,
@ -58,13 +58,12 @@ void CAEFireAudioEntity::PlayFireSounds(eAudioEvents audioId, CVector& posn) {
);
m_SoundLeft = AESoundManager.RequestNewSound(&sound);
if (!AEAudioHardware.IsSoundBankLoaded(138, 19)) {
AEAudioHardware.LoadSoundBank(138, 19);
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_VEHICLE_GEN, SND_BANK_SLOT_VEHICLE_GEN)) {
return;
}
sound.Initialise(
19,
SND_BANK_SLOT_VEHICLE_GEN,
26,
this,
posn,
@ -78,21 +77,21 @@ void CAEFireAudioEntity::PlayFireSounds(eAudioEvents audioId, CVector& posn) {
0
);
sound.m_ClientVariable = volume + 3.0f;
sound.m_nEvent = AE_FRONTEND_SELECT;
sound.m_Event = AE_FRONTEND_SELECT;
AESoundManager.RequestNewSound(&sound);
}
// 0x4DD270
void CAEFireAudioEntity::PlayWaterSounds(eAudioEvents audioId, CVector& posn) {
CAESound sound;
sound.Initialise(2, 3, this, posn, GetDefaultVolume(audioId), 2.0f, 0.75f, 0.6f, 0, SOUND_REQUEST_UPDATES, 0.0f, 0);
sound.m_nEvent = AE_FRONTEND_HIGHLIGHT;
sound.m_fSpeedVariability = 0.06f;
sound.Initialise(SND_BANK_SLOT_COLLISIONS, 3, this, posn, GetDefaultVolume(audioId), 2.0f, 0.75f, 0.6f, 0, SOUND_REQUEST_UPDATES, 0.0f, 0);
sound.m_Event = AE_FRONTEND_HIGHLIGHT;
sound.m_SpeedVariance = 0.06f;
m_SoundLeft = AESoundManager.RequestNewSound(&sound);
sound.Initialise(0, 0, this, posn, GetDefaultVolume(audioId) + 20.0f, 2.0f, 1.78f, 0.6f, 0, SOUND_REQUEST_UPDATES, 0.0f, 0);
sound.m_fSpeedVariability = 0.06f;
sound.m_nEvent = AE_FRONTEND_ERROR;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 0, this, posn, GetDefaultVolume(audioId) + 20.0f, 2.0f, 1.78f, 0.6f, 0, SOUND_REQUEST_UPDATES, 0.0f, 0);
sound.m_SpeedVariance = 0.06f;
sound.m_Event = AE_FRONTEND_ERROR;
m_SoundRight = AESoundManager.RequestNewSound(&sound);
}
@ -115,29 +114,29 @@ void CAEFireAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
sound->SetPosition(matrix.pos);
}
switch (sound->m_nEvent) {
switch (sound->m_Event) {
case AE_FRONTEND_SELECT:
if (sound->m_fVolume >= sound->m_ClientVariable) {
sound->m_nEvent = AE_FRONTEND_BACK;
if (sound->m_Volume >= sound->m_ClientVariable) {
sound->m_Event = AE_FRONTEND_BACK;
} else {
sound->m_fVolume = std::min(sound->m_fVolume + 2.0f, sound->m_ClientVariable);
sound->m_Volume = std::min(sound->m_Volume + 2.0f, sound->m_ClientVariable);
}
break;
case AE_FRONTEND_BACK:
if (sound->m_fVolume <= -30.0f)
if (sound->m_Volume <= -30.0f)
sound->StopSoundAndForget();
else
sound->m_fVolume -= 0.75f;
sound->m_Volume -= 0.75f;
break;
case AE_FRONTEND_ERROR:
if (m_FxSystem && m_FxSystem->GetPlayStatus() == eFxSystemPlayStatus::FX_STOPPED) {
sound->m_fVolume = -100.0f;
sound->m_Volume = -100.0f;
}
break;
case AE_FRONTEND_HIGHLIGHT:
if (m_FxSystem && m_FxSystem->GetPlayStatus() == eFxSystemPlayStatus::FX_STOPPED) {
if (sound->m_fVolume > -100.0f) {
sound->m_fVolume -= 1.0f;
if (sound->m_Volume > -100.0f) {
sound->m_Volume -= 1.0f;
}
}
break;
@ -155,4 +154,4 @@ void CAEFireAudioEntity::InjectHooks() {
RH_ScopedInstall(PlayFireSounds, 0x4DD0D0);
RH_ScopedInstall(PlayWaterSounds, 0x4DD270);
RH_ScopedVMTInstall(UpdateParameters, 0x4DCF60);
}
}

View File

@ -8,22 +8,18 @@
#include "AEAudioUtility.h"
#include "AESound.h"
#include "config/eAudioBank.h"
#include "config/eSFX.h"
#include "config/eAudioSlot.h"
// 0x5B9AB0
void CAEFrontendAudioEntity::Initialise() {
m_bAmplifierWakeUp = false;
m_pAmplifierWakeUp = nullptr;
AEAudioHardware.LoadSoundBank(BANK_FRONTEND, SLOT_FRONTEND);
AEAudioHardware.LoadSoundBank(BANK_EXTRAS, SLOT_EXTRAS);
AEAudioHardware.LoadSoundBank(BANK_WEAPON_BULLET_SWISH, SLOT_WEAPON_BULLET_SWISH);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_FRONTEND_MENU, SND_BANK_SLOT_FRONTEND_MENU);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_BULLET_PASS_1, SND_BANK_SLOT_BULLET_PASS);
m_nbLoadingTuneSeed = CAEAudioUtility::GetRandomNumberInRange(0, 3);
AEAudioHardware.LoadSound(BANK_LOADING_TUNE, 2 * m_nbLoadingTuneSeed + 0, SLOT_LOADING_TUNE_LEFT);
AEAudioHardware.LoadSound(BANK_LOADING_TUNE, 2 * m_nbLoadingTuneSeed + 1, SLOT_LOADING_TUNE_RIGHT);
AEAudioHardware.LoadSound(SND_BANK_GENRL_LOADING, 2 * m_nbLoadingTuneSeed + 0, SND_BANK_SLOT_COLLISIONS);
AEAudioHardware.LoadSound(SND_BANK_GENRL_LOADING, 2 * m_nbLoadingTuneSeed + 1, SND_BANK_SLOT_WEAPON_GEN);
}
// 0x4DD440
@ -31,7 +27,7 @@ void CAEFrontendAudioEntity::Reset() {
m_nLastFrameGeneral_or_nFrameCount = 0;
m_nLastFrameMissionComplete = 0;
m_nLastFrameBulletPass = 0;
m_nNumBulletSounds = 0;
m_BulletPassCount = 0;
m_f7E = -1;
AESoundManager.CancelSoundsOfThisEventPlayingForThisEntity(AE_FRONTEND_SCANNER_NOISE_START, this);
}
@ -46,78 +42,85 @@ void CAEFrontendAudioEntity::AddAudioEvent(eAudioEvents event, float fVolumeBoos
CVector XVECM = { -1.0f, 0.0f, 0.0f };
CVector YVECP = { +0.0f, 1.0f, 0.0f };
const auto IncrementBulletHitsBank = [&]() {
m_BulletPassBank = (eSoundBank)(m_BulletPassBank + 1);
if (m_BulletPassBank > SND_BANK_GENRL_BULLET_PASS_LAST) {
m_BulletPassBank = SND_BANK_GENRL_BULLET_PASS_FIRST;
}
};
float volume = GetDefaultVolume(event) + fVolumeBoost;
switch (event) {
case AE_FRONTEND_START:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
sound.Initialise(0, 25, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 25, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(0, 26, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 26, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_SELECT:
if (AEAudioHardware.IsSoundBankLoaded(60u, 1)) {
sound.Initialise(1, 6, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_MENU, SND_BANK_SLOT_FRONTEND_MENU)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_MENU, 6, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(1, 7, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_MENU, 7, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_BACK:
if (AEAudioHardware.IsSoundBankLoaded(60u, 1)) {
sound.Initialise(1, 0, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_MENU, SND_BANK_SLOT_FRONTEND_MENU)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_MENU, 0, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(1, 1, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_MENU, 1, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_HIGHLIGHT:
if (AEAudioHardware.IsSoundBankLoaded(60u, 1)) {
sound.Initialise(1, 4, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_MENU, SND_BANK_SLOT_FRONTEND_MENU)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_MENU, 4, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(1, 5, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_MENU, 5, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_ERROR:
if (AEAudioHardware.IsSoundBankLoaded(60u, 1)) {
sound.Initialise(1, 2, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_MENU, SND_BANK_SLOT_FRONTEND_MENU)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_MENU, 2, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(1, 3, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_MENU, 3, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_NOISE_TEST:
if (AEAudioHardware.IsSoundBankLoaded(60u, 1)) {
sound.Initialise(1, 8, this, YVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_MENU, SND_BANK_SLOT_FRONTEND_MENU)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_MENU, 8, this, YVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;;
AESoundManager.RequestNewSound(&sound);
}
return;
@ -126,16 +129,16 @@ void CAEFrontendAudioEntity::AddAudioEvent(eAudioEvents event, float fVolumeBoos
case AE_FRONTEND_CAR_FIT_BOMB_BOOBY_TRAPPED:
case AE_FRONTEND_CAR_FIT_BOMB_REMOTE_CONTROLLED:
case AE_FRONTEND_PURCHASE_WEAPON:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0) && CTimer::GetFrameCounter() >= m_nLastFrameGeneral_or_nFrameCount + 5) {
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME) && CTimer::GetFrameCounter() >= m_nLastFrameGeneral_or_nFrameCount + 5) {
m_nLastFrameGeneral_or_nFrameCount = CTimer::GetFrameCounter();
sound.Initialise(0, 27, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 27, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(0, 28, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 28, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
@ -143,66 +146,66 @@ void CAEFrontendAudioEntity::AddAudioEvent(eAudioEvents event, float fVolumeBoos
case AE_FRONTEND_PICKUP_HEALTH:
case AE_FRONTEND_PICKUP_ADRENALINE:
case AE_FRONTEND_PICKUP_BODY_ARMOUR:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0) && CTimer::GetFrameCounter() >= m_nLastFrameGeneral_or_nFrameCount + 5) {
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME) && CTimer::GetFrameCounter() >= m_nLastFrameGeneral_or_nFrameCount + 5) {
m_nLastFrameGeneral_or_nFrameCount = CTimer::GetFrameCounter();
sound.Initialise(0, 16, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 16, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(0, 17, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 17, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_PICKUP_INFO:
case AE_FRONTEND_DISPLAY_INFO:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
sound.Initialise(0, 14, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 14, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(0, 15, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 15, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_PICKUP_DRUGS:
case AE_FRONTEND_PICKUP_COLLECTABLE1:
case AE_FRONTEND_PART_MISSION_COMPLETE:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0) && CTimer::GetFrameCounter() >= m_nLastFrameMissionComplete + 5) {
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME) && CTimer::GetFrameCounter() >= m_nLastFrameMissionComplete + 5) {
m_nLastFrameMissionComplete = CTimer::GetFrameCounter();
sound.Initialise(0, 18, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 18, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(0, 19, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 19, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_CAR_NO_CASH:
case AE_FRONTEND_CAR_IS_HOT:
case AE_FRONTEND_CAR_ALREADY_RIGGED:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0) && CTimer::GetFrameCounter() >= m_nLastFrameGeneral_or_nFrameCount + 5) {
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME) && CTimer::GetFrameCounter() >= m_nLastFrameGeneral_or_nFrameCount + 5) {
m_nLastFrameGeneral_or_nFrameCount = CTimer::GetFrameCounter();
sound.Initialise(0, 27, this, XVECM, volume, 1.0f, 0.841f);
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 27, this, XVECM, volume, 1.0f, 0.841f);
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(0, 28, this, XVECP, volume, 1.0f, 0.841f);
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 28, this, XVECP, volume, 1.0f, 0.841f);
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_CAR_RESPRAY:
{
if (!AEAudioHardware.IsSoundBankLoaded(143u, 5))
if (!AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN))
return;
float speed0, speed1;
@ -213,118 +216,110 @@ void CAEFrontendAudioEntity::AddAudioEvent(eAudioEvents event, float fVolumeBoos
speed0 = 1.0f;
speed1 = 1.1892101f;
}
sound.Initialise(5, 28, this, XVECM, volume, 1.0f, speed0);
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_PLAY_PHYSICALLY | SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.m_nEvent = AE_FRONTEND_CAR_RESPRAY;
sound.Initialise(SND_BANK_SLOT_WEAPON_GEN, 28, this, XVECM, volume, 1.0f, speed0);
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_PLAY_PHYSICALLY | SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
sound.m_Event = AE_FRONTEND_CAR_RESPRAY;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(5, 28, this, XVECP, volume, 1.0f, speed1);
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_PLAY_PHYSICALLY | SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.m_nEvent = AE_FRONTEND_CAR_RESPRAY;
sound.Initialise(SND_BANK_SLOT_WEAPON_GEN, 28, this, XVECP, volume, 1.0f, speed1);
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_PLAY_PHYSICALLY | SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
sound.m_Event = AE_FRONTEND_CAR_RESPRAY;
AESoundManager.RequestNewSound(&sound);
m_nLastTimeCarRespray = CTimer::GetTimeInMS();
return;
}
case AE_FRONTEND_BULLET_PASS_LEFT_REAR:
if (!AEAudioHardware.IsSoundBankLoaded(m_nBankId, 42) || CTimer::GetFrameCounter() < m_nLastFrameBulletPass + 5)
if (!AEAudioHardware.IsSoundBankLoaded(m_BulletPassBank, SND_BANK_SLOT_BULLET_PASS) || CTimer::GetFrameCounter() < m_nLastFrameBulletPass + 5)
return;
// inlined
if (m_nNumBulletSounds > 10) {
if (!AESoundManager.AreSoundsPlayingInBankSlot(42)) {
if (++m_nBankId > 31) {
m_nBankId = 28;
}
AEAudioHardware.LoadSoundBank(m_nBankId, 42);
m_nNumBulletSounds = 0;
if (m_BulletPassCount > 10) {
if (!AESoundManager.AreSoundsPlayingInBankSlot(SND_BANK_SLOT_BULLET_PASS)) {
IncrementBulletHitsBank();
AEAudioHardware.LoadSoundBank(m_BulletPassBank, SND_BANK_SLOT_BULLET_PASS);
m_BulletPassCount = 0;
}
return;
}
m_nLastFrameBulletPass = CTimer::GetFrameCounter();
sound.Initialise(42, CAEAudioUtility::GetRandomNumberInRange(0, 2), this, { -0.1f, -1.0f, 0.0f }, volume);
sound.m_nEvent = AE_FRONTEND_BULLET_PASS_LEFT_REAR;
sound.m_fSpeedVariability = 0.03125f;
sound.m_nEnvironmentFlags = SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_BULLET_PASS, CAEAudioUtility::GetRandomNumberInRange(0, 2), this, { -0.1f, -1.0f, 0.0f }, volume);
sound.m_Event = AE_FRONTEND_BULLET_PASS_LEFT_REAR;
sound.m_SpeedVariance = 0.03125f;
sound.m_Flags = SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
++m_nNumBulletSounds;
++m_BulletPassCount;
return;
case AE_FRONTEND_BULLET_PASS_LEFT_FRONT:
if (!AEAudioHardware.IsSoundBankLoaded(m_nBankId, 42) || CTimer::GetFrameCounter() < m_nLastFrameBulletPass + 5)
if (!AEAudioHardware.IsSoundBankLoaded(m_BulletPassBank, SND_BANK_SLOT_BULLET_PASS) || CTimer::GetFrameCounter() < m_nLastFrameBulletPass + 5)
return;
// inlined
if (m_nNumBulletSounds > 10) {
if (!AESoundManager.AreSoundsPlayingInBankSlot(42)) {
if (++m_nBankId > 31) {
m_nBankId = 28;
}
AEAudioHardware.LoadSoundBank(m_nBankId, 42);
m_nNumBulletSounds = 0;
if (m_BulletPassCount > 10) {
if (!AESoundManager.AreSoundsPlayingInBankSlot(SND_BANK_SLOT_BULLET_PASS)) {
IncrementBulletHitsBank();
AEAudioHardware.LoadSoundBank(m_BulletPassBank, SND_BANK_SLOT_BULLET_PASS);
m_BulletPassCount = 0;
}
return;
}
m_nLastFrameBulletPass = CTimer::GetFrameCounter();
sound.Initialise(42, CAEAudioUtility::GetRandomNumberInRange(0, 2), this, { -0.1f, +1.0f, 0.0f }, volume);
sound.m_nEvent = AE_FRONTEND_BULLET_PASS_LEFT_FRONT;
sound.m_fSpeedVariability = 0.03125f;
sound.m_nEnvironmentFlags = SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_BULLET_PASS, CAEAudioUtility::GetRandomNumberInRange(0, 2), this, { -0.1f, +1.0f, 0.0f }, volume);
sound.m_Event = AE_FRONTEND_BULLET_PASS_LEFT_FRONT;
sound.m_SpeedVariance = 0.03125f;
sound.m_Flags = SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
++m_nNumBulletSounds;
++m_BulletPassCount;
return;
case AE_FRONTEND_BULLET_PASS_RIGHT_REAR:
if (!AEAudioHardware.IsSoundBankLoaded(m_nBankId, 42) || CTimer::GetFrameCounter() < m_nLastFrameBulletPass + 5)
if (!AEAudioHardware.IsSoundBankLoaded(m_BulletPassBank, SND_BANK_SLOT_BULLET_PASS) || CTimer::GetFrameCounter() < m_nLastFrameBulletPass + 5)
return;
if (m_nNumBulletSounds <= 10) {
if (m_BulletPassCount <= 10) {
m_nLastFrameBulletPass = CTimer::GetFrameCounter();
sound.Initialise(42, CAEAudioUtility::GetRandomNumberInRange(0, 2), this, { 0.1f, -1.0f, 0.0f }, volume);
sound.m_nEvent = AE_FRONTEND_BULLET_PASS_RIGHT_REAR;
sound.m_fSpeedVariability = 0.03125f;
sound.m_nEnvironmentFlags = SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_BULLET_PASS, CAEAudioUtility::GetRandomNumberInRange(0, 2), this, { 0.1f, -1.0f, 0.0f }, volume);
sound.m_Event = AE_FRONTEND_BULLET_PASS_RIGHT_REAR;
sound.m_SpeedVariance = 0.03125f;
sound.m_Flags = SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
++m_nNumBulletSounds;
++m_BulletPassCount;
return;
}
if (!AESoundManager.AreSoundsPlayingInBankSlot(42)) {
if (!AESoundManager.AreSoundsPlayingInBankSlot(SND_BANK_SLOT_BULLET_PASS)) {
// inlined
if (++m_nBankId > 31) {
m_nBankId = 28;
}
AEAudioHardware.LoadSoundBank(m_nBankId, 42);
m_nNumBulletSounds = 0;
IncrementBulletHitsBank();
AEAudioHardware.LoadSoundBank(m_BulletPassBank, SND_BANK_SLOT_BULLET_PASS);
m_BulletPassCount = 0;
}
return;
case AE_FRONTEND_BULLET_PASS_RIGHT_FRONT:
if (AEAudioHardware.IsSoundBankLoaded(m_nBankId, 42) && CTimer::GetFrameCounter() >= m_nLastFrameBulletPass + 5) {
if (m_nNumBulletSounds <= 10) {
if (AEAudioHardware.IsSoundBankLoaded(m_BulletPassBank, SND_BANK_SLOT_BULLET_PASS) && CTimer::GetFrameCounter() >= m_nLastFrameBulletPass + 5) {
if (m_BulletPassCount <= 10) {
m_nLastFrameBulletPass = CTimer::GetFrameCounter();
sound.Initialise(42, CAEAudioUtility::GetRandomNumberInRange(0, 2), this, { 0.1f, +1.0f, 0.0f }, volume);
sound.m_nEvent = AE_FRONTEND_BULLET_PASS_RIGHT_FRONT;
sound.m_fSpeedVariability = 0.03125f;
sound.m_nEnvironmentFlags = SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_BULLET_PASS, CAEAudioUtility::GetRandomNumberInRange(0, 2), this, { 0.1f, +1.0f, 0.0f }, volume);
sound.m_Event = AE_FRONTEND_BULLET_PASS_RIGHT_FRONT;
sound.m_SpeedVariance = 0.03125f;
sound.m_Flags = SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
++m_nNumBulletSounds;
++m_BulletPassCount;
} else {
if (!AESoundManager.AreSoundsPlayingInBankSlot(42)) {
if (!AESoundManager.AreSoundsPlayingInBankSlot(SND_BANK_SLOT_BULLET_PASS)) {
// inlined
if (++m_nBankId > 31) {
m_nBankId = 28;
}
AEAudioHardware.LoadSoundBank(m_nBankId, 42);
m_nNumBulletSounds = 0;
IncrementBulletHitsBank();
AEAudioHardware.LoadSoundBank(m_BulletPassBank, SND_BANK_SLOT_BULLET_PASS);
m_BulletPassCount = 0;
}
}
}
return;
case AE_FRONTEND_WAKEUP_AMPLIFIER:
if (!m_bAmplifierWakeUp && AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
sound.Initialise(0, 8, this, YVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
if (!m_bAmplifierWakeUp && AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 8, this, YVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
m_pAmplifierWakeUp = AESoundManager.RequestNewSound(&sound);
m_bAmplifierWakeUp = m_pAmplifierWakeUp != nullptr;
}
@ -335,33 +330,33 @@ void CAEFrontendAudioEntity::AddAudioEvent(eAudioEvents event, float fVolumeBoos
return;
}
if (AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
sound.Initialise(0, 4, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_PLAY_PHYSICALLY | SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.m_nEvent = AE_FRONTEND_TIMER_COUNT;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 4, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_PLAY_PHYSICALLY | SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
sound.m_Event = AE_FRONTEND_TIMER_COUNT;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(0, 5, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_PLAY_PHYSICALLY | SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.m_nEvent = AE_FRONTEND_TIMER_COUNT;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 5, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_PLAY_PHYSICALLY | SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
sound.m_Event = AE_FRONTEND_TIMER_COUNT;
AESoundManager.RequestNewSound(&sound);
m_nLatestTimerCount = CTimer::GetTimeInMS();
}
return;
case AE_FRONTEND_RADIO_RETUNE_START:
{
auto flags0 = eSoundEnvironment(SOUND_UNDUCKABLE | SOUND_MUSIC_MASTERED | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END);
auto flags1 = eSoundEnvironment(flags0 | SOUND_UNPAUSABLE);
if (AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
auto flags0 = eSoundEnvironment(SOUND_IS_DUCKABLE | SOUND_MUSIC_MASTERED | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END);
auto flags1 = eSoundEnvironment(flags0 | SOUND_IS_PAUSABLE);
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
if (CTimer::GetIsPaused()) {
if (!m_objRetunePaused.m_bIsInitialised) {
m_objRetunePaused.Initialise(0, 2, 1, this, 200, 650, -1, -1);
if (!m_objRetunePaused.IsActive()) {
m_objRetunePaused.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 2, 1, this, 200, 650, -1, -1);
m_objRetunePaused.PlayTwinLoopSound(YVECP, volume, 1.0f, 1.0f, 1.0f, flags1);
}
} else if (!m_objRetune.m_bIsInitialised) {
m_objRetune.Initialise(0, 2, 1, this, 200, 650, -1, -1);
} else if (!m_objRetune.IsActive()) {
m_objRetune.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 2, 1, this, 200, 650, -1, -1);
m_objRetune.PlayTwinLoopSound(YVECP, volume, 1.0f, 1.0f, 1.0f, flags0);
}
}
@ -369,91 +364,88 @@ void CAEFrontendAudioEntity::AddAudioEvent(eAudioEvents event, float fVolumeBoos
}
case AE_FRONTEND_RADIO_RETUNE_STOP:
if (CTimer::GetIsPaused()) {
if (m_objRetunePaused.m_bIsInitialised) {
if (m_objRetunePaused.IsActive()) {
m_objRetunePaused.StopSoundAndForget();
}
return;
}
if (m_objRetune.m_bIsInitialised) {
} else if (m_objRetune.IsActive()) {
m_objRetune.StopSoundAndForget();
}
return;
case AE_FRONTEND_RADIO_RETUNE_STOP_PAUSED:
if (m_objRetunePaused.m_bIsInitialised) {
if (m_objRetunePaused.IsActive()) {
m_objRetunePaused.StopSoundAndForget();
}
return;
case AE_FRONTEND_RADIO_CLICK_ON:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
sound.Initialise(0, 23, this, YVECP, volume);
sound.m_nEnvironmentFlags = SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 23, this, YVECP, volume);
sound.m_Flags = SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_RADIO_CLICK_OFF:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
sound.Initialise(0, 23, this, YVECP, volume, 1.0f, 0.8909f);
sound.m_nEnvironmentFlags = SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 23, this, YVECP, volume, 1.0f, 0.8909f);
sound.m_Flags = SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_FIRE_FAIL_SNIPERRIFFLE:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
sound.Initialise(0, 10, this, YVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FRONT_END | SOUND_UNCANCELLABLE;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 10, this, YVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FRONT_END | SOUND_IS_CANCELLABLE;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_FIRE_FAIL_ROCKET:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
sound.Initialise(0, 11, this, YVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FRONT_END | SOUND_UNCANCELLABLE;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 11, this, YVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FRONT_END | SOUND_IS_CANCELLABLE;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_RACE_321:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
sound.Initialise(0, 6, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 6, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(0, 7, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 7, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_RACE_GO:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
sound.Initialise(0, 12, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 12, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(0, 13, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 13, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_ROLLED_OFF | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_BUY_CAR_MOD:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0)) {
sound.Initialise(0, 9, this, YVECP, volume);
sound.m_nEnvironmentFlags = SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;;
sound.m_fSpeedVariability = 0.0588f;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 9, this, YVECP, volume);
sound.m_Flags = SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;;
sound.m_SpeedVariance = 0.0588f;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_SCANNER_NOISE_START:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0) && !AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_FRONTEND_SCANNER_NOISE_START, this)) {
sound.Initialise(0, 3, this, YVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_UNDUCKABLE | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.m_nEvent = AE_FRONTEND_SCANNER_NOISE_START;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME) && !AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_FRONTEND_SCANNER_NOISE_START, this)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 3, this, YVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_IS_DUCKABLE | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
sound.m_Event = AE_FRONTEND_SCANNER_NOISE_START;
AESoundManager.RequestNewSound(&sound);
}
return;
@ -461,29 +453,29 @@ void CAEFrontendAudioEntity::AddAudioEvent(eAudioEvents event, float fVolumeBoos
AESoundManager.CancelSoundsOfThisEventPlayingForThisEntity(47, this);
return;
case AE_FRONTEND_SCANNER_CLICK:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0) && !AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_FRONTEND_SCANNER_CLICK, this)) {
sound.Initialise(0, 24, this, YVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_UNDUCKABLE | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.m_nEvent = AE_FRONTEND_SCANNER_CLICK;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME) && !AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_FRONTEND_SCANNER_CLICK, this)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 24, this, YVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_IS_DUCKABLE | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
sound.m_Event = AE_FRONTEND_SCANNER_CLICK;
AESoundManager.RequestNewSound(&sound);
}
return;
case AE_FRONTEND_LOADING_TUNE_START:
if ( AEAudioHardware.IsSoundLoaded(BANK_LOADING_TUNE, 2 * m_nbLoadingTuneSeed, 2)
&& AEAudioHardware.IsSoundLoaded(BANK_LOADING_TUNE, 2 * m_nbLoadingTuneSeed + 1, 5)
if ( AEAudioHardware.IsSoundLoaded(SND_BANK_GENRL_LOADING, 2 * m_nbLoadingTuneSeed, SND_BANK_SLOT_COLLISIONS)
&& AEAudioHardware.IsSoundLoaded(SND_BANK_GENRL_LOADING, 2 * m_nbLoadingTuneSeed + 1, SND_BANK_SLOT_WEAPON_GEN)
&& !AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_FRONTEND_LOADING_TUNE_START, this)
) {
sound.Initialise(2, 2 * m_nbLoadingTuneSeed, this, XVECM, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.m_nEvent = AE_FRONTEND_LOADING_TUNE_START;
sound.Initialise(SND_BANK_SLOT_WEAPON_GEN, 2 * m_nbLoadingTuneSeed, this, XVECM, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
sound.m_Event = AE_FRONTEND_LOADING_TUNE_START;
AESoundManager.RequestNewSound(&sound);
sound.Initialise(5, 2 * m_nbLoadingTuneSeed + 1, this, XVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_FORCED_FRONT | SOUND_UNDUCKABLE | SOUND_UNPAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_UNCANCELLABLE | SOUND_FRONT_END;
sound.m_nEvent = AE_FRONTEND_LOADING_TUNE_START;
sound.Initialise(SND_BANK_SLOT_WEAPON_GEN, 2 * m_nbLoadingTuneSeed + 1, this, XVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_FORCED_FRONT | SOUND_IS_DUCKABLE | SOUND_IS_PAUSABLE | SOUND_PLAY_PHYSICALLY | SOUND_IS_CANCELLABLE | SOUND_FRONT_END;
sound.m_Event = AE_FRONTEND_LOADING_TUNE_START;
AESoundManager.RequestNewSound(&sound);
}
return;
@ -491,11 +483,11 @@ void CAEFrontendAudioEntity::AddAudioEvent(eAudioEvents event, float fVolumeBoos
AESoundManager.CancelSoundsOfThisEventPlayingForThisEntity(50, this);
return;
case AE_MISSILE_LOCK:
if (AEAudioHardware.IsSoundBankLoaded(59u, 0) && !AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_MISSILE_LOCK, this)) {
sound.Initialise(0, 13, this, YVECP, volume);
sound.m_fSpeed = fSpeed;
sound.m_nEnvironmentFlags = SOUND_UNDUCKABLE | SOUND_FRONT_END;
sound.m_nEvent = AE_MISSILE_LOCK;
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME) && !AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_MISSILE_LOCK, this)) {
sound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 13, this, YVECP, volume);
sound.m_Speed = fSpeed;
sound.m_Flags = SOUND_IS_DUCKABLE | SOUND_FRONT_END;
sound.m_Event = AE_MISSILE_LOCK;
AESoundManager.RequestNewSound(&sound);
}
return;
@ -506,10 +498,9 @@ void CAEFrontendAudioEntity::AddAudioEvent(eAudioEvents event, float fVolumeBoos
// 0x4DD480
bool CAEFrontendAudioEntity::IsRadioTuneSoundActive() {
if (CTimer::GetIsPaused())
return m_objRetunePaused.m_bIsInitialised;
else
return m_objRetune.m_bIsInitialised;
return CTimer::GetIsPaused()
? m_objRetunePaused.IsActive()
: m_objRetune.IsActive();
}
// 0x4DD470
@ -535,7 +526,7 @@ void CAEFrontendAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos)
}
};
switch (sound->m_nEvent) {
switch (sound->m_Event) {
case AE_FRONTEND_CAR_RESPRAY:
if (curPlayPos > 0 && CTimer::GetTimeInMS() > m_nLastTimeCarRespray + 1900) {
sound->StopSoundAndForget();
@ -578,4 +569,4 @@ void CAEFrontendAudioEntity::InjectHooks() {
RH_ScopedInstall(IsRadioTuneSoundActive, 0x4DD480);
RH_ScopedInstall(IsLoadingTuneActive, 0x4DD470);
RH_ScopedVMTInstall(UpdateParameters, 0x4DEDA0, { .reversed = false });
}
}

View File

@ -8,8 +8,8 @@ protected:
bool m_bAmplifierWakeUp;
uint8 m_nbLoadingTuneSeed;
int16 m_f7E; // unused
int16 m_nNumBulletSounds;
int16 m_nBankId;
int16 m_BulletPassCount;
eSoundBank m_BulletPassBank;
uint32 m_nLastFrameGeneral_or_nFrameCount;
uint32 m_nLastFrameMissionComplete;
uint32 m_nLastFrameBulletPass;

View File

@ -19,19 +19,20 @@ CAEGlobalWeaponAudioEntity::~CAEGlobalWeaponAudioEntity() {
// 0x4DEF90
void CAEGlobalWeaponAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
if (curPlayPos != -1)
if (curPlayPos != -1) {
return;
}
if (sound == pFogHorn) {
pFogHorn = nullptr;
return;
}
for (auto& waterfall : pWaterfall) {
if (sound == waterfall) {
waterfall = nullptr;
} else {
for (auto& waterfall : pWaterfall) {
if (sound == waterfall) {
waterfall = nullptr;
}
}
}
}
// 0x4DFAA0
@ -63,7 +64,7 @@ void CAEGlobalWeaponAudioEntity::ProjectileFire(eWeaponType weaponType, CPhysica
constexpr float gfRocketFrequencyVariations[] = { 1.08f, 1.0f, 0.92f, 3.3f };// 0x8AE5AC
m_FrequencyVariation = (m_FrequencyVariation + 1) % (std::size(gfRocketFrequencyVariations) - 1);
const auto PlayRocketSound = [&](int16 bankSlotID, eSoundID soundID, float speedMult, float volumeOffsetdB) {
const auto PlayRocketSound = [&](eSoundBankSlot bankSlotID, eSoundID soundID, float speedMult, float volumeOffsetdB) {
AESoundManager.PlaySound({
.BankSlotID = bankSlotID,
.SoundID = soundID,
@ -75,22 +76,18 @@ void CAEGlobalWeaponAudioEntity::ProjectileFire(eWeaponType weaponType, CPhysica
.Flags = SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY,
.FrequencyVariance = 0.02f,
.RegisterWithEntity = physical
});
};
});
};
if (!AEAudioHardware.IsSoundBankLoaded(143, 5)) {
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(143, 5);
}
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN, true)) {
return;
}
PlayRocketSound(5, 68, 1.f, -8.f);
PlayRocketSound(SND_BANK_SLOT_WEAPON_GEN, SND_GENRL_WEAPONS_ROCKET_LAUNCH, 1.f, -8.f);
if (!AEAudioHardware.IsSoundBankLoaded(138, 19)) {
AEAudioHardware.LoadSoundBank(138, 19);
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN)) {
return;
}
PlayRocketSound(19, 26, 1.25f, 0.f);
PlayRocketSound(SND_BANK_SLOT_VEHICLE_GEN, SND_GENRL_WEAPONS_SNIPER_SHOT_L, 1.25f, 0.f);
}
// 0x4DF210
@ -144,7 +141,7 @@ void CAEGlobalWeaponAudioEntity::ServiceAmbientGunFire() {
break;
}
case WEATHER_REGION_LV: { // 0x4DF580
if (!AEAudioHardware.IsSoundBankLoaded(39u, 2)) {
if (!AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_COLLISIONS, SND_BANK_SLOT_COLLISIONS)) {
return;
}
if (!rng::all_of(pWaterfall, notsa::IsNull{})) {
@ -155,7 +152,7 @@ void CAEGlobalWeaponAudioEntity::ServiceAmbientGunFire() {
}
const auto PlayWaterfallSound = [&](int32 i, float speed) {
pWaterfall[i] = AESoundManager.PlaySound({
.BankSlotID = 2,
.BankSlotID = SND_BANK_SLOT_COLLISIONS,
.SoundID = 3,
.AudioEntity = this,
.Pos = s_WaterfallPositions[i],
@ -193,7 +190,7 @@ void CAEGlobalWeaponAudioEntity::ServiceAmbientGunFire() {
}
pFogHorn = AESoundManager.PlaySound({
.BankSlotID = 17,
.BankSlotID = SND_BANK_SLOT_HORN_AND_SIREN,
.SoundID = 13,
.AudioEntity = this,
.Pos = s_FogHornPositions[0],
@ -243,10 +240,10 @@ void CAEGlobalWeaponAudioEntity::ServiceAmbientGunFire() {
}
s_State = s_State == eState::FOGHORN_0
? eState::STATE_3 // FOGHORN_0 -> S3
: eState::INITIAL; // FOGHORN_1 -> S0
: eState::INITIAL; // FOGHORN_1 -> INITIAL
} else if (CTimer::GetTimeInMS() > s_LastTime + FOGHORN_FADE_OUT_DELAY) { // BUG: Since `FOGHORN_TTL` and `FOGHORN_FADE_OUT_DELAY` are both 5000 the `if` here will never be true.
if (pFogHorn) {
pFogHorn->m_fVolume -= 3.3f;
pFogHorn->m_Volume -= 3.3f;
}
}
break;
@ -255,12 +252,12 @@ void CAEGlobalWeaponAudioEntity::ServiceAmbientGunFire() {
if (s_LastTime + 6500 < CTimer::GetTimeInMS()) {
return;
}
if (!AEAudioHardware.IsSoundBankLoaded(59, 0)) { // BUG: Pretty sure the `bankSlotId` param should be 17 here
if (!AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME)) { // NB (Bug?): Why check this sound bank, when it's not even used below?
return;
}
if (!pFogHorn) {
pFogHorn = AESoundManager.PlaySound({
.BankSlotID = 17,
.BankSlotID = SND_BANK_SLOT_HORN_AND_SIREN,
.SoundID = 13,
.AudioEntity = this,
.Pos = s_FogHornPositions[1],

View File

@ -63,8 +63,8 @@ void CAEPedAudioEntity::Initialise(CPed* ped) {
// 0x5B98A0
void CAEPedAudioEntity::StaticInitialise() {
AEAudioHardware.LoadSoundBank(0, 41);
AEAudioHardware.LoadSoundBank(128, 32);
AEAudioHardware.LoadSoundBank(SND_BANK_FEET_GENERIC, SND_BANK_SLOT_FOOTSTEPS_GENERIC);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_SWIMMING, SND_BANK_SLOT_SWIMMING);
}
// 0x4E1360
@ -73,7 +73,7 @@ void CAEPedAudioEntity::Terminate() {
m_pPed = nullptr;
StopJetPackSound();
AESoundManager.CancelSoundsOwnedByAudioEntity(this, true);
if (m_sTwinLoopSoundEntity.m_bIsInitialised) {
if (m_sTwinLoopSoundEntity.IsActive()) {
m_sTwinLoopSoundEntity.StopSoundAndForget();
}
}
@ -127,27 +127,27 @@ void CAEPedAudioEntity::AddAudioEvent(eAudioEvents event, float volume, float sp
HandleSwimWake(event);
break;
case AE_PED_CRUNCH: {
if (!AEAudioHardware.IsSoundBankLoaded(39u, 2) || AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_PED_CRUNCH, this))
if (!AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_COLLISIONS, SND_BANK_SLOT_COLLISIONS) || AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_PED_CRUNCH, this))
break;
const auto vol = GetDefaultVolume(AE_PED_CRUNCH) + volume;
CAESound sound;
sound.Initialise(2, 29, this, ped->GetPosition(), vol, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
sound.m_fSpeed = speed;
sound.m_fSpeedVariability = 0.06f;
sound.m_fSoundDistance = 1.5f;
sound.m_nEvent = AE_PED_CRUNCH;
sound.Initialise(SND_BANK_SLOT_COLLISIONS, 29, this, ped->GetPosition(), vol, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
sound.m_Speed = speed;
sound.m_SpeedVariance = 0.06f;
sound.m_RollOffFactor = 1.5f;
sound.m_Event = AE_PED_CRUNCH;
AESoundManager.RequestNewSound(&sound);
if (AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_PED_KNOCK_DOWN, this) != 0)
break;
auto RandomNumberInRange = CAEAudioUtility::GetRandomNumberInRange(47, 49);
sound.Initialise(2, RandomNumberInRange, this, ped->GetPosition(), vol, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
sound.m_fSpeed = speed;
sound.m_fSpeedVariability = 0.06f;
sound.m_fSoundDistance = 1.5f;
sound.m_nEvent = AE_PED_KNOCK_DOWN;
sound.Initialise(SND_BANK_SLOT_COLLISIONS, RandomNumberInRange, this, ped->GetPosition(), vol, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
sound.m_Speed = speed;
sound.m_SpeedVariance = 0.06f;
sound.m_RollOffFactor = 1.5f;
sound.m_Event = AE_PED_KNOCK_DOWN;
AESoundManager.RequestNewSound(&sound);
break;
}
@ -171,19 +171,19 @@ void CAEPedAudioEntity::TurnOnJetPack() {
m_bJetPackPlaying = true;
m_tempSound.Initialise(19, 26, this, m_pPed->GetPosition(), -100.0f, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_fSpeed = 1.0f;
m_tempSound.m_nEnvironmentFlags = SOUND_REQUEST_UPDATES;
m_tempSound.Initialise(SND_BANK_SLOT_VEHICLE_GEN, 26, this, m_pPed->GetPosition(), -100.0f, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_Speed = 1.0f;
m_tempSound.m_Flags = SOUND_REQUEST_UPDATES;
m_JetPackSound0 = AESoundManager.RequestNewSound(&m_tempSound);
m_tempSound.Initialise(5, 10, this, m_pPed->GetPosition(), -100.0f, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_fSpeed = 1.0f;
m_tempSound.m_nEnvironmentFlags = SOUND_REQUEST_UPDATES;
m_tempSound.Initialise(SND_BANK_SLOT_WEAPON_GEN, 10, this, m_pPed->GetPosition(), -100.0f, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_Speed = 1.0f;
m_tempSound.m_Flags = SOUND_REQUEST_UPDATES;
m_JetPackSound1 = AESoundManager.RequestNewSound(&m_tempSound);
m_tempSound.Initialise(0, 0, this, m_pPed->GetPosition(), -100.0f, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_fSpeed = 1.0f;
m_tempSound.m_nEnvironmentFlags = SOUND_REQUEST_UPDATES;
m_tempSound.Initialise(SND_BANK_SLOT_FRONTEND_GAME, 0, this, m_pPed->GetPosition(), -100.0f, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_Speed = 1.0f;
m_tempSound.m_Flags = SOUND_REQUEST_UPDATES;
m_JetPackSound2 = AESoundManager.RequestNewSound(&m_tempSound);
}
@ -233,14 +233,14 @@ void CAEPedAudioEntity::UpdateJetPack(float thrustFwd, float thrustAngle) {
const float speed = angle < 0.0f ? -angle : angle; // maybe wrong
// 0.0f == 0xB61384 (uninitialized)
m_JetPackSound0->m_fVolume = m_fVolume1 + 0.0f;
m_JetPackSound0->m_fSpeed = speed * -0.07f + 1.0f;
m_JetPackSound0->m_Volume = m_fVolume1 + 0.0f;
m_JetPackSound0->m_Speed = speed * -0.07f + 1.0f;
m_JetPackSound1->m_fVolume = m_fVolume2 + 0.0f;
m_JetPackSound1->m_fSpeed = 0.56f;
m_JetPackSound1->m_Volume = m_fVolume2 + 0.0f;
m_JetPackSound1->m_Speed = 0.56f;
m_JetPackSound2->m_fVolume = m_fVolume3 + 0.0f;
m_JetPackSound2->m_fSpeed = (speed / 5.0f + 1.0f) * m_JetPackSoundSpeedMult;
m_JetPackSound2->m_Volume = m_fVolume3 + 0.0f;
m_JetPackSound2->m_Speed = (speed / 5.0f + 1.0f) * m_JetPackSoundSpeedMult;
}
// 0x4E1170
@ -294,7 +294,7 @@ void CAEPedAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
if (curPlayPos < 0)
return;
switch (sound->m_nEvent) {
switch (sound->m_Event) {
case AE_PED_SWING:
case AE_PED_HIT_HIGH:
case AE_PED_HIT_LOW:
@ -311,28 +311,28 @@ void CAEPedAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
case AE_PED_JACKED_DOZER:
if (CTimer::GetTimeInMS() < (uint32)sound->m_ClientVariable)
return;
sound->m_fSpeed = 1.0f;
sound->m_Speed = 1.0f;
return;
case AE_PED_SWIM_WAKE: {
const auto volume = GetDefaultVolume(AE_PED_SWIM_WAKE);
if (CTimer::GetTimeInMS() <= m_nTimeInMS + 100) {
if (sound->m_fVolume >= volume) {
if (sound->m_Volume >= volume) {
return;
}
if (sound->m_fVolume + 0.6f >= volume) {
sound->m_fVolume = volume;
if (sound->m_Volume + 0.6f >= volume) {
sound->m_Volume = volume;
return;
}
} else {
auto vol = volume - 20.0f;
if (sound->m_fVolume <= vol) {
if (sound->m_Volume <= vol) {
sound->StopSoundAndForget();
m_nTimeInMS = 0;
return;
}
sound->m_fVolume = std::max(sound->m_fVolume - 0.6f, vol);
sound->m_Volume = std::max(sound->m_Volume - 0.6f, vol);
}
return;
@ -352,8 +352,7 @@ void CAEPedAudioEntity::HandleSkateEvent(eAudioEvents event, float volume, float
if (m_pPed->bIsInTheAir)
return;
if (!AEAudioHardware.IsSoundBankLoaded(0, 41)) {
AEAudioHardware.LoadSoundBank(0, 41);
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_FEET_GENERIC, SND_BANK_SLOT_FOOTSTEPS_GENERIC)) {
return;
}
@ -363,7 +362,7 @@ void CAEPedAudioEntity::HandleSkateEvent(eAudioEvents event, float volume, float
+ volume
);
const auto sfxId = (event != AE_PED_SKATE_LEFT) + 7; // what?
m_tempSound.Initialise(41, sfxId, this, m_pPed->GetPosition(), vol, 1.0f, speed, 1.0f, 0, SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY, 0.0588f, 0);
m_tempSound.Initialise(SND_BANK_SLOT_FOOTSTEPS_GENERIC, sfxId, this, m_pPed->GetPosition(), vol, 1.0f, speed, 1.0f, 0, SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY, 0.0588f, 0);
m_tempSound.RegisterWithPhysicalEntity(m_pPed);
AESoundManager.RequestNewSound(&m_tempSound);
}
@ -373,29 +372,27 @@ void CAEPedAudioEntity::HandleLandingEvent(eAudioEvents event) {
if (m_pPed->bIsInTheAir)
return;
int16 bankSlotId;
eSoundBankSlot bankSlotId;
int16 sfxId;
int16 playPosn;
auto volume = GetDefaultVolume(event);
if (g_surfaceInfos.IsAudioWater(m_pPed->m_nContactSurface)) {
if (!AEAudioHardware.IsSoundBankLoaded(128u, 32)) {
AEAudioHardware.LoadSoundBank(128, 32);
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_SWIMMING, SND_BANK_SLOT_SWIMMING)) {
return;
}
bankSlotId = 32;
bankSlotId = SND_BANK_SLOT_SWIMMING;
sfxId = CAEAudioUtility::GetRandomNumberInRange(0, 4);
playPosn = 50;
if (volume <= 0.0f) {
volume = 0.0f;
}
} else {
if (!AEAudioHardware.IsSoundBankLoaded(0, 41)) {
AEAudioHardware.LoadSoundBank(0, 41);
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_FEET_GENERIC, SND_BANK_SLOT_FOOTSTEPS_GENERIC)) {
return;
}
bankSlotId = 41;
bankSlotId = SND_BANK_SLOT_FOOTSTEPS_GENERIC;
sfxId = event != 58 ? 0 : 6;
playPosn = 0;
}
@ -423,16 +420,15 @@ void CAEPedAudioEntity::HandlePedJacked(eAudioEvents event) {
// 0x4E26A0
void CAEPedAudioEntity::HandleSwimSplash(eAudioEvents event) {
if (!AEAudioHardware.IsSoundBankLoaded(128, 32)) {
AEAudioHardware.LoadSoundBank(128, 32);
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_SWIMMING, SND_BANK_SLOT_SWIMMING)) {
return;
}
const auto volume = GetDefaultVolume(event);
m_nSfxId = (m_nSfxId + 1) % 4;
m_tempSound.Initialise(32, m_nSfxId, this, m_pPed->GetPosition(), volume, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_fSpeedVariability = 0.0588f;
m_tempSound.SetIndividualEnvironment(SOUND_PLAY_PHYSICALLY | SOUND_START_PERCENTAGE | SOUND_UNDUCKABLE, true);
m_nSfxId = std::max(0, m_nSfxId + 1);
m_tempSound.Initialise(SND_BANK_SLOT_SWIMMING, m_nSfxId, this, m_pPed->GetPosition(), volume, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_SpeedVariance = 0.0588f;
m_tempSound.SetFlags(SOUND_PLAY_PHYSICALLY | SOUND_START_PERCENTAGE | SOUND_IS_DUCKABLE, true);
m_tempSound.RegisterWithPhysicalEntity(m_pPed);
AESoundManager.RequestNewSound(&m_tempSound);
}
@ -444,12 +440,12 @@ void CAEPedAudioEntity::HandleSwimWake(eAudioEvents event) {
return;
}
if (AEAudioHardware.IsSoundBankLoaded(39u, 2)) {
if (AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_COLLISIONS, SND_BANK_SLOT_COLLISIONS)) {
auto volume = GetDefaultVolume(event) - 20.0f;
m_tempSound.Initialise(2, 3, this, m_pPed->GetPosition(), volume, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_fSpeed = 0.75f;
m_tempSound.m_nEnvironmentFlags = SOUND_REQUEST_UPDATES | SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY;
m_tempSound.m_nEvent = event;
m_tempSound.Initialise(SND_BANK_SLOT_COLLISIONS, 3, this, m_pPed->GetPosition(), volume, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_Speed = 0.75f;
m_tempSound.m_Flags = SOUND_REQUEST_UPDATES | SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY;
m_tempSound.m_Event = event;
m_tempSound.RegisterWithPhysicalEntity(m_pPed);
AESoundManager.RequestNewSound(&m_tempSound);
m_nTimeInMS = CTimer::GetTimeInMS();
@ -457,16 +453,16 @@ void CAEPedAudioEntity::HandleSwimWake(eAudioEvents event) {
}
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(39, 2);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_COLLISIONS, SND_BANK_SLOT_COLLISIONS);
}
}
// 0x4E2A90
void CAEPedAudioEntity::PlayShirtFlap(float volume, float speed) {
if (m_sTwinLoopSoundEntity.m_bIsInitialised) {
if (m_sTwinLoopSoundEntity.IsActive()) {
m_sTwinLoopSoundEntity.UpdateTwinLoopSound(m_pPed->GetPosition(), volume, speed);
} else {
m_sTwinLoopSoundEntity.Initialise(5, 19, 20, this, 200, 1000, -1, -1);
m_sTwinLoopSoundEntity.Initialise(SND_BANK_SLOT_WEAPON_GEN, 19, 20, this, 200, 1000, -1, -1);
m_sTwinLoopSoundEntity.PlayTwinLoopSound(m_pPed->GetPosition(), volume, speed, 2.0f, 1.0f, SOUND_DEFAULT);
}
}

View File

@ -86,7 +86,7 @@ CAEPedSpeechAudioEntity::CAEPedSpeechAudioEntity(eAudioPedType pt) noexcept :
CAEPedSpeechAudioEntity::CAEPedSpeechAudioEntity(CPed* ped) noexcept :
CAEPedSpeechAudioEntity{}
{
m_pEntity = ped;
m_Entity = ped;
if (ped->GetModelID() != MODEL_INVALID) {
auto* const mi = ped->GetPedModelInfo();
m_PedAudioType = mi->m_nPedAudioType;
@ -225,8 +225,10 @@ void CAEPedSpeechAudioEntity::Service() { // static
s_bForceAudible = false;
for (auto&& [i, speech] : rngv::enumerate(s_PedSpeechSlots)) {
// Waiting for sound to load, and has loaded?
if (speech.Status == CAEPedSpeechSlot::eStatus::LOADING && AEAudioHardware.IsSoundLoaded(speech.SoundBankID, speech.SoundID, SND_BANK_SLOT_SPEECH1 + i)) {
speech.Status = CAEPedSpeechSlot::eStatus::WAITING;
if (speech.Status == CAEPedSpeechSlot::eStatus::LOADING) {
if (AEAudioHardware.IsSoundLoaded(speech.SoundBankID, speech.SoundID, (eSoundBankSlot)(SND_BANK_SLOT_SPEECH1 + i))) {
speech.Status = CAEPedSpeechSlot::eStatus::WAITING;
}
}
// Sound is now loaded, waiting to be played
@ -742,7 +744,7 @@ void CAEPedSpeechAudioEntity::LoadAndPlaySpeech(uint32 playbackTimeOffsetMS) {
return;
}
AEAudioHardware.LoadSound(m_BankID, m_SoundID, SND_BANK_SLOT_SPEECH1 + m_PedSpeechSlotID);
AEAudioHardware.LoadSound(m_BankID, m_SoundID, (eSoundBankSlot)(SND_BANK_SLOT_SPEECH1 + m_PedSpeechSlotID));
*speech = CAEPedSpeechSlot{
.Status = CAEPedSpeechSlot::eStatus::LOADING,
.AudioEntity = this,
@ -938,7 +940,7 @@ int16 CAEPedSpeechAudioEntity::CanWePlayGlobalSpeechContext(eGlobalSpeechContext
// 0x4E6550
int16 CAEPedSpeechAudioEntity::AddSayEvent(eAudioEvents audioEvent, eGlobalSpeechContext gCtx, uint32 startTimeDelayMs, float probability, bool overrideSilence, bool isForceAudible, bool isFrontEnd) {
return I_AddSayEvent<false>(m_pEntity->GetPosition(), audioEvent, gCtx, startTimeDelayMs, probability, overrideSilence, isForceAudible, isFrontEnd);
return I_AddSayEvent<false>(m_Entity->GetPosition(), audioEvent, gCtx, startTimeDelayMs, probability, overrideSilence, isForceAudible, isFrontEnd);
}
// 0x4E68D0
@ -971,7 +973,7 @@ void CAEPedSpeechAudioEntity::StopCurrentSpeech() {
return;
}
if (auto* const tFacial = notsa::cast<CTaskComplexFacial>(m_pEntity->AsPed()->GetTaskManager().GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX))) {
if (auto* const tFacial = notsa::cast<CTaskComplexFacial>(m_Entity->AsPed()->GetTaskManager().GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX))) {
tFacial->StopAll();
}
@ -1087,7 +1089,7 @@ void CAEPedSpeechAudioEntity::AddScriptSayEvent(eAudioEvents audioEvent, eAudioE
m_IsFrontend = isFrontEnd;
m_IsForcedAudible = isForceAudible;
if (const auto veh = m_pEntity->AsPed()->GetVehicleIfInOne()) {
if (const auto veh = m_Entity->AsPed()->GetVehicleIfInOne()) {
if (veh == FindPlayerVehicle()) {
m_IsForcedAudible = true;
}
@ -1114,7 +1116,7 @@ void CAEPedSpeechAudioEntity::Terminate() {
// 0x4E5CD0
void CAEPedSpeechAudioEntity::PlayLoadedSound() {
return I_PlayLoadedSound<false>(m_pEntity);
return I_PlayLoadedSound<false>(m_Entity);
}
// 0x4E4120
@ -1277,7 +1279,7 @@ int16 CAEPedSpeechAudioEntity::I_AddSayEvent(CVector pos, eAudioEvents audioEven
return -1;
}
if (!m_pEntity->AsPed()->IsAlive() && !IsGlobalContextPain(gCtx)) { // 0x4E66A7
if (!m_Entity->AsPed()->IsAlive() && !IsGlobalContextPain(gCtx)) { // 0x4E66A7
return -1;
}
}
@ -1292,7 +1294,7 @@ int16 CAEPedSpeechAudioEntity::I_AddSayEvent(CVector pos, eAudioEvents audioEven
if constexpr (!IsPedless) {
if (m_PedAudioType == PED_TYPE_PLAYER) {
if (FindPlayerPed() != m_pEntity || s_bAPlayerSpeaking && !m_IsPlayingSpeech) {
if (FindPlayerPed() != m_Entity || s_bAPlayerSpeaking && !m_IsPlayingSpeech) {
return -1;
}
}
@ -1322,7 +1324,7 @@ int16 CAEPedSpeechAudioEntity::I_AddSayEvent(CVector pos, eAudioEvents audioEven
m_IsFrontend = isFrontEnd;
if constexpr (!IsPedless) {
if (const auto veh = m_pEntity->AsPed()->GetVehicleIfInOne()) {
if (const auto veh = m_Entity->AsPed()->GetVehicleIfInOne()) {
if (veh == FindPlayerVehicle() && gCtx != CTX_GLOBAL_STOMACH_RUMBLE) {
m_IsFrontend = true;
}
@ -1357,7 +1359,7 @@ int16 CAEPedSpeechAudioEntity::I_AddSayEvent<true>(CVector pos, eAudioEvents aud
// 0x4E3520 / 0x4E4D10
template<bool IsPedless>
void CAEPedSpeechAudioEntity::I_UpdateParameters(CAESound* sound, int16 playTime) {
auto* const ped = IsPedless ? nullptr : m_pEntity->AsPed();
auto* const ped = IsPedless ? nullptr : m_Entity->AsPed();
auto* const speech = GetCurrentSpeech();
if (playTime == -1) { // Sound has finished?
*speech = {
@ -1388,21 +1390,21 @@ void CAEPedSpeechAudioEntity::I_UpdateParameters(CAESound* sound, int16 playTime
}
}
if (auto* const tFacial = notsa::cast<CTaskComplexFacial>(m_pEntity->AsPed()->GetTaskManager().GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX))) {
if (auto* const tFacial = notsa::cast<CTaskComplexFacial>(m_Entity->AsPed()->GetTaskManager().GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX))) {
tFacial->StopAll();
}
}
} else { // Update sound
speech->Status = CAEPedSpeechSlot::eStatus::PLAYING;
if constexpr (IsPedless) {
if (!m_IsFrontend || sound->m_nEvent == AE_SPEECH_PED) {
sound->SetPosition(m_pEntity->GetPosition());
if (!m_IsFrontend || sound->m_Event == AE_SPEECH_PED) {
sound->SetPosition(m_Entity->GetPosition());
}
} else {
if (ped->bIsTalking && ped->m_nBodypartToRemove == PED_NODE_HEAD) {
sound->StopSound();
} else if (!m_IsFrontend) {
sound->SetPosition(m_pEntity->GetPosition());
sound->SetPosition(m_Entity->GetPosition());
}
}
}
@ -1428,7 +1430,7 @@ void CAEPedSpeechAudioEntity::I_PlayLoadedSound(CEntity* attachTo) {
}
CAESound s;
s.Initialise(
SND_BANK_SLOT_SPEECH1 + m_PedSpeechSlotID,
(eSoundBankSlot)(SND_BANK_SLOT_SPEECH_FIRST + m_PedSpeechSlotID),
m_SoundID,
this,
pos,
@ -1449,14 +1451,14 @@ void CAEPedSpeechAudioEntity::I_PlayLoadedSound(CEntity* attachTo) {
if (m_IsFrontend) {
RequestSound(
{0.f, 1.f, 0.f},
SOUND_UNCOMPRESSABLE | SOUND_UNDUCKABLE | SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE | SOUND_FRONT_END,
SOUND_IS_COMPRESSABLE | SOUND_IS_DUCKABLE | SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE | SOUND_FRONT_END,
3.f,
1.f
);
} else {
RequestSound(
attachTo->GetPosition(),
SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE,
SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE,
IsPedless ? 12.f : m_EventVolume,
IsPedless ? 3.5f : CAEVehicleAudioEntity::s_pVehicleAudioSettingsForRadio ? 3.f : 2.f
);
@ -1472,7 +1474,7 @@ void CAEPedSpeechAudioEntity::I_PlayLoadedSound(CEntity* attachTo) {
case CTX_GLOBAL_STOMACH_RUMBLE:
break;
default: {
notsa::cast<CTaskComplexFacial>(m_pEntity->AsPed()->GetTaskManager().GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX))->SetRequest(
notsa::cast<CTaskComplexFacial>(m_Entity->AsPed()->GetTaskManager().GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX))->SetRequest(
eFacialExpression::TALKING,
2800
);

View File

@ -59,7 +59,7 @@ void CAEPoliceScannerAudioEntity::AddAudioEvent(eAudioEvents event, eCrimeType c
// 0x4E6BC0
void CAEPoliceScannerAudioEntity::PrepSlots() {
for (auto i = 0; i < NUM_POLICE_SCANNER_SLOTS; i++) {
s_SlotState[i] = s_pCurrentSlots[i].IsNotInitialized();
s_SlotState[i] = s_pCurrentSlots[i].IsActive();
}
}
@ -69,38 +69,30 @@ void CAEPoliceScannerAudioEntity::LoadSlots() {
return;
}
int16 bankSlotId = 33;
bool canPlay = true;
for (auto i = 0; i < NUM_POLICE_SCANNER_SLOTS; i++) {
const auto slot = (eSoundBankSlot)(SND_BANK_SLOT_SCANNER_FIRST + i);
auto& currentSlot = s_pCurrentSlots[i];
if (s_SlotState[i])
{
if (s_SlotState[i]) {
if (s_SlotState[i] == 2) {
bool loaded = AEAudioHardware.IsSoundLoaded(currentSlot.bankId, currentSlot.sfxId, bankSlotId);
if (loaded)
bool loaded = AEAudioHardware.IsSoundLoaded(currentSlot.Bank, currentSlot.SoundID, slot);
if (loaded) {
s_SlotState[i] = 3;
else
} else {
canPlay = false;
}
}
}
else if (currentSlot.IsNotInitialized())
{
} else if (currentSlot.IsActive()) {
s_SlotState[i] = 1;
}
else
{
} else {
if (!CStreaming::IsVeryBusy()) {
AEAudioHardware.LoadSound(currentSlot.bankId, currentSlot.sfxId, bankSlotId);
AEAudioHardware.LoadSound(currentSlot.Bank, currentSlot.SoundID, slot);
s_SlotState[i] = 2;
}
canPlay = false;
}
++bankSlotId;
}
if (canPlay) {
s_nScannerPlaybackState = FOUR;
}
@ -149,10 +141,8 @@ void CAEPoliceScannerAudioEntity::FinishedPlayingScannerDialogue() {
std::ranges::fill(s_SlotState, -1);
s_SlotState[4] = 1;
for (auto i = 0; i < NUM_POLICE_SCANNER_SLOTS; i++) {
s_ScannerSlotFirst[i].Clear();
s_ScannerSlotSecond[i].Clear();
}
rng::fill(s_ScannerSlotFirst, tScannerSlot{});
rng::fill(s_ScannerSlotSecond, tScannerSlot{});
}
// 0x4E6F60
@ -203,10 +193,10 @@ void CAEPoliceScannerAudioEntity::PlayLoadedDialogue() {
auto volume = GetDefaultVolume(AE_CRIME_COMMITTED) + s_fVolumeOffset;
CAESound sound;
sound.Initialise(i + 33, s_pCurrentSlots[i].sfxId, this, { 0.0, 1.0f, 0.0f }, volume, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
sound.Initialise((eSoundBankSlot)(SND_BANK_SLOT_SCANNER_FIRST + i), s_pCurrentSlots[i].SoundID, this, { 0.0, 1.0f, 0.0f }, volume, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
sound.m_ClientVariable = (float)i;
sound.m_nEnvironmentFlags = SOUND_FRONT_END | SOUND_UNCANCELLABLE | SOUND_REQUEST_UPDATES | SOUND_UNDUCKABLE;
sound.m_nEvent = AE_CRIME_COMMITTED;
sound.m_Flags = SOUND_FRONT_END | SOUND_IS_CANCELLABLE | SOUND_REQUEST_UPDATES | SOUND_IS_DUCKABLE;
sound.m_Event = AE_CRIME_COMMITTED;
s_pSound = AESoundManager.RequestNewSound(&sound);
if (s_pSound) {
@ -276,12 +266,12 @@ void CAEPoliceScannerAudioEntity::UpdateParameters(CAESound* sound, int16 curPla
}
if (s_bStoppingScanner) {
sound->m_fVolume = sound->m_fVolume - 6.0f; // todo: *(float*)&gSpeechContextLookup[366][4]
sound->m_Volume = sound->m_Volume - 6.0f; // todo: *(float*)&gSpeechContextLookup[366][4]
return;
}
if (sound->m_nSoundLength > 0 && curPlayPos > sound->m_nSoundLength - 40 && sound->m_nBankSlotId != 37) { // todo: -40 should be replaced with by gSpeechContextLookup[366][2]
sound->SetIndividualEnvironment(eSoundEnvironment::SOUND_REQUEST_UPDATES, false);
if (sound->m_Length > 0 && curPlayPos > sound->m_Length - 40 && sound->m_BankSlot != 37) { // todo: -40 should be replaced with by gSpeechContextLookup[366][2]
sound->SetFlags(eSoundEnvironment::SOUND_REQUEST_UPDATES, false);
s_pSound = nullptr;
PlayLoadedDialogue();
return;
@ -372,4 +362,4 @@ CAEPoliceScannerAudioEntity* CAEPoliceScannerAudioEntity::Constructor() {
CAEPoliceScannerAudioEntity* CAEPoliceScannerAudioEntity::Destructor() {
this->CAEPoliceScannerAudioEntity::~CAEPoliceScannerAudioEntity();
return this;
}
}

View File

@ -3,33 +3,12 @@
#include "AEAudioEntity.h"
struct tScannerSlot {
int16 bankId;
int16 sfxId;
tScannerSlot() {
Clear();
}
void Clear() {
bankId = -1;
sfxId = -1;
}
eSoundBank Bank{SND_BANK_UNK};
eSoundID SoundID{-1};
// bad name?
[[nodiscard]] bool IsNotInitialized() const {
return bankId < 0 || sfxId < 0;
}
tScannerSlot& operator=(int16 value) {
bankId = value;
sfxId = value;
return *this;
}
tScannerSlot& operator=(const tScannerSlot& right) {
bankId = right.bankId;
sfxId = right.sfxId;
return *this;
[[nodiscard]] bool IsActive() const {
return Bank < 0 || SoundID < 0;
}
};

View File

@ -11,8 +11,8 @@ CAEScriptAudioEntity::CAEScriptAudioEntity() : CAEAudioEntity() {
m_nLastTimeHornPlayed = 0;
field_7E = 0;
field_7C = 0;
m_fVolume = 0.0f;
m_fSpeed = 1.0f;
m_Volume = 0.0f;
m_Speed = 1.0f;
field_7D = 0;
field_8C = 0.0f;
}
@ -30,7 +30,7 @@ void CAEScriptAudioEntity::Reset() {
ClearMissionAudio(i);
}
field_7C = 0;
m_pEntity = nullptr;
m_Entity = nullptr;
field_7D = 0;
field_8C = 2.0f;
}
@ -82,9 +82,10 @@ void CAEScriptAudioEntity::PlayMissionBankSound(uint8 sampleId, CVector& posn, C
// event eAudioEvents
// 0x4EC550
void CAEScriptAudioEntity::PlayResidentSoundEvent(int16 bankSlotId, int16 bankId, int16 sfxId, uint16 event, CVector& posn, CPhysical* physical, float vol, float speed, int16 playPosn, float maxDistance) {
if (!AEAudioHardware.IsSoundBankLoaded(bankId, bankSlotId))
void CAEScriptAudioEntity::PlayResidentSoundEvent(eSoundBankSlot slot, eSoundBank bank, eSoundID sfx, eAudioEvents event, CVector& posn, CPhysical* physical, float vol, float speed, int16 playPosn, float maxDistance) {
if (!AEAudioHardware.IsSoundBankLoaded(bank, slot)) {
return;
}
bool bFrontend = false;
const auto volume = GetDefaultVolume(static_cast<eAudioEvents>(event)) + vol;
@ -99,15 +100,15 @@ void CAEScriptAudioEntity::PlayResidentSoundEvent(int16 bankSlotId, int16 bankId
}
}();
m_tempSound.Initialise(bankSlotId, sfxId, this, pos, volume, maxDistance, speed, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_nCurrentPlayPosition = playPosn;
m_tempSound.m_nEnvironmentFlags = SOUND_START_PERCENTAGE | SOUND_REQUEST_UPDATES | SOUND_UNCANCELLABLE;
m_tempSound.SetIndividualEnvironment(SOUND_FRONT_END, bFrontend);
m_tempSound.Initialise(slot, sfx, this, pos, volume, maxDistance, speed, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_PlayTime = playPosn;
m_tempSound.m_Flags = SOUND_START_PERCENTAGE | SOUND_REQUEST_UPDATES | SOUND_IS_CANCELLABLE;
m_tempSound.SetFlags(SOUND_FRONT_END, bFrontend);
if (physical) {
m_tempSound.SetIndividualEnvironment(SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY, true);
m_tempSound.SetFlags(SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY, true);
m_tempSound.RegisterWithPhysicalEntity(physical);
}
m_tempSound.m_nEvent = static_cast<eAudioEvents>(event);
m_tempSound.m_Event = static_cast<eAudioEvents>(event);
AESoundManager.RequestNewSound(&m_tempSound);
}
@ -352,7 +353,7 @@ void CAEScriptAudioEntity::ProcessMissionAudioEvent(eAudioEvents eventId, CVecto
AESoundManager.CancelSoundsInBankSlot(40, 0);
AEAudioHardware.LoadSoundBank(44, 40);
}
m_pEntity = physical;
m_Entity = physical;
field_7D = 1;
break;
case AE_CAS4_FJ:
@ -374,7 +375,7 @@ void CAEScriptAudioEntity::ProcessMissionAudioEvent(eAudioEvents eventId, CVecto
if (field_7D) {
AESoundManager.CancelSoundsInBankSlot(40, 1);
PlayResidentSoundEvent(40, 44, 3, eventId, posn, physical, 0.0f, 1.0f, 0, 2.5f);
m_pEntity = nullptr;
m_Entity = nullptr;
field_7D = 0;
}
break;
@ -738,8 +739,8 @@ void CAEScriptAudioEntity::ProcessMissionAudioEvent(eAudioEvents eventId, CVecto
if (!AESoundManager.AreSoundsOfThisEventPlayingForThisEntityAndPhysical(eventId, this, physical)) {
PlayResidentSoundEvent(40, 44, 1, eventId, posn, physical, volume, speed, 0, 2.5f);
}
m_fSpeed = speed;
m_fVolume = GetDefaultVolume(AE_CRANE_WINCH_MOVE) + volume;
m_Speed = speed;
m_Volume = GetDefaultVolume(AE_CRANE_WINCH_MOVE) + volume;
m_nLastTimeHornPlayed = CTimer::GetTimeInMS();
break;
default:
@ -772,7 +773,7 @@ void CAEScriptAudioEntity::Service() {
if (AESoundManager.AreSoundsOfThisEventPlayingForThisEntity(AE_SCRIPT_CRANE_ENTER, this) != 0)
return;
PlayResidentSoundEvent(40, 44, 0, AE_SCRIPT_CRANE_ENTER, posn, m_Physical, 0.0f, 1.0f, 0, 2.5f);
PlayResidentSoundEvent(SND_BANK_SLOT_PLAYER_ENGINE_P, SND_BANK_GENRL_CRANE_P, 0, AE_SCRIPT_CRANE_ENTER, posn, m_Physical, 0.0f, 1.0f, 0, 2.5f);
}
void CAEScriptAudioEntity::InjectHooks() {

View File

@ -37,8 +37,8 @@ public:
uint8 field_7E;
uint8 field_7F;
uint32 m_nLastTimeHornPlayed;
float m_fVolume;
float m_fSpeed;
float m_Volume;
float m_Speed;
float field_8C;
CAudioLink wavLinks[MISSION_AUDIO_COUNT];
CPhysical* m_Physical;
@ -63,7 +63,7 @@ public:
CVector* GetMissionAudioPosition(uint8);
void PlayMissionBankSound(uint8 sampleId, CVector& posn, CPhysical* physical, int16 sfxId, uint8 linkId, uint8 a7 = 0, float volume = 0.0f, float maxDistance = 2.0f, float speed = 1.0f);
void PlayResidentSoundEvent(int16 bankSlotId, int16 bankId, int16 sfxId, uint16 event, CVector& posn, CPhysical* physical, float vol, float speed = 1.0f, int16 playPosn = 0, float maxDistance = 1.0f);
void PlayResidentSoundEvent(eSoundBankSlot slot, eSoundBank bank, eSoundID sfx, eAudioEvents event, CVector& posn, CPhysical* physical, float vol, float speed = 1.0f, int16 playPosn = 0, float maxDistance = 1.0f);
void PlayLoadedMissionAudio(uint8);
void PreloadMissionAudio(uint8 slotId, int32 sampleId);

View File

@ -3,174 +3,182 @@
#include "AEAudioUtility.h"
#include "AESoundManager.h"
// 0x4F63B0
CAETwinLoopSoundEntity::CAETwinLoopSoundEntity() : CAEAudioEntity() {
m_bIsInitialised = 0;
m_pSound1 = nullptr;
m_pSound2 = nullptr;
}
// 0x4F2AE0
CAETwinLoopSoundEntity::CAETwinLoopSoundEntity(int16 bankSlotId, int16 soundType1, int16 soundType2, CAEAudioEntity* audio, uint16 minTime, uint16 maxTime, int16 sfxPlayStart1, int16 sfxPlayStart2) : CAEAudioEntity() {
Initialise(bankSlotId, soundType1, soundType2, audio, minTime, maxTime, sfxPlayStart1, sfxPlayStart2);
CAETwinLoopSoundEntity::CAETwinLoopSoundEntity(
eSoundBankSlot bankSlot,
eSoundID soundA,
eSoundID soundB,
CAEAudioEntity* parent,
uint16 swapTimeMin,
uint16 swapTimeMax,
int16 playPercentageA,
int16 playPercentageB
) :
m_IsPlayingFirstSound{ true },
m_IsInUse{ true },
m_SwapTimeMin{ swapTimeMin },
m_SwapTimeMax{ swapTimeMax },
m_BankSlot{ bankSlot },
m_AudioEntity{ parent },
m_SoundIDs{ soundA, soundB },
m_SoundPlayPercentages{ playPercentageA, playPercentageB }
{
rng::fill(m_SoundsLengths, -1);
}
// 0x4F2B80
CAETwinLoopSoundEntity::~CAETwinLoopSoundEntity() {
if (!m_bIsInitialised)
return;
StopSoundAndForget();
m_bIsInitialised = 0;
if (m_IsInUse) {
StopSoundAndForget();
}
m_IsInUse = false;
}
// 0x4F28A0
void CAETwinLoopSoundEntity::Initialise(int16 bankSlotId, int16 sfx1, int16 sfx2, CAEAudioEntity* audio, uint16 minTime, uint16 maxTime, int16 sfxPlayStart1, int16 sfxPlayStart2) {
m_nBankSlotId = bankSlotId;
m_nSoundId1 = sfx1;
m_nSoundId2 = sfx2;
m_pBaseAudio = audio;
m_nPlayTimeMin = minTime;
m_nPlayTimeMax = maxTime;
m_nSoundPlayStart1 = sfxPlayStart1;
m_nSoundPlayStart2 = sfxPlayStart2;
unused_field_8A = -1;
unused_field_8C = -1;
m_pSound1 = nullptr;
m_pSound2 = nullptr;
m_bPlayingFirstSound = true;
m_bIsInitialised = 1;
void CAETwinLoopSoundEntity::Initialise(
eSoundBankSlot bank,
eSoundID soundA,
eSoundID soundB,
CAEAudioEntity* parent,
uint16 swapTimeMin,
uint16 swapTimeMax,
int16 playPercentageA,
int16 playPercentageB
) {
assert(!m_IsInUse);
*this = CAETwinLoopSoundEntity{
bank,
soundA,
soundB,
parent,
swapTimeMin,
swapTimeMax,
playPercentageA,
playPercentageB,
};
}
// 0x4F29A0
void CAETwinLoopSoundEntity::UpdateTwinLoopSound(CVector posn, float volume, float speed) {
if (m_pSound1) {
m_pSound1->SetPosition(posn);
if (m_bPlayingFirstSound)
m_pSound1->m_fVolume = volume;
m_pSound1->m_fSpeed = speed;
}
if (m_pSound2) {
m_pSound2->SetPosition(posn);
if (!m_bPlayingFirstSound)
m_pSound2->m_fVolume = volume;
m_pSound2->m_fSpeed = speed;
void CAETwinLoopSoundEntity::UpdateTwinLoopSound(CVector pos, float volume, float speed) {
for (auto&& [i, sound] : rngv::enumerate(m_Sounds)) {
if (!sound) {
continue;
}
sound->SetPosition(pos);
if (i == (m_IsPlayingFirstSound ? 0 : 1)) {
sound->SetVolume(volume);
}
sound->SetSpeed(speed);
}
}
// 0x4F2E90
void CAETwinLoopSoundEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
if (curPlayPos == -1) {
if (sound == m_pSound1)
m_pSound1 = nullptr;
if (sound == m_pSound2)
m_pSound2 = nullptr;
for (auto*& s : m_Sounds) {
if (s == sound) {
s = nullptr;
}
}
}
if (DoSoundsSwitchThisFrame()) {
if (sound == m_Sounds[0]) {
SwapSounds();
}
}
if (sound == m_pSound1 && CTimer::GetTimeInMSPauseMode() > m_nTimeToSwapSounds)
SwapSounds();
}
// 0x4F2C10
void CAETwinLoopSoundEntity::SwapSounds() {
if (m_pSound1 && m_pSound2) {
if (m_bPlayingFirstSound) {
m_pSound2->m_fVolume = m_pSound1->m_fVolume;
m_pSound1->m_fVolume = -100.0f;
m_bPlayingFirstSound = false;
} else {
m_pSound1->m_fVolume = m_pSound2->m_fVolume;
m_pSound2->m_fVolume = -100.0f;
m_bPlayingFirstSound = true;
}
m_nTimeToSwapSounds = CTimer::GetTimeInMSPauseMode() + CAEAudioUtility::GetRandomNumberInRange(m_nPlayTimeMin, m_nPlayTimeMax);
auto* curr = m_Sounds[m_IsPlayingFirstSound ? 0 : 1];
auto* next = m_Sounds[m_IsPlayingFirstSound ? 1 : 0];
if (!curr || !next) {
return;
}
next->m_Volume = std::exchange(curr->m_Volume, -100.f);
m_IsPlayingFirstSound = !m_IsPlayingFirstSound;
ReCalculateSwapTime();
}
// unused
// 0x4F2930
void CAETwinLoopSoundEntity::StopSound() {
if (m_pSound1)
m_pSound1->StopSound();
if (m_pSound2)
m_pSound2->StopSound();
for (auto&& s : m_Sounds) {
if (s) {
s->StopSound();
}
}
}
// 0x4F2960
void CAETwinLoopSoundEntity::StopSoundAndForget() {
if (m_pSound1) {
m_pSound1->StopSoundAndForget();
m_pSound1 = nullptr;
for (auto&& sound : m_Sounds) {
if (auto* const s = std::exchange(sound, nullptr)) {
s->StopSoundAndForget();
}
}
if (m_pSound2) {
m_pSound2->StopSoundAndForget();
m_pSound2 = nullptr;
}
m_bIsInitialised = 0;
m_IsInUse = false;
}
// unused
// 0x4F2A80
float CAETwinLoopSoundEntity::GetEmittedVolume() {
if (m_pSound1 && m_bPlayingFirstSound) {
return m_pSound1->m_fVolume;
} else if (m_pSound2 != nullptr && !m_bPlayingFirstSound) {
return m_pSound2->m_fVolume;
} else
return -100.0f;
float CAETwinLoopSoundEntity::GetEmittedVolume() const {
auto* const s = m_Sounds[m_IsPlayingFirstSound ? 0 : 1];
return s
? s->GetVolume()
: -100.f;
}
// unused
// 0x4F2A40
void CAETwinLoopSoundEntity::SetEmittedVolume(float volume) {
if (m_pSound1 && m_bPlayingFirstSound)
m_pSound1->m_fVolume = volume;
if (m_pSound2 && !m_bPlayingFirstSound)
m_pSound2->m_fVolume = volume;
void CAETwinLoopSoundEntity::SetEmittedVolume(float volume) const {
auto* const s = m_Sounds[m_IsPlayingFirstSound ? 0 : 1];
s->SetVolume(volume);
}
// unused
// 0x4F2AC0
bool CAETwinLoopSoundEntity::IsTwinLoopPlaying() {
return m_pSound1 || m_pSound2;
bool CAETwinLoopSoundEntity::IsTwinLoopPlaying() const {
return rng::any_of(m_Sounds, notsa::NotIsNull{});
}
// 0x4F2CA0
bool CAETwinLoopSoundEntity::DoSoundsSwitchThisFrame() {
return CTimer::GetTimeInMSPauseMode() > m_nTimeToSwapSounds;
bool CAETwinLoopSoundEntity::DoSoundsSwitchThisFrame() const {
return CTimer::GetTimeInMSPauseMode() > m_TimeToSwapSoundsMs;
}
// 0x4F2CB0
void CAETwinLoopSoundEntity::PlayTwinLoopSound(CVector posn, float volume, float speed, float maxDistance, float timeScale, eSoundEnvironment flags) {
if (m_pSound1)
m_pSound1->StopSoundAndForget();
void CAETwinLoopSoundEntity::PlayTwinLoopSound(CVector pos, float volume, float speed, float rollOffFactor, float doppler, eSoundEnvironment flags) {
assert(m_IsInUse && "Must initialize sound first using `Initialise()`");
if (m_pSound2)
m_pSound2->StopSoundAndForget();
StopSoundAndForget();
for (int32 i = 0; i < NUM_SOUNDS; i++) {
assert(!m_Sounds[i]);
m_Sounds[i] = AESoundManager.PlaySound({
.BankSlotID = m_BankSlot,
.SoundID = m_SoundIDs[i],
.AudioEntity = this,
.Pos = pos,
.Volume = i == 0 ? volume : -100.f,
.RollOffFactor = rollOffFactor,
.Speed = speed,
.Doppler = doppler,
.Flags = (eSoundEnvironment)(flags | SOUND_START_PERCENTAGE | SOUND_REQUEST_UPDATES),
.PlayTime = m_SoundPlayPercentages[i] != -1
? m_SoundPlayPercentages[i]
: CAEAudioUtility::GetRandomNumberInRange<int16>(0, 99),
});
}
m_IsInUse = true;
m_IsPlayingFirstSound = true;
ReCalculateSwapTime();
}
auto envFlags = static_cast<eSoundEnvironment>(flags | SOUND_START_PERCENTAGE | SOUND_REQUEST_UPDATES);
void CAETwinLoopSoundEntity::ReCalculateSwapTime() {
m_TimeToSwapSoundsMs = CTimer::GetTimeInMSPauseMode() + CAEAudioUtility::GetRandomNumberInRange(m_SwapTimeMin, m_SwapTimeMax);
}
CAESound sound;
sound.Initialise(m_nBankSlotId, m_nSoundId1, this, posn, volume, maxDistance, speed, timeScale, 0, envFlags, 0.0f, 0);
sound.m_nCurrentPlayPosition = m_nSoundPlayStart1 == -1 ? CAEAudioUtility::GetRandomNumberInRange(0, 99) : m_nSoundPlayStart1;
m_pSound1 = AESoundManager.RequestNewSound(&sound);
sound.Initialise(m_nBankSlotId, m_nSoundId2, this, posn, -100.0f, maxDistance, speed, timeScale, 0, envFlags, 0.0f, 0);
sound.m_nCurrentPlayPosition = m_nSoundPlayStart2 == -1 ? CAEAudioUtility::GetRandomNumberInRange(0, 99) : m_nSoundPlayStart2;
m_pSound2 = AESoundManager.RequestNewSound(&sound);
m_nTimeToSwapSounds = CTimer::GetTimeInMSPauseMode() + CAEAudioUtility::GetRandomNumberInRange(m_nPlayTimeMin, m_nPlayTimeMax);
m_bPlayingFirstSound = true;
}void CAETwinLoopSoundEntity::InjectHooks() {
void CAETwinLoopSoundEntity::InjectHooks() {
RH_ScopedVirtualClass(CAETwinLoopSoundEntity, 0x85F438, 1);
RH_ScopedCategory("Audio/Entities");

View File

@ -7,62 +7,82 @@
#pragma once
/* This class is used to control 2 sounds as one. There are 2 sounds
created with PlayTwinLoopSound(), and one of them is playing when second
is simply muted. When time m_nTimeToSwapSounds is reached, these sounds
created with `PlayTwinLoopSound()`, and one of them is playing when second
is simply muted. When time m_TimeToSwapSoundsMs is reached, these sounds
are switched: second starts playing, first begins being muted.
The time m_nTimeToSwapSounds is calculated as:
CAEAudioUtility::GetRandomNumberInRange(m_nPlayTimeMin, m_nPlayTimeMax);
The time m_TimeToSwapSoundsMs is calculated as:
`CAEAudioUtility::GetRandomNumberInRange(m_SwapTimeMin, m_SwapTimeMax)`
Notice these sounds must be situated in same bank slot.
m_pBaseAudio is a pointer to audio which created twin sound. For example,
`m_AudioEntity` is a pointer to audio which created twin sound. For example,
this could be CAEVehicleAudioEntity for playing skid sounds. */
#include "AEAudioEntity.h"
class NOTSA_EXPORT_VTABLE CAETwinLoopSoundEntity : public CAEAudioEntity {
public:
int16 m_nBankSlotId;
int16 m_nSoundId1;
int16 m_nSoundId2;
CAEAudioEntity* m_pBaseAudio;
int16 m_bIsInitialised;
int16 unused_field_8A;
int16 unused_field_8C;
uint16 m_nPlayTimeMin;
uint16 m_nPlayTimeMax;
uint32 m_nTimeToSwapSounds;
bool m_bPlayingFirstSound;
int16 m_nSoundPlayStart1; // 0 - 99 percentage
int16 m_nSoundPlayStart2; // 0 - 99 percentage
CAESound* m_pSound1;
CAESound* m_pSound2;
#include <Enums/SoundIDs.h>
#include <Enums/eSoundBankSlot.h>
class NOTSA_EXPORT_VTABLE CAETwinLoopSoundEntity : public CAEAudioEntity {
static constexpr uint32 NUM_SOUNDS = 2;
public:
CAETwinLoopSoundEntity();
CAETwinLoopSoundEntity(int16 bank, int16 soundType1, int16 soundType2, CAEAudioEntity* audio, uint16 minTime, uint16 maxTime, int16 sfxPlayStart1, int16 sfxPlayStart2);
CAETwinLoopSoundEntity() = default;
CAETwinLoopSoundEntity(
eSoundBankSlot bank,
eSoundID soundA,
eSoundID soundB,
CAEAudioEntity* parent,
uint16 swapTimeMin,
uint16 swapTimeMax,
int16 playPercentageA,
int16 playPercentageB
);
~CAETwinLoopSoundEntity();
void Initialise(int16 bank, int16 sfx1, int16 sfx2, CAEAudioEntity* audio, uint16 minTime, uint16 maxTime, int16 sfxPlayStart1, int16 sfxPlayStart2);
void Initialise(
eSoundBankSlot bank,
eSoundID soundA,
eSoundID soundB,
CAEAudioEntity* parent,
uint16 swapTimeMin,
uint16 swapTimeMax,
int16 playPercentageA = -1,
int16 playPercentageB = -1
);
void UpdateParameters(CAESound* sound, int16 curPlayPos) override;
void UpdateTwinLoopSound(CVector posn, float volume, float speed);
void UpdateTwinLoopSound(CVector pos, float volume, float speed);
void SwapSounds();
void StopSound();
void StopSoundAndForget();
float GetEmittedVolume();
void SetEmittedVolume(float volume);
float GetEmittedVolume() const;
void SetEmittedVolume(float volume) const;
bool IsTwinLoopPlaying();
bool DoSoundsSwitchThisFrame();
bool IsTwinLoopPlaying() const;
bool DoSoundsSwitchThisFrame() const;
void PlayTwinLoopSound(CVector posn, float volume, float speed, float maxDistance, float timeScale, eSoundEnvironment flags);
void PlayTwinLoopSound(CVector pos, float volume, float speed, float rollOffFactor, float doppler = 1.f, eSoundEnvironment flags = SOUND_DEFAULT);
bool IsActive() const noexcept { return m_IsInUse; }
private:
void ReCalculateSwapTime();
private:
friend void InjectHooksMain();
static void InjectHooks();
private:
eSoundBankSlotS16 m_BankSlot{};
eSoundID m_SoundIDs[NUM_SOUNDS]{};
CAEAudioEntity* m_AudioEntity{};
int16 m_IsInUse{};
int16 m_SoundsLengths[NUM_SOUNDS]{};
uint16 m_SwapTimeMin{};
uint16 m_SwapTimeMax{};
uint32 m_TimeToSwapSoundsMs{};
bool m_IsPlayingFirstSound{};
int16 m_SoundPlayPercentages[NUM_SOUNDS]{}; // 0 - 99%
CAESound* m_Sounds[NUM_SOUNDS]{};
};
VALIDATE_SIZE(CAETwinLoopSoundEntity, 0xA8);

View File

@ -0,0 +1,285 @@
#pragma once
#include "Enums/eModelID.h"
#include <Audio/Enums/eAEVehicleSoundType.h>
#include <Audio/Enums/eAEVehicleAudioTypeForName.h>
#include <Audio/Enums/eAEVehicleAudioType.h>
#include <Audio/Enums/eAERadioType.h>
#include <Audio/Enums/SoundIDs.h>
#include <Audio/Enums/eBassSetting.h>
#include <Audio/Enums/eAEVehicleDoorType.h>
#include <Audio/Enums/eAEVehicleHornType.h>
struct tVehicleAudioSettings {
eAEVehicleSoundType VehicleAudioType{};
eSoundBankS16 PlayerBank{}; //!< Bank used when the player *is* in the vehicle
eSoundBankS16 DummyBank{}; //!< Bank used when the player *is not* in the vehicle
eBassSetting BassSetting{};
float BassFactor{};
float EnginePitch{};
eAEVehicleHornType HornType{}; //!< Actually just the sound ID
float HornPitch{};
eAEVehicleDoorType DoorType{}; //!< Door type,
uint8 EngineUpgrade{}; //!< [UNUSED?] No clue
eRadioID RadioStation{};
eAERadioType RadioType{};
eAEVehicleAudioTypeForName VehicleAudioTypeForName{};
float EngineVolumeOffset{}; //!< Engine's base volume
public:
[[nodiscard]] bool IsHeli() const { return VehicleAudioType == eAEVehicleSoundType::AE_AIRCRAFT_HELICOPTER; }
[[nodiscard]] bool IsPlane() const { return VehicleAudioType == eAEVehicleSoundType::AE_AIRCRAFT_PLANE; }
[[nodiscard]] bool IsPlaneOrHeli() const { return IsPlane() || IsHeli(); }
[[nodiscard]] bool IsSeaplane() const { return VehicleAudioType == eAEVehicleSoundType::AE_AIRCRAFT_SEAPLANE; }
[[nodiscard]] bool IsAircraftEngineSound() const { return notsa::contains({AE_AIRCRAFT_HELICOPTER, AE_AIRCRAFT_PLANE, AE_AIRCRAFT_SEAPLANE}, VehicleAudioType); }
[[nodiscard]] bool IsCar() const { return VehicleAudioType == eAEVehicleSoundType::AE_CAR; }
[[nodiscard]] bool IsBike() const { return VehicleAudioType == eAEVehicleSoundType::AE_BIKE; }
[[nodiscard]] bool IsCarEngineSound() const { return notsa::contains({eAEVehicleSoundType::AE_BIKE, eAEVehicleSoundType::AE_CAR}, VehicleAudioType); }
[[nodiscard]] bool IsBMX() const { return VehicleAudioType == eAEVehicleSoundType::AE_BMX; }
};
VALIDATE_SIZE(tVehicleAudioSettings, 0x24);
// 0x860AF0
// Array not marked as `constexpr` so that it can be edited by the debug tool
// Order of entries is the same as the model IDs (Starting at 400 - LANDSTAL)
#pragma warning(push)
#pragma warning(disable : 4305) // truncation from 'double' to 'float'
inline std::array<tVehicleAudioSettings, 232> VehicleAudioSettings = {{
{ AE_CAR, SND_BANK_GENRL_PATHFINDER_P, SND_BANK_GENRL_PATHFINDER_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::PICKUP, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_OFFROAD, 0.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::CHEVY56, 1.1892071, eAEVehicleDoorType::NEW, 0, RADIO_HOUSE_CLASSICS, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_COBRA_P, SND_BANK_GENRL_COBRA_D, eBassSetting::BOOST, 0.89999998, 1.0, eAEVehicleHornType::CHEVY56, 1.0594631, eAEVehicleDoorType::NEW, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MACKTRUCK_P, SND_BANK_GENRL_MACKTRUCK_D, eBassSetting::NORMAL, 0.0, 1.0, eAEVehicleHornType::TRUCK, 0.84089643, eAEVehicleDoorType::TRUCK, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_RIG, 6.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::PICKUP, 1.122462, eAEVehicleDoorType::OLD, 0, RADIO_REGGAE, AE_RT_CIVILIAN, AE_VAT_STATION_WAGON, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::BMW328, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_DISCO_FUNK, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MACKTRUCK_P, SND_BANK_GENRL_MACKTRUCK_D, eBassSetting::NORMAL, 0.69999999, 0.84089643, eAEVehicleHornType::BUS_A, 0.79370052, eAEVehicleDoorType::TRUCK, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_TRUCK, 6.0 },
{ AE_CAR, SND_BANK_GENRL_MACKTRUCK_P, SND_BANK_GENRL_MACKTRUCK_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_A, 0.8908987, eAEVehicleDoorType::TRUCK, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_FIRETRUCK, 5.0 },
{ AE_CAR, SND_BANK_GENRL_JALOPY_P, SND_BANK_GENRL_JALOPY_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_B, 0.8908987, eAEVehicleDoorType::TRUCK, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_GARBAGE_TRUCK, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::CHEVY56, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_RARE_GROOVE, AE_RT_CIVILIAN, AE_VAT_STRETCH, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::ESCORT, 1.0594631, eAEVehicleDoorType::OLD, 0, RADIO_DISCO_FUNK, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_COBRA_P, SND_BANK_GENRL_COBRA_D, eBassSetting::BOOST, 0.89999998, 1.0, eAEVehicleHornType::PORSCHE, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_CUTLASS_P, SND_BANK_GENRL_CUTLASS_D, eBassSetting::NORMAL, 1.0, 1.0, eAEVehicleHornType::CHEVY56, 1.122462, eAEVehicleDoorType::OLD, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_LOWRIDER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VAN_P, SND_BANK_GENRL_VAN_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::CHEVY56, 1.2599211, eAEVehicleDoorType::VAN, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VAN_P, SND_BANK_GENRL_VAN_D, eBassSetting::NORMAL, 0.69999999, 1.3348398, eAEVehicleHornType::PICKUP, 0.9438743, eAEVehicleDoorType::VAN, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_VAN, 5.0 },
{ AE_CAR, SND_BANK_GENRL_PORSCHE_P, SND_BANK_GENRL_PORSCHE_D, eBassSetting::BOOST, 0.89999998, 1.0, eAEVehicleHornType::PORSCHE, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_HOUSE_CLASSICS, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VAN_P, SND_BANK_GENRL_VAN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::PICKUP, 0.9438743, eAEVehicleDoorType::VAN, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_AMBULANCE, 0.0 },
{ AE_AIRCRAFT_HELICOPTER, SND_BANK_GENRL_APACHE, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_HELICOPTER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::ESCORT, 0.8908987, eAEVehicleDoorType::VAN, 0, RADIO_TALK, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MUSTANG_P, SND_BANK_GENRL_MUSTANG_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::CHEVY56, 1.0594631, eAEVehicleDoorType::OLD, 0, RADIO_RARE_GROOVE, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::BUS_B, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_TAXI, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BMW328, 0.8908987, eAEVehicleDoorType::NEW, 0, RADIO_TALK, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::PICKUP, 1.0, eAEVehicleDoorType::VAN, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_PICK_UP, 0.0 },
{ AE_CAR, SND_BANK_GENRL_ICEVAN_P, SND_BANK_GENRL_VW_VAN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_B, 0.9438743, eAEVehicleDoorType::VAN, 0, RADIO_OFF, AE_RT_CIVILIAN, AE_VAT_ICE_CREAM_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_HOTROD_P, SND_BANK_GENRL_HOTROD_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::JEEP, 0.8908987, eAEVehicleDoorType::UNSET, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_BUGGY, 0.0 },
{ AE_AIRCRAFT_HELICOPTER, SND_BANK_GENRL_APACHE, SND_BANK_UNK, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_HELICOPTER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::PORSCHE, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_JALOPY_P, SND_BANK_GENRL_JALOPY_D, eBassSetting::NORMAL, 0.69999999, 1.3348398, eAEVehicleHornType::TRUCK, 1.122462, eAEVehicleDoorType::TRUCK, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_POLICE_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VAN_P, SND_BANK_GENRL_VAN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_A, 0.8908987, eAEVehicleDoorType::VAN, 0, RADIO_DISCO_FUNK, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PORSCHE_P, SND_BANK_GENRL_PORSCHE_D, eBassSetting::BOOST, 1.0, 1.0, eAEVehicleHornType::BMW328, 1.0594631, eAEVehicleDoorType::NEW, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_BOAT, SND_BANK_GENRL_BOAT_INBOARD_P, SND_BANK_GENRL_BOAT_INBOARD_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_BOAT, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BUS_P, SND_BANK_GENRL_BUS_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_B, 0.84089643, eAEVehicleDoorType::UNSET, 0, RADIO_RARE_GROOVE, AE_RT_CIVILIAN, AE_VAT_COACH, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MACKTRUCK_P, SND_BANK_GENRL_MACKTRUCK_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::TRUCK, 0.8908987, eAEVehicleDoorType::TRUCK, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_TANK, 6.0 },
{ AE_CAR, SND_BANK_GENRL_JALOPY_P, SND_BANK_GENRL_JALOPY_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::TRUCK, 0.9438743, eAEVehicleDoorType::TRUCK, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_TRUCK, 0.0 },
{ AE_CAR, SND_BANK_GENRL_HOTROD_P, SND_BANK_GENRL_HOTROD_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BMW328, 1.122462, eAEVehicleDoorType::OLD, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_BUGGY, 0.0 },
{ AE_SPECIAL, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_NONE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::ESCORT, 0.8908987, eAEVehicleDoorType::NEW, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BUS_P, SND_BANK_GENRL_BUS_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_B, 0.8908987, eAEVehicleDoorType::UNSET, 0, RADIO_TALK, AE_RT_CIVILIAN, AE_VAT_COACH, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BUICK_P, SND_BANK_GENRL_BUICK_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::BUS_A, 1.0594631, eAEVehicleDoorType::OLD, 0, RADIO_DISCO_FUNK, AE_RT_CIVILIAN, AE_VAT_TAXI, 0.0 },
{ AE_CAR, SND_BANK_GENRL_CUTLASS_P, SND_BANK_GENRL_CUTLASS_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::PICKUP, 1.122462, eAEVehicleDoorType::OLD, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_CONVERTIBLE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VW_VAN_P, SND_BANK_GENRL_VW_VAN_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::ESCORT, 0.84089643, eAEVehicleDoorType::VAN, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_SPECIAL, SND_BANK_GENRL_CHAINSAW_P, SND_BANK_GENRL_SCOOTER_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_NONE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::BUS_B, 1.122462, eAEVehicleDoorType::VAN, 0, RADIO_OFF, AE_RT_CIVILIAN, AE_VAT_HEARSE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MACKTRUCK_P, SND_BANK_GENRL_MACKTRUCK_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::TRUCK, 1.0, eAEVehicleDoorType::TRUCK, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_TRUCK, 6.0 },
{ AE_CAR, SND_BANK_GENRL_HEAVY_V8_P, SND_BANK_GENRL_HEAVY_V8_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::TRUCK, 1.0594631, eAEVehicleDoorType::NEW, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_MONSTER_TRUCK, 6.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::BMW328, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_BOAT, SND_BANK_GENRL_BOAT_INBOARD_P, SND_BANK_GENRL_BOAT_INBOARD_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_BOAT, 0.0 },
{ AE_AIRCRAFT_HELICOPTER, SND_BANK_GENRL_R22, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_HELICOPTER, 0.0 },
{ AE_BIKE, SND_BANK_GENRL_SCOOTER_P, SND_BANK_GENRL_SCOOTER_D, eBassSetting::CUT, 1.0, 1.0, eAEVehicleHornType::ESCORT, 1.0594631, eAEVehicleDoorType::UNSET, 0, RADIO_REGGAE, AE_RT_CIVILIAN, AE_VAT_MOPED, 0.0 },
{ AE_TRAIN, SND_BANK_GENRL_TRAIN_P, SND_BANK_GENRL_TRAM_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_TRAM, 0.0 },
{ AE_SPECIAL, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_NONE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PORSCHE_P, SND_BANK_GENRL_PORSCHE_D, eBassSetting::BOOST, 0.89999998, 1.0, eAEVehicleHornType::PORSCHE, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_HOUSE_CLASSICS, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_BOAT, SND_BANK_GENRL_BOAT_INBOARD_P, SND_BANK_GENRL_BOAT_INBOARD_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_BOAT, 0.0 },
{ AE_BOAT, SND_BANK_GENRL_BOAT_INBOARD_P, SND_BANK_GENRL_BOAT_INBOARD_D, eBassSetting::CUT, 0.85000002, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_BOAT, 0.0 },
{ AE_BOAT, SND_BANK_GENRL_BOAT_INBOARD_P, SND_BANK_GENRL_BOAT_INBOARD_D, eBassSetting::CUT, 0.85000002, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_REGGAE, AE_RT_CIVILIAN, AE_VAT_BOAT, 0.0 },
{ AE_CAR, SND_BANK_GENRL_JALOPY_P, SND_BANK_GENRL_JALOPY_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::TRUCK, 0.9438743, eAEVehicleDoorType::TRUCK, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_TRUCK, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VW_VAN_P, SND_BANK_GENRL_VW_VAN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_A, 0.9438743, eAEVehicleDoorType::TRUCK, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_SPECIAL, SND_BANK_GENRL_GOLF_P, SND_BANK_GENRL_GOLF_D, eBassSetting::CUT, 0.89999998, 1.0, eAEVehicleHornType::ESCORT, 1.2599211, eAEVehicleDoorType::UNSET, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_GOLF_CART, 0.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::BMW328, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_TALK, AE_RT_CIVILIAN, AE_VAT_STATION_WAGON, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VAN_P, SND_BANK_GENRL_VAN_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::CHEVY56, 1.0594631, eAEVehicleDoorType::VAN, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_AIRCRAFT_PLANE, SND_BANK_GENRL_SINGLEPROP, SND_BANK_GENRL_FASTPROP_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_SEA_PLANE, 0.0 },
{ AE_BIKE, SND_BANK_GENRL_SPORTSBIKE_P, SND_BANK_GENRL_SPORTSBIKE_D, eBassSetting::CUT, 0.69999999, 1.1892071, eAEVehicleHornType::JEEP, 1.122462, eAEVehicleDoorType::UNSET, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_BIKE, 0.0 },
{ AE_BIKE, SND_BANK_GENRL_SCOOTER_P, SND_BANK_GENRL_SCOOTER_D, eBassSetting::CUT, 1.0, 1.0, eAEVehicleHornType::ESCORT, 1.0594631, eAEVehicleDoorType::UNSET, 0, RADIO_RARE_GROOVE, AE_RT_CIVILIAN, AE_VAT_MOPED, 0.0 },
{ AE_BIKE, SND_BANK_GENRL_VTWINBIKE_P, SND_BANK_GENRL_VTWINBIKE_D, eBassSetting::CUT, 0.64999998, 1.0, eAEVehicleHornType::ESCORT, 0.84089643, eAEVehicleDoorType::UNSET, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_BIKE, 0.0 },
{ AE_SPECIAL, SND_BANK_GENRL_RC_CAR_P, SND_BANK_GENRL_RC_CAR_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_NONE, 0.0 },
{ AE_SPECIAL, SND_BANK_GENRL_RC_HELI_P, SND_BANK_GENRL_RC_HELI_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_NONE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BELAIR_P, SND_BANK_GENRL_BELAIR_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::BUS_B, 0.9438743, eAEVehicleDoorType::OLD, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BELAIR_P, SND_BANK_GENRL_BELAIR_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::CHEVY56, 1.0, eAEVehicleDoorType::OLD, 0, RADIO_DISCO_FUNK, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_BIKE, SND_BANK_GENRL_DIRTBIKE_P, SND_BANK_GENRL_DIRTBIKE_D, eBassSetting::CUT, 0.85000002, 1.0, eAEVehicleHornType::JEEP, 0.8908987, eAEVehicleDoorType::UNSET, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_BIKE, 0.0 },
{ AE_AIRCRAFT_HELICOPTER, SND_BANK_GENRL_R22, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_HELICOPTER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PATHFINDER_P, SND_BANK_GENRL_PATHFINDER_D, eBassSetting::NORMAL, 0.89999998, 1.1892071, eAEVehicleHornType::TRUCK, 1.2599211, eAEVehicleDoorType::VAN, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_OFFROAD, 0.0 },
{ AE_CAR, SND_BANK_GENRL_DIRTBIKE_P, SND_BANK_GENRL_DIRTBIKE_D, eBassSetting::CUT, 0.30000001, 1.0, eAEVehicleHornType::ESCORT, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_QUADBIKE, 0.0 },
{ AE_BOAT, SND_BANK_GENRL_BOAT_INBOARD_P, SND_BANK_GENRL_BOAT_INBOARD_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_BOAT, 0.0 },
{ AE_BOAT, SND_BANK_GENRL_BOAT_INBOARD_P, SND_BANK_GENRL_BOAT_INBOARD_D, eBassSetting::CUT, 0.89999998, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_DINGHY, 0.0 },
{ AE_CAR, SND_BANK_GENRL_CADILLAC_P, SND_BANK_GENRL_CADILLAC_D, eBassSetting::NORMAL, 1.0, 1.0, eAEVehicleHornType::BUS_A, 1.0594631, eAEVehicleDoorType::OLD, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_CUTLASS_P, SND_BANK_GENRL_CUTLASS_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::PORSCHE, 0.9438743, eAEVehicleDoorType::OLD, 0, RADIO_RARE_GROOVE, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_AIRCRAFT_PLANE, SND_BANK_GENRL_FASTPROP, SND_BANK_GENRL_FASTPROP_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_PLANE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::BOOST, 0.89999998, 1.0, eAEVehicleHornType::BMW328, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_HOUSE_CLASSICS, AE_RT_CIVILIAN, AE_VAT_COUPE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MODEL_T_P, SND_BANK_GENRL_MODEL_T_D, eBassSetting::NORMAL, 0.64999998, 1.0, eAEVehicleHornType::CHEVY56, 0.9438743, eAEVehicleDoorType::VAN, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_PICK_UP, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.64999998, 1.0, eAEVehicleHornType::PICKUP, 1.1892071, eAEVehicleDoorType::NEW, 0, RADIO_REGGAE, AE_RT_CIVILIAN, AE_VAT_STATION_WAGON, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PORSCHE_P, SND_BANK_GENRL_PORSCHE_D, eBassSetting::BOOST, 0.89999998, 1.0, eAEVehicleHornType::PORSCHE, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_BMX, SND_BANK_GENRL_BICYCLE_P, SND_BANK_GENRL_BICYCLE_D, eBassSetting::CUT, 0.69999999, 1.0, eAEVehicleHornType::BIKE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_BICYCLE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VAN_P, SND_BANK_GENRL_VAN_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::PICKUP, 1.122462, eAEVehicleDoorType::VAN, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VW_VAN_P, SND_BANK_GENRL_VW_VAN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::CHEVY56, 1.122462, eAEVehicleDoorType::VAN, 0, RADIO_REGGAE, AE_RT_CIVILIAN, AE_VAT_CAMPER_VAN, 0.0 },
{ AE_BOAT, SND_BANK_GENRL_BOAT_INBOARD_P, SND_BANK_GENRL_BOAT_INBOARD_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_BOAT, 0.0 },
{ AE_CAR, SND_BANK_GENRL_AIRPORT_P, SND_BANK_GENRL_AIRPORT_D, eBassSetting::CUT, 1.0, 1.0, eAEVehicleHornType::ESCORT, 1.122462, eAEVehicleDoorType::UNSET, 0, RADIO_REGGAE, AE_RT_CIVILIAN, AE_VAT_TRUCK, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MODEL_T_P, SND_BANK_GENRL_MODEL_T_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::TRUCK, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_BULLDOZER, 0.0 },
{ AE_AIRCRAFT_HELICOPTER, SND_BANK_GENRL_MAVERICK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_HELICOPTER, 0.0 },
{ AE_AIRCRAFT_HELICOPTER, SND_BANK_GENRL_MAVERICK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_HELICOPTER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PATHFINDER_P, SND_BANK_GENRL_PATHFINDER_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::BUS_B, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_OFFROAD, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PATHFINDER_P, SND_BANK_GENRL_PATHFINDER_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_B, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_OFFROAD, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BMW328, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_DISCO_FUNK, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::PICKUP, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_BOAT, SND_BANK_GENRL_BOAT_INBOARD_P, SND_BANK_GENRL_BOAT_INBOARD_D, eBassSetting::BOOST, 0.85000002, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_BOAT, 0.0 },
{ AE_CAR, SND_BANK_GENRL_COBRA_P, SND_BANK_GENRL_COBRA_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::BMW328, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PATHFINDER_P, SND_BANK_GENRL_PATHFINDER_D, eBassSetting::NORMAL, 0.69999999, 1.1892071, eAEVehicleHornType::BUS_B, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_OFFROAD, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MUSTANG_P, SND_BANK_GENRL_MUSTANG_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::PORSCHE, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_HOUSE_CLASSICS, AE_RT_CIVILIAN, AE_VAT_COUPE, 0.0 },
{ AE_AIRCRAFT_HELICOPTER, SND_BANK_GENRL_MAVERICK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_HELICOPTER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VW_VAN_P, SND_BANK_GENRL_VW_VAN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BMW328, 0.84089643, eAEVehicleDoorType::TRUCK, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MACKTRUCK_P, SND_BANK_GENRL_MACKTRUCK_D, eBassSetting::NORMAL, 0.64999998, 1.3348398, eAEVehicleHornType::CHEVY56, 0.9438743, eAEVehicleDoorType::TRUCK, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_VAN, 3.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::JEEP, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_TALK, AE_RT_CIVILIAN, AE_VAT_OFFROAD, 0.0 },
{ AE_SPECIAL, SND_BANK_GENRL_RC_HELI_P, SND_BANK_GENRL_RC_HELI_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_NONE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_COBRA_P, SND_BANK_GENRL_COBRA_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::BMW328, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PONTIAC_P, SND_BANK_GENRL_PONTIAC_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::PICKUP, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_HEAVY_V8_P, SND_BANK_GENRL_HEAVY_V8_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::CHEVY56, 0.9438743, eAEVehicleDoorType::OLD, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PATHFINDER_P, SND_BANK_GENRL_PATHFINDER_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_B, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_OFFROAD, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PORSCHE_P, SND_BANK_GENRL_PORSCHE_D, eBassSetting::BOOST, 0.89999998, 1.0, eAEVehicleHornType::BUS_A, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::PICKUP, 1.1892071, eAEVehicleDoorType::NEW, 0, RADIO_TALK, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VAN_P, SND_BANK_GENRL_VAN_D, eBassSetting::NORMAL, 0.64999998, 1.0, eAEVehicleHornType::BUS_A, 1.1892071, eAEVehicleDoorType::LIGHT, 0, RADIO_REGGAE, AE_RT_CIVILIAN, AE_VAT_CAMPER_VAN, 0.0 },
{ AE_BMX, SND_BANK_GENRL_BICYCLE_P, SND_BANK_GENRL_BICYCLE_D, eBassSetting::CUT, 0.69999999, 1.0, eAEVehicleHornType::BIKE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_BICYCLE, 0.0 },
{ AE_BMX, SND_BANK_GENRL_BICYCLE_P, SND_BANK_GENRL_BICYCLE_D, eBassSetting::CUT, 0.69999999, 1.0, eAEVehicleHornType::BIKE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_BICYCLE, 0.0 },
{ AE_AIRCRAFT_PLANE, SND_BANK_GENRL_TWINPROP, SND_BANK_GENRL_TWINPROP_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_PLANE, 0.0 },
{ AE_AIRCRAFT_PLANE, SND_BANK_GENRL_SINGLEPROP, SND_BANK_GENRL_FASTPROP_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_PLANE, 0.0 },
{ AE_AIRCRAFT_PLANE, SND_BANK_GENRL_FASTPROP, SND_BANK_GENRL_FASTPROP_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_PLANE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MACKTRUCK_P, SND_BANK_GENRL_MACKTRUCK_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::TRUCK, 0.79370052, eAEVehicleDoorType::TRUCK, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_RIG, 6.0 },
{ AE_CAR, SND_BANK_GENRL_MACKTRUCK_P, SND_BANK_GENRL_MACKTRUCK_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::TRUCK, 0.84089643, eAEVehicleDoorType::TRUCK, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_RIG, 6.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_A, 1.2599211, eAEVehicleDoorType::NEW, 0, RADIO_RARE_GROOVE, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MUSTANG_P, SND_BANK_GENRL_MUSTANG_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::PORSCHE, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_DISCO_FUNK, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_CUTLASS_P, SND_BANK_GENRL_CUTLASS_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BMW328, 1.0, eAEVehicleDoorType::OLD, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_AIRCRAFT_PLANE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_PLANE, 0.0 },
{ AE_AIRCRAFT_PLANE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_PLANE, 0.0 },
{ AE_BIKE, SND_BANK_GENRL_RS427_P, SND_BANK_GENRL_RS427_D, eBassSetting::CUT, 0.77999997, 1.0594631, eAEVehicleHornType::PICKUP, 1.2599211, eAEVehicleDoorType::UNSET, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_BIKE, 0.0 },
{ AE_BIKE, SND_BANK_GENRL_SPORTSBIKE_P, SND_BANK_GENRL_SPORTSBIKE_D, eBassSetting::CUT, 0.64999998, 1.0, eAEVehicleHornType::JEEP, 1.1892071, eAEVehicleDoorType::UNSET, 0, RADIO_HOUSE_CLASSICS, AE_RT_CIVILIAN, AE_VAT_BIKE, 0.0 },
{ AE_BIKE, SND_BANK_GENRL_COPBIKE_P, SND_BANK_GENRL_COPBIKE_D, eBassSetting::CUT, 0.89999998, 1.0, eAEVehicleHornType::JEEP, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_BIKE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MACKTRUCK_P, SND_BANK_GENRL_MACKTRUCK_D, eBassSetting::NORMAL, 0.64999998, 1.0, eAEVehicleHornType::BUS_A, 0.9438743, eAEVehicleDoorType::TRUCK, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_TRUCK, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VAN_P, SND_BANK_GENRL_VAN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_A, 1.0, eAEVehicleDoorType::VAN, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_TRUCK, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BUICK_P, SND_BANK_GENRL_BUICK_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::BMW328, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::PORSCHE, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_DISCO_FUNK, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_JALOPY_P, SND_BANK_GENRL_JALOPY_D, eBassSetting::NORMAL, 0.69999999, 1.1892071, eAEVehicleHornType::BUS_B, 0.9438743, eAEVehicleDoorType::VAN, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_POLICE_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BUICK_P, SND_BANK_GENRL_BUICK_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::CHEVY56, 1.1892071, eAEVehicleDoorType::NEW, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_FORKLIFT_P, SND_BANK_GENRL_FORKLIFT_D, eBassSetting::CUT, 1.0, 1.0, eAEVehicleHornType::ESCORT, 1.0594631, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_FORKLIFT, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MODEL_T_P, SND_BANK_GENRL_MODEL_T_D, eBassSetting::CUT, 0.64999998, 1.0, eAEVehicleHornType::PICKUP, 0.8908987, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_TRACTOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_HARVESTER_P, SND_BANK_GENRL_HARVESTER_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_A, 0.84089643, eAEVehicleDoorType::LIGHT, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_COMBINE_HARVESTER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MUSTANG_P, SND_BANK_GENRL_MUSTANG_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::CHEVY56, 1.1892071, eAEVehicleDoorType::NEW, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_CONVERTIBLE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_CADILLAC_P, SND_BANK_GENRL_CADILLAC_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::BMW328, 1.0594631, eAEVehicleDoorType::OLD, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_LOWRIDER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_HOTROD_P, SND_BANK_GENRL_HOTROD_D, eBassSetting::NORMAL, 1.0, 1.0, eAEVehicleHornType::PICKUP, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_LOWRIDER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_CUTLASS_P, SND_BANK_GENRL_CUTLASS_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::CHEVY56, 1.1892071, eAEVehicleDoorType::OLD, 1, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_LOWRIDER, 0.0 },
{ AE_TRAIN, SND_BANK_GENRL_TRAIN_P, SND_BANK_GENRL_TRAIN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::TRUCK, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_TRAIN, 0.0 },
{ AE_TRAIN, SND_BANK_GENRL_TRAIN_P, SND_BANK_GENRL_TRAIN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::TRUCK, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_TRAIN, 0.0 },
{ AE_SPECIAL, SND_BANK_GENRL_HOVERCRAFT_P, SND_BANK_GENRL_HOVERCRAFT_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_HOVERCRAFT, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BUICK_P, SND_BANK_GENRL_BUICK_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::BMW328, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BELAIR_P, SND_BANK_GENRL_BELAIR_D, eBassSetting::BOOST, 1.0, 1.1892071, eAEVehicleHornType::CHEVY56, 1.2599211, eAEVehicleDoorType::NEW, 0, RADIO_HOUSE_CLASSICS, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_CUTLASS_P, SND_BANK_GENRL_CUTLASS_D, eBassSetting::NORMAL, 0.64999998, 1.0, eAEVehicleHornType::PICKUP, 1.1892071, eAEVehicleDoorType::OLD, 0, RADIO_REGGAE, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::PICKUP, 1.0594631, eAEVehicleDoorType::OLD, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_PICK_UP, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MACKTRUCK_P, SND_BANK_GENRL_MACKTRUCK_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::TRUCK, 0.9438743, eAEVehicleDoorType::TRUCK, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_FIRETRUCK, 5.0 },
{ AE_CAR, SND_BANK_GENRL_HOTROD_P, SND_BANK_GENRL_HOTROD_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::PORSCHE, 0.9438743, eAEVehicleDoorType::OLD, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BUICK_P, SND_BANK_GENRL_BUICK_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::BMW328, 0.8908987, eAEVehicleDoorType::NEW, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::ESCORT, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_DISCO_FUNK, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_AIRCRAFT_HELICOPTER, SND_BANK_GENRL_APACHE, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_HELICOPTER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.64999998, 1.0, eAEVehicleHornType::CHEVY56, 0.9438743, eAEVehicleDoorType::OLD, 0, RADIO_REGGAE, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BUICK_P, SND_BANK_GENRL_BUICK_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::PORSCHE, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::JEEP, 0.84089643, eAEVehicleDoorType::NEW, 0, RADIO_TALK, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VAN_P, SND_BANK_GENRL_VAN_D, eBassSetting::NORMAL, 0.64999998, 1.0, eAEVehicleHornType::PICKUP, 1.122462, eAEVehicleDoorType::VAN, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_AIRCRAFT_PLANE, SND_BANK_GENRL_TWINPROP, SND_BANK_GENRL_TWINPROP_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_PLANE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BUICK_P, SND_BANK_GENRL_BUICK_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::PICKUP, 1.0594631, eAEVehicleDoorType::NEW, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_PICK_UP, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PONTIAC_P, SND_BANK_GENRL_PONTIAC_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::CHEVY56, 1.2599211, eAEVehicleDoorType::OLD, 0, RADIO_RARE_GROOVE, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_HEAVY_V8_P, SND_BANK_GENRL_HEAVY_V8_D, eBassSetting::BOOST, 0.89999998, 1.1892071, eAEVehicleHornType::TRUCK, 1.0594631, eAEVehicleDoorType::NEW, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_MONSTER_TRUCK, 6.0 },
{ AE_CAR, SND_BANK_GENRL_HEAVY_V8_P, SND_BANK_GENRL_HEAVY_V8_D, eBassSetting::BOOST, 0.89999998, 1.1892071, eAEVehicleHornType::TRUCK, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_MONSTER_TRUCK, 6.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::PORSCHE, 1.0594631, eAEVehicleDoorType::NEW, 2, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_COUPE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MUSTANG_P, SND_BANK_GENRL_MUSTANG_D, eBassSetting::BOOST, 0.89999998, 1.0, eAEVehicleHornType::BMW328, 1.122462, eAEVehicleDoorType::NEW, 2, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_COUPE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 1.0, 1.0, eAEVehicleHornType::PICKUP, 1.1892071, eAEVehicleDoorType::NEW, 2, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::BMW328, 1.0594631, eAEVehicleDoorType::NEW, 2, RADIO_DISCO_FUNK, AE_RT_CIVILIAN, AE_VAT_STATION_WAGON, 0.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::BMW328, 1.122462, eAEVehicleDoorType::NEW, 2, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_TWO_DOOR, 0.0 },
{ AE_AIRCRAFT_HELICOPTER, SND_BANK_GENRL_APACHE, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_HELICOPTER, 0.0 },
{ AE_SPECIAL, SND_BANK_GENRL_RC_TANK_P, SND_BANK_GENRL_RC_TANK_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_NONE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MUSTANG_P, SND_BANK_GENRL_MUSTANG_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::CHEVY56, 1.2599211, eAEVehicleDoorType::NEW, 2, RADIO_HOUSE_CLASSICS, AE_RT_CIVILIAN, AE_VAT_COUPE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MUSTANG_P, SND_BANK_GENRL_MUSTANG_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::BMW328, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_CUTLASS_P, SND_BANK_GENRL_CUTLASS_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::PICKUP, 0.9438743, eAEVehicleDoorType::OLD, 1, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_LOWRIDER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_RS427_P, SND_BANK_GENRL_RS427_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::PICKUP, 1.2599211, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_BUGGY, 0.0 },
{ AE_TRAIN, SND_BANK_GENRL_TRAIN_P, SND_BANK_GENRL_TRAIN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_TRAIN, SND_BANK_GENRL_TRAIN_P, SND_BANK_GENRL_TRAIN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_GOKART_P, SND_BANK_GENRL_GOKART_D, eBassSetting::CUT, 0.77999997, 1.0, eAEVehicleHornType::ESCORT, 1.122462, eAEVehicleDoorType::UNSET, 0, RADIO_MODERN_ROCK, AE_RT_CIVILIAN, AE_VAT_KART, 0.0 },
{ AE_CAR, SND_BANK_GENRL_GOKART_P, SND_BANK_GENRL_GOKART_D, eBassSetting::CUT, 0.89999998, 1.0, eAEVehicleHornType::ESCORT, 0.9438743, eAEVehicleDoorType::UNSET, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_MOWER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_JALOPY_P, SND_BANK_GENRL_JALOPY_D, eBassSetting::NORMAL, 0.69999999, 1.1892071, eAEVehicleHornType::BUS_A, 0.8908987, eAEVehicleDoorType::TRUCK, 0, RADIO_REGGAE, AE_RT_CIVILIAN, AE_VAT_OFFROAD, 0.0 },
{ AE_CAR, SND_BANK_GENRL_SWEEPER_P, SND_BANK_GENRL_SWEEPER_D, eBassSetting::CUT, 0.85000002, 1.0, eAEVehicleHornType::BUS_B, 1.1892071, eAEVehicleDoorType::VAN, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_CADILLAC_P, SND_BANK_GENRL_CADILLAC_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::BMW328, 0.8908987, eAEVehicleDoorType::OLD, 1, RADIO_RARE_GROOVE, AE_RT_CIVILIAN, AE_VAT_LOWRIDER, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BELAIR_P, SND_BANK_GENRL_BELAIR_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::BUS_B, 1.122462, eAEVehicleDoorType::OLD, 1, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_LOWRIDER, 0.0 },
{ AE_AIRCRAFT_PLANE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_PLANE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BUS_P, SND_BANK_GENRL_BUS_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::BUS_A, 0.84089643, eAEVehicleDoorType::TRUCK, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_TRUCK, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PATHFINDER_P, SND_BANK_GENRL_PATHFINDER_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::PICKUP, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_TALK, AE_RT_CIVILIAN, AE_VAT_OFFROAD, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::BOOST, 0.85000002, 1.0, eAEVehicleHornType::CHEVY56, 0.8908987, eAEVehicleDoorType::NEW, 0, RADIO_TALK, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_BIKE, SND_BANK_GENRL_SPORTSBIKE_P, SND_BANK_GENRL_SPORTSBIKE_D, eBassSetting::CUT, 0.77999997, 1.0, eAEVehicleHornType::JEEP, 0.8908987, eAEVehicleDoorType::UNSET, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_BIKE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VAN_P, SND_BANK_GENRL_VAN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_A, 1.0594631, eAEVehicleDoorType::VAN, 0, RADIO_TALK, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_AIRPORT_P, SND_BANK_GENRL_AIRPORT_D, eBassSetting::CUT, 0.64999998, 1.0, eAEVehicleHornType::ESCORT, 0.84089643, eAEVehicleDoorType::VAN, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_SPECIAL, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::TRUCK, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_NONE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 0.77999997, 1.0, eAEVehicleHornType::PORSCHE, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_NEW_JACK_SWING, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_BIKE, SND_BANK_GENRL_COPBIKE_P, SND_BANK_GENRL_COPBIKE_D, eBassSetting::CUT, 0.30000001, 0.8908987, eAEVehicleHornType::PICKUP, 1.1892071, eAEVehicleDoorType::UNSET, 0, RADIO_COUNTRY, AE_RT_CIVILIAN, AE_VAT_BIKE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_90S_P, SND_BANK_GENRL_90S_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::BUS_B, 1.2599211, eAEVehicleDoorType::NEW, 0, RADIO_REGGAE, AE_RT_CIVILIAN, AE_VAT_COUPE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VW_VAN_P, SND_BANK_GENRL_VW_VAN_D, eBassSetting::NORMAL, 0.64999998, 1.0, eAEVehicleHornType::BUS_A, 0.9438743, eAEVehicleDoorType::VAN, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MUSTANG_P, SND_BANK_GENRL_MUSTANG_D, eBassSetting::NORMAL, 1.0, 1.0, eAEVehicleHornType::JEEP, 0.9438743, eAEVehicleDoorType::NEW, 0, RADIO_HOUSE_CLASSICS, AE_RT_CIVILIAN, AE_VAT_COUPE, 0.0 },
{ AE_TRAIN, SND_BANK_GENRL_TRAIN_P, SND_BANK_GENRL_TRAIN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_SPECIAL, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_SPECIAL, AE_VAT_NONE, 0.0 },
{ AE_AIRCRAFT_PLANE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_NONE, 0.0 },
{ AE_AIRCRAFT_PLANE, SND_BANK_GENRL_SINGLEPROP, SND_BANK_GENRL_FASTPROP_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::LIGHT, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_PLANE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_BOAT, SND_BANK_GENRL_BOAT_INBOARD_P, SND_BANK_GENRL_BOAT_INBOARD_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_BOAT, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::CHEVY56, 1.0594631, eAEVehicleDoorType::NEW, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_POLICE_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::CHEVY56, 1.0594631, eAEVehicleDoorType::NEW, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_POLICE_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_MERC_P, SND_BANK_GENRL_MERC_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::PICKUP, 1.0594631, eAEVehicleDoorType::NEW, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_POLICE_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PATHFINDER_P, SND_BANK_GENRL_PATHFINDER_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BUS_A, 1.0594631, eAEVehicleDoorType::NEW, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_POLICE_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BUICK_P, SND_BANK_GENRL_BUICK_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::PICKUP, 1.122462, eAEVehicleDoorType::NEW, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_PICK_UP, 0.0 },
{ AE_CAR, SND_BANK_GENRL_JALOPY_P, SND_BANK_GENRL_JALOPY_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::TRUCK, 0.9438743, eAEVehicleDoorType::TRUCK, 0, RADIO_OFF, AE_RT_EMERGENCY, AE_VAT_POLICE_VAN, 0.0 },
{ AE_CAR, SND_BANK_GENRL_COBRA_P, SND_BANK_GENRL_COBRA_D, eBassSetting::NORMAL, 0.85000002, 1.0, eAEVehicleHornType::BMW328, 1.0, eAEVehicleDoorType::NEW, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_COUPE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PONTIAC_P, SND_BANK_GENRL_PONTIAC_D, eBassSetting::NORMAL, 0.89999998, 1.0, eAEVehicleHornType::PORSCHE, 1.0594631, eAEVehicleDoorType::OLD, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_SPORTS_CAR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_BELAIR_P, SND_BANK_GENRL_BELAIR_D, eBassSetting::NORMAL, 0.64999998, 1.0, eAEVehicleHornType::BUS_B, 1.0594631, eAEVehicleDoorType::OLD, 0, RADIO_CLASSIC_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_FOUR_DOOR, 0.0 },
{ AE_CAR, SND_BANK_GENRL_PACARD_P, SND_BANK_GENRL_PACARD_D, eBassSetting::NORMAL, 0.64999998, 1.0, eAEVehicleHornType::PICKUP, 1.0594631, eAEVehicleDoorType::OLD, 0, RADIO_CLASSIC_ROCK, AE_RT_CIVILIAN, AE_VAT_PICK_UP, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_GENRL_TEMP_P, SND_BANK_GENRL_TEMP_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_GENRL_TEMP_P, SND_BANK_GENRL_TEMP_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_GENRL_TEMP_P, SND_BANK_GENRL_TEMP_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_CAR, SND_BANK_GENRL_VAN_P, SND_BANK_GENRL_VAN_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::BMW328, 0.84089643, eAEVehicleDoorType::UNSET, 0, RADIO_MODERN_HIP_HOP, AE_RT_CIVILIAN, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_GENRL_TEMP_P, SND_BANK_GENRL_TEMP_D, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_NO_VEHICLE, SND_BANK_UNK, SND_BANK_UNK, eBassSetting::NORMAL, 0.69999999, 1.0, eAEVehicleHornType::NONE, 1.0, eAEVehicleDoorType::UNSET, 0, RADIO_OFF, AE_RT_DISABLED, AE_VAT_NONE, 0.0 },
{ AE_CAR, SND_BANK_FEET_GENERIC, SND_BANK_FEET_GENERIC, eBassSetting::NORMAL, 0.0, 0.0, eAEVehicleHornType::BIKE, 0.0, eAEVehicleDoorType::LIGHT, 0, RADIO_EMERGENCY_AA, AE_RT_SPECIAL, AE_VAT_TWO_DOOR, 2.3694278e-38 }
}};
#pragma warning(pop)
inline tVehicleAudioSettings& GetVehicleAudioSettings(eModelID model) {
return VehicleAudioSettings[model - (+MODEL_VEHICLE_FIRST)];
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ CAEWaterCannonAudioEntity::~CAEWaterCannonAudioEntity() {
// 0x503060
void CAEWaterCannonAudioEntity::Initialise(CWaterCannon* waterCannon) {
m_pEntity = reinterpret_cast<CEntity*>(waterCannon); // bruh
m_Entity = reinterpret_cast<CEntity*>(waterCannon); // bruh
ClearSplashInfo();
m_bInitialized = true;
}
@ -67,19 +67,19 @@ void CAEWaterCannonAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayP
}
// 0x502F80
void CAEWaterCannonAudioEntity::UpdateGenericWaterCannonSound(bool splashInfoEnabled, int16 id, int16 bankSlotId, int16 sfxId, float speed, float volume, CVector posn, float soundDistance) {
void CAEWaterCannonAudioEntity::UpdateGenericWaterCannonSound(bool splashInfoEnabled, int16 id, eSoundBankSlot bankSlotId, int16 sfxId, float speed, float volume, CVector posn, float soundDistance) {
auto& sound = m_Sounds[id];
if (splashInfoEnabled) {
if (sound) {
sound->m_fVolume = volume;
sound->m_fSpeed = speed;
sound->m_Volume = volume;
sound->m_Speed = speed;
sound->SetPosition(posn);
} else {
m_tempSound.Initialise(bankSlotId, sfxId, this, posn, volume, 1.0f, 1.0f, 1.0f, 0, SOUND_DEFAULT, 0.0f, 0);
m_tempSound.m_fVolume = volume;
m_tempSound.m_fSoundDistance = soundDistance;
m_tempSound.m_fSpeed = speed;
m_tempSound.m_nEnvironmentFlags = SOUND_REQUEST_UPDATES;
m_tempSound.m_Volume = volume;
m_tempSound.m_RollOffFactor = soundDistance;
m_tempSound.m_Speed = speed;
m_tempSound.m_Flags = SOUND_REQUEST_UPDATES;
sound = AESoundManager.RequestNewSound(&m_tempSound);
}
@ -105,11 +105,11 @@ void CAEWaterCannonAudioEntity::Service() {
if (!m_bInitialized)
return;
if (!AEAudioHardware.IsSoundBankLoaded(59, 0) || !AEAudioHardware.IsSoundBankLoaded(39, 2))
if (!AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_FRONTEND_GAME, SND_BANK_SLOT_FRONTEND_GAME) || !AEAudioHardware.IsSoundBankLoaded( SND_BANK_GENRL_COLLISIONS, SND_BANK_SLOT_COLLISIONS))
return;
bool enabled = false;
auto* cannon = reinterpret_cast<CWaterCannon*>(m_pEntity);
auto* cannon = reinterpret_cast<CWaterCannon*>(m_Entity);
if (cannon->m_abUsed[cannon->m_nSectionsCount]) {
if (cannon->m_nId) {
enabled = true;
@ -117,10 +117,10 @@ void CAEWaterCannonAudioEntity::Service() {
}
const auto& sectionLastPoint = cannon->m_sectionPoint[cannon->m_nSectionsCount];
UpdateGenericWaterCannonSound(enabled, 0, 0, 0, speed0, volume0, sectionLastPoint, 2.0f);
UpdateGenericWaterCannonSound(enabled, 1, 2, 3, speed1, volume1, sectionLastPoint, 2.0f);
UpdateGenericWaterCannonSound(m_bSplashInfoEnabled, 2, 2, 3, speed2, volume2, m_vecPosn, 2.0f);
UpdateGenericWaterCannonSound(m_bSplashInfoEnabled, 3, 2, 3, speed3, volume3, m_vecPosn, 2.0f);
UpdateGenericWaterCannonSound(enabled, 0, SND_BANK_SLOT_FRONTEND_GAME, 0, speed0, volume0, sectionLastPoint, 2.0f);
UpdateGenericWaterCannonSound(enabled, 1, SND_BANK_SLOT_COLLISIONS, 3, speed1, volume1, sectionLastPoint, 2.0f);
UpdateGenericWaterCannonSound(m_bSplashInfoEnabled, 2, SND_BANK_SLOT_COLLISIONS, 3, speed2, volume2, m_vecPosn, 2.0f);
UpdateGenericWaterCannonSound(m_bSplashInfoEnabled, 3, SND_BANK_SLOT_COLLISIONS, 3, speed3, volume3, m_vecPosn, 2.0f);
}
void CAEWaterCannonAudioEntity::InjectHooks() {
@ -139,4 +139,4 @@ void CAEWaterCannonAudioEntity::InjectHooks() {
CAEWaterCannonAudioEntity* CAEWaterCannonAudioEntity::Constructor() {
this->CAEWaterCannonAudioEntity::CAEWaterCannonAudioEntity();
return this;
}
}

View File

@ -25,7 +25,7 @@ public:
void SetSplashInfo(CVector posn, float magnitude);
void ClearSplashInfo();
void UpdateParameters(CAESound* sound, int16 curPlayPos) override;
void UpdateGenericWaterCannonSound(bool splashInfoEnabled, int16 id, int16 bankSlotId, int16 sfxId, float speed, float volume, CVector posn, float soundDistance);
void UpdateGenericWaterCannonSound(bool splashInfoEnabled, int16 id, eSoundBankSlot bankSlotId, int16 sfxId, float speed, float volume, CVector posn, float soundDistance);
void Service();
private:

View File

@ -46,7 +46,7 @@ void CAEWeaponAudioEntity::Initialise() {
m_MiniGunState = eMiniGunState::STOPPED;
m_ChainsawState = eChainsawState::STOPPED;
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(143, 5);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN);
}
}
@ -281,20 +281,18 @@ void CAEWeaponAudioEntity::WeaponFire(eWeaponType weaponType, CPhysical* parent,
// 0x503690
void CAEWeaponAudioEntity::WeaponReload(eWeaponType type, CPhysical* entity, eAudioEvents event) {
if (!entity)
if (!entity) {
return;
}
if (!AEAudioHardware.IsSoundBankLoaded(143, 5)) {
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(143, 5);
}
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN, true)) {
return;
}
const auto PlaySound = [&](eSoundID soundID, float volumeOffsetdB = 0.f) {
CAESound s;
s.Initialise(
5,
SND_BANK_SLOT_WEAPON_GEN,
soundID,
this,
entity->GetPosition(),
@ -351,10 +349,7 @@ void CAEWeaponAudioEntity::PlayGunSounds(
float primarySpeed,
float tailFrequencyScalingFactor
) {
if (!AEAudioHardware.IsSoundBankLoaded(143u, 5)) {
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(143, 5);
}
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN, true)) {
return;
}
@ -382,7 +377,7 @@ void CAEWeaponAudioEntity::PlayGunSounds(
const auto PlaySound = [&](int16 sfxID, CVector pos, float volume, float rollOffFactor, float speed, uint32 flags, eAudioEvents audioEventOverride = AE_UNDEFINED) {
CAESound s;
s.Initialise(
5,
SND_BANK_SLOT_WEAPON_GEN,
sfxID,
this,
pos,
@ -400,10 +395,10 @@ void CAEWeaponAudioEntity::PlayGunSounds(
switch (audioEvent) {
case AE_WEAPON_FIRE_MINIGUN_PLANE:
case AE_WEAPON_FIRE_MINIGUN_AMMO:
s.m_nEvent = AE_FRONTEND_PICKUP_WEAPON;
s.m_Event = AE_FRONTEND_PICKUP_WEAPON;
}
} else {
s.m_nEvent = audioEventOverride;
s.m_Event = audioEventOverride;
}
AESoundManager.RequestNewSound(&s);
};
@ -504,9 +499,9 @@ void CAEWeaponAudioEntity::ReportStealthKill(eWeaponType type, CPhysical* entity
return;
}
const auto PlayStealthKillSound = [&](int16 bankSlotID, eSoundID soundID, float volumeOffsetdB, int32 eventID) {
const auto PlayStealthKillSound = [&](eSoundBankSlot bankSlotID, eSoundID soundID, float volumeOffsetdB, int32 eventID) {
AESoundManager.PlaySound({
.BankSlotID = bankSlotID,
.BankSlotID = bankSlotID,
.SoundID = soundID,
.AudioEntity = this,
.Pos = entity->GetPosition(),
@ -519,30 +514,24 @@ void CAEWeaponAudioEntity::ReportStealthKill(eWeaponType type, CPhysical* entity
});
};
if (!AEAudioHardware.IsSoundBankLoaded(143, 5)) {
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(143, 5);
}
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN, true)) {
return;
}
PlayStealthKillSound(5, 81, -6.f, AE_WEAPON_SOUND_CAT_STEALTH_KNIFE_IN);
PlayStealthKillSound(SND_BANK_SLOT_WEAPON_GEN, 81, -6.f, AE_WEAPON_SOUND_CAT_STEALTH_KNIFE_IN);
if (!AEAudioHardware.IsSoundBankLoaded(39, 2)) {
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(39, 2);
}
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_COLLISIONS, SND_BANK_SLOT_COLLISIONS, true)) {
return;
}
PlayStealthKillSound(2, 471, 0.f, AE_WEAPON_SOUND_CAT_STEALTH_KNIFE_OUT);
PlayStealthKillSound(SND_BANK_SLOT_COLLISIONS, 471, 0.f, AE_WEAPON_SOUND_CAT_STEALTH_KNIFE_OUT);
}
// 0x503910
void CAEWeaponAudioEntity::ReportChainsawEvent(CPhysical* entity, eAudioEvents audioEvent) {
if (!AEAudioHardware.IsSoundBankLoaded(36, 40)) {
if (AESoundManager.AreSoundsPlayingInBankSlot(40)) {
AESoundManager.CancelSoundsInBankSlot(40, false);
if (!AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_CHAINSAW_P, SND_BANK_SLOT_PLAYER_ENGINE_P)) {
if (AESoundManager.AreSoundsPlayingInBankSlot(SND_BANK_SLOT_PLAYER_ENGINE_P)) {
AESoundManager.CancelSoundsInBankSlot(SND_BANK_SLOT_PLAYER_ENGINE_P, false);
}
AEAudioHardware.LoadSoundBank(36, 40);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_CHAINSAW_P, SND_BANK_SLOT_PLAYER_ENGINE_P);
return;
}
@ -552,7 +541,7 @@ void CAEWeaponAudioEntity::ReportChainsawEvent(CPhysical* entity, eAudioEvents a
}
CAESound s;
s.Initialise(
40,
SND_BANK_SLOT_PLAYER_ENGINE_P,
sfxID,
this,
entity->GetPosition(),
@ -563,7 +552,7 @@ void CAEWeaponAudioEntity::ReportChainsawEvent(CPhysical* entity, eAudioEvents a
0,
SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY | SOUND_REQUEST_UPDATES
);
s.m_nEvent = soundCat;
s.m_Event = soundCat;
s.RegisterWithPhysicalEntity(entity);
AESoundManager.RequestNewSound(&s);
};
@ -609,14 +598,11 @@ void CAEWeaponAudioEntity::ReportChainsawEvent(CPhysical* entity, eAudioEvents a
// 0x504610
void CAEWeaponAudioEntity::PlayWeaponLoopSound(CPhysical* entity, int16 sfxId, eAudioEvents startEvent, float volumeOffsetdB, float speed, eWeaponSoundCategories soundCat) {
if (!AEAudioHardware.IsSoundBankLoaded(143u, 5)) {
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(143, 5);
}
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN, true)) {
return;
}
AESoundManager.PlaySound({
.BankSlotID = 5,
.BankSlotID = SND_BANK_SLOT_WEAPON_GEN,
.SoundID = sfxId,
.AudioEntity = this,
.Pos = entity->GetPosition(),
@ -639,17 +625,14 @@ void CAEWeaponAudioEntity::PlayMiniGunStopSound(CPhysical* entity) {
return;
}
if (!AEAudioHardware.IsSoundBankLoaded(143u, 5)) {
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(143, 5);
}
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN, true)) {
return;
}
const auto PlayMiniGunFireStopSound = [&](float speed, float maxDist) {
CAESound s;
s.Initialise(
5,
SND_BANK_SLOT_WEAPON_GEN,
63,
this,
entity->GetPosition(),
@ -661,7 +644,7 @@ void CAEWeaponAudioEntity::PlayMiniGunStopSound(CPhysical* entity) {
SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY | SOUND_REQUEST_UPDATES
);
s.RegisterWithPhysicalEntity(entity);
s.m_nEvent = AE_FRONTEND_PICKUP_HEALTH; // ???
s.m_Event = AE_FRONTEND_PICKUP_HEALTH; // ???
AESoundManager.RequestNewSound(&s);
};
if (entity->IsVehicle() && entity->AsVehicle()->IsSubPlane()) {
@ -692,14 +675,14 @@ void CAEWeaponAudioEntity::PlayMiniGunFireSounds(CPhysical* entity, eAudioEvents
}
case AE_WEAPON_FIRE_MINIGUN_NO_AMMO: { // 0x5048FC - Minigun is just spinning
if (!m_IsMiniGunSpinActive) {
if (!AEAudioHardware.IsSoundBankLoaded(143, 5)) { // SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN
if (!AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN)) { // SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(143, 5);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN);
}
break;
}
AESoundManager.PlaySound({
.BankSlotID = 5,
.BankSlotID = SND_BANK_SLOT_WEAPON_GEN,
.SoundID = 14,
.AudioEntity = this,
.Pos = entity->GetPosition(),
@ -722,16 +705,13 @@ void CAEWeaponAudioEntity::PlayMiniGunFireSounds(CPhysical* entity, eAudioEvents
// 0x503500
void CAEWeaponAudioEntity::PlayGoggleSound(int16 sfxId, eAudioEvents event) {
if (!AEAudioHardware.IsSoundBankLoaded(143u, 5)) {
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(143, 5);
}
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN, true)) {
return;
}
const auto PlaySound = [&](float offsetX, float speed) {
CAESound s;
s.Initialise(5, sfxId, this, { offsetX, 0.0f, 0.0f }, GetDefaultVolume(event) - 9.f, 1.0f, speed, 1.0f, 0, SOUND_DEFAULT);
s.m_nEnvironmentFlags = SOUND_FRONT_END | SOUND_FORCED_FRONT;
s.Initialise(SND_BANK_SLOT_WEAPON_GEN, sfxId, this, { offsetX, 0.0f, 0.0f }, GetDefaultVolume(event) - 9.f, 1.0f, speed, 1.0f, 0, SOUND_DEFAULT);
s.m_Flags = SOUND_FRONT_END | SOUND_FORCED_FRONT;
AESoundManager.RequestNewSound(&s);
};
const auto r = CAEAudioUtility::ResolveProbability(0.5f);
@ -740,8 +720,8 @@ void CAEWeaponAudioEntity::PlayGoggleSound(int16 sfxId, eAudioEvents event) {
}
// 0x504470
void CAEWeaponAudioEntity::PlayFlameThrowerSounds(CPhysical* entity, int16 dryFireSfxID, int16 flameSfxID, eAudioEvents audioEvent, float volumeOffsetdB, float speed) {
const auto PlaySound = [&](int16 bankSlotID, int16 sfxID, float sfxVolumeOffsetdB, float rollOffFactor, float sfxSpeed, float sfxFreqVariance, eAudioEvents sfxAE) {
void CAEWeaponAudioEntity::PlayFlameThrowerSounds(CPhysical* entity, eSoundID dryFireSfxID, eSoundID flameSfxID, eAudioEvents audioEvent, float volumeOffsetdB, float speed) {
const auto PlaySound = [&](eSoundBankSlot bankSlotID, eSoundID sfxID, float sfxVolumeOffsetdB, float rollOffFactor, float sfxSpeed, float sfxFreqVariance, eAudioEvents sfxAE) {
CAESound s;
s.Initialise(
bankSlotID,
@ -756,19 +736,16 @@ void CAEWeaponAudioEntity::PlayFlameThrowerSounds(CPhysical* entity, int16 dryFi
SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY|SOUND_REQUEST_UPDATES,
sfxFreqVariance
);
s.m_nEvent = sfxAE;
s.m_Event = sfxAE;
s.RegisterWithPhysicalEntity(entity);
AESoundManager.RequestNewSound(&s);
};
if (!AEAudioHardware.IsSoundBankLoaded(143u, 5)) {
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(143, 5);
}
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN, true)) {
return;
}
PlaySound(
5,
SND_BANK_SLOT_WEAPON_GEN,
dryFireSfxID,
-6.f,
2.f / 3.f,
@ -777,12 +754,11 @@ void CAEWeaponAudioEntity::PlayFlameThrowerSounds(CPhysical* entity, int16 dryFi
AE_UNDEFINED
);
if (!AEAudioHardware.IsSoundBankLoaded(138, 19)) {
AEAudioHardware.LoadSoundBank(138, 19);
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_VEHICLE_GEN, SND_BANK_SLOT_VEHICLE_GEN)) {
return;
}
PlaySound(
19,
SND_BANK_SLOT_VEHICLE_GEN,
flameSfxID,
-20.f,
2.f,
@ -798,7 +774,7 @@ void CAEWeaponAudioEntity::PlayFlameThrowerIdleGasLoop(CPhysical* entity) {
return;
}
m_FlameThrowerIdleGasLoopSound = AESoundManager.PlaySound({
.BankSlotID = 5,
.BankSlotID = SND_BANK_SLOT_WEAPON_GEN,
.SoundID = 10,
.AudioEntity = this,
.Pos = entity->GetPosition(),
@ -818,10 +794,10 @@ void CAEWeaponAudioEntity::StopFlameThrowerIdleGasLoop() {
// 0x504AA0
void CAEWeaponAudioEntity::PlayChainsawStopSound(CPhysical* entity) {
if (entity && AEAudioHardware.IsSoundBankLoaded(36, 40)) {
if (entity && AEAudioHardware.IsSoundBankLoaded(SND_BANK_GENRL_CHAINSAW_P, SND_BANK_SLOT_PLAYER_ENGINE_P)) {
if (m_ChainsawState != eChainsawState::STOPPING) {
AESoundManager.PlaySound({
.BankSlotID = 40,
.BankSlotID = SND_BANK_SLOT_PLAYER_ENGINE_P,
.SoundID = 2,
.AudioEntity = this,
.Pos = entity->GetPosition(),
@ -840,20 +816,17 @@ void CAEWeaponAudioEntity::PlayChainsawStopSound(CPhysical* entity) {
// 0x5046F0
void CAEWeaponAudioEntity::PlayCameraSound(CPhysical* entity, eAudioEvents event, float audability) {
if (!AEAudioHardware.IsSoundBankLoaded(143, 5)) {
if (!AudioEngine.IsLoadingTuneActive()) {
AEAudioHardware.LoadSoundBank(143, 5);
}
if (!AEAudioHardware.EnsureSoundBankIsLoaded(SND_BANK_GENRL_WEAPONS, SND_BANK_SLOT_WEAPON_GEN, true)) {
return;
}
AESoundManager.PlaySound({
.BankSlotID = 5,
.BankSlotID = SND_BANK_SLOT_WEAPON_GEN,
.SoundID = 45,
.AudioEntity = this,
.Pos = entity->GetPosition(),
.Volume = GetDefaultVolume(event),
.RollOffFactor = 2.f / 3.f,
.Flags = SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY | SOUND_UNPAUSABLE, // NOTE/BUG: `UNPAUSABLE` typo?
.Flags = SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY | SOUND_IS_PAUSABLE, // NOTE/BUG: `UNPAUSABLE` typo?
.RegisterWithEntity = entity,
.EventID = AE_WEAPON_SOUND_CAT_CHAINSAW_STOP
});
@ -864,22 +837,22 @@ void CAEWeaponAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
if (curPlayPos == -1) {
if (sound == m_FlameThrowerIdleGasLoopSound) {
m_FlameThrowerIdleGasLoopSound = nullptr;
} else if (sound->m_nEvent == AE_WEAPON_SOUND_CAT_MINIGUN_STOP && m_MiniGunState == eMiniGunState::STOPPING) {
} else if (sound->m_Event == AE_WEAPON_SOUND_CAT_MINIGUN_STOP && m_MiniGunState == eMiniGunState::STOPPING) {
m_MiniGunState = eMiniGunState::STOPPED;
}
return;
}
switch (sound->m_nEvent) {
switch (sound->m_Event) {
case AE_WEAPON_SOUND_CAT_TAIL: { // 0x504BAA
if (!CGame::CanSeeOutSideFromCurrArea()) {
sound->m_fVolume -= 1.f;
sound->m_Volume -= 1.f;
}
break;
}
case AE_WEAPON_SOUND_CAT_FLAME: { // 0x504BC3
if (m_LastFlameThrowerFireTimeMs + 300 >= CTimer::GetTimeInMS()) {
sound->m_fVolume = std::min(GetDefaultVolume(AE_WEAPON_FIRE) - 14.f, sound->m_fVolume + 2.f); // TODO: Use TimeStep
sound->m_Volume = std::min(GetDefaultVolume(AE_WEAPON_FIRE) - 14.f, sound->GetVolume() + 2.f); // TODO: Use TimeStep
} else {
sound->StopSoundAndForget();
m_LastFlameThrowerFireTimeMs = 0;
@ -895,7 +868,7 @@ void CAEWeaponAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
}
case AE_WEAPON_SOUND_CAT_EXT: { // 0x504C5F
if (m_LastFireExtFireTimeMs + 300 >= CTimer::GetTimeInMS()) {
sound->m_fSpeed = std::min(0.85f, sound->m_fSpeed + 0.01f); // TODO: Use TimeStep
sound->m_Speed = std::min(0.85f, sound->GetSpeed() + 0.01f); // TODO: Use TimeStep
} else {
sound->StopSoundAndForget();
m_LastFireExtFireTimeMs = 0;
@ -904,7 +877,7 @@ void CAEWeaponAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
}
case AE_WEAPON_SOUND_CAT_MINIGUN_SPIN: { // 0x504CBC
if (m_LastMiniGunFireTimeMs + 300 < CTimer::GetTimeInMS()) {
PlayMiniGunStopSound(sound->m_pPhysicalEntity->AsPhysical());
PlayMiniGunStopSound(sound->m_PhysicalEntity->AsPhysical());
}
switch (m_MiniGunState) {
case eMiniGunState::STOPPING:
@ -917,7 +890,7 @@ void CAEWeaponAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
}
case AE_WEAPON_SOUND_CAT_MINIGUN_FIRE: { // 0x504CFB
if (m_LastMiniGunFireTimeMs + 300 < CTimer::GetTimeInMS()) {
PlayMiniGunStopSound(sound->m_pPhysicalEntity->AsPhysical());
PlayMiniGunStopSound(sound->m_PhysicalEntity->AsPhysical());
}
if (m_MiniGunState != eMiniGunState::FIRING) {
sound->StopSoundAndForget();
@ -927,10 +900,10 @@ void CAEWeaponAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
}
case AE_WEAPON_SOUND_CAT_MINIGUN_TAIL: { // 0x504D31
if (m_MiniGunState != eMiniGunState::FIRING) {
if (sound->m_fVolume <= -30.0) {
if (sound->m_Volume <= -30.0) {
sound->StopSoundAndForget();
} else {
sound->m_fVolume -= 1.5f;
sound->m_Volume -= 1.5f;
}
}
break;
@ -948,7 +921,7 @@ void CAEWeaponAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
switch (m_ChainsawState) {
case eChainsawState::CUTTING: { // 0x504DA5
if (m_LastChainsawEventTimeMs + 400 >= CTimer::m_snTimeInMilliseconds) {
sound->m_fSpeed = std::max(0.85f, sound->m_fSpeed - 0.15f); // TODO: Use TimeStep
sound->m_Speed = std::max(0.85f, sound->m_Speed - 0.15f); // TODO: Use TimeStep
} else {
m_LastChainsawEventTimeMs = CTimer::m_snTimeInMilliseconds;
m_ChainsawState = eChainsawState::ACTIVE;
@ -956,9 +929,9 @@ void CAEWeaponAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
break;
}
case eChainsawState::ACTIVE: { // 0x504E0E
sound->m_fSpeed = std::min(1.f, sound->m_fSpeed + 0.03f); // TODO: Use TimeStep
sound->m_Speed = std::min(1.f, sound->m_Speed + 0.03f); // TODO: Use TimeStep
if (m_LastChainsawEventTimeMs + 300 < CTimer::GetTimeInMS()) {
PlayChainsawStopSound(sound->m_pPhysicalEntity->AsPhysical());
PlayChainsawStopSound(sound->m_PhysicalEntity->AsPhysical());
}
break;
}
@ -977,19 +950,19 @@ void CAEWeaponAudioEntity::UpdateParameters(CAESound* sound, int16 curPlayPos) {
}
case AE_WEAPON_SOUND_CAT_STEALTH_KNIFE_IN: { // 0x504E8B
if ((uint32)sound->m_ClientVariable + 820 < CTimer::GetTimeInMS()) {
sound->m_fSpeed = 0.84f;
sound->m_Speed = 0.84f;
}
break;
}
case AE_WEAPON_SOUND_CAT_STEALTH_KNIFE_OUT: { // 0x504EBF
if ((uint32)sound->m_ClientVariable + 2200 < CTimer::GetTimeInMS()) {
sound->m_fSpeed = 1.f;
sound->m_Speed = 1.f;
}
break;
}
default: { // 0x504ECD
if (sound->m_fVolume > 0.0f) {
sound->m_fVolume = std::max(0.0f, sound->m_fVolume - 2.5f);
if (sound->m_Volume > 0.0f) {
sound->m_Volume = std::max(0.0f, sound->m_Volume - 2.5f);
}
break;
}

View File

@ -83,7 +83,7 @@ public:
void PlayMiniGunFireSounds(CPhysical* entity, eAudioEvents audioEventId);
void PlayMiniGunStopSound(CPhysical* entity);
void PlayFlameThrowerSounds(CPhysical* entity, int16 sfx1, int16 sfx2, eAudioEvents audioEventId, float audability, float speed);
void PlayFlameThrowerSounds(CPhysical* entity, eSoundID dryFireSfxID, eSoundID flameSfxID, eAudioEvents audioEvent, float volumeOffsetdB, float speed);
void PlayFlameThrowerIdleGasLoop(CPhysical* entity);
void StopFlameThrowerIdleGasLoop();

View File

@ -17,18 +17,20 @@ CAEWeatherAudioEntity::CAEWeatherAudioEntity() : CAEAudioEntity() {
// 0x5B9A70
void CAEWeatherAudioEntity::StaticInitialise() {
AEAudioHardware.LoadSoundBank(105, 6);
AEAudioHardware.LoadSoundBank(SND_BANK_GENRL_RAIN, SND_BANK_SLOT_WEATHER);
}
// 0x5052B0
void CAEWeatherAudioEntity::StaticReset() {
m_sfRainVolume = -100.0f;
if (gTwinLoopSoundEntityFirst.m_bIsInitialised)
if (gTwinLoopSoundEntityFirst.IsActive()) {
gTwinLoopSoundEntityFirst.StopSoundAndForget();
}
if (gTwinLoopSoundEntitySecond.m_bIsInitialised)
if (gTwinLoopSoundEntitySecond.IsActive()) {
gTwinLoopSoundEntitySecond.StopSoundAndForget();
}
}
// 0x506800, see discord gists channel
@ -55,4 +57,4 @@ void CAEWeatherAudioEntity::InjectHooks() {
RH_ScopedInstall(AddAudioEvent, 0x506800, { .reversed = false });
RH_ScopedVMTInstall(UpdateParameters, 0x505A00, { .reversed = false });
RH_ScopedInstall(Service, 0x5052F0, { .reversed = false });
}
}

View File

@ -31,7 +31,7 @@ CAEAudioChannel::CAEAudioChannel(IDirectSound* directSound, uint16 channelId, ui
m_nBufferStatus = 0;
m_nFrequency = samplesPerSec;
m_nOriginalFrequency = samplesPerSec;
m_fVolume = -100.0f;
m_Volume = -100.0f;
m_pDirectSoundBuffer = nullptr;
m_pDirectSound3DBuffer = nullptr;
m_bPaused = false;
@ -85,8 +85,8 @@ void CAEAudioChannel::SetFrequencyScalingFactor(float factor) {
m_pDirectSoundBuffer->Play(0, 0, m_bLooped);
if (curPos != 0 && !AESmoothFadeThread.RequestFade(m_pDirectSoundBuffer, m_fVolume, -2, false)) {
const auto volume = static_cast<LONG>(m_fVolume * 100.0F);
if (curPos != 0 && !AESmoothFadeThread.RequestFade(m_pDirectSoundBuffer, m_Volume, -2, false)) {
const auto volume = static_cast<LONG>(m_Volume * 100.0F);
m_pDirectSoundBuffer->SetVolume(volume);
}
}
@ -112,20 +112,20 @@ void CAEAudioChannel::SetVolume(float volume) {
if (!m_pDirectSoundBuffer)
return;
if (IsBufferPlaying() && fabs(volume - m_fVolume) > 60.0F) {
if (volume <= m_fVolume) {
if (IsBufferPlaying() && fabs(volume - m_Volume) > 60.0F) {
if (volume <= m_Volume) {
if (AESmoothFadeThread.RequestFade(m_pDirectSoundBuffer, volume, -1, false)) {
m_fVolume = volume;
m_Volume = volume;
return;
}
} else if (AESmoothFadeThread.RequestFade(m_pDirectSoundBuffer, volume, -2, false)) {
m_fVolume = volume;
m_Volume = volume;
return;
}
}
AESmoothFadeThread.SetBufferVolume(m_pDirectSoundBuffer, volume);
m_fVolume = volume;
m_Volume = volume;
}
// 0x4D79A0

View File

@ -21,7 +21,7 @@ public:
uint32 m_nFlags;
uint32 m_nLengthInBytes;
uint32 m_dwStopTime; // unused
float m_fVolume;
float m_Volume;
bool m_bPaused;
uint8 field_39; // unused
uint16 m_nChannelId;
@ -57,7 +57,7 @@ public:
virtual void SetFrequencyScalingFactor(float factor);
void SetPosition(const CVector& vecPos) const;
float GetVolume() const { return m_fVolume; };
float GetVolume() const { return m_Volume; };
void SetVolume(float volume);
bool IsBufferPlaying() const { return m_nBufferStatus & DSBSTATUS_PLAYING; };
uint32 GetCurrentPlaybackPosition() const;

View File

@ -264,10 +264,10 @@ int16 CAEAudioHardware::AllocateChannels(uint16 numChannels) {
}
// 0x4D94A0
void CAEAudioHardware::SetBassSetting(int8 nBassSet, float fBassEqGain) {
m_nBassSet = nBassSet;
m_fBassEqGain = fBassEqGain;
m_pStreamingChannel->SetBassEQ(nBassSet, fBassEqGain);
void CAEAudioHardware::SetBassSetting(eBassSetting bassSetting, float bassGain) {
m_BassSetting = bassSetting;
m_BassGain = bassGain;
m_pStreamingChannel->SetBassEQ(bassSetting, bassGain);
}
// 0x4D8810
@ -292,41 +292,53 @@ void CAEAudioHardware::SetChannelVolume(int16 channel, uint16 channelId, float v
}
// 0x4D88A0
void CAEAudioHardware::LoadSoundBank(uint16 bankId, int16 bankSlotId) {
void CAEAudioHardware::LoadSoundBank(eSoundBank bank, eSoundBankSlot slot) {
if (!m_bDisableEffectsLoading) {
m_pMP3BankLoader->LoadSoundBank((eSoundBank)(bankId), (eSoundBankSlot)(bankSlotId));
m_pMP3BankLoader->LoadSoundBank(bank, slot);
}
}
// 0x4D88C0
bool CAEAudioHardware::IsSoundBankLoaded(uint16 bankId, int16 bankSlotId) {
return m_pMP3BankLoader->IsSoundBankLoaded((eSoundBank)(bankId), (eSoundBankSlot)(bankSlotId));
bool CAEAudioHardware::IsSoundBankLoaded(eSoundBank bank, eSoundBankSlot slot) {
return m_pMP3BankLoader->IsSoundBankLoaded(bank, slot);
}
// 0x4D88D0
int8 CAEAudioHardware::GetSoundBankLoadingStatus(uint16 bankId, int16 bankSlotId) {
return m_pMP3BankLoader->GetSoundBankLoadingStatus((eSoundBank)(bankId), (eSoundBankSlot)(bankSlotId));
int8 CAEAudioHardware::GetSoundBankLoadingStatus(eSoundBank bank, eSoundBankSlot slot) {
return m_pMP3BankLoader->GetSoundBankLoadingStatus(bank, slot);
}
// notsa
bool CAEAudioHardware::EnsureSoundBankIsLoaded(eSoundBank bank, eSoundBankSlot slot, bool checkLoadingTune) {
if (AEAudioHardware.IsSoundBankLoaded(bank, slot)) {
return true;
}
if (checkLoadingTune && AudioEngine.IsLoadingTuneActive()) {
return false;
}
LoadSoundBank(bank, slot);
return false;
}
// 0x4D8ED0
void CAEAudioHardware::LoadSound(uint16 bank, uint16 sound, int16 slot) {
void CAEAudioHardware::LoadSound(eSoundBank bank, eSoundID sound, eSoundBankSlot slot) {
if (!m_bDisableEffectsLoading) {
m_pMP3BankLoader->LoadSound((eSoundBank)(bank), sound, (eSoundBankSlot)(slot));
m_pMP3BankLoader->LoadSound(bank, sound, slot);
}
}
// 0x4D8EF0
bool CAEAudioHardware::IsSoundLoaded(uint16 bankId, uint16 sfxId, int16 bankSlot) {
return m_pMP3BankLoader->IsSoundLoaded((eSoundBank)(bankId), sfxId, (eSoundBankSlot)(bankSlot));
bool CAEAudioHardware::IsSoundLoaded(eSoundBank bank, eSoundID sfx, eSoundBankSlot slot) {
return m_pMP3BankLoader->IsSoundLoaded(bank, sfx, slot);
}
// 0x4D8F00
bool CAEAudioHardware::GetSoundLoadingStatus(uint16 bankId, uint16 sfxId, int16 bankSlot) {
return m_pMP3BankLoader->GetSoundLoadingStatus((eSoundBank)(bankId), sfxId, (eSoundBankSlot)(bankSlot));
bool CAEAudioHardware::GetSoundLoadingStatus(eSoundBank bank, eSoundID sfx, eSoundBankSlot slot) {
return m_pMP3BankLoader->GetSoundLoadingStatus(bank, sfx, slot);
}
// 0x4D88E0
void CAEAudioHardware::StopSound(int16 channel, uint16 channelId) {
void CAEAudioHardware::StopSound(int16 channel, uint16 channelId) const {
if (channel >= 0 && channelId < m_anNumChannelsInSlot[channel]) {
const auto ch = m_aChannels[channel + channelId];
if (ch) {
@ -336,7 +348,7 @@ void CAEAudioHardware::StopSound(int16 channel, uint16 channelId) {
}
// 0x4D8920
void CAEAudioHardware::SetChannelPosition(int16 slotId, uint16 channelId, const CVector& posn, uint8 unused) {
void CAEAudioHardware::SetChannelPosition(int16 slotId, uint16 channelId, const CVector& posn, uint8 unused) const {
if (slotId >= 0 && channelId < m_anNumChannelsInSlot[slotId]) {
const auto ch = m_aChannels[slotId + channelId];
if (ch) {
@ -365,18 +377,20 @@ void CAEAudioHardware::UpdateReverbEnvironment() {
if (reverb == m_nReverbEnvironment && depth == m_nReverbDepth) { // Nothing is changing?
return;
}
if (!rng::none_of(GetChannels(), [=](CAEAudioChannel* ch) { // Also covers the case of `m_nNumChannels == 0`
return ch && ch->SetReverbAndDepth(reverb, depth); }
)) {
return;
}
m_nReverbEnvironment = reverb;
m_nReverbDepth = depth;
}
// 0x4D8E30
float CAEAudioHardware::GetSoundHeadroom(uint16 sfxId, int16 bankSlotId) {
return m_pMP3BankLoader->GetSoundHeadroom(sfxId, (eSoundBankSlot)(bankSlotId));
float CAEAudioHardware::GetSoundHeadroom(eSoundID sfx, eSoundBankSlot slot) {
return m_pMP3BankLoader->GetSoundHeadroom(sfx, slot);
}
// 0x4D8E40
@ -390,19 +404,20 @@ void CAEAudioHardware::DisableEffectsLoading() {
}
// 0x4D8E60
void CAEAudioHardware::RequestVirtualChannelSoundInfo(uint16 idx, uint16 sfxId, uint16 bankSlotId) {
assert(idx < MAX_NUM_SOUNDS);
m_aBankSlotIds[idx] = bankSlotId;
m_aSoundIdsInSlots[idx] = sfxId;
void CAEAudioHardware::RequestVirtualChannelSoundInfo(uint16 vch, eSoundID sfx, eSoundBankSlot slot) {
assert(vch < MAX_NUM_SOUNDS);
m_VirtualChannelSettings.BankSlotIDs[vch] = slot;
m_VirtualChannelSettings.SoundIDs[vch] = sfx;
}
// 0x4D8E90
void CAEAudioHardware::GetVirtualChannelSoundLengths(int16* soundLengths) {
void CAEAudioHardware::GetVirtualChannelSoundLengths(int16* soundLengths) const {
memcpy(soundLengths, m_VirtualChannelSoundLengths, sizeof(m_VirtualChannelSoundLengths));
}
// 0x4D8EB0
void CAEAudioHardware::GetVirtualChannelSoundLoopStartTimes(int16* soundLoopStartTimes) {
void CAEAudioHardware::GetVirtualChannelSoundLoopStartTimes(int16* soundLoopStartTimes) const {
memcpy(soundLoopStartTimes, m_VirtualChannelLoopTimes, sizeof(m_VirtualChannelLoopTimes)); // size is 600, replaced by loop?
}
@ -504,12 +519,12 @@ void CAEAudioHardware::GetBeatInfo(tBeatInfo* beatInfo) {
// 0x4D94E0
void CAEAudioHardware::EnableBassEq() {
m_pStreamingChannel->SetBassEQ(m_nBassSet, m_fBassEqGain);
m_pStreamingChannel->SetBassEQ(m_BassSetting, m_BassGain);
}
// 0x4D94D0
void CAEAudioHardware::DisableBassEq() {
m_pStreamingChannel->SetBassEQ(0, 0.f);
m_pStreamingChannel->SetBassEQ(eBassSetting::NORMAL, 0.f);
}
// 0x4D9500
@ -647,3 +662,7 @@ void CAEAudioHardware::Service() {
);
m_pMP3BankLoader->Service();
}
const CAEBankSlot& CAEAudioHardware::GetBankSlot(eSoundBankSlot slot) const {
return m_pMP3BankLoader->GetBankSlot(slot);
}

View File

@ -23,19 +23,19 @@ union CAEAudioHardwarePlayFlags {
uint16 m_bIsSmoothDucking : 1;
uint16 m_bIsForcedFront : 1;
uint16 m_bUnpausable : 1;
uint16 m_IsPausable : 1;
};
void CopyFromAESound(const CAESound& sound) {
m_bIsFrontend = sound.GetFrontEnd();
m_bIsUncompressable = sound.GetUncompressable();
m_bIsUnduckable = sound.GetUnduckable();
m_bIsStartPercentage = sound.GetStartPercentage();
m_bIsMusicMastered = sound.GetMusicMastered();
m_bIsFrontend = sound.IsFrontEnd();
m_bIsUncompressable = sound.IsIncompressible();
m_bIsUnduckable = sound.IsUnduckable();
m_bIsStartPercentage = sound.GetPlayTimeIsPercentage();
m_bIsMusicMastered = sound.IsMusicMastered();
m_bIsRolledOff = sound.GetRolledOff();
m_bIsSmoothDucking = sound.GetSmoothDucking();
m_bIsForcedFront = sound.GetForcedFront();
m_bUnpausable = m_bIsFrontend ? sound.GetUnpausable() : false;
m_bIsForcedFront = sound.IsForcedFront();
m_IsPausable = m_bIsFrontend && sound.IsUnpausable();
}
};
@ -74,18 +74,18 @@ public:
float field_428{};
float field_42C{};
union { // TODO: Get rid of the union, and use `m_VirtualChannelSettings` directly
tVirtualChannelSettings m_VirtualChannelSettings{};
struct {
int16 m_aBankSlotIds[MAX_NUM_SOUNDS];
int16 m_aSoundIdsInSlots[MAX_NUM_SOUNDS];
};
};
tVirtualChannelSettings m_VirtualChannelSettings{};
//union { // TODO: Get rid of the union, and use `m_VirtualChannelSettings` directly
// struct {
// int16 m_aBankSlotIds[MAX_NUM_SOUNDS];
// int16 m_aSoundIdsInSlots[MAX_NUM_SOUNDS];
// };
//};
int16 m_VirtualChannelLoopTimes[MAX_NUM_SOUNDS]{};
int16 m_VirtualChannelSoundLengths[MAX_NUM_SOUNDS]{};
uint8 m_nBassSet{};
float m_fBassEqGain{};
eBassSetting m_BassSetting{};
float m_BassGain{};
CAEMP3BankLoader* m_pMP3BankLoader{};
CAEMP3TrackLoader* m_pMP3TrackLoader{};
IDirectSound8* m_pDSDevice{};
@ -108,7 +108,6 @@ public:
~CAEAudioHardware() = default;
bool Initialise();
void InitOpenALListener();
bool InitDirectSoundListener(uint32 numChannels, uint32 samplesPerSec, uint32 bitsPerSample);
void Terminate();
@ -119,27 +118,28 @@ public:
void GetChannelPlayTimes(int16 channel, int16* playTimes);
void SetChannelVolume(int16 channel, uint16 channelId, float volume, uint8 unused);
void LoadSoundBank(uint16 bankId, int16 bankSlotId);
bool IsSoundBankLoaded(uint16 bankId, int16 bankSlotId);
int8 GetSoundBankLoadingStatus(uint16 bankId, int16 bankSlotId);
void LoadSoundBank(eSoundBank bank, eSoundBankSlot slot);
bool IsSoundBankLoaded(eSoundBank bank, eSoundBankSlot slot);
int8 GetSoundBankLoadingStatus(eSoundBank bank, eSoundBankSlot slot);
bool EnsureSoundBankIsLoaded(eSoundBank bank, eSoundBankSlot slot, bool checkLoadingTune = false);
void LoadSound(uint16 bank, uint16 sound, int16 slot);
bool IsSoundLoaded(uint16, uint16, int16);
bool GetSoundLoadingStatus(uint16 bankId, uint16 sfxId, int16 bankSlot);
void LoadSound(eSoundBank bank, eSoundID sfx, eSoundBankSlot slot);
bool IsSoundLoaded(eSoundBank bank, eSoundID sfx, eSoundBankSlot slot);
bool GetSoundLoadingStatus(eSoundBank bank, eSoundID sfx, eSoundBankSlot slot);
void StopSound(int16 channel, uint16 channelSlot);
void SetChannelPosition(int16 slotId, uint16 channelSlot, const CVector& vecPos, uint8 unused);
void StopSound(int16 channel, uint16 channelSlot) const;
void SetChannelPosition(int16 slotId, uint16 channelSlot, const CVector& vecPos, uint8 unused) const;
void SetChannelFrequencyScalingFactor(int16 channel, uint16 channelSlot, float freqFactor);
void RescaleChannelVolumes();
void UpdateReverbEnvironment();
float GetSoundHeadroom(uint16 soundId, int16 bankSlotId);
float GetSoundHeadroom(eSoundID sfx, eSoundBankSlot slot);
void EnableEffectsLoading();
void DisableEffectsLoading();
void RequestVirtualChannelSoundInfo(uint16 soundIndex, uint16 soundIdInSlot, uint16 bankSlotId);
void GetVirtualChannelSoundLengths(int16* outArr);
void GetVirtualChannelSoundLoopStartTimes(int16* outArr);
void RequestVirtualChannelSoundInfo(uint16 vch, eSoundID sfx, eSoundBankSlot slot);
void GetVirtualChannelSoundLengths(int16* outArr) const;
void GetVirtualChannelSoundLoopStartTimes(int16* outArr) const;
void PlayTrack(uint32 trackID, int nextTrackID, uint32 startOffsetMs, uint8 trackFlags, bool bUserTrack, bool bUserNextTrack);
void StartTrackPlayback() const;
@ -152,7 +152,7 @@ public:
void GetBeatInfo(tBeatInfo* beatInfo);
void GetActualNumberOfHardwareChannels();
void SetBassSetting(int8 nBassSet, float fBassEqGain);
void SetBassSetting(eBassSetting bassSetting, float bassGain);
void EnableBassEq();
void DisableBassEq();
@ -183,6 +183,9 @@ public:
void Service();
// notsa
const CAEBankSlot& GetBankSlot(eSoundBankSlot slot) const;
private:
auto GetChannels() const { return std::span{m_aChannels, m_nNumChannels}; }

View File

@ -115,8 +115,8 @@ void CAEStaticChannel::SynchPlayback() {
if (m_bUnkn2) {
m_pDirectSoundBuffer->SetVolume(-10000);
if (!AESmoothFadeThread.RequestFade(m_pDirectSoundBuffer, m_fVolume, -2, false)) {
const auto dwVolume = static_cast<LONG>(m_fVolume * 100.0F);
if (!AESmoothFadeThread.RequestFade(m_pDirectSoundBuffer, m_Volume, -2, false)) {
const auto dwVolume = static_cast<LONG>(m_Volume * 100.0F);
m_pDirectSoundBuffer->SetVolume(dwVolume);
}
}

View File

@ -6,33 +6,38 @@
#include "AEAudioUtility.h"
//! Stereo channel FX Param EQ presets [0x8CBA70]
static inline DSFXParamEq s_FXParamEqPresets[3][2]{
{{ 0.0f, 0.0f, 0.0f }, { 0.f, 0.0f, 0.0f }}, // Preset 1
{{ 80.f, 30.f, 4.0f }, { 180.f, 30.f, 1.5f }}, // Preset 2
{{ 80.f, 36.f, -15.f }, { 80.f, 36.f, -15.f }}, // Preset 3
static inline DSFXParamEq s_FXParamEqPresets[(+eBassSetting::NUM)][2]{
{{ 0.0f, 0.0f, 0.0f }, { 0.f, 0.0f, 0.0f }}, // Preset NORMAL [Unused]
{{ 80.f, 30.f, 4.0f }, { 180.f, 30.f, 1.5f }}, // Preset BOOST
{{ 80.f, 36.f, -15.f }, { 80.f, 36.f, -15.f }}, // Preset CUT
};
// 0x4F2200
CAEStreamingChannel::~CAEStreamingChannel() {
DirectSoundBufferFadeToSilence();
m_nState = StreamingChannelState::Stopping;
m_nState = StreamingChannelState::Stopping;
m_lStoppingFrameCount = 0;
if (m_pDirectSoundBuffer8)
if (m_pDirectSoundBuffer8) {
m_pDirectSoundBuffer8->SetFX(0, nullptr, nullptr);
}
if (m_pSilenceBuffer)
if (m_pSilenceBuffer) {
std::exchange(m_pSilenceBuffer, nullptr)->Release();
}
if (m_pDirectSoundBuffer)
if (m_pDirectSoundBuffer) {
std::exchange(m_pDirectSoundBuffer, nullptr)->Release();
}
if (m_pStreamingDecoder)
if (m_pStreamingDecoder) {
delete std::exchange(m_pStreamingDecoder, nullptr);
}
if (m_pNextStreamingDecoder)
if (m_pNextStreamingDecoder) {
delete std::exchange(m_pNextStreamingDecoder, nullptr);
}
}
// 0x4F22F0
@ -107,10 +112,11 @@ void CAEStreamingChannel::SetReady() {
}
// 0x4F1F30
void CAEStreamingChannel::SetBassEQ(uint8 mode, float gain) {
if (mode == 0) {
if (m_bEQEnabled)
void CAEStreamingChannel::SetBassEQ(eBassSetting mode, float gain) {
if (mode == eBassSetting::NORMAL) {
if (m_bEQEnabled) {
RemoveFX();
}
return;
}
@ -118,18 +124,18 @@ void CAEStreamingChannel::SetBassEQ(uint8 mode, float gain) {
return;
}
for (auto i = 0; i < 2; i++) {
for (auto ch = 0; ch < 2; ch++) {
IDirectSoundFXParamEq* fxEqParam;
if (FAILED(m_pDirectSoundBuffer8->GetObjectInPath(
GUID_All_Objects,
i,
ch,
IID_IDirectSoundFXParamEq,
reinterpret_cast<LPVOID*>(&fxEqParam)
))) {
continue;
}
DSFXParamEq savedFxExParam{ s_FXParamEqPresets[mode][i] };
DSFXParamEq savedFxExParam{ s_FXParamEqPresets[(+mode)][ch] };
savedFxExParam.fGain *= gain;
VERIFY(SUCCEEDED(fxEqParam->SetAllParameters(&savedFxExParam)));
fxEqParam->Release();
@ -156,8 +162,8 @@ void CAEStreamingChannel::SetFrequencyScalingFactor(float factor) {
m_pDirectSoundBuffer->SetVolume(-10'000);
m_pDirectSoundBuffer->Play(0, 0, m_bLooped ? DSBPLAY_LOOPING : 0);
if (!AESmoothFadeThread.RequestFade(m_pDirectSoundBuffer, m_fVolume, 35, true))
m_pDirectSoundBuffer->SetVolume(static_cast<int32>(m_fVolume * 100.0f));
if (!AESmoothFadeThread.RequestFade(m_pDirectSoundBuffer, m_Volume, 35, true))
m_pDirectSoundBuffer->SetVolume(static_cast<int32>(m_Volume * 100.0f));
m_nState = StreamingChannelState::Started;
}
@ -452,7 +458,7 @@ void CAEStreamingChannel::Play(int16 startOffsetMs, int8 soundFlags, float freqF
}
m_nState = StreamingChannelState::Started;
m_pDirectSoundBuffer->SetVolume(static_cast<int32>(m_fVolume * 100.0f));
m_pDirectSoundBuffer->SetVolume(static_cast<int32>(m_Volume * 100.0f));
m_pDirectSoundBuffer->Play(0, 0, DSBPLAY_LOOPING);
}

View File

@ -64,7 +64,7 @@ public:
int32 GetPlayingTrackID();
void SetNextStream(CAEStreamingDecoder* decoder);
uint32 FillBuffer(void* buffer, uint32 size);
void SetBassEQ(uint8 mode, float gain);
void SetBassEQ(eBassSetting mode, float gain);
void SetReady();
void Stop(bool bUpdateState);
void PrepareStream(CAEStreamingDecoder* stream, int8 arg2, uint32 audioBytes);

View File

@ -123,7 +123,7 @@ void CAEMP3BankLoader::UpdateVirtualChannels(tVirtualChannelSettings* settings,
for (auto i = 0u; i < std::size(settings->BankSlotIDs); i++) {
const auto sfx = settings->SoundIDs[i];
const auto slotID = settings->BankSlotIDs[i];
const auto slot = slotID != SND_BANK_SLOT_UNK
const auto slot = slotID != SND_BANK_SLOT_NONE
? &GetBankSlot(slotID)
: nullptr;
@ -346,3 +346,7 @@ void CAEMP3BankLoader::Service() {
}
}
}
CAEBankSlot& CAEMP3BankLoader::GetBankSlot(eSoundBankSlot slot) const {
return m_BankSlots[slot];
}

View File

@ -6,7 +6,7 @@ struct tVirtualChannelSettings {
eSoundID SoundIDs[300]{};
tVirtualChannelSettings() {
rng::fill(BankSlotIDs, SND_BANK_SLOT_UNK);
rng::fill(BankSlotIDs, SND_BANK_SLOT_NONE);
rng::fill(SoundIDs, -1);
}
};
@ -32,6 +32,8 @@ public:
void LoadSound(eSoundBank bankId, eSoundID soundId, eSoundBankSlot bankSlot);
void Service();
// notsa
CAEBankSlot& GetBankSlot(eSoundBankSlot slot) const;
private:
void AddRequest(eSoundBank bank, eSoundBankSlot slot, std::optional<eSoundID> sound);

View File

@ -256,11 +256,11 @@ void CAEAmbienceTrackManager::UpdateAmbienceTrackAndVolume() {
AudioEngine.StopRadio(nullptr, false);
}
} else {
AudioEngine.StartRadio(m_AmbienceRadioStation, 2);
AudioEngine.StartRadio(m_AmbienceRadioStation, eBassSetting::CUT);
}
} else if (prevAmbienceRadioStation != RADIO_INVALID) { //>0x4D71E5 - Radio was running previously, but isn't anymore, so stop it
if (AudioEngine.IsRadioOn()) {
AudioEngine.StopRadio(0, 0);
AudioEngine.StopRadio(nullptr, false);
}
} else if (AudioEngine.IsRadioOn()) { // 0x4D720A
if (m_OverrideRadio) {
@ -286,7 +286,7 @@ void CAEAmbienceTrackManager::UpdateAmbienceTrackAndVolume() {
} else {
StopAmbienceTrack();
if (m_LastAmbienceOverrodeRadio || AudioEngine.IsVehicleRadioActive()) {
AudioEngine.StartRadio(AudioEngine.GetCurrentRadioStationID(), 0);
AudioEngine.StartRadio(AudioEngine.GetCurrentRadioStationID(), eBassSetting::NORMAL);
}
m_FreqFactor = 1.f;
}
@ -317,9 +317,9 @@ void CAEAmbienceTrackManager::UpdateAmbienceTrackAndVolume() {
} else if (m_RequestedSettings.TrackID != 174) { // 0x4D73AE
FadeOutAndStop();
} else { // 0x4D73E7
m_Volume = stepto(m_Volume, volume, 1.f);
m_Volume = notsa::step_to(m_Volume, volume, 1.f);
}
m_FreqFactor = stepto(m_FreqFactor, CWeather::UnderWaterness < 0.5f ? 1.f : 0.0625f, 0.25f);
m_FreqFactor = notsa::step_to(m_FreqFactor, CWeather::UnderWaterness < 0.5f ? 1.f : 0.0625f, 0.25f);
} else if (specialTrackId != m_SpecialMissionAmbienceTrackID) { // 0x4D7250
if (m_AmbienceStatus == 8) {
m_RequestedSettings.TrackID = specialTrackId;

View File

@ -55,8 +55,8 @@ void CAERadioTrackManager::InjectHooks() {
RH_ScopedInstall(AddAdvertIndexToHistory, 0x4E9760);
RH_ScopedInstall(AddIdentIndexToHistory, 0x4E9720);
RH_ScopedInstall(AddMusicTrackIndexToHistory, 0x4E96C0);
RH_ScopedOverloadedInstall(StartRadio, "manual", 0x4EB3C0, void (CAERadioTrackManager::*)(eRadioID, int8, float, uint8));
RH_ScopedOverloadedInstall(StartRadio, "with-settings", 0x4EB550, void (CAERadioTrackManager::*)(tVehicleAudioSettings*));
RH_ScopedOverloadedInstall(StartRadio, "manual", 0x4EB3C0, void (CAERadioTrackManager::*)(eRadioID, eBassSetting, float, bool));
RH_ScopedOverloadedInstall(StartRadio, "with-settings", 0x4EB550, void (CAERadioTrackManager::*)(const tVehicleAudioSettings&));
RH_ScopedInstall(CheckForStationRetuneDuringPause, 0x4EB890);
RH_ScopedInstall(TrackRadioStation, 0x4EAC30, { .reversed = false });
RH_ScopedInstall(ChooseTracksForStation, 0x4EB180);
@ -117,7 +117,7 @@ bool CAERadioTrackManager::Initialise(int32 channelId) {
// 0x4E8330
void CAERadioTrackManager::InitialiseRadioStationID(eRadioID id) {
m_RequestedSettings.m_nCurrentRadioStation = m_ActiveSettings.m_nCurrentRadioStation = id;
m_RequestedSettings.StationID = m_ActiveSettings.StationID = id;
}
// 0x4E7F80
@ -195,7 +195,7 @@ int32* CAERadioTrackManager::GetRadioStationListenTimes() {
// 0x4E83F0
eRadioID CAERadioTrackManager::GetCurrentRadioStationID() const {
return m_RequestedSettings.m_nCurrentRadioStation == RADIO_INVALID ? RADIO_OFF : m_RequestedSettings.m_nCurrentRadioStation;
return m_RequestedSettings.StationID == RADIO_INVALID ? RADIO_OFF : m_RequestedSettings.StationID;
}
// 0x4E82E0
@ -204,22 +204,22 @@ void CAERadioTrackManager::SetRadioAutoRetuneOnOff(bool enable) {
}
// 0x4E82F0
void CAERadioTrackManager::SetBassSetting(int8 nBassSet, float fBassGrain) {
m_RequestedSettings.m_fBassGain = m_ActiveSettings.m_fBassGain = fBassGrain;
m_RequestedSettings.m_nBassSet = m_ActiveSettings.m_nBassSet = nBassSet;
AEAudioHardware.SetBassSetting(m_bBassEnhance ? nBassSet : 0, fBassGrain);
void CAERadioTrackManager::SetBassSetting(eBassSetting bassSetting, float bassGrain) {
m_RequestedSettings.BassGain = m_ActiveSettings.BassGain = bassGrain;
m_RequestedSettings.BassSetting = m_ActiveSettings.BassSetting = bassSetting;
AEAudioHardware.SetBassSetting(m_bBassEnhance ? bassSetting : eBassSetting::NORMAL, bassGrain);
}
// 0x4E9DB0
void CAERadioTrackManager::SetBassEnhanceOnOff(bool enable) {
m_bBassEnhance = enable;
if (m_nMode == eRadioTrackMode::RADIO_PLAYING) {
m_RequestedSettings.m_nBassSet = m_ActiveSettings.m_nBassSet;
m_RequestedSettings.m_fBassGain = m_ActiveSettings.m_fBassGain;
m_RequestedSettings.BassSetting = m_ActiveSettings.BassSetting;
m_RequestedSettings.BassGain = m_ActiveSettings.BassGain;
if (enable) {
AEAudioHardware.SetBassSetting(m_ActiveSettings.m_nBassSet, m_ActiveSettings.m_fBassGain);
AEAudioHardware.SetBassSetting(m_ActiveSettings.BassSetting, m_ActiveSettings.BassGain);
} else {
AEAudioHardware.SetBassSetting(0, m_ActiveSettings.m_fBassGain);
AEAudioHardware.SetBassSetting(eBassSetting::NORMAL, m_ActiveSettings.BassGain);
}
}
}
@ -262,7 +262,7 @@ void CAERadioTrackManager::DisplayRadioStationName() {
}
if (CTimer::GetTimeInMS() < m_nTimeToDisplayRadioName) {
int station = m_nStationsListed + m_RequestedSettings.m_nCurrentRadioStation;
int station = m_nStationsListed + m_RequestedSettings.StationID;
if (station) {
if (station >= RADIO_COUNT) {
station -= RADIO_COUNT - 1;
@ -317,10 +317,10 @@ void CAERadioTrackManager::GetRadioStationNameKey(eRadioID id, char* outStr) {
// 0x4E9800
bool CAERadioTrackManager::IsVehicleRadioActive() {
if (const auto opts = CAEVehicleAudioEntity::StaticGetPlayerVehicleAudioSettingsForRadio()) {
switch (opts->m_nRadioType) {
case RADIO_CIVILIAN:
case RADIO_EMERGENCY:
case RADIO_UNKNOWN:
switch (opts->RadioType) {
case AE_RT_CIVILIAN:
case AE_RT_EMERGENCY:
case AE_RT_UNKNOWN:
return true;
default:
break;
@ -443,26 +443,26 @@ void CAERadioTrackManager::CheckForStationRetune() {
// 0x4EB890
void CAERadioTrackManager::CheckForStationRetuneDuringPause() {
if (m_ActiveSettings.m_nCurrentRadioStation == RADIO_EMERGENCY_AA && IsRadioOn() || m_iRadioStationMenuRequest <= RADIO_INVALID)
if (m_ActiveSettings.StationID == RADIO_EMERGENCY_AA && IsRadioOn() || m_iRadioStationMenuRequest <= RADIO_INVALID)
return;
if (m_iRadioStationMenuRequest != RADIO_OFF) {
if (m_ActiveSettings.m_nCurrentRadioStation == RADIO_OFF) {
if (m_ActiveSettings.StationID == RADIO_OFF) {
AudioEngine.ReportFrontendAudioEvent(AE_FRONTEND_RADIO_CLICK_ON);
m_ActiveSettings.m_nCurrentRadioStation = RADIO_INVALID;
m_ActiveSettings.StationID = RADIO_INVALID;
} else {
AudioEngine.StopRadio(nullptr, true);
}
AudioEngine.ReportFrontendAudioEvent(AE_FRONTEND_RADIO_RETUNE_START);
if (CTimer::GetTimeInMSPauseMode() > m_nRetuneStartedTime + 700u) {
StartRadio((eRadioID)m_iRadioStationMenuRequest, m_ActiveSettings.m_nBassSet, m_ActiveSettings.m_fBassGain, 0);
StartRadio((eRadioID)m_iRadioStationMenuRequest, m_ActiveSettings.BassSetting, m_ActiveSettings.BassGain, 0);
m_iRadioStationMenuRequest = RADIO_INVALID;
}
} else {
AudioEngine.ReportFrontendAudioEvent(AE_FRONTEND_RADIO_CLICK_OFF);
AudioEngine.ReportFrontendAudioEvent(AE_FRONTEND_RADIO_RETUNE_STOP);
StartRadio(RADIO_OFF, m_ActiveSettings.m_nBassSet, m_ActiveSettings.m_fBassGain, 0);
StartRadio(RADIO_OFF, m_ActiveSettings.BassSetting, m_ActiveSettings.BassGain, 0);
m_iRadioStationMenuRequest = RADIO_INVALID;
}
}
@ -533,8 +533,8 @@ void CAERadioTrackManager::UpdateRadioVolumes() {
volume = volume - 20.0f;
}
if (m_bBassEnhance && m_ActiveSettings.m_nBassSet) {
switch (m_ActiveSettings.m_nBassSet) {
if (m_bBassEnhance && m_ActiveSettings.m_BassSetting) {
switch (m_ActiveSettings.m_BassSetting) {
case 1:
volume -= 2.0f;
break;
@ -554,18 +554,18 @@ void CAERadioTrackManager::PlayRadioAnnouncement(uint32) {
}
// 0x4EB550
void CAERadioTrackManager::StartRadio(tVehicleAudioSettings* settings) {
void CAERadioTrackManager::StartRadio(const tVehicleAudioSettings& settings) {
// plugin::CallMethod<0x4EB550, CAERadioTrackManager*, tVehicleAudioSettings*>(this, settings);
if (CReplay::Mode == MODE_PLAYBACK)
return;
if (settings->m_nRadioType == RADIO_EMERGENCY) {
StartRadio(RADIO_EMERGENCY_AA, settings->m_nBassSetting, settings->m_fBassEq, 0);
if (settings.RadioType == AE_RT_EMERGENCY) {
StartRadio(RADIO_EMERGENCY_AA, settings.BassSetting, settings.BassFactor, 0);
return;
}
if (settings->m_nRadioType != RADIO_CIVILIAN)
if (settings.RadioType != AE_RT_CIVILIAN)
return;
const bool needsRetune = [&] {
@ -573,7 +573,7 @@ void CAERadioTrackManager::StartRadio(tVehicleAudioSettings* settings) {
return false;
const auto savedId = m_nSavedRadioStationId;
if (savedId < 0 || savedId == settings->m_nRadioID || savedId == RADIO_OFF || savedId == RADIO_EMERGENCY_AA)
if (savedId < 0 || savedId == settings.RadioStation || savedId == RADIO_OFF || savedId == RADIO_EMERGENCY_AA)
return false;
if (CTimer::GetTimeInMS() > m_nSavedTimeMs + 60'000)
@ -597,21 +597,20 @@ void CAERadioTrackManager::StartRadio(tVehicleAudioSettings* settings) {
if (needsRetune) {
AudioEngine.ReportFrontendAudioEvent(AE_FRONTEND_RADIO_RETUNE_START);
StartRadio((eRadioID)m_nSavedRadioStationId, settings->m_nBassSetting, settings->m_fBassEq, 0);
StartRadio((eRadioID)m_nSavedRadioStationId, settings.BassSetting, settings.BassFactor, 0);
} else {
StartRadio(settings->m_nRadioID, settings->m_nBassSetting, settings->m_fBassEq, 0);
StartRadio(settings.RadioStation, settings.BassSetting, settings.BassFactor, 0);
}
}
// 0x4EB3C0
void CAERadioTrackManager::StartRadio(eRadioID id, int8 bassValue, float bassGain, uint8 a5) {
// plugin::CallMethod<0x4EB3C0, CAERadioTrackManager*, int8, int8, float, uint8>(this, id, bassValue, bassGain, a5);
void CAERadioTrackManager::StartRadio(eRadioID id, eBassSetting bassSetting, float bassGain, bool skipTrack) {
id = std::min(id, RADIO_OFF);
if (CTimer::GetIsPaused()) {
m_bEnabledInPauseMode = true;
if (IsRadioOn() && id == m_ActiveSettings.m_nCurrentRadioStation) {
if (IsRadioOn() && id == m_ActiveSettings.StationID) {
m_aRadioState[id].m_iTimeInPauseModeInMs = CTimer::GetTimeInMSPauseMode();
return;
}
@ -625,33 +624,30 @@ void CAERadioTrackManager::StartRadio(eRadioID id, int8 bassValue, float bassGai
AudioEngine.StopAmbienceTrack(false);
}
m_RequestedSettings.m_nCurrentRadioStation = id;
m_RequestedSettings.m_nBassSet = bassValue;
m_RequestedSettings.m_fBassGain = bassGain;
auto* const rs = &m_RequestedSettings;
rs->StationID = id;
rs->BassSetting = bassSetting;
rs->BassGain = bassGain;
if (id == RADIO_OFF) {
m_RequestedSettings.Reset();
} else if (m_aRadioState[id].m_iTimeInMs < 0 || !TrackRadioStation(id, a5)) {
ChooseTracksForStation(m_RequestedSettings.m_nCurrentRadioStation);
m_RequestedSettings.m_iTrackPlayTime = CAEAudioUtility::GetRandomNumberInRange(0, 300'000);
rs->Reset();
} else if (m_aRadioState[id].m_iTimeInMs < 0 || !TrackRadioStation(id, skipTrack)) {
ChooseTracksForStation(rs->StationID);
rs->PlayTime = CAEAudioUtility::GetRandomNumberInRange(0, 300'000);
}
m_bInitialised = true;
switch (m_nMode) {
case eRadioTrackMode::RADIO_STARTING:
case eRadioTrackMode::RADIO_WAITING_TO_PLAY:
case eRadioTrackMode::RADIO_PLAYING:
m_nMode = eRadioTrackMode::RADIO_STOPPING;
break;
default:
break;
}
m_aRadioState[m_RequestedSettings.m_nCurrentRadioStation].m_iTimeInPauseModeInMs = -1;
m_aRadioState[rs->StationID].m_iTimeInPauseModeInMs = -1;
m_bInitialised = true;
}
// 0x4EAC30
bool CAERadioTrackManager::TrackRadioStation(eRadioID id, uint8 a2) {
return plugin::CallMethodAndReturn<bool, 0x4EAC30, CAERadioTrackManager*, int8, uint8>(this, id, a2);
bool CAERadioTrackManager::TrackRadioStation(eRadioID id, bool skipTrack) {
return plugin::CallMethodAndReturn<bool, 0x4EAC30, CAERadioTrackManager*, int8, uint8>(this, id, skipTrack);
}
// 0x4EA670
@ -736,7 +732,7 @@ void CAERadioTrackManager::ChooseTracksForStation(eRadioID id) {
}
QueueUpTracksForStation(id, &trackCount, TYPE_OUTRO, m_RequestedSettings);
AddMusicTrackIndexToHistory(id, m_RequestedSettings.m_aTrackIndexes[trackCount - 1]);
AddMusicTrackIndexToHistory(id, m_RequestedSettings.TrackIndices[trackCount - 1]);
if (id == RADIO_EMERGENCY_AA) {
QueueUpTracksForStation(id, &trackCount, TYPE_DJ_BANTER, m_RequestedSettings);
@ -798,25 +794,14 @@ void CAERadioTrackManager::CheckForPause() {
if (CTimer::GetIsPaused()) {
m_bPauseMode = true;
AEAudioHardware.SetChannelFrequencyScalingFactor(m_HwClientHandle, 0, m_bEnabledInPauseMode ? 1.0f : 0.0f);
return;
}
// todo: See CAEVehicleAudioEntity::Terminate:437 m_nRadioType.
tVehicleAudioSettings* settings = CAEVehicleAudioEntity::StaticGetPlayerVehicleAudioSettingsForRadio();
const bool isRadioTypeOrdinary = settings && [radioType = settings->m_nRadioType]{
switch (radioType) {
case RADIO_CIVILIAN:
case RADIO_EMERGENCY:
case RADIO_UNKNOWN:
return true;
default:
return false;
}
}();
if (isRadioTypeOrdinary || CAudioEngine::IsAmbienceRadioActive()) {
} else if (
notsa::contains({
AE_RT_CIVILIAN,
AE_RT_EMERGENCY,
AE_RT_UNKNOWN
}, CAEVehicleAudioEntity::StaticGetPlayerVehicleAudioSettingsForRadio()->RadioType)
|| CAudioEngine::IsAmbienceRadioActive()
) {
m_bPauseMode = false;
AEAudioHardware.SetChannelFrequencyScalingFactor(m_HwClientHandle, 0, 1.0f);
} else {

View File

@ -20,48 +20,47 @@ enum {
struct tRadioSettings {
static constexpr size_t NUM_TRACKS = 5u;
std::array<int32, NUM_TRACKS> m_aTrackQueue{-1};
int32 m_iCurrentTrackID{-1};
int32 m_iPrevTrackID{-1};
int32 m_iTrackPlayTime{0};
int32 m_iTrackLengthMs{0};
int8 m_nTrackFlags{2}; // TODO: enum
eRadioID m_nCurrentRadioStation{RADIO_OFF}; // NOTSA init value.
int8 m_nBassSet{0};
float m_fBassGain{}; // unk. init
std::array<int8, NUM_TRACKS> m_aTrackTypes{TYPE_NONE};
int8 m_iCurrentTrackType{TYPE_NONE};
int8 m_iPrevTrackType{TYPE_NONE};
std::array<int8, NUM_TRACKS> m_aTrackIndexes{-1};
int8 m_iCurrentTrackIndex{-1};
int8 m_iPrevTrackIndex{-1};
tRadioSettings(eRadioID currentStation = RADIO_OFF)
: m_nCurrentRadioStation(currentStation)
{}
tRadioSettings(eRadioID currentStation = RADIO_OFF) :
StationID(currentStation)
{
rng::fill(TrackQueue, -1);
rng::fill(TrackTypes, TYPE_NONE);
rng::fill(TrackIndices, -1);
}
void Reset() {
for (auto i = 0u; i < std::size(m_aTrackQueue); i++) {
m_aTrackQueue[i] = -1;
m_aTrackTypes[i] = TYPE_NONE;
m_aTrackIndexes[i] = -1;
}
*this = {};
}
void SwitchToNextTrack() {
m_iPrevTrackID = m_aTrackQueue.front();
m_iPrevTrackType = m_aTrackTypes.front();
m_iPrevTrackIndex = m_aTrackIndexes.front();
PrevTrackID = TrackQueue.front();
PrevTrackType = TrackTypes.front();
PrevTrackIdx = TrackIndices.front();
const auto Rotate = [](auto& arr, auto invalidValue) {
std::copy(arr.begin() + 1, arr.end(), arr.begin());
arr.back() = invalidValue;
};
Rotate(m_aTrackQueue, -1);
Rotate(m_aTrackTypes, TYPE_NONE);
Rotate(m_aTrackIndexes, -1);
Rotate(TrackQueue, -1);
Rotate(TrackTypes, TYPE_NONE);
Rotate(TrackIndices, -1);
}
std::array<int32, NUM_TRACKS> TrackQueue{ -1 };
int32 CurrTrackID{ -1 };
int32 PrevTrackID{ -1 };
int32 PlayTime{ 0 };
int32 TrackLengthMs{ 0 };
int8 TrackFlags{ 2 }; // TODO: enum
eRadioID StationID{ RADIO_OFF }; // NOTSA init value.
eBassSetting BassSetting{ eBassSetting::NORMAL };
float BassGain{}; // unk. init
std::array<int8, NUM_TRACKS> TrackTypes{ TYPE_NONE };
int8 CurrTrackType{ TYPE_NONE };
int8 PrevTrackType{ TYPE_NONE };
std::array<int8, NUM_TRACKS> TrackIndices{ -1 };
int8 CurrTrackIdx{ -1 }; //!< Index into `TrackIndices`
int8 PrevTrackIdx{ -1 }; //!< Index into `TrackIndices`
};
VALIDATE_SIZE(tRadioSettings, 0x3C);
@ -220,7 +219,7 @@ public:
int32* GetRadioStationListenTimes();
void SetRadioAutoRetuneOnOff(bool enable);
void SetBassEnhanceOnOff(bool enable);
void SetBassSetting(int8 nBassSet, float fBassGrain);
void SetBassSetting(eBassSetting bassSetting, float bassGrain);
void RetuneRadio(eRadioID radioId);
void DisplayRadioStationName();
@ -231,8 +230,8 @@ public:
void StartTrackPlayback();
void UpdateRadioVolumes();
void PlayRadioAnnouncement(uint32);
void StartRadio(eRadioID id, int8 bassValue, float bassGain, uint8 a5);
void StartRadio(tVehicleAudioSettings* settings);
void StartRadio(eRadioID id, eBassSetting bassSetting, float bassGain, bool skipTrack);
void StartRadio(const tVehicleAudioSettings& settings);
void StopRadio(tVehicleAudioSettings* settings, bool bDuringPause);
void Service(int32 playTime);
@ -261,7 +260,7 @@ protected:
void CheckForPause();
bool QueueUpTracksForStation(eRadioID id, int8* iTrackCount, int8 radioState, tRadioSettings& settings);
bool TrackRadioStation(eRadioID id, uint8 a2);
bool TrackRadioStation(eRadioID id, bool skipTrack);
};
VALIDATE_SIZE(CAERadioTrackManager, 0x370);

View File

@ -46,8 +46,8 @@ bool CAESoundManager::Initialise() {
m_PrioritisedSoundList = new tSoundReference[m_NumAllocatedPhysicalChannels];
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
sound.m_nIsUsed = 0;
sound.m_IsPhysicallyPlaying = 0;
sound.m_IsInUse = false;
sound.m_IsPhysicallyPlaying = false;
}
std::fill_n(m_PhysicallyPlayingSoundList, m_NumAllocatedPhysicalChannels, -1);
@ -75,7 +75,7 @@ void CAESoundManager::Terminate() {
// 0x4EF4D0
void CAESoundManager::Reset() {
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
if (!sound.IsUsed()) {
if (!sound.IsActive()) {
continue;
}
@ -119,17 +119,17 @@ void CAESoundManager::Service() {
// 0x4F011C - Initialize sounds that are using percentage specified start positions
for (auto&& [i, sound] : rngv::enumerate(m_VirtuallyPlayingSoundList)) {
if (!sound.IsUsed() || !sound.WasServiced() || !sound.GetStartPercentage()) {
if (!sound.IsActive() || !sound.IsAudioHardwareAware() || !sound.GetPlayTimeIsPercentage()) {
continue;
}
sound.SetIndividualEnvironment(eSoundEnvironment::SOUND_START_PERCENTAGE, false);
sound.SetFlags(eSoundEnvironment::SOUND_START_PERCENTAGE, false);
if (sound.m_IsPhysicallyPlaying) {
continue;
}
//sound.m_nCurrentPlayPosition *= uint16(static_cast<float>(m_aSoundLengths[i]) / 100.0F);
sound.m_nCurrentPlayPosition = static_cast<uint16>((float)(sound.m_nCurrentPlayPosition * m_VirtualChannelSoundLengths[i]) / 100.0f);
//sound.m_PlayTime *= uint16(static_cast<float>(m_aSoundLengths[i]) / 100.0F);
sound.m_PlayTime = static_cast<uint16>((float)(sound.m_PlayTime * m_VirtualChannelSoundLengths[i]) / 100.0f);
}
// 0x4F016D - Stop sounds that turned inactive
@ -138,15 +138,15 @@ void CAESoundManager::Service() {
continue;
}
auto& sound = m_VirtuallyPlayingSoundList[ref];
sound.m_nCurrentPlayPosition = m_ChannelPosition[i];
if (sound.GetPlayingState() != eSoundState::SOUND_ACTIVE) {
sound.m_PlayTime = m_ChannelPosition[i];
if (sound.m_HasRequestedStopped) {
AEAudioHardware.StopSound(m_AudioHardwareHandle, i);
}
}
// 0x4F01E4 - Update sounds playtime
for (auto&& [i, sound] : rngv::enumerate(m_VirtuallyPlayingSoundList)) {
if (!sound.IsUsed() || !sound.WasServiced() || sound.m_FrameDelay) {
if (!sound.IsActive() || !sound.IsAudioHardwareAware() || sound.m_FrameDelay) {
continue;
}
auto usedProgress = CAESoundManager::IsSoundPaused(sound) ? 0 : timeSinceLastUpdate;
@ -162,7 +162,7 @@ void CAESoundManager::Service() {
// 0x4F0329 - Mark sounds that ended as finished
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
if (!sound.IsUsed() || !sound.WasServiced() || sound.m_nCurrentPlayPosition != -1) {
if (!sound.IsActive() || !sound.IsAudioHardwareAware() || sound.m_PlayTime != -1) {
continue;
}
sound.SoundHasFinished();
@ -170,10 +170,10 @@ void CAESoundManager::Service() {
// 0x4F03E5, 0x4F040D - Update sounds positions and volumes
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
if (!sound.IsUsed()) {
if (!sound.IsActive()) {
continue;
}
sound.UpdateParameters(sound.m_nCurrentPlayPosition);
sound.UpdateParameters(sound.m_PlayTime);
sound.CalculateVolume();
}
@ -183,7 +183,7 @@ void CAESoundManager::Service() {
if (ref == -1) {
continue;
}
if (!m_VirtuallyPlayingSoundList[ref].GetUncancellable()) {
if (!m_VirtuallyPlayingSoundList[ref].IsUnancellable()) {
continue;
}
m_PrioritisedSoundList[numPrioritisedSounds++] = ref;
@ -191,10 +191,10 @@ void CAESoundManager::Service() {
// Check if we need to insert any of the already playing sounds into the list
for (auto&& [i, sound] : rngv::enumerate(m_VirtuallyPlayingSoundList)) {
if (!sound.IsUsed()) {
if (!sound.IsActive()) {
continue;
}
if (sound.m_IsPhysicallyPlaying && sound.GetUncancellable()) {
if (sound.m_IsPhysicallyPlaying && sound.IsUnancellable()) {
continue;
}
if (sound.m_FrameDelay != 0) {
@ -281,7 +281,7 @@ void CAESoundManager::Service() {
CAEAudioHardwarePlayFlags flags{};
flags.CopyFromAESound(sound);
AEAudioHardware.PlaySound(m_AudioHardwareHandle, chN, sound.m_nSoundIdInSlot, sound.m_nBankSlotId, sound.m_nCurrentPlayPosition, flags.m_nFlags, sound.m_fSpeed);
AEAudioHardware.PlaySound(m_AudioHardwareHandle, chN, sound.m_SoundID, sound.m_BankSlot, sound.m_PlayTime, flags.m_nFlags, sound.GetSpeed());
AEAudioHardware.SetChannelVolume(m_AudioHardwareHandle, chN, sound.m_ListenerVolume, 0);
AEAudioHardware.SetChannelPosition(m_AudioHardwareHandle, chN, sound.GetRelativePosition(), 0);
AEAudioHardware.SetChannelFrequencyScalingFactor(m_AudioHardwareHandle, chN, freqFactor);
@ -295,7 +295,7 @@ void CAESoundManager::Service() {
}
auto& sound = m_VirtuallyPlayingSoundList[ref];
if (!sound.IsUsed()) {
if (!sound.IsActive()) {
continue;
}
@ -316,11 +316,11 @@ void CAESoundManager::Service() {
// 0x4F0B05
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
if (!sound.IsUsed()) {
if (!sound.IsActive()) {
continue;
}
sound.m_bWasServiced = true;
sound.m_IsAudioHardwareAware = true;
if (sound.m_FrameDelay > 0 && !CAESoundManager::IsSoundPaused(sound)) {
--sound.m_FrameDelay;
}
@ -334,8 +334,8 @@ CAESound* CAESoundManager::RequestNewSound(CAESound* pSound) {
if (s) {
*s = *pSound;
pSound->UnregisterWithPhysicalEntity();
s->NewVPSLentry();
AEAudioHardware.RequestVirtualChannelSoundInfo((uint16)sidx, s->m_nSoundIdInSlot, s->m_nBankSlotId);
s->NewVPSLEntry();
AEAudioHardware.RequestVirtualChannelSoundInfo((uint16)sidx, s->m_SoundID, s->m_BankSlot);
}
return s;
}
@ -359,7 +359,7 @@ CAESound* CAESoundManager::PlaySound(tSoundPlayParams p) {
p.FrequencyVariance,
p.PlayTime
);
s.m_nEvent = p.EventID;
s.m_Event = p.EventID;
s.m_ClientVariable = p.ClientVariable;
if (p.Flags & SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY) {
s.RegisterWithPhysicalEntity(p.RegisterWithEntity);
@ -371,7 +371,7 @@ CAESound* CAESoundManager::PlaySound(tSoundPlayParams p) {
int16 CAESoundManager::AreSoundsPlayingInBankSlot(int16 bankSlot) {
auto nPlaying = eSoundPlayingStatus::SOUND_NOT_PLAYING;
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
if (!sound.IsUsed() || sound.m_nBankSlotId != bankSlot) {
if (!sound.IsActive() || sound.m_BankSlot != bankSlot) {
continue;
}
if (sound.m_IsPhysicallyPlaying) {
@ -386,7 +386,7 @@ int16 CAESoundManager::AreSoundsPlayingInBankSlot(int16 bankSlot) {
int16 CAESoundManager::AreSoundsOfThisEventPlayingForThisEntity(int16 eventId, CAEAudioEntity* audioEntity) {
auto nPlaying = eSoundPlayingStatus::SOUND_NOT_PLAYING;
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
if (!sound.IsUsed() || sound.m_nEvent != eventId || sound.m_pBaseAudio != audioEntity) {
if (!sound.IsActive() || sound.m_Event != eventId || sound.m_AudioEntity != audioEntity) {
continue;
}
if (sound.m_IsPhysicallyPlaying) {
@ -402,7 +402,7 @@ int16 CAESoundManager::AreSoundsOfThisEventPlayingForThisEntity(int16 eventId, C
int16 CAESoundManager::AreSoundsOfThisEventPlayingForThisEntityAndPhysical(int16 eventId, CAEAudioEntity* audioEntity, CPhysical* physical) {
bool nPlaying = eSoundPlayingStatus::SOUND_NOT_PLAYING;
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
if (!sound.IsUsed() || sound.m_nEvent != eventId || sound.m_pBaseAudio != audioEntity || sound.m_pPhysicalEntity != physical) {
if (!sound.IsActive() || sound.m_Event != eventId || sound.m_AudioEntity != audioEntity || sound.m_PhysicalEntity != physical) {
continue;
}
if (sound.m_IsPhysicallyPlaying) {
@ -417,7 +417,7 @@ int16 CAESoundManager::AreSoundsOfThisEventPlayingForThisEntityAndPhysical(int16
// 0x4EFB90
void CAESoundManager::CancelSoundsOfThisEventPlayingForThisEntity(int16 eventId, CAEAudioEntity* audioEntity) {
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
if (!sound.IsUsed() || sound.m_nEvent != eventId || sound.m_pBaseAudio != audioEntity) {
if (!sound.IsActive() || sound.m_Event != eventId || sound.m_AudioEntity != audioEntity) {
continue;
}
sound.StopSoundAndForget();
@ -427,7 +427,7 @@ void CAESoundManager::CancelSoundsOfThisEventPlayingForThisEntity(int16 eventId,
// 0x4EFBF0
void CAESoundManager::CancelSoundsOfThisEventPlayingForThisEntityAndPhysical(int16 eventId, CAEAudioEntity* audioEntity, CPhysical* physical) {
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
if (!sound.IsUsed() || sound.m_nEvent != eventId || sound.m_pBaseAudio != audioEntity || sound.m_pPhysicalEntity != physical) {
if (!sound.IsActive() || sound.m_Event != eventId || sound.m_AudioEntity != audioEntity || sound.m_PhysicalEntity != physical) {
continue;
}
sound.StopSoundAndForget();
@ -437,7 +437,7 @@ void CAESoundManager::CancelSoundsOfThisEventPlayingForThisEntityAndPhysical(int
// 0x4EFC60
void CAESoundManager::CancelSoundsInBankSlot(int16 bankSlot, bool bFullStop) {
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
if (!sound.IsUsed() || sound.m_nBankSlotId != bankSlot) {
if (!sound.IsActive() || sound.m_BankSlot != bankSlot) {
continue;
}
if (bFullStop) {
@ -451,7 +451,7 @@ void CAESoundManager::CancelSoundsInBankSlot(int16 bankSlot, bool bFullStop) {
// 0x4EFCD0
void CAESoundManager::CancelSoundsOwnedByAudioEntity(CAEAudioEntity* audioEntity, bool bFullStop) {
for (CAESound& sound : m_VirtuallyPlayingSoundList) {
if (!sound.IsUsed() || sound.m_pBaseAudio != audioEntity) {
if (!sound.IsActive() || sound.m_AudioEntity != audioEntity) {
continue;
}
if (bFullStop) {
@ -474,7 +474,7 @@ int16 CAESoundManager::GetVirtualChannelForPhysicalChannel(int16 physicalChannel
// NOTSA
CAESound* CAESoundManager::GetFreeSound(size_t* outIdx) {
for (auto&& [i, s] : rngv::enumerate(m_VirtuallyPlayingSoundList)) {
if (!s.IsUsed()) {
if (!s.IsActive()) {
if (outIdx) {
*outIdx = (size_t)i;
}

View File

@ -3,6 +3,8 @@
#include "AESound.h"
#include "Physical.h"
#undef PlaySound
static constexpr int32 MAX_NUM_SOUNDS = 300;
static constexpr int32 MAX_NUM_AUDIO_CHANNELS = 64;
@ -43,7 +45,7 @@ public:
CAESound* RequestNewSound(CAESound* pSound);
struct tSoundPlayParams {
int16 BankSlotID; //!< The slot to play the sound from (From the currently loaded bank (?))
eSoundBankSlot BankSlotID; //!< The slot to play the sound from
eSoundID SoundID; //!< The sound ID to play (From the specified bank slot)
CAEAudioEntity* AudioEntity; //!< The audio entity that requested this sound
CVector Pos; //!< The position
@ -54,7 +56,7 @@ public:
uint8 FrameDelay{ 0 }; //!< After how many frames the sound will be played
uint32 Flags{ 0 }; //!< See `eSoundEnvironment`
float FrequencyVariance{ 0.f }; //!< Random speed variance (?)
int16 PlayTime{ 0 }; //!< Where to start the sound
int16 PlayTime{ 0 }; //!< Where to start the sound (AKA `CurrentPlayPosition`)
// NOTSA Args //
CEntity* RegisterWithEntity{}; //!< The entity to register this sound with (Automatically adds the `SOUND_LIFESPAN_TIED_TO_PHYSICAL_ENTITY` flag)
@ -84,7 +86,7 @@ private:
public:
bool IsPaused() const { return CTimer::GetIsPaused() || m_IsManuallyPaused; }
bool IsSoundPaused(const CAESound& sound) const { return CAESoundManager::IsPaused() && !sound.GetUnpausable(); }
bool IsSoundPaused(const CAESound& sound) const { return CAESoundManager::IsPaused() && !sound.IsUnpausable(); }
};
VALIDATE_SIZE(CAESoundManager, 0x8CBC);

View File

@ -657,7 +657,7 @@ void CCarAI::UpdateCarAI(CVehicle* veh) {
if (sq(FindSwitchDistanceFar(veh)) < vehPlyrDist2DSq) { // 0x41DD4F | 0x41E13A
if (!CCarCtrl::JoinCarWithRoadSystemGotoCoors(veh, FindPlayerCoors(), true, false)) {
ap->m_nCarMission = MISSION_RAMPLAYER_FARAWAY;
veh->m_nHornCounter = 0;
veh->m_HornCounter = 0;
veh->vehicleFlags.bSirenOrAlarm = false;
}
if (veh->vehicleFlags.bIsLawEnforcer) {
@ -813,7 +813,7 @@ void CCarAI::UpdateCarAI(CVehicle* veh) {
if ((veh->GetPosition() - ap->m_TargetEntity->GetPosition()).SquaredMagnitude2D() >= sq(FindSwitchDistanceClose(veh))) {
veh->vehicleFlags.bSirenOrAlarm = false;
veh->m_nHornCounter = 0;
veh->m_HornCounter = 0;
CCarCtrl::JoinCarWithRoadSystem(veh);
}
@ -925,7 +925,7 @@ void CCarAI::UpdateCarAI(CVehicle* veh) {
}
} else if (!CCarCtrl::JoinCarWithRoadSystemGotoCoors(veh, FindPlayerCoors())) {
veh->vehicleFlags.bSirenOrAlarm = false;
veh->m_nHornCounter = 0;
veh->m_HornCounter = 0;
ap->SetCarMission(MISSION_APPROACHPLAYER_FARAWAY);
}
@ -1262,7 +1262,7 @@ void CCarAI::UpdateCarAI(CVehicle* veh) {
//> 0x4203C1
if (veh->vehicleFlags.bSirenOrAlarm && ((uint8)veh->m_nRandomSeed ^ (uint8)rand()) == 0xAD) {
veh->m_nHornCounter = 45;
veh->m_HornCounter = 45;
}
//> 0x4203F0 - Handle speed mult change based on time

View File

@ -54,7 +54,7 @@ void CCarEnterExit::AddInCarAnim(const CVehicle* vehicle, CPed* ped, bool bAsDri
const auto [grpId, animId] = [&]() -> std::pair<AssocGroupId, AnimationId> {
if (bAsDriver) { // Inverted
if (const auto data = const_cast<CVehicle*>(vehicle)->GetRideAnimData()) {
return { data->m_nAnimGroup, ANIM_ID_BIKE_RIDE };
return { data->AnimGroup, ANIM_ID_BIKE_RIDE };
} else if (vehicle->IsBoat()) {
if (vehicle->m_pHandlingData->m_bSitInBoat) {
return { ANIM_GROUP_DEFAULT, ANIM_ID_DRIVE_BOAT };
@ -66,7 +66,7 @@ void CCarEnterExit::AddInCarAnim(const CVehicle* vehicle, CPed* ped, bool bAsDri
return { ANIM_GROUP_DEFAULT, ANIM_ID_CAR_SIT };
} else {
if (const auto data = const_cast<CVehicle*>(vehicle)->GetRideAnimData()) {
return { data->m_nAnimGroup, ANIM_ID_BIKE_RIDE };
return { data->AnimGroup, ANIM_ID_BIKE_RIDE };
} else if (vehicle->vehicleFlags.bLowVehicle) {
return { ANIM_GROUP_DEFAULT, ANIM_ID_CAR_SITPLO };
}

View File

@ -430,3 +430,39 @@ uint32 CCarGenerator::CalcNextGen()
{
return CTimer::GetTimeInMS() + 4;
}
// notsa
CVehicle* CCarGenerator::CreateVehicle(eModelID model, eVehicleCreatedBy createdBy) {
const auto* mi = CModelInfo::GetModelInfo(model)->AsVehicleModelInfoPtr();
switch (const auto vt = mi->m_nVehicleType) {
case VEHICLE_TYPE_AUTOMOBILE:
return new CAutomobile{model, createdBy, true};
case VEHICLE_TYPE_MTRUCK:
return new CMonsterTruck{model, createdBy};
case VEHICLE_TYPE_QUAD:
return new CQuadBike{model, createdBy};
case VEHICLE_TYPE_HELI:
return new CHeli{model, createdBy};
case VEHICLE_TYPE_PLANE:
return new CPlane{model, createdBy};
case VEHICLE_TYPE_BOAT:
return new CBoat{model, createdBy};
case VEHICLE_TYPE_BIKE: {
auto* bike = new CBike{model, createdBy};
bike->bikeFlags.bOnSideStand = true;
return bike;
}
case VEHICLE_TYPE_BMX: {
auto* const bmx = new CBmx{model, createdBy};
bmx->bikeFlags.bOnSideStand = true;
return bmx;
}
case VEHICLE_TYPE_TRAILER:
return new CTrailer{model, createdBy};
case VEHICLE_TYPE_TRAIN:
return new CTrain{model, createdBy};
default:
NOTSA_LOG_WARN("Invalid vehicle type ({})", (int32)(vt));
}
return nullptr;
}

View File

@ -79,6 +79,8 @@ public:
void SwitchOn();
static uint32 CalcNextGen();
static CVehicle* CreateVehicle(eModelID model, eVehicleCreatedBy createdBy);
};
VALIDATE_SIZE(CCarGenerator, 0x20);

View File

@ -8,6 +8,7 @@
#include "TaskSimpleJetPack.h"
#include "PostEffects.h"
#include "Hud.h"
#include <CarGenerator.h>
/*
* Interesting links:
@ -132,32 +133,6 @@ const auto cheats = std::to_array<Cheat>({
{ 0x0, nullptr, "", 0x2bdd2fa1, CHEAT_ALL_TAXIS_NITRO },
});
void CCheat::InjectHooks() {
RH_ScopedClass(CCheat);
RH_ScopedCategoryGlobal();
RH_ScopedInstall(AddToCheatString, 0x438480);
RH_ScopedInstall(HandleSpecialCheats, 0x439A10);
RH_ScopedInstall(DoCheats, 0x439AF0);
RH_ScopedInstall(ResetCheats, 0x438450);
RH_ScopedInstall(IsZoneStreamingAllowed, 0x407410);
RH_ScopedInstall(ApplyCheat, 0x438370);
for (auto& cheat: cheats) {
if (cheat.installAddress == 0x0) {
continue;
}
RH_ScopedNamedGlobalInstall(cheat.method, cheat.methodName, cheat.installAddress);
for (auto& cheatFunc: CCheat::m_aCheatFunctions) {
if (reinterpret_cast<unsigned long>(cheatFunc) == cheat.installAddress) {
cheatFunc = static_cast<void (*)()>(cheat.method);
}
}
}
}
// 0x438480
void CCheat::AddToCheatString(char LastPressedKey) {
if (CCutsceneMgr::ms_running) {
@ -732,8 +707,6 @@ void CCheat::TankerCheat() {
// 0x43A0B0
CVehicle* CCheat::VehicleCheat(eModelID modelId) {
return plugin::CallAndReturn<CVehicle*, 0x43A0B0, eModelID>(modelId);
const auto player = FindPlayerPed();
if (player->m_nAreaCode != AREA_CODE_NORMAL_WORLD) {
return nullptr;
@ -754,52 +727,31 @@ CVehicle* CCheat::VehicleCheat(eModelID modelId) {
CStreaming::SetModelIsDeletable(modelId);
CStreaming::SetModelTxdIsDeletable(modelId);
}
auto* const vehicle = CCarGenerator::CreateVehicle(modelId, RANDOM_VEHICLE); // NB(NOTSA): Made this function instead of having shit here (Also fixes train spawning!)
if (!vehicle) {
return nullptr;
}
const auto GetVehicle = [](auto modelId) -> CVehicle* {
const auto* mi = CModelInfo::GetModelInfo(modelId)->AsVehicleModelInfoPtr();
switch (mi->m_nVehicleType) {
case VEHICLE_TYPE_MTRUCK:
return new CMonsterTruck(modelId, RANDOM_VEHICLE);
case VEHICLE_TYPE_QUAD:
return new CQuadBike(modelId, RANDOM_VEHICLE);
case VEHICLE_TYPE_HELI:
return new CHeli(modelId, RANDOM_VEHICLE);
case VEHICLE_TYPE_PLANE:
return new CPlane(modelId, RANDOM_VEHICLE);
case VEHICLE_TYPE_BOAT:
return new CBoat(modelId, RANDOM_VEHICLE);
case VEHICLE_TYPE_BIKE: {
auto* vehicle = new CBike(modelId, RANDOM_VEHICLE);
vehicle->bikeFlags.bOnSideStand = true;
return vehicle;
}
case VEHICLE_TYPE_BMX: {
auto* vehicle = new CBmx(modelId, RANDOM_VEHICLE);
vehicle->bikeFlags.bOnSideStand = true;
return vehicle;
}
case VEHICLE_TYPE_TRAILER:
return new CTrailer(modelId, RANDOM_VEHICLE);
default:
return new CAutomobile(modelId, RANDOM_VEHICLE, true);
}
};
auto* vehicle = GetVehicle(modelId);
const float radius = vehicle->GetModelInfo()->GetColModel()->GetBoundRadius();
const auto rotZ = player->m_fCurrentRotation + HALF_PI;
const auto pos = player->GetPosition() + (radius + 2.0f) * player->GetForward();
const float radius = vehicle->GetModelInfo()->GetColModel()->GetBoundRadius();
const auto rotZ = player->m_fCurrentRotation + HALF_PI;
const auto vehiclePosn = player->GetPosition() + (radius + 2.0f) * player->GetForward();
vehicle->SetPosn(vehiclePosn);
vehicle->SetPosn(pos);
vehicle->SetOrientation(0.0f, 0.0f, rotZ);
vehicle->m_nStatus = STATUS_ABANDONED;
vehicle->m_nDoorLock = CARLOCK_UNLOCKED;
CWorld::Add(vehicle);
CTheScripts::ClearSpaceForMissionEntity(vehiclePosn, vehicle);
CTheScripts::ClearSpaceForMissionEntity(pos, vehicle);
switch (vehicle->m_nVehicleType) {
case VEHICLE_TYPE_BOAT:
case VEHICLE_TYPE_TRAIN: {
const auto train = vehicle->AsTrain();
train->FindPositionOnTrackFromCoors();
break;
}
case VEHICLE_TYPE_BOAT:
break; /* nop */
case VEHICLE_TYPE_BIKE:
vehicle->AsBike()->PlaceOnRoadProperly();
break;
@ -1241,3 +1193,31 @@ void CCheat::WeaponSlotCheat() {
// SLOT_EQUIPMENT "NIGHT-VISION GOGGLES" "FIRE EXTINGUISHER" "SPRAY CAN" "PARACHUTE" "CAMERA" "THERMAL GOGGLES"
// SLOT_OTHER "VIBRA2" "DILDO1" "CANE" "DILDO2" "FLOWERS" "VIBRA1"
}
void CCheat::InjectHooks() {
RH_ScopedClass(CCheat);
RH_ScopedCategoryGlobal();
RH_ScopedInstall(AddToCheatString, 0x438480);
RH_ScopedInstall(HandleSpecialCheats, 0x439A10);
RH_ScopedInstall(DoCheats, 0x439AF0);
RH_ScopedInstall(ResetCheats, 0x438450);
RH_ScopedInstall(IsZoneStreamingAllowed, 0x407410);
RH_ScopedInstall(ApplyCheat, 0x438370);
RH_ScopedInstall(VehicleCheat, 0x43A0B0);
for (auto& cheat: cheats) {
if (cheat.installAddress == 0x0) {
continue;
}
RH_ScopedNamedGlobalInstall(cheat.method, cheat.methodName, cheat.installAddress);
for (auto& cheatFunc: CCheat::m_aCheatFunctions) {
if (reinterpret_cast<unsigned long>(cheatFunc) == cheat.installAddress) {
cheatFunc = static_cast<void (*)()>(cheat.method);
}
}
}
}

View File

@ -149,7 +149,7 @@ void CClouds::MovingFog_Create(CVector* posn) {
ms_mf.m_fSize[slotId] = CGeneral::GetRandomNumberInRange(4.0f, 10.0f);
ms_mf.m_fIntensity[slotId] = 1.0f;
ms_mf.m_fMaxIntensity[slotId] = CGeneral::GetRandomNumberInRange(8.0f, 20.0f);
ms_mf.m_fSpeed[slotId] = CGeneral::GetRandomNumberInRange(0.5f, 1.2f);
ms_mf.m_Speed[slotId] = CGeneral::GetRandomNumberInRange(0.5f, 1.2f);
ms_mf.m_bFogSlots[slotId] = true;
}
@ -174,8 +174,8 @@ void CClouds::MovingFog_Update() {
CVector& fogPosn = ms_mf.m_vecPosn[i];
CVector offset = fogPosn - camPos;
fogPosn.x += MovingFog_GetWind().x * ms_mf.m_fSpeed[i];
fogPosn.y += MovingFog_GetWind().y * ms_mf.m_fSpeed[i];
fogPosn.x += MovingFog_GetWind().x * ms_mf.m_Speed[i];
fogPosn.y += MovingFog_GetWind().y * ms_mf.m_Speed[i];
if (offset.Magnitude() <= 60.f)
{

View File

@ -27,7 +27,7 @@ struct tMovingFog {
float m_fIntensity[MAX_MOVING_FOG];
float m_fMaxIntensity[MAX_MOVING_FOG];
CVector m_vecWind;
float m_fSpeed[MAX_MOVING_FOG];
float m_Speed[MAX_MOVING_FOG];
int field_27B4[12];
std::array<uint32, 6> m_nPrimIndices;
};

View File

@ -523,6 +523,15 @@ void CMatrix::operator*=(const CMatrix& rvalue)
*this = (*this * rvalue);
}
CMatrix CMatrix::GetIdentity() {
CMatrix m;
m.m_right = CVector{ 1.f, 0.f, 0.f };
m.m_forward = CVector{ 0.f, 1.f, 0.f };
m.m_up = CVector{ 0.f, 0.f, 1.f };
m.m_pos = CVector{ 0.f, 0.f, 0.f };
return m;
}
CMatrix operator*(const CMatrix& a, const CMatrix& b)
{
auto result = CMatrix();

View File

@ -222,14 +222,7 @@ public:
m_pos = pos;
}
static auto GetIdentity() {
CMatrix mat;
mat.m_right = CVector{ 1.f, 0.f, 0.f };
mat.m_forward = CVector{ 0.f, 1.f, 0.f };
mat.m_up = CVector{ 0.f, 0.f, 1.f };
mat.m_pos = CVector{ 0.f, 0.f, 0.f };
return mat;
}
static CMatrix GetIdentity();
// Similar to ::Scale but this also scales the position vector.
// 0x45AF40

View File

@ -63,7 +63,7 @@ float CVector::Magnitude2D() const
// Normalises a vector
void CVector::Normalise()
{
NormaliseAndMag();
(void)NormaliseAndMag();
}
// Normalises a vector and returns length

View File

@ -42,10 +42,9 @@ public:
/// Get a normalized copy of this vector
auto Normalized(float* outMag = nullptr) const -> CVector {
CVector cpy = *this;
const float mag = cpy.NormaliseAndMag();
if (outMag) {
*outMag = cpy.NormaliseAndMag();
} else {
cpy.Normalise();
*outMag = mag;
}
return cpy;
}

View File

@ -1296,7 +1296,7 @@ void CPed::SetRadioStation()
if (m_pVehicle->m_pDriver == this) {
const auto& mi = *(CPedModelInfo*)GetModelInfo();
m_pVehicle->m_vehicleAudio.m_Settings.m_nRadioID = (CGeneral::GetRandomNumber() <= RAND_MAX / 2) ? mi.m_nRadio1 : mi.m_nRadio2;
m_pVehicle->m_vehicleAudio.m_AuSettings.RadioStation = (CGeneral::GetRandomNumber() <= RAND_MAX / 2) ? mi.m_nRadio1 : mi.m_nRadio2;
}
}
@ -3963,36 +3963,39 @@ bool CPed::IsPedStandingInPlace() const {
// 0x6497A0
bool SayJacked(CPed* jacked, CVehicle* vehicle, uint32 timeDelay) {
if (vehicle->m_vehicleAudio.GetVehicleTypeForAudio())
return jacked->Say(CTX_GLOBAL_JACKED_GENERIC, timeDelay) != -1;
else
switch (vehicle->m_vehicleAudio.GetVehicleTypeForAudio()) {
case eAEVehicleAudioType::CAR:
return jacked->Say(CTX_GLOBAL_JACKED_CAR, timeDelay) != -1;
case eAEVehicleAudioType::BIKE:
case eAEVehicleAudioType::GENERIC:
return jacked->Say(CTX_GLOBAL_JACKED_GENERIC, timeDelay) != -1;
default:
NOTSA_UNREACHABLE();
}
}
// 0x6497F0
bool SayJacking(CPed* jacker, CPed* jacked, CVehicle* vehicle, uint32 timeDelay) {
if (vehicle->m_vehicleAudio.GetVehicleTypeForAudio() == 1)
switch (vehicle->m_vehicleAudio.GetVehicleTypeForAudio()) {
case eAEVehicleAudioType::BIKE:
return jacker->Say(CTX_GLOBAL_JACKING_BIKE, timeDelay) != -1;
if (vehicle->m_vehicleAudio.GetVehicleTypeForAudio())
case eAEVehicleAudioType::CAR:
return jacked->GetSpeechAE().IsPedFemaleForAudio()
? jacker->Say(CTX_GLOBAL_JACKING_CAR_FEM, timeDelay) != -1
: jacker->Say(CTX_GLOBAL_JACKING_CAR_MALE, timeDelay) != -1;
case eAEVehicleAudioType::GENERIC:
return jacker->Say(CTX_GLOBAL_JACKING_GENERIC, timeDelay) != -1;
if (jacked->GetSpeechAE().IsPedFemaleForAudio())
return jacker->Say(CTX_GLOBAL_JACKING_CAR_FEM, timeDelay) != -1;
return jacker->Say(CTX_GLOBAL_JACKING_CAR_MALE, timeDelay) != -1;
default:
NOTSA_UNREACHABLE();
}
}
// NOTSA
int32 CPed::GetPadNumber() const {
switch (m_nPedType) {
case PED_TYPE_PLAYER1:
return 0;
case PED_TYPE_PLAYER2:
return 1;
default:
assert(true && "Inappropriate usage of GetPadNumber");
return 0;
case PED_TYPE_PLAYER1: return 0;
case PED_TYPE_PLAYER2: return 1;
default: NOTSA_UNREACHABLE();
}
}

View File

@ -176,8 +176,8 @@ void CPlayerPed::RemovePlayerPed(int32 playerId) {
if (playerVehicle && playerVehicle->m_pDriver == player)
{
playerVehicle->m_nStatus = STATUS_PHYSICS;
playerVehicle->m_fGasPedal = 0.0f;
playerVehicle->m_fBreakPedal = 0.1f;
playerVehicle->m_GasPedal = 0.0f;
playerVehicle->m_BrakePedal = 0.1f;
}
CWorld::Remove(static_cast<CEntity*>(player));
delete player;

View File

@ -178,7 +178,7 @@ CAutomobile::CAutomobile(int32 modelIndex, eVehicleCreatedBy createdBy, bool set
}
field_804 = 20.0f;
m_fGasPedalAudio = 0.0f;
m_GasPedalAudioRevs = 0.0f;
m_fIntertiaValue1 = 0.0f;
m_fIntertiaValue2 = 0.0f;
@ -351,11 +351,11 @@ CAutomobile::CAutomobile(int32 modelIndex, eVehicleCreatedBy createdBy, bool set
m_nBusDoorTimerEnd = 0;
m_nBusDoorTimerStart = 0;
m_fSteerAngle = 0.0f;
m_fGasPedal = 0.0f;
m_fBreakPedal = 0.0f;
m_GasPedal = 0.0f;
m_BrakePedal = 0.0f;
m_pExplosionVictim = nullptr;
m_fGasPedalAudio = 0.0f;
m_fMoveDirection = 0.0f;
m_GasPedalAudioRevs = 0.0f;
m_PrevSpeed = 0.0f;
m_wMiscComponentAngle = 0;
m_wMiscComponentAnglePrev = 0;
@ -364,8 +364,8 @@ CAutomobile::CAutomobile(int32 modelIndex, eVehicleCreatedBy createdBy, bool set
rng::fill(m_fWheelsSuspensionCompressionPrev, 1.f);
m_nNumContactWheels = 0;
m_nWheelsOnGround = 0;
m_wheelsOnGrounPrev = 0;
m_NumDriveWheelsOnGround = 0;
m_NumDriveWheelsOnGroundLastFrame = 0;
m_fFrontHeightAboveRoad = 0.0f;
m_fRearHeightAboveRoad = 0.0f;
m_fCarTraction = 1.0f;
@ -712,8 +712,8 @@ void CAutomobile::ProcessControl()
float speedForward = DotProduct(m_vecMoveSpeed, GetForward());
if (vehicleFlags.bAudioChangingGear
&& m_fGasPedal > 0.4f
&& m_fBreakPedal < 0.1f
&& m_GasPedal > 0.4f
&& m_BrakePedal < 0.1f
&& speedForward > 0.15f
&& this == FindPlayerVehicle()
&& CCamera::GetActiveCamera().m_nMode != MODE_1STPERSON)
@ -739,20 +739,20 @@ void CAutomobile::ProcessControl()
}
}
float brake = m_pHandlingData->m_fBrakeDeceleration * m_fBreakPedal * CTimer::GetTimeStep();
float brake = m_pHandlingData->m_fBrakeDeceleration * m_BrakePedal * CTimer::GetTimeStep();
m_wheelsOnGrounPrev = m_nWheelsOnGround;
m_NumDriveWheelsOnGroundLastFrame = m_NumDriveWheelsOnGround;
m_nNumContactWheels = 0;
m_nWheelsOnGround = 0;
m_NumDriveWheelsOnGround = 0;
for (int32 i = 0; i < 4; i++) {
if (m_fWheelsSuspensionCompression[i] >= 1.0f) {
m_aWheelTimer[i] = std::max(m_aWheelTimer[i] - CTimer::GetTimeStep(), 0.0f);
if (m_aWheelTimer[i] <= 0.0f)
m_WheelCounts[i] = std::max(m_WheelCounts[i] - CTimer::GetTimeStep(), 0.0f);
if (m_WheelCounts[i] <= 0.0f)
continue;
}
else {
m_aWheelTimer[i] = 4.0f;
m_WheelCounts[i] = 4.0f;
}
m_nNumContactWheels++;
@ -760,17 +760,17 @@ void CAutomobile::ProcessControl()
switch (m_pHandlingData->GetTransmission().m_nDriveType)
{
case '4':
m_nWheelsOnGround++;
m_NumDriveWheelsOnGround++;
break;
case 'F':
if (i == CAR_WHEEL_FRONT_LEFT || i == CAR_WHEEL_FRONT_RIGHT) {
m_nWheelsOnGround++;
m_NumDriveWheelsOnGround++;
break;
}
break;
case 'R':
if (i == CAR_WHEEL_REAR_LEFT || i == CAR_WHEEL_REAR_RIGHT) {
m_nWheelsOnGround++;
m_NumDriveWheelsOnGround++;
break;
}
}
@ -785,13 +785,13 @@ void CAutomobile::ProcessControl()
float acceleration = 0.0f;
if (vehicleFlags.bEngineOn && !m_pHandlingData->m_bIsPlane && !m_pHandlingData->m_bIsHeli) {
acceleration = m_pHandlingData->GetTransmission().CalculateDriveAcceleration(
m_fGasPedal,
m_GasPedal,
m_nCurrentGear,
m_fGearChangeCount,
speedForward,
&m_fIntertiaValue1,
&m_fIntertiaValue2,
m_nWheelsOnGround,
m_NumDriveWheelsOnGround,
cheatType
);
acceleration /= m_fVelocityFrequency;
@ -815,7 +815,7 @@ void CAutomobile::ProcessControl()
}
float steerAngle = 1.0f; // todo: Repeated branch in conditional chain
if (speedForward <= 0.01f || m_aWheelTimer[CAR_WHEEL_FRONT_LEFT] <= 0.0f && m_aWheelTimer[CAR_WHEEL_REAR_LEFT] <= 0.0f)
if (speedForward <= 0.01f || m_WheelCounts[CAR_WHEEL_FRONT_LEFT] <= 0.0f && m_WheelCounts[CAR_WHEEL_REAR_LEFT] <= 0.0f)
steerAngle = 1.0f;
else if (m_nStatus != STATUS_PLAYER)
steerAngle = 1.0f;
@ -943,14 +943,14 @@ void CAutomobile::ProcessControl()
}
uint32 handlingId = m_pHandlingData->m_nVehicleId;
cTransmission& transmission = gHandlingDataMgr.GetVehiclePointer(handlingId)->GetTransmission();
if (m_aWheelTimer[i] <= 0.0f
&& (m_fGasPedal > 0.5f || m_fGasPedal < -0.5f)
if (m_WheelCounts[i] <= 0.0f
&& (m_GasPedal > 0.5f || m_GasPedal < -0.5f)
&& ((i == CAR_WHEEL_FRONT_LEFT || i == CAR_WHEEL_FRONT_RIGHT) && transmission.m_nDriveType != 'R'
|| (i == CAR_WHEEL_REAR_LEFT || i == CAR_WHEEL_REAR_RIGHT) && transmission.m_nDriveType != 'F'))
{
wheelSpinRate += CVehicle::WHEELSPIN_INAIR_TARGET_RATE;
}
else if (m_aWheelState[i] == WHEEL_STATE_SPINNING) {
else if (m_WheelStates[i] == WHEEL_STATE_SPINNING) {
wheelSpinRate += CVehicle::WHEELSPIN_TARGET_RATE;
}
@ -1069,7 +1069,7 @@ void CAutomobile::ProcessControl()
ResetFrictionTurnSpeed();
}
else if (!skipPhysics
&& (m_fGasPedal == 0.0f || m_nStatus == STATUS_WRECKED)
&& (m_GasPedal == 0.0f || m_nStatus == STATUS_WRECKED)
&& std::fabs(m_vecMoveSpeed.x) < 0.0045f
&& std::fabs(m_vecMoveSpeed.y) < 0.0045f
&& std::fabs(m_vecMoveSpeed.z) < 0.0045f)
@ -1256,8 +1256,8 @@ bool CAutomobile::ProcessAI(uint32& extraHandlingFlags) {
CPhysical::ProcessControl();
CCarCtrl::UpdateCarOnRails(this);
m_nNumContactWheels = 4;
m_wheelsOnGrounPrev = m_nWheelsOnGround;
m_nWheelsOnGround = 4;
m_NumDriveWheelsOnGroundLastFrame = m_NumDriveWheelsOnGround;
m_NumDriveWheelsOnGround = 4;
float speed = m_autoPilot.m_speed / 50.0f;
m_pHandlingData->GetTransmission().CalculateGearForSimpleCar(speed, m_nCurrentGear);
float wheelRot = CVehicle::ProcessWheelRotation(WHEEL_STATE_NORMAL, GetForward(), m_vecMoveSpeed, 0.35f);
@ -1278,8 +1278,8 @@ bool CAutomobile::ProcessAI(uint32& extraHandlingFlags) {
CCarCtrl::ReconsiderRoute(this);
PlayHornIfNecessary();
if (vehicleFlags.bIsBeingCarJacked) {
m_fGasPedal = 0.0f;
m_fBreakPedal = 1.0f;
m_GasPedal = 0.0f;
m_BrakePedal = 1.0f;
vehicleFlags.bIsHandbrakeOn = true;
}
if (!IsAnyWheelTouchingSand())
@ -1302,37 +1302,37 @@ bool CAutomobile::ProcessAI(uint32& extraHandlingFlags) {
}
if (IsSubHeli() || IsSubPlane() && m_vecMoveSpeed.SquaredMagnitude() < 0.1f)
m_fBreakPedal = 1.0f;
m_BrakePedal = 1.0f;
if (vehicleFlags.bRestingOnPhysical)
m_fBreakPedal = 0.5f;
m_BrakePedal = 0.5f;
else if (m_vecMoveSpeed.SquaredMagnitude() < 0.01f)
m_fBreakPedal = 0.2f;
m_BrakePedal = 0.2f;
else
m_fBreakPedal = 0.0f;
m_BrakePedal = 0.0f;
vehicleFlags.bIsHandbrakeOn = false;
m_fSteerAngle = 0.0f;
m_fGasPedal = 0.0f;
m_GasPedal = 0.0f;
if (CanUpdateHornCounter())
m_nHornCounter = 0;
m_HornCounter = 0;
if (!vehicleFlags.bIsBeingCarJacked)
return false;
vehicleFlags.bIsHandbrakeOn = true;
m_fGasPedal = 0.0f;
m_fBreakPedal = 1.0f;
m_GasPedal = 0.0f;
m_BrakePedal = 1.0f;
return false;
case STATUS_WRECKED:
m_fBreakPedal = 0.05f;
m_BrakePedal = 0.05f;
vehicleFlags.bIsHandbrakeOn = true;
m_fSteerAngle = 0.0f;
m_fGasPedal = 0.0f;
m_GasPedal = 0.0f;
if (!CanUpdateHornCounter())
return false;
m_nHornCounter = 0;
m_HornCounter = 0;
return false;
case STATUS_REMOTE_CONTROLLED:
if (CPad::GetPad()->CarGunJustDown() && !CVehicle::bDisableRemoteDetonation) {
@ -1356,27 +1356,27 @@ bool CAutomobile::ProcessAI(uint32& extraHandlingFlags) {
&& m_pDriver->IsPlayer()
&& (m_pDriver->m_nPedState == PEDSTATE_ARRESTED || m_pDriver->GetTaskManager().HasAnyOf<TASK_COMPLEX_CAR_SLOW_BE_DRAGGED_OUT, TASK_COMPLEX_CAR_QUICK_BE_DRAGGED_OUT, TASK_SIMPLE_CAR_WAIT_TO_SLOW_DOWN>()))
{
m_fBreakPedal = 1.0f;
m_fGasPedal = 0.0f;
m_BrakePedal = 1.0f;
m_GasPedal = 0.0f;
vehicleFlags.bIsHandbrakeOn = true;
}
else
{
m_fBreakPedal = 0.0f;
m_BrakePedal = 0.0f;
vehicleFlags.bIsHandbrakeOn = false;
}
m_fSteerAngle = 0.0f;
m_fGasPedal = 0.0f;
m_GasPedal = 0.0f;
if (!CanUpdateHornCounter())
return false;
m_nHornCounter = 0;
m_HornCounter = 0;
return false;
case STATUS_IS_TOWED:
vehicleFlags.bIsHandbrakeOn = false;
m_fBreakPedal = 0.0f;
m_BrakePedal = 0.0f;
m_fSteerAngle = 0.0f;
m_fGasPedal = 0.0f;
m_GasPedal = 0.0f;
if (!m_pTowingVehicle)
BreakTowLink();
return false;
@ -1494,9 +1494,9 @@ void CAutomobile::ResetSuspension()
{
for (int32 i = 0; i < 4; i++) {
m_fWheelsSuspensionCompression[i] = 1.0f;
m_aWheelTimer[i] = 0.0f;
m_WheelCounts[i] = 0.0f;
m_wheelRotation[i] = 0.0f;
m_aWheelState[i] = WHEEL_STATE_NORMAL;
m_WheelStates[i] = WHEEL_STATE_NORMAL;
}
}
@ -2014,7 +2014,7 @@ void CAutomobile::ProcessControlInputs(uint8 playerNum) {
m_fRawSteerAngle = std::clamp(m_fRawSteerAngle, -1.f, 1.f);
//> Calculate gas/brake pedal values
std::tie(m_fGasPedal, m_fBreakPedal) = [&, this]() -> std::pair<float, float> {
std::tie(m_GasPedal, m_BrakePedal) = [&, this]() -> std::pair<float, float> {
if (automaticallyHandBrake) { // 0x6ADA8D
return { 0.f, 1.f };
}
@ -2059,7 +2059,7 @@ void CAutomobile::ProcessControlInputs(uint8 playerNum) {
}
}
if (gasPedalInput >= 0.f && (m_fGasPedal <= 0.5f || fwdvel <= -0.15f)) { // 0x6ADBD9 - Simplified
if (gasPedalInput >= 0.f && (m_GasPedal <= 0.5f || fwdvel <= -0.15f)) { // 0x6ADBD9 - Simplified
return { 0.f, gasPedalInput }; // Apply braking
}
@ -2067,13 +2067,13 @@ void CAutomobile::ProcessControlInputs(uint8 playerNum) {
}();
//> 0x6ADC18 and 0x6ADC64 - Check if we can go towards that direction
if (m_fGasPedal != 0.f && plyrdriver) {
if (m_GasPedal != 0.f && plyrdriver) {
if (!CGameLogic::IsPlayerAllowedToGoInThisDirection(
plyrdriver,
m_fGasPedal > 0.f ? GetForward() : -GetForward(),
m_GasPedal > 0.f ? GetForward() : -GetForward(),
0.f
)) {
m_fGasPedal = 0.f;
m_GasPedal = 0.f;
}
}
@ -2116,8 +2116,8 @@ void CAutomobile::ProcessControlInputs(uint8 playerNum) {
if (const auto pad0 = CPad::GetPad(0); (pad0->DisablePlayerControls && CGameLogic::SkipState != 2) || pad0->bApplyBrakes) {
vehicleFlags.bIsHandbrakeOn = true;
m_fGasPedal = 0.f;
m_fBreakPedal = 1.f;
m_GasPedal = 0.f;
m_BrakePedal = 1.f;
FindPlayerPed()->KeepAreaAroundPlayerClear();
if (const auto speedsq = GetMoveSpeed().SquaredMagnitude(); speedsq >= sq(0.28f)) {
GetMoveSpeed() *= 0.28f / std::sqrt(speedsq);
@ -2128,8 +2128,8 @@ void CAutomobile::ProcessControlInputs(uint8 playerNum) {
if (vehicleFlags.bEngineBroken) {
vehicleFlags.bIsHandbrakeOn = false;
m_fBreakPedal = 0.05f;
m_fGasPedal = 0.f;
m_BrakePedal = 0.05f;
m_GasPedal = 0.f;
}
}
@ -2810,7 +2810,7 @@ void CAutomobile::DoBurstAndSoftGroundRatios()
// 0x6A3770
void CAutomobile::PlayCarHorn()
{
if (m_nAlarmState && m_nAlarmState != -1 && m_nStatus != STATUS_WRECKED || m_nHornCounter) {
if (m_nAlarmState && m_nAlarmState != -1 && m_nStatus != STATUS_WRECKED || m_HornCounter) {
return;
}
@ -2826,7 +2826,7 @@ void CAutomobile::PlayCarHorn()
m_pDriver->Say(CTX_GLOBAL_BLOCKED);
}
}
m_nHornCounter = 45;
m_HornCounter = 45;
} else {
if (m_pDriver) {
m_pDriver->Say(CTX_GLOBAL_BLOCKED);
@ -3183,15 +3183,10 @@ void CAutomobile::VehicleDamage(float damageIntensity, eVehicleCollisionComponen
// Make our driver say something reacting to the collision..
if (&damagedVeh != FindPlayerVehicle() || damagedVeh.IsMissionVehicle()) {
switch (m_vehicleAudio.GetVehicleTypeForAudio()) {
case 1:
m_pDriver->Say(CTX_GLOBAL_CRASH_BIKE);
break;
case 0:
m_pDriver->Say(CTX_GLOBAL_CRASH_CAR);
break;
default:
m_pDriver->Say(CTX_GLOBAL_CRASH_GENERIC);
break;
case eAEVehicleAudioType::BIKE: m_pDriver->Say(CTX_GLOBAL_CRASH_BIKE); break;
case eAEVehicleAudioType::CAR: m_pDriver->Say(CTX_GLOBAL_CRASH_CAR); break;
case eAEVehicleAudioType::GENERIC: m_pDriver->Say(CTX_GLOBAL_CRASH_GENERIC); break;
default: NOTSA_UNREACHABLE();
}
}
}
@ -3559,8 +3554,8 @@ void CAutomobile::HydraulicControl() {
}
bool setPrevRatio = false;
if (m_wMiscComponentAngle >= 20 || m_fMoveDirection <= 0.02f || m_fGasPedal == 0.0f) {
if (m_wMiscComponentAngle && m_wMiscComponentAngle < 61 && m_fMoveDirection < 0.01f) {
if (m_wMiscComponentAngle >= 20 || m_PrevSpeed <= 0.02f || m_GasPedal == 0.0f) {
if (m_wMiscComponentAngle && m_wMiscComponentAngle < 61 && m_PrevSpeed < 0.01f) {
m_wMiscComponentAngle--;
if (m_wMiscComponentAngle == 1)
m_vehicleAudio.AddAudioEvent(AE_SUSPENSION_OFF, 0.0f);
@ -3745,30 +3740,36 @@ bool CAutomobile::UpdateMovingCollision(float angle) {
return false;
pad = driver->GetPadFromPlayer();
}
else if (!IsCreatedBy(MISSION_VEHICLE) || angle < 0.0f
|| !ModelIndices::HasMiscComponent(m_nModelIndex) && !ModelIndices::IsFireTruckLadder(m_nModelIndex))
{
return false;
} else {
if ( !IsCreatedBy(MISSION_VEHICLE)
|| angle < 0.0f
|| !ModelIndices::HasMiscComponent(m_nModelIndex) && !ModelIndices::IsFireTruckLadder(m_nModelIndex)
) {
return false;
}
}
if (!ModelIndices::IsCementTruck(m_nModelIndex) && !ModelIndices::IsFireTruckLadder(m_nModelIndex)) {
CColModel* colModel = GetVehicleModelInfo()->GetColModel();
CCollisionData* colData = colModel->m_pColData;
if (!ModelIndices::IsCementTruck(m_nModelIndex) && !ModelIndices::IsFireTruckLadder(m_nModelIndex)) { // Inverted(!)
CColModel* cm = GetVehicleModelInfo()->GetColModel();
CCollisionData* cd = cm->m_pColData;
if (!GetSpecialColModel()) {
return false;
}
CColModel& specialColModel = m_aSpecialColModel[m_vehicleSpecialColIndex];
CCollisionData* specialColData = specialColModel.m_pColData;
m_wMiscComponentAnglePrev = m_wMiscComponentAngle;
if (angle < 0.0f) {
if (!pad || std::fabs((float)pad->GetCarGunUpDown()) <= 10.0f)
if (!pad || std::abs(pad->GetCarGunUpDown()) <= 10) {
return false;
}
}
if (angle >= 0.0f) {
m_wMiscComponentAngle = static_cast<uint16>(angle * DEFAULT_COLLISION_EXTENDLIMIT);
}
else {
} else {
float colAngleMult = 10.0f;
if (ModelIndices::IsForklift(m_nModelIndex) ) {
if ((float)pad->GetCarGunUpDown() >= 0.0f)
@ -3820,9 +3821,9 @@ bool CAutomobile::UpdateMovingCollision(float angle) {
for (uint16 triIndx = 0; triIndx < specialColData->m_nNumTriangles; triIndx++) {
CColTriangle& specialColTriangle = specialColData->m_pTriangles[triIndx];
if (specialColTriangle.m_nMaterial == SURFACE_CAR_MOVINGCOMPONENT) {
const CColTriangle& colTriangle = colData->m_pTriangles[triIndx];
const CColTriangle& colTriangle = cd->m_pTriangles[triIndx];
for (int32 i = 0; i < 3; i++) {
CVector vertexPos = UncompressVector(colData->m_pVertices[colTriangle.m_vertIndices[i]]);
CVector vertexPos = UncompressVector(cd->m_pVertices[colTriangle.m_vertIndices[i]]);
CVector distance = vertexPos - componentPos;
vertexPos = rotMatrix.TransformPoint(distance) + componentPos;
specialColData->m_pVertices[specialColTriangle.m_vertIndices[i]] = CompressVector(vertexPos);
@ -3844,7 +3845,7 @@ bool CAutomobile::UpdateMovingCollision(float angle) {
for (uint16 i = 0; i < specialColData->m_nNumSpheres; i++) {
CColSphere& specialColSphere = specialColData->m_pSpheres[i];
if (specialColSphere.m_Surface.m_nMaterial == SURFACE_CAR_MOVINGCOMPONENT) {
CColSphere& colSphere = colData->m_pSpheres[i];
CColSphere& colSphere = cd->m_pSpheres[i];
CVector distance = colSphere.m_vecCenter - componentPos;
specialColSphere.m_vecCenter = (rotMatrix.TransformPoint(distance)) + componentPos;
const float newMaxZ = specialColSphere.m_fRadius + specialColSphere.m_vecCenter.z;
@ -3855,23 +3856,23 @@ bool CAutomobile::UpdateMovingCollision(float angle) {
minZ = newMinZ;
}
}
if (colModel->GetBoundingBox().m_vecMax.z < maxZ)
if (cm->GetBoundingBox().m_vecMax.z < maxZ)
specialColModel.GetBoundingBox().m_vecMax.z = maxZ;
if (colModel->GetBoundingBox().m_vecMin.z > minZ)
if (cm->GetBoundingBox().m_vecMin.z > minZ)
specialColModel.GetBoundingBox().m_vecMin.z = minZ;
return true;
}
m_wMiscComponentAnglePrev = m_wMiscComponentAngle;
if (angle >= 0.0f) {
m_wMiscComponentAngle = static_cast<uint16>(angle * DEFAULT_COLLISION_EXTENDLIMIT);
if (angle >= 0.0f) { // Inverted
m_wMiscComponentAngle = static_cast<uint16>(angle * DEFAULT_COLLISION_EXTENDLIMIT); // 0x6A1DA6
return false;
}
if (!pad)
return false;
if ((float)pad->GetCarGunUpDown() < -10.0f) {
if (pad->GetCarGunUpDown() < -10) {
m_wMiscComponentAngle -= static_cast<uint16>(2 * ((float)pad->GetCarGunUpDown() / 128.0f) * 10.0f * CTimer::GetTimeStep());
m_wMiscComponentAngle = std::min(m_wMiscComponentAngle, DEFAULT_COLLISION_EXTENDLIMIT);
return false;
@ -4118,8 +4119,8 @@ RpMaterial* DisableMatFx(RpMaterial* material, void* data) {
// 0x6A29A0
void CAutomobile::ReduceHornCounter() {
if (m_nHornCounter) {
m_nHornCounter--;
if (m_HornCounter) {
m_HornCounter--;
}
}
@ -4149,7 +4150,7 @@ void CAutomobile::CustomCarPlate_AfterRenderingStop(CVehicleModelInfo* model) {
* @addr 0x6A2F70
*/
bool CAutomobile::GetAllWheelsOffGround() const {
return m_nWheelsOnGround == 0;
return m_NumDriveWheelsOnGround == 0;
}
// 0x6A2F80
@ -4407,7 +4408,7 @@ void CAutomobile::NitrousControl(int8 boost) {
}
if (m_fTireTemperature >= 0.f) {
const auto a = std::max(0.25f, 1.f - m_fGasPedal);
const auto a = std::max(0.25f, 1.f - m_GasPedal);
const auto b = a * (CTimer::GetTimeStep() / 100.f) + m_fTireTemperature;
m_fTireTemperature = std::min(1.0f, b);
const auto power = (1.0f - m_fTireTemperature) / 2.f;
@ -4425,9 +4426,9 @@ void CAutomobile::NitrousControl(int8 boost) {
}
}
DoNitroEffect(
m_fGasPedal <= 0.0f
m_GasPedal <= 0.0f
? 0.5f
: std::abs(m_fGasPedal) / 2.0f + 0.5f
: std::abs(m_GasPedal) / 2.0f + 0.5f
);
}
@ -4618,7 +4619,7 @@ void CAutomobile::ProcessCarWheelPair(eCarWheel leftWheel, eCarWheel rightWheel,
}
}
if (m_aWheelTimer[leftWheel] > 0.0f || m_aWheelTimer[rightWheel] > 0.0f) {
if (m_WheelCounts[leftWheel] > 0.0f || m_WheelCounts[rightWheel] > 0.0f) {
// TOOD: Refactor
float sinSteerAngle = 0.0f;
float cosSteerAngle = 0.0f;
@ -4646,7 +4647,7 @@ void CAutomobile::ProcessCarWheelPair(eCarWheel leftWheel, eCarWheel rightWheel,
CVector wheelFwd{};
CVector wheelRight{};
if (m_aWheelTimer[leftWheel] > 0.0f) {
if (m_WheelCounts[leftWheel] > 0.0f) {
float thrust = driveWheels ? acceleration : 0.0f;
wheelFwd = GetForward();
@ -4676,7 +4677,7 @@ void CAutomobile::ProcessCarWheelPair(eCarWheel leftWheel, eCarWheel rightWheel,
adhesion *= 1.15f;
}
}
tWheelState wheelState = m_aWheelState[leftWheel];
tWheelState wheelState = m_WheelStates[leftWheel];
if (m_damageManager.GetWheelStatus(leftWheel) == WHEEL_STATUS_BURST) {
CVehicle::ProcessWheel(wheelFwd, wheelRight, contactSpeeds[leftWheel], contactPoints[leftWheel], m_nNumContactWheels,
thrust,
@ -4691,13 +4692,13 @@ void CAutomobile::ProcessCarWheelPair(eCarWheel leftWheel, eCarWheel rightWheel,
adhesion * tractionBias,
leftWheel, &m_fWheelBurnoutSpeed[leftWheel], &wheelState, WHEEL_STATUS_OK);
}
if (driveWheels && m_fGasPedal < 0.0f && wheelState == WHEEL_STATE_SPINNING)
m_aWheelState[leftWheel] = WHEEL_STATE_NORMAL;
if (driveWheels && m_GasPedal < 0.0f && wheelState == WHEEL_STATE_SPINNING)
m_WheelStates[leftWheel] = WHEEL_STATE_NORMAL;
else
m_aWheelState[leftWheel] = wheelState;
m_WheelStates[leftWheel] = wheelState;
}
if (m_aWheelTimer[rightWheel] > 0.0f) {
if (m_WheelCounts[rightWheel] > 0.0f) {
float thrust = driveWheels ? acceleration : 0.0f;
wheelFwd = GetForward();
wheelFwd -= DotProduct(wheelFwd, m_wheelColPoint[rightWheel].m_vecNormal) * m_wheelColPoint[rightWheel].m_vecNormal;
@ -4726,7 +4727,7 @@ void CAutomobile::ProcessCarWheelPair(eCarWheel leftWheel, eCarWheel rightWheel,
adhesion *= 1.15f;
}
}
tWheelState wheelState = m_aWheelState[rightWheel];
tWheelState wheelState = m_WheelStates[rightWheel];
if (m_damageManager.GetWheelStatus(rightWheel) == WHEEL_STATUS_BURST) {
CVehicle::ProcessWheel(wheelFwd, wheelRight, contactSpeeds[rightWheel], contactPoints[rightWheel], m_nNumContactWheels,
thrust,
@ -4743,17 +4744,17 @@ void CAutomobile::ProcessCarWheelPair(eCarWheel leftWheel, eCarWheel rightWheel,
rightWheel, &m_fWheelBurnoutSpeed[rightWheel], &wheelState, WHEEL_STATUS_OK
);
}
if (driveWheels && m_fGasPedal < 0.0f && wheelState == WHEEL_STATE_SPINNING)
m_aWheelState[rightWheel] = WHEEL_STATE_NORMAL;
if (driveWheels && m_GasPedal < 0.0f && wheelState == WHEEL_STATE_SPINNING)
m_WheelStates[rightWheel] = WHEEL_STATE_NORMAL;
else
m_aWheelState[rightWheel] = wheelState;
m_WheelStates[rightWheel] = wheelState;
}
}
if (!bFront && !handlingFlags.bNosInst) {
if (m_bDoingBurnout && driveWheels &&
(m_aWheelState[CAR_WHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING ||
m_aWheelState[CAR_WHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING))
(m_WheelStates[CAR_WHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING ||
m_WheelStates[CAR_WHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING))
{
m_fTireTemperature += CTimer::GetTimeStep() / 1000.0f;
m_fTireTemperature = std::min(m_fTireTemperature, 3.0f);
@ -4767,7 +4768,7 @@ void CAutomobile::ProcessCarWheelPair(eCarWheel leftWheel, eCarWheel rightWheel,
return;
}
if (m_aWheelTimer[leftWheel] <= 0.0f) {
if (m_WheelCounts[leftWheel] <= 0.0f) {
if (driveWheels && acceleration != 0.0f) {
if (acceleration > 0.0f) {
if (m_wheelSpeed[leftWheel] < 1.0f) {
@ -4784,7 +4785,7 @@ void CAutomobile::ProcessCarWheelPair(eCarWheel leftWheel, eCarWheel rightWheel,
m_wheelRotation[leftWheel] += CTimer::GetTimeStep() * m_wheelSpeed[leftWheel];
}
if (m_aWheelTimer[rightWheel] <= 0.0f) {
if (m_WheelCounts[rightWheel] <= 0.0f) {
if (driveWheels && acceleration != 0.0f) {
if (acceleration > 0.0f) {
if (m_wheelSpeed[rightWheel] < 1.0f) {

View File

@ -45,7 +45,7 @@ public:
std::array<CColPoint, 4> m_wheelColPoint; // 0x724
std::array<float, 4> m_fWheelsSuspensionCompression; // 0x7D4 - [0-1] with 0 being suspension fully compressed, and 1 being completely relaxed - Filled with 1.f in the ctor
std::array<float, 4> m_fWheelsSuspensionCompressionPrev; // 0x7E4 - Filled with 1.f in the ctor
std::array<float, 4> m_aWheelTimer;
std::array<float, 4> m_WheelCounts;
float field_804;
float m_fIntertiaValue1; // m_anWheelSurfaceType[2]
@ -90,7 +90,7 @@ public:
float m_fTireTemperature;
float m_fAircraftGoToHeading;
float m_fRotationBalance; // Controls destroyed helicopter rotation
float m_fMoveDirection;
float m_PrevSpeed;
CVector m_moveForce;
CVector m_turnForce;
std::array<float, 6> DoorRotation; // Inited in ctor with random values, but seemingly unused.
@ -110,11 +110,11 @@ public:
float m_fForcedOrientation;
std::array<float, 2> m_fUpDownLightAngle;
uint8 m_nNumContactWheels;
uint8 m_nWheelsOnGround;
uint8 m_wheelsOnGrounPrev;
float m_fGasPedalAudio; // [0; 1] adjusts the speed of playback of the skiding sound
uint8 m_NumDriveWheelsOnGround;
uint8 m_NumDriveWheelsOnGroundLastFrame;
float m_GasPedalAudioRevs; // [0; 1] adjusts the speed of playback of the skiding sound
std::array<tWheelState, 4> m_aWheelState;
std::array<tWheelState, 4> m_WheelStates;
std::array<FxSystem_c*, 2> m_exhaustNitroFxSystem;
uint8 m_harvesterParticleCounter;
@ -405,7 +405,7 @@ VALIDATE_OFFSET(CAutomobile, m_wheelColPoint, 0x724);
VALIDATE_OFFSET(CAutomobile, autoFlags, 0x868);
VALIDATE_OFFSET(CAutomobile, m_bDoingBurnout, 0x86A);
VALIDATE_OFFSET(CAutomobile, m_wMiscComponentAngle, 0x86C);
VALIDATE_OFFSET(CAutomobile, m_fGasPedalAudio, 0x964);
VALIDATE_OFFSET(CAutomobile, m_GasPedalAudioRevs, 0x964);
// Disable matfx (material effects) for material (callback), "data" parameter is unused
RpMaterial *DisableMatFx(RpMaterial* material, void* data);

View File

@ -63,9 +63,9 @@ CBike::CBike(int32 modelIndex, eVehicleCreatedBy createdBy) : CVehicle(createdBy
auto mi = CModelInfo::GetModelInfo(modelIndex)->AsVehicleModelInfoPtr();
if (mi->m_nVehicleType == VEHICLE_TYPE_BIKE) {
const auto& animationStyle = CAnimManager::GetAnimBlocks()[mi->GetAnimFileIndex()].GroupId;
m_RideAnimData.m_nAnimGroup = animationStyle;
m_RideAnimData.AnimGroup = animationStyle;
if (animationStyle < ANIM_GROUP_BIKES || animationStyle > ANIM_GROUP_WAYFARER) {
m_RideAnimData.m_nAnimGroup = ANIM_GROUP_BIKES;
m_RideAnimData.AnimGroup = ANIM_GROUP_BIKES;
}
}
@ -97,14 +97,14 @@ CBike::CBike(int32 modelIndex, eVehicleCreatedBy createdBy) : CVehicle(createdBy
m_fElasticity = 0.05f;
m_fBuoyancyConstant = m_pHandlingData->m_fBuoyancyConstant;
m_fSteerAngle = 0.0f;
m_fGasPedal = 0.0f;
m_fBreakPedal = 0.0f;
m_GasPedal = 0.0f;
m_BrakePedal = 0.0f;
m_Damager = nullptr;
m_pWhoInstalledBombOnMe = nullptr;
m_fGasPedalAudioRevs = 0.0f;
m_GasPedalAudioRevs = 0.0f;
m_fTyreTemp = 1.0f;
m_fBrakingSlide = 0.0f;
m_fPrevSpeed = 0.0f;
m_PrevSpeed = 0.0f;
for (auto i = 0; i < 2; ++i) {
m_nWheelStatus[i] = 0;
@ -115,14 +115,14 @@ CBike::CBike(int32 modelIndex, eVehicleCreatedBy createdBy) : CVehicle(createdBy
m_aWheelAngularVelocity[i] = 0.0f;
m_aWheelSuspensionHeights[i] = 0.0f;
m_aWheelOrigHeights[i] = 0.0f;
m_aWheelState[i] = WHEEL_STATE_NORMAL;
m_WheelStates[i] = WHEEL_STATE_NORMAL;
}
for (auto i = 0; i < 4; ++i) {
m_aWheelColPoints[i] = {};
m_aWheelRatios[i] = 1.0f;
m_aRatioHistory[i] = 0.0f;
m_aWheelCounts[i] = 0.0f;
m_WheelCounts[i] = 0.0f;
m_fSuspensionLength[i] = 0.0f;
m_fLineLength[i] = 0.0f;
m_aGroundPhysicalPtrs[i] = nullptr;
@ -130,8 +130,8 @@ CBike::CBike(int32 modelIndex, eVehicleCreatedBy createdBy) : CVehicle(createdBy
}
m_nNoOfContactWheels = 0;
m_nDriveWheelsOnGround = 0;
m_nDriveWheelsOnGroundLastFrame = 0;
m_NumDriveWheelsOnGround = 0;
m_NumDriveWheelsOnGroundLastFrame = 0;
m_fHeightAboveRoad = 0.0f;
m_fExtraTractionMult = 1.0f;
@ -187,8 +187,8 @@ void CBike::SetRemoveAnimFlags(CPed* ped) {
// 0x6B5F90
void CBike::ReduceHornCounter() {
if (m_nHornCounter)
m_nHornCounter -= 1;
if (m_HornCounter)
m_HornCounter -= 1;
}
// 0x6B5FB0
@ -462,12 +462,12 @@ void CBike::CalculateLeanMatrix() {
return;
CMatrix mat;
mat.SetRotateX(fabs(m_RideAnimData.m_fAnimLean) * -0.05f);
mat.RotateY(m_RideAnimData.m_fAnimLean);
mat.SetRotateX(fabs(m_RideAnimData.LeanAngle) * -0.05f);
mat.RotateY(m_RideAnimData.LeanAngle);
m_mLeanMatrix = GetMatrix();
m_mLeanMatrix = m_mLeanMatrix * mat;
// place wheel back on ground
m_mLeanMatrix.GetPosition() += GetUp() * (1.0f - cos(m_RideAnimData.m_fAnimLean)) * GetColModel()->GetBoundingBox().m_vecMin.z;
m_mLeanMatrix.GetPosition() += GetUp() * (1.0f - cos(m_RideAnimData.LeanAngle)) * GetColModel()->GetBoundingBox().m_vecMin.z;
m_bLeanMatrixCalculated = true;
}

View File

@ -54,7 +54,7 @@ public:
CColPoint m_aWheelColPoints[NUM_SUSP_LINES];
float m_aWheelRatios[NUM_SUSP_LINES];
float m_aRatioHistory[NUM_SUSP_LINES];
float m_aWheelCounts[NUM_SUSP_LINES];
float m_WheelCounts[NUM_SUSP_LINES];
float m_fBrakeCount;
eSkidmarkType m_aWheelSkidmarkType[2];
bool m_bWheelBloody[2];
@ -77,16 +77,16 @@ public:
uint8 m_nFixLeftHand;
uint8 m_nFixRightHand;
uint8 m_nTestPedCollision;
float m_fPrevSpeed;
float m_PrevSpeed;
float m_BlowUpTimer;
CPhysical* m_aGroundPhysicalPtrs[4];
CVector m_aGroundOffsets[4];
CEntity* m_Damager; // Entity That Set Us On Fire
uint8 m_nNoOfContactWheels;
uint8 m_nDriveWheelsOnGround;
uint8 m_nDriveWheelsOnGroundLastFrame;
float m_fGasPedalAudioRevs;
tWheelState m_aWheelState[2];
uint8 m_NumDriveWheelsOnGround;
uint8 m_NumDriveWheelsOnGroundLastFrame;
float m_GasPedalAudioRevs;
tWheelState m_WheelStates[2];
static constexpr auto Type = VEHICLE_TYPE_BIKE;
@ -162,4 +162,4 @@ public: // NOTSA
CBike* Destructor() {this->CBike::~CBike(); return this; }
};
VALIDATE_SIZE(CBike, 0x814);
VALIDATE_OFFSET(CBike, m_fGasPedalAudioRevs, 0x808);
VALIDATE_OFFSET(CBike, m_GasPedalAudioRevs, 0x808);

View File

@ -18,12 +18,13 @@ void CBmx::InjectHooks() {
// 0x6BF820
CBmx::CBmx(int32 modelIndex, eVehicleCreatedBy createdBy) :
CBike(modelIndex, createdBy) {
CBike(modelIndex, createdBy)
{
auto mi = CModelInfo::GetModelInfo(modelIndex);
m_nVehicleSubType = VEHICLE_TYPE_BMX;
m_RideAnimData.m_nAnimGroup = CAnimManager::GetAnimBlocks()[mi->GetAnimFileIndex()].GroupId;
if (m_RideAnimData.m_nAnimGroup < ANIM_GROUP_BMX || m_RideAnimData.m_nAnimGroup > ANIM_GROUP_CHOPPA) {
m_RideAnimData.m_nAnimGroup = ANIM_GROUP_BMX;
m_RideAnimData.AnimGroup = CAnimManager::GetAnimBlocks()[mi->GetAnimFileIndex()].GroupId;
if (m_RideAnimData.AnimGroup < ANIM_GROUP_BMX || m_RideAnimData.AnimGroup > ANIM_GROUP_CHOPPA) {
m_RideAnimData.AnimGroup = ANIM_GROUP_BMX;
}
m_fControlJump = 0.0f;
@ -97,7 +98,7 @@ void CBmx::ProcessControl() {
auto animBikePedal = RpAnimBlendClumpGetAssociation(m_pDriver->m_pRwClump, ANIM_ID_BIKE_PEDAL);
if (animBikePedal && animBikePedal->GetBlendAmount() > 0.01f) {
float mult = isMountainBike ? MTB_PEDAL_LEANMULT : BMX_PEDAL_LEANMULT;
GetRideAnimData()->m_fAnimLean += std::sin(animBikePedal->GetCurrentTime() / animBikePedal->GetHier()->GetTotalTime() * TWO_PI + BMX_PEDAL_LEANSTART) * animBikePedal->GetBlendAmount() * mult;
GetRideAnimData()->LeanAngle += std::sin(animBikePedal->GetCurrentTime() / animBikePedal->GetHier()->GetTotalTime() * TWO_PI + BMX_PEDAL_LEANSTART) * animBikePedal->GetBlendAmount() * mult;
}
m_fSprintLeanAngle *= 0.95f;
}
@ -112,7 +113,9 @@ void CBmx::ProcessDrivingAnims(CPed* driver, bool blend) {
// 0x6C0390
void CBmx::LaunchBunnyHopCB(CAnimBlendAssociation* assoc, void* data) {
auto bmx = static_cast<CBmx*>(data);
if ((bmx->m_aWheelCounts[0] > 0.0f || bmx->m_aWheelCounts[1] > 0.0f) && (bmx->m_aWheelCounts[2] > 0.0f || bmx->m_aWheelCounts[3] > 0.0f)) {
if ((bmx->m_WheelCounts[0] > 0.0f || bmx->m_WheelCounts[1] > 0.0f) &&
(bmx->m_WheelCounts[2] > 0.0f || bmx->m_WheelCounts[3] > 0.0f)
) {
auto power = std::min(bmx->m_fControlJump / 25.0f, 1.0f) + 1.0f;
if (bmx->m_nStatus == STATUS_PLAYER) {
power *= CStats::GetFatAndMuscleModifier(STAT_MOD_6);
@ -163,7 +166,7 @@ void CBmx::ProcessBunnyHop() {
if (pad->IsLeftShoulder1Pressed() && !pad->DisablePlayerControls && m_fControlJump == 0.0f) {
m_fControlJump += CTimer::GetTimeStep();
anim = CAnimManager::BlendAnimation(m_pDriver->m_pRwClump, m_RideAnimData.m_nAnimGroup, ANIM_ID_BIKE_BUNNYHOP, 8.0f);
anim = CAnimManager::BlendAnimation(m_pDriver->m_pRwClump, m_RideAnimData.AnimGroup, ANIM_ID_BIKE_BUNNYHOP, 8.0f);
if (anim) {
anim->SetCurrentTime(0.0f);
anim->SetFlag(ANIMATION_IS_PLAYING, false);
@ -197,7 +200,7 @@ void CBmx::ProcessBunnyHop() {
if (anim) {
if (anim->GetBlendAmount() > 0.5f) {
m_fGasPedal = 0.0f;
m_GasPedal = 0.0f;
FindPlayerPed()->m_pPlayerData->m_fMoveSpeed = 0.0f;
if (!vehicleFlags.bIsHandbrakeOn && (m_aWheelRatios[0] < 1.0f || m_aWheelRatios[1] < 1.0f || m_aWheelRatios[2] < 1.0f || m_aWheelRatios[3] < 1.0f)) {
m_bIsFreewheeling = true;

View File

@ -84,8 +84,8 @@ CBoat::CBoat(int32 modelIndex, eVehicleCreatedBy createdBy) : CVehicle(createdBy
m_nBoatFlags.bOnWater = true;
m_fSteerAngle = 0.0f;
m_fGasPedal = 0.0f;
m_fBreakPedal = 0.0f;
m_GasPedal = 0.0f;
m_BrakePedal = 0.0f;
m_fRawSteerAngle = 0.0f;
field_63C = 0;
m_fLastWaterImmersionDepth = 7.0F;
@ -524,8 +524,8 @@ void CBoat::ProcessControl() {
m_nBoatFlags.bMovingOnWater = true;
m_fSteerAngle = 0.0F;
m_fBreakPedal = 0.5F;
m_fGasPedal = 0.0F;
m_BrakePedal = 0.5F;
m_GasPedal = 0.0F;
auto fDist = (GetPosition() - FindPlayerCentreOfWorld_NoSniperShift(0)).Magnitude();
if (fDist > 150.0F) {
@ -541,16 +541,16 @@ void CBoat::ProcessControl() {
auto fROCPropSpeed = CPlane::PLANE_ROC_PROP_SPEED;
if (m_nModelIndex == MODEL_SKIMMER)
fSTDPropSpeed = CPlane::PLANE_STD_PROP_SPEED;
else if (m_fGasPedal != 0.0F)
else if (m_GasPedal != 0.0F)
fROCPropSpeed *= 5.0F;
if (m_fGasPedal == 0.0F)
if (m_GasPedal == 0.0F)
m_fPropSpeed += (fSTDPropSpeed - m_fPropSpeed) * CTimer::GetTimeStep() * fROCPropSpeed;
else if (m_fGasPedal < 0.0F) {
fSTDPropSpeed = (CPlane::PLANE_STD_PROP_SPEED - 0.05F) * m_fGasPedal + CPlane::PLANE_STD_PROP_SPEED;
else if (m_GasPedal < 0.0F) {
fSTDPropSpeed = (CPlane::PLANE_STD_PROP_SPEED - 0.05F) * m_GasPedal + CPlane::PLANE_STD_PROP_SPEED;
m_fPropSpeed += (fSTDPropSpeed - m_fPropSpeed) * CTimer::GetTimeStep() * fROCPropSpeed;
} else {
fSTDPropSpeed = (CPlane::PLANE_MAX_PROP_SPEED - CPlane::PLANE_STD_PROP_SPEED) * m_fGasPedal + CPlane::PLANE_STD_PROP_SPEED;
fSTDPropSpeed = (CPlane::PLANE_MAX_PROP_SPEED - CPlane::PLANE_STD_PROP_SPEED) * m_GasPedal + CPlane::PLANE_STD_PROP_SPEED;
m_fPropSpeed += (fSTDPropSpeed - m_fPropSpeed) * CTimer::GetTimeStep() * fROCPropSpeed;
}
} else if (m_fPropSpeed > 0.0F) {
@ -911,16 +911,16 @@ void CBoat::ProcessControlInputs(uint8 ucPadNum) {
m_nPadNumber = 3;
auto pad = CPad::GetPad(ucPadNum);
float fBrakePower = (static_cast<float>(pad->GetBrake()) * (1.0F / 255.0F) - m_fBreakPedal) * 0.1F + m_fBreakPedal;
float fBrakePower = (static_cast<float>(pad->GetBrake()) * (1.0F / 255.0F) - m_BrakePedal) * 0.1F + m_BrakePedal;
fBrakePower = std::clamp(fBrakePower, 0.0F, 1.0F);
m_fBreakPedal = fBrakePower;
m_BrakePedal = fBrakePower;
auto fGasPower = fBrakePower * -0.3F;
if (fBrakePower < 0.05F) {
m_fBreakPedal = 0.0F;
m_BrakePedal = 0.0F;
fGasPower = static_cast<float>(pad->GetAccelerate()) * (1.0F / 255.0F);
}
m_fGasPedal = fGasPower;
m_GasPedal = fGasPower;
// Mouse steering
// TODO: Try copy paste code from `CAutomobile::ProcessControlInputs` for this...

View File

@ -424,17 +424,17 @@ void CPlane::ProcessControl() {
CAutomobile::ProcessControl();
m_vehicleAudio.field_7C = static_cast<int16>(field_9A0);
m_vehicleAudio.m_DoCountStalls = static_cast<int16>(field_9A0);
if (field_9A0) {
field_9A0 = 0;
}
CVehicle::ProcessWeapons();
if (m_nModelIndex == MODEL_VORTEX) {
m_aWheelState[0] = WHEEL_STATE_NORMAL;
m_aWheelState[1] = WHEEL_STATE_NORMAL;
m_aWheelState[2] = WHEEL_STATE_NORMAL;
m_aWheelState[3] = WHEEL_STATE_NORMAL;
m_WheelStates[0] = WHEEL_STATE_NORMAL;
m_WheelStates[1] = WHEEL_STATE_NORMAL;
m_WheelStates[2] = WHEEL_STATE_NORMAL;
m_WheelStates[3] = WHEEL_STATE_NORMAL;
}
if (m_pSmokeParticle) {

View File

@ -105,7 +105,7 @@ void CQuadBike::PreRender() {
if (m_aCarNodes[QUAD_HANDLEBARS]) {
mat.Attach(RwFrameGetMatrix(m_aCarNodes[QUAD_HANDLEBARS]), false);
mat.SetRotateZOnly(QUAD_HBSTEER_ANIM_MULT * m_sRideAnimData.m_fHandlebarsAngle);
mat.SetRotateZOnly(QUAD_HBSTEER_ANIM_MULT * m_sRideAnimData.AnimLeanLeft);
mat.UpdateRW();
}
}
@ -131,25 +131,25 @@ bool CQuadBike::ProcessAI(uint32& extraHandlingFlags) {
m_pDriver->GetTaskManager().HasAnyOf<TASK_SIMPLE_CAR_WAIT_TO_SLOW_DOWN, TASK_COMPLEX_CAR_SLOW_BE_DRAGGED_OUT, TASK_COMPLEX_CAR_QUICK_BE_DRAGGED_OUT>()
) {
vehicleFlags.bIsHandbrakeOn = true;
m_fBreakPedal = 1.0f;
m_fGasPedal = 0.0f;
m_BrakePedal = 1.0f;
m_GasPedal = 0.0f;
} else {
ProcessControlInputs((uint8)m_pDriver->m_nPedType);
CPad* pad = m_pDriver->AsPlayer()->GetPadFromPlayer();
float fTurnForcePerTimeStep = 0.0f;
const float fLeanDirection = DotProduct(m_vecTurnSpeed, m_matrix->GetRight());
if (m_sRideAnimData.m_fLeanFwd >= 0.0f || fLeanDirection >= m_pHandling->m_fLeanBakCOM) {
if (m_sRideAnimData.LeanFwd >= 0.0f || fLeanDirection >= m_pHandling->m_fLeanBakCOM) {
// Lean forward
if (m_sRideAnimData.m_fLeanFwd > 0.0f) {
if (m_sRideAnimData.LeanFwd > 0.0f) {
if (fLeanDirection > -m_pHandling->m_fLeanFwdCOM) {
if (m_nNumContactWheels) {
if (m_fBreakPedal > 0.0f) {
if (m_BrakePedal > 0.0f) {
fTurnForcePerTimeStep =
m_pHandling->m_fLeanFwdForce * m_fTurnMass * m_sRideAnimData.m_fLeanFwd * std::min(0.1f, m_vecMoveSpeed.Magnitude());
m_pHandling->m_fLeanFwdForce * m_fTurnMass * m_sRideAnimData.LeanFwd * std::min(0.1f, m_vecMoveSpeed.Magnitude());
}
} else {
fTurnForcePerTimeStep = m_fTurnMass * m_sRideAnimData.m_fLeanFwd * 0.0015f;
fTurnForcePerTimeStep = m_fTurnMass * m_sRideAnimData.LeanFwd * 0.0015f;
}
const float fTurnForce = -CTimer::GetTimeStep() * fTurnForcePerTimeStep;
ApplyTurnForce(m_matrix->GetUp() * fTurnForce, m_vecCentreOfMass + m_matrix->GetForward());
@ -158,12 +158,12 @@ bool CQuadBike::ProcessAI(uint32& extraHandlingFlags) {
} else {
// Lean back
if (m_nNumContactWheels) {
if (m_fBreakPedal == 0.0f && !vehicleFlags.bIsHandbrakeOn) {
if (m_BrakePedal == 0.0f && !vehicleFlags.bIsHandbrakeOn) {
fTurnForcePerTimeStep =
m_pHandling->m_fLeanBakForce * m_fTurnMass * m_sRideAnimData.m_fLeanFwd * std::min(0.1f, m_vecMoveSpeed.Magnitude());
m_pHandling->m_fLeanBakForce * m_fTurnMass * m_sRideAnimData.LeanFwd * std::min(0.1f, m_vecMoveSpeed.Magnitude());
}
} else {
fTurnForcePerTimeStep = m_fTurnMass * m_sRideAnimData.m_fLeanFwd * 0.0015f;
fTurnForcePerTimeStep = m_fTurnMass * m_sRideAnimData.LeanFwd * 0.0015f;
}
const float fTurnForce = -CTimer::GetTimeStep() * fTurnForcePerTimeStep;
ApplyTurnForce(m_matrix->GetUp() * fTurnForce, m_vecCentreOfMass + m_matrix->GetForward());
@ -193,7 +193,7 @@ bool CQuadBike::ProcessAI(uint32& extraHandlingFlags) {
}
}
const float fValue = std::pow(m_pHandling->m_fDesLean, CTimer::GetTimeStep()); // TODO: Name this variable properly
m_sRideAnimData.m_fAnimLean = fValue * m_sRideAnimData.m_fAnimLean - m_pHandling->m_fFullAnimLean * m_fSteerAngle / DegreesToRadians(m_pHandlingData->m_fSteeringLock) * (1.0f - fValue);
m_sRideAnimData.LeanAngle = fValue * m_sRideAnimData.LeanAngle - m_pHandling->m_fFullAnimLean * m_fSteerAngle / DegreesToRadians(m_pHandlingData->m_fSteeringLock) * (1.0f - fValue);
DoDriveByShootings();
@ -222,7 +222,7 @@ void CQuadBike::ProcessControl() {
v5 = vecQuadResistance.x - std::min(0.07f, fabs(m_pHandling->m_fWheelieAng - m_matrix->GetForward().z) * 0.25f);
}
} else {
if (m_aWheelTimer[CAR_WHEEL_REAR_LEFT] == 1.0f && m_aWheelTimer[CAR_WHEEL_REAR_RIGHT] == 1.0f) {
if (m_WheelCounts[CAR_WHEEL_REAR_LEFT] == 1.0f && m_WheelCounts[CAR_WHEEL_REAR_RIGHT] == 1.0f) {
if (m_matrix->GetForward().z < 0.0f) {
v5 = vecQuadResistance.x * (0.9f + std::min(0.1f, fabs(m_pHandling->m_fStoppieAng - m_matrix->GetForward().z) * 0.3f));
}
@ -254,28 +254,28 @@ void CQuadBike::ProcessControlInputs(uint8 playerNum) {
CPad* pad = CPad::GetPad(playerNum);
if (!CCamera::m_bUseMouse3rdPerson || !m_bEnableMouseSteering) {
m_sRideAnimData.m_fLeanFwd += (float(-pad->GetSteeringUpDown()) / 128.0f - m_sRideAnimData.m_fLeanFwd) * CTimer::GetTimeStep() / 5.0f;
m_sRideAnimData.LeanFwd += (float(-pad->GetSteeringUpDown()) / 128.0f - m_sRideAnimData.LeanFwd) * CTimer::GetTimeStep() / 5.0f;
} else {
if (CPad::NewMouseControllerState.m_AmountMoved.IsZero() &&
(std::fabs(m_fRawSteerAngle) <= 0.0f || m_nLastControlInput != eControllerType::MOUSE || pad->IsSteeringInAnyDirection())
) {
if (pad->GetSteeringUpDown() || m_nLastControlInput != eControllerType::MOUSE) {
m_nLastControlInput = eControllerType::KEYBOARD;
m_sRideAnimData.m_fLeanFwd += (float(-pad->GetSteeringUpDown()) / 128.0f - m_sRideAnimData.m_fLeanFwd) * CTimer::GetTimeStep() / 5.0f;
m_sRideAnimData.LeanFwd += (float(-pad->GetSteeringUpDown()) / 128.0f - m_sRideAnimData.LeanFwd) * CTimer::GetTimeStep() / 5.0f;
}
} else {
m_nLastControlInput = eControllerType::MOUSE;
if (!pad->NewState.m_bVehicleMouseLook) {
m_sRideAnimData.m_fLeanFwd += CPad::NewMouseControllerState.m_AmountMoved.y * -0.035f;
m_sRideAnimData.LeanFwd += CPad::NewMouseControllerState.m_AmountMoved.y * -0.035f;
}
if (pad->NewState.m_bVehicleMouseLook || std::fabs(m_sRideAnimData.m_fLeanFwd) < 0.35f) {
m_sRideAnimData.m_fLeanFwd *= std::pow(0.98f, CTimer::GetTimeStep());
if (pad->NewState.m_bVehicleMouseLook || std::fabs(m_sRideAnimData.LeanFwd) < 0.35f) {
m_sRideAnimData.LeanFwd *= std::pow(0.98f, CTimer::GetTimeStep());
}
}
}
m_sRideAnimData.m_fLeanFwd = std::clamp(m_sRideAnimData.m_fLeanFwd, -1.0f, 1.0f);
m_sRideAnimData.LeanFwd = std::clamp(m_sRideAnimData.LeanFwd, -1.0f, 1.0f);
if (pad->DisablePlayerControls) {
m_sRideAnimData.m_fLeanFwd = 0.0f;
m_sRideAnimData.LeanFwd = 0.0f;
}
}

View File

@ -314,8 +314,8 @@ CVehicle::CVehicle(eVehicleCreatedBy createdBy) : CPhysical(), m_vehicleAudio(),
m_nGunFiringTime = 0;
m_nCopsInCarTimer = 0;
m_nUsedForCover = 0;
m_nHornCounter = 0;
m_nRandomIdRelatedToSiren = 0;
m_HornCounter = 0;
m_HornPattern = 0;
m_nCarHornTimer = 0;
field_4EC = 0;
m_pTowingVehicle = nullptr;
@ -974,7 +974,7 @@ void CVehicle::ProcessDrivingAnims(CPed* driver, bool blend) {
if (!driveByAnim) driveByAnim = RpAnimBlendClumpGetAssociation(driver->m_pRwClump, ANIM_ID_DRIVEBYL_R);
if (!vehicleFlags.bLowVehicle
&& m_fGasPedal < 0.0F
&& m_GasPedal < 0.0F
&& !driveByAnim
&& GetVehicleAppearance() != VEHICLE_APPEARANCE_HELI
&& GetVehicleAppearance() != VEHICLE_APPEARANCE_PLANE
@ -1730,7 +1730,7 @@ void CVehicle::ProcessCarAlarm() {
m_nAlarmState = ts;
} else {
m_nAlarmState = 0;
m_nHornCounter = 0;
m_HornCounter = 0;
}
}
@ -2160,7 +2160,7 @@ void CVehicle::ClearWindowOpenFlag(uint8 doorId) {
// 0x6D30E0
bool CVehicle::SetVehicleUpgradeFlags(int32 upgradeModelIndex, int32 modId, int32& resultModelIndex) {
// At the one and only place this function is called from
// componentIndex == CModelInfo::GetModelInfo(upgradeModelIndex)->AsVehicleModelInfo().nCarmodId
// componentIndex == CModelInfo::GetModelInfo(upgradeModelIndex)->AsVehicleModelInfo().CarMod
// Now, I'm not sure what value it has, so..
switch (modId) {
@ -2198,26 +2198,18 @@ bool CVehicle::SetVehicleUpgradeFlags(int32 upgradeModelIndex, int32 modId, int3
return GetModelInfo()->AsVehicleModelInfoPtr()->m_pVehicleStruct->m_aUpgrades[15].m_nParentComponentId < 0;
}
case 17: {
if (m_vehicleAudio.m_Settings.m_nRadioType != RADIO_CIVILIAN || vehicleFlags.bUpgradedStereo) {
if (m_vehicleAudio.m_AuSettings.RadioType != AE_RT_CIVILIAN || vehicleFlags.bUpgradedStereo) {
resultModelIndex = upgradeModelIndex;
return true;
}
auto& bassSetting = m_vehicleAudio.m_Settings.m_nBassSetting;
switch (bassSetting) {
case 1:
return true;
case 2: {
bassSetting = 0;
break;
auto& bs = m_vehicleAudio.m_AuSettings.BassSetting;
switch (bs) {
case eBassSetting::CUT: bs = eBassSetting::NORMAL; break;
case eBassSetting::NORMAL: bs = eBassSetting::BOOST; break;
case eBassSetting::BOOST: return true;
}
case 0: {
bassSetting = 1;
break;
}
}
AudioEngine.SetRadioBassSetting(bassSetting);
AudioEngine.SetRadioBassSetting(bs);
vehicleFlags.bUpgradedStereo = true;
@ -2235,19 +2227,13 @@ bool CVehicle::ClearVehicleUpgradeFlags(int32 arg0, int32 modId) {
switch (modId) {
case 17: { // 0x6D3270
if (m_vehicleAudio.m_Settings.m_nRadioType != RADIO_CIVILIAN && vehicleFlags.bUpgradedStereo) {
auto& bassSetting = m_vehicleAudio.m_Settings.m_nBassSetting;
switch (bassSetting) {
case 1: {
bassSetting = 0;
break;
if (m_vehicleAudio.m_AuSettings.RadioType != AE_RT_CIVILIAN && vehicleFlags.bUpgradedStereo) {
auto& bs = m_vehicleAudio.m_AuSettings.BassSetting;
switch (bs) {
case eBassSetting::BOOST: bs = eBassSetting::NORMAL; break;
case eBassSetting::NORMAL: bs = eBassSetting::CUT; break;
}
case 0: {
bassSetting = 2;
break;
}
}
AudioEngine.SetRadioBassSetting(bassSetting);
AudioEngine.SetRadioBassSetting(bs);
vehicleFlags.bUpgradedStereo = false;
}
return true;
@ -3201,7 +3187,7 @@ void CVehicle::ProcessWheel(CVector& wheelFwd, CVector& wheelRight,
adhesion *= m_pHandlingData->m_fTractionLoss;
if (*wheelState == WHEEL_STATE_SPINNING) {
if (m_nStatus == STATUS_PLAYER || m_nStatus == STATUS_REMOTE_CONTROLLED)
adhesion *= (1.0f - fabs(m_fGasPedal) * WS_ALREADY_SPINNING_LOSS);
adhesion *= (1.0f - fabs(m_GasPedal) * WS_ALREADY_SPINNING_LOSS);
}
}
@ -3221,7 +3207,7 @@ void CVehicle::ProcessWheel(CVector& wheelFwd, CVector& wheelRight,
}
else if (contactSpeedFwd != 0.0f) {
fwd = -contactSpeedFwd / wheelsOnGround;
if (!bBraking && std::fabs(m_fGasPedal) < 0.01f) {
if (!bBraking && std::fabs(m_GasPedal) < 0.01f) {
if (IsBike())
brake = gHandlingDataMgr.fWheelFriction * 0.6f / (m_pHandlingData->m_fMass + 200.0f);
else if (IsSubPlane())
@ -3261,7 +3247,7 @@ void CVehicle::ProcessWheel(CVector& wheelFwd, CVector& wheelRight,
tractionLoss = 1.0f;
} else if (*wheelState == WHEEL_STATE_SPINNING) {
if (m_nStatus == STATUS_PLAYER || m_nStatus == STATUS_REMOTE_CONTROLLED) {
tractionLoss = tractionLoss * (1.0f - std::fabs(m_fGasPedal) * WS_ALREADY_SPINNING_LOSS);
tractionLoss = tractionLoss * (1.0f - std::fabs(m_GasPedal) * WS_ALREADY_SPINNING_LOSS);
}
}
float l = sqrt(speedSq);
@ -3757,11 +3743,11 @@ void CVehicle::ProcessBoatControl(tBoatHandlingData* boatHandling, float* fLastW
if (!bPostCollision && bOnWater && GetUp().z > 0.0F) {
auto fMoveForce = m_vecMoveSpeed.SquaredMagnitude() * boatHandling->m_fAqPlaneForce * CTimer::GetTimeStep() * vecBuoyancyForce.z * 0.5F;
if (m_nModelIndex == MODEL_SKIMMER)
fMoveForce *= (m_fGasPedal + 1.0F);
else if (m_fGasPedal <= 0.05F)
fMoveForce *= (m_GasPedal + 1.0F);
else if (m_GasPedal <= 0.05F)
fMoveForce = 0.0F;
else
fMoveForce *= m_fGasPedal;
fMoveForce *= m_GasPedal;
auto fMaxMoveForce = CTimer::GetTimeStep() * boatHandling->m_fAqPlaneLimit * m_fMass / 125.0F;
fMoveForce = std::min(fMoveForce, fMaxMoveForce);
@ -3782,11 +3768,11 @@ void CVehicle::ProcessBoatControl(tBoatHandlingData* boatHandling, float* fLastW
// 0x6DC3AF
if (GetUp().z > -0.6F) {
float fMoveSpeed = 1.0F;
if (std::fabs(m_fGasPedal) <= 0.05F) {
if (std::fabs(m_GasPedal) <= 0.05F) {
fMoveSpeed = m_vecMoveSpeed.Magnitude2D();
}
if (std::fabs(m_fGasPedal) > 0.05F || fMoveSpeed > 0.01F) {
if (std::fabs(m_GasPedal) > 0.05F || fMoveSpeed > 0.01F) {
if (IsSubBoat() && bOnWater && fMoveSpeed > 0.05F) {
//GetColModel(); Unused call
AsBoat()->AddWakePoint(GetPosition());
@ -3825,7 +3811,7 @@ void CVehicle::ProcessBoatControl(tBoatHandlingData* boatHandling, float* fLastW
AsBoat()->m_nBoatFlags.bMovingOnWater = true;
bool bIsSlowingDown = false;
auto fGasState = std::fabs(m_fGasPedal);
auto fGasState = std::fabs(m_GasPedal);
if (fGasState < 0.01F || m_nModelIndex == MODEL_SKIMMER) {
bIsSlowingDown = true;
}
@ -3836,13 +3822,13 @@ void CVehicle::ProcessBoatControl(tBoatHandlingData* boatHandling, float* fLastW
auto fSteerAngle = std::fabs(m_fSteerAngle);
CVector vecSteer(-fSteerAngleSin, fSteerAngleCos, -fSteerAngle);
CVector vecSteerMoveForce = GetMatrix().TransformVector(vecSteer);
vecSteerMoveForce *= fThrustDepth * m_fGasPedal * 40.0F * m_pHandlingData->m_transmissionData.m_EngineAcceleration * m_fMass;
vecSteerMoveForce *= fThrustDepth * m_GasPedal * 40.0F * m_pHandlingData->m_transmissionData.m_EngineAcceleration * m_fMass;
if (vecSteerMoveForce.z > 0.2F)
vecSteerMoveForce.z = sq(1.2F - vecSteerMoveForce.z) + 0.2F;
if (bPostCollision) {
if (m_fGasPedal < 0.0F)
if (m_GasPedal < 0.0F)
vecSteerMoveForce *= CVector(5.0F, 5.0F, 1.0F);
vecSteerMoveForce.z = std::max(0.0F, vecSteerMoveForce.z);
@ -3880,8 +3866,8 @@ void CVehicle::ProcessBoatControl(tBoatHandlingData* boatHandling, float* fLastW
fTractionLoss *= 5.0F;
}
if (m_fGasPedal < 0.0f && fTractionLoss > 0.0f ||
m_fGasPedal > 0.0f && fTractionLoss < 0.0f
if (m_GasPedal < 0.0f && fTractionLoss > 0.0f ||
m_GasPedal > 0.0f && fTractionLoss < 0.0f
) {
fTractionLoss *= -1.0F;
}
@ -4175,7 +4161,7 @@ void CVehicle::AddExhaustParticles() {
}
}
if (CGeneral::GetRandomNumberInRange(1.0f, 3.0f) * (m_fGasPedal + 1.1f) <= 2.5f)
if (CGeneral::GetRandomNumberInRange(1.0f, 3.0f) * (m_GasPedal + 1.1f) <= 2.5f)
return;
float fMoveSpeed = m_vecMoveSpeed.Magnitude() * 0.5f;
@ -4204,7 +4190,7 @@ void CVehicle::AddExhaustParticles() {
secondExhaustFxSystem->AddParticle(&secondExhaustPos, &vecParticleVelocity, 0.0f, &fxPrt, -1.0f, m_fContactSurfaceBrightness, 0.6f, 0);
}
if (m_fGasPedal > 0.5f && m_nCurrentGear < 3) {
if (m_GasPedal > 0.5f && m_nCurrentGear < 3) {
if (CGeneral::GetRandomNumber() % 2) {
FxSystem_c* secondaryExhaustFxSystem = g_fx.m_SmokeII3expand;
if (bFirstExhaustSubmergedInWater) {

View File

@ -334,8 +334,8 @@ public:
CFire* m_pFire;
float m_fSteerAngle;
float m_f2ndSteerAngle; // used for steering 2nd set of wheels or elevators etc..
float m_fGasPedal;
float m_fBreakPedal;
float m_GasPedal;
float m_BrakePedal;
eVehicleCreatedBy m_nCreatedBy;
int16 m_nExtendedRemovalRange; // when game wants to delete a vehicle, it gets min(m_wExtendedRemovalRange, 170.0)
uint8 m_nBombOnBoard : 3; // 0 = None
@ -358,8 +358,8 @@ public:
float m_fGearChangeCount; // used as parameter for cTransmission::CalculateDriveAcceleration, but doesn't change
float m_fWheelSpinForAudio;
float m_fHealth; // 1000.0f = full health. 0 -> explode
CVehicle* m_pTowingVehicle;
CVehicle* m_pVehicleBeingTowed;
CVehicle* m_pTowingVehicle; // m_pTractor
CVehicle* m_pVehicleBeingTowed; // m_pTrailer
CPed* m_pWhoInstalledBombOnMe;
uint32 m_nTimeTillWeNeedThisCar; // game won't try to delete this car while this time won't reach
uint32 m_nGunFiringTime; // last time when gun on vehicle was fired (used on boats)
@ -383,8 +383,8 @@ public:
char field_511; // initialised, but not used?
char field_512; // initialised, but not used?
eCarWeapon m_nVehicleWeaponInUse;
uint32 m_nHornCounter;
int8 m_nRandomIdRelatedToSiren;
uint32 m_HornCounter;
int8 m_HornPattern;
char m_nCarHornTimer; // car horn related
eComedyControlState m_comedyControlState;
char m_nHasslePosId;
@ -565,7 +565,7 @@ public:
void ClearGettingOutFlags(uint8 doorId);
void SetWindowOpenFlag(uint8 doorId);
void ClearWindowOpenFlag(uint8 doorId);
bool SetVehicleUpgradeFlags(int32 upgradeModelIndex, int32 componentIndex, int32& resultModelIndex);
bool SetVehicleUpgradeFlags(int32 upgradeModelIndex, int32 mod, int32& resultModelIndex);
bool ClearVehicleUpgradeFlags(int32 arg0, int32 componentIndex);
RpAtomic* CreateUpgradeAtomic(CBaseModelInfo* model, const UpgradePosnDesc* upgradePosn, RwFrame* parentComponent, bool isDamaged);
void RemoveUpgrade(int32 upgradeId);
@ -659,6 +659,9 @@ public:
auto GetPassengerIndex(const CPed* ped) const -> std::optional<size_t>;
auto GetHealth() const noexcept { return m_fHealth; }
static void Shutdown();
static void SetComponentAtomicAlpha(RpAtomic* atomic, int32 alpha);

View File

@ -13,7 +13,7 @@ enum eGameState : uint8 {
GAME_STATE_IDLE = 9, // In-game (loop state)
};
inline const char* EnumToString(eGameState gs) {
inline std::optional<const char*> EnumToString(eGameState gs) {
switch (gs) {
case GAME_STATE_INITIAL: return "INITIAL";
case GAME_STATE_LOGO: return "LOGO";
@ -25,6 +25,6 @@ inline const char* EnumToString(eGameState gs) {
case GAME_STATE_FRONTEND_IDLE: return "FRONTEND_IDLE";
case GAME_STATE_LOADING_STARTED: return "LOADING_STARTED";
case GAME_STATE_IDLE: return "IDLE";
default: return "UNKNOWN";
default: return std::nullopt;
}
}

View File

@ -389,7 +389,9 @@ enum eModelID : int32 { // Number of entries: 14832
MODEL_SHANDR = 395,
MODEL_FHANDL = 396,
MODEL_FHANDR = 397,
MODEL_LANDSTAL = 400,
MODEL_VEHICLE_FIRST = 400,
MODEL_LANDSTAL = MODEL_VEHICLE_FIRST,
MODEL_BRAVURA = 401,
MODEL_BUFFALO = 402,
MODEL_LINERUN = 403,
@ -601,6 +603,8 @@ enum eModelID : int32 { // Number of entries: 14832
MODEL_BOXBURG = 609,
MODEL_FARMTR1 = 610,
MODEL_UTILTR1 = 611,
MODEL_VEHICLE_END,
MODEL_VEG_TREE3 = 615,
MODEL_VEG_TREEA1 = 616,
MODEL_VEG_TREEB1 = 617,

View File

@ -26,3 +26,25 @@ enum eRadioID : int8 {
RADIO_OFF,
RADIO_COUNT,
};
inline std::optional<const char*> EnumToString(eRadioID v) {
using namespace std::string_view_literals;
switch (v) {
case RADIO_INVALID: return "INVALID";
case RADIO_EMERGENCY_AA: return "EMERGENCY_AA";
case RADIO_CLASSIC_HIP_HOP: return "CLASSIC_HIP_HOP";
case RADIO_COUNTRY: return "COUNTRY";
case RADIO_CLASSIC_ROCK: return "CLASSIC_ROCK";
case RADIO_DISCO_FUNK: return "DISCO_FUNK";
case RADIO_HOUSE_CLASSICS: return "HOUSE_CLASSICS";
case RADIO_MODERN_HIP_HOP: return "MODERN_HIP_HOP";
case RADIO_MODERN_ROCK: return "MODERN_ROCK";
case RADIO_NEW_JACK_SWING: return "NEW_JACK_SWING";
case RADIO_REGGAE: return "REGGAE";
case RADIO_RARE_GROOVE: return "RARE_GROOVE";
case RADIO_TALK: return "TALK";
case RADIO_USER_TRACKS: return "USER_TRACKS";
case RADIO_OFF: return "OFF";
default: return std::nullopt;
}
}

View File

@ -575,278 +575,278 @@ enum eTaskType : int32 {
MAX_NUM_TASK_TYPES
};
static const char* GetTaskTypeName(eTaskType taskType) {
#define CASE_FOR(tt) case tt: return #tt
inline std::optional<const char*> EnumToString(eTaskType taskType) {
#define ECASE(tt) case tt: return #tt
switch (taskType) {
CASE_FOR(TASK_SIMPLE_PLAYER_ON_FOOT);
CASE_FOR(TASK_SIMPLE_PLAYER_IN_CAR);
CASE_FOR(TASK_COMPLEX_MEDIC_TREAT_INJURED_PED);
CASE_FOR(TASK_COMPLEX_TREAT_ACCIDENT);
CASE_FOR(TASK_SIMPLE_GIVE_CPR);
CASE_FOR(TASK_COMPLEX_COP_ARREST_PED);
CASE_FOR(TASK_COMPLEX_COP_HASSLE_PED);
CASE_FOR(TASK_COMPLEX_HASSLED_BY_COP);
CASE_FOR(TASK_COMPLEX_PRESENT_ID_TO_COP);
CASE_FOR(TASK_COMPLEX_DRIVE_FIRE_TRUCK);
CASE_FOR(TASK_COMPLEX_USE_SWAT_ROPE);
CASE_FOR(TASK_COMPLEX_USE_WATER_CANNON);
CASE_FOR(TASK_COMPLEX_EXTINGUISH_FIRE_ON_FOOT);
CASE_FOR(TASK_NONE);
CASE_FOR(TASK_SIMPLE_UNINTERRUPTABLE);
CASE_FOR(TASK_SIMPLE_PAUSE);
CASE_FOR(TASK_SIMPLE_STAND_STILL);
CASE_FOR(TASK_SIMPLE_SET_STAY_IN_SAME_PLACE);
CASE_FOR(TASK_SIMPLE_GET_UP);
CASE_FOR(TASK_COMPLEX_GET_UP_AND_STAND_STILL);
CASE_FOR(TASK_SIMPLE_FALL);
CASE_FOR(TASK_COMPLEX_FALL_AND_GET_UP);
CASE_FOR(TASK_COMPLEX_FALL_AND_STAY_DOWN);
CASE_FOR(TASK_SIMPLE_JUMP);
CASE_FOR(TASK_COMPLEX_JUMP);
CASE_FOR(TASK_SIMPLE_DIE);
CASE_FOR(TASK_SIMPLE_DROWN);
CASE_FOR(TASK_SIMPLE_DIE_IN_CAR);
CASE_FOR(TASK_COMPLEX_DIE_IN_CAR);
CASE_FOR(TASK_SIMPLE_DROWN_IN_CAR);
CASE_FOR(TASK_COMPLEX_DIE);
CASE_FOR(TASK_SIMPLE_DEAD);
CASE_FOR(TASK_SIMPLE_TIRED);
CASE_FOR(TASK_SIMPLE_SIT_DOWN);
CASE_FOR(TASK_SIMPLE_SIT_IDLE);
CASE_FOR(TASK_SIMPLE_STAND_UP);
CASE_FOR(TASK_COMPLEX_SIT_DOWN_THEN_IDLE_THEN_STAND_UP);
CASE_FOR(TASK_COMPLEX_OBSERVE_TRAFFIC_LIGHTS);
CASE_FOR(TASK_COMPLEX_OBSERVE_TRAFFIC_LIGHTS_AND_ACHIEVE_HEADING);
CASE_FOR(TASK_NOT_USED);
CASE_FOR(TASK_COMPLEX_CROSS_ROAD_LOOK_AND_ACHIEVE_HEADING);
CASE_FOR(TASK_SIMPLE_TURN_180);
CASE_FOR(TASK_SIMPLE_HAIL_TAXI);
CASE_FOR(TASK_COMPLEX_HIT_RESPONSE);
CASE_FOR(TASK_COMPLEX_HIT_BY_GUN_RESPONSE);
CASE_FOR(TASK_UNUSED_SLOT);
CASE_FOR(TASK_COMPLEX_USE_EFFECT);
CASE_FOR(TASK_COMPLEX_WAIT_AT_ATTRACTOR);
CASE_FOR(TASK_COMPLEX_USE_ATTRACTOR);
CASE_FOR(TASK_COMPLEX_WAIT_FOR_DRY_WEATHER);
CASE_FOR(TASK_COMPLEX_WAIT_FOR_BUS);
CASE_FOR(TASK_SIMPLE_WAIT_FOR_BUS);
CASE_FOR(TASK_SIMPLE_WAIT_FOR_PIZZA);
CASE_FOR(TASK_COMPLEX_IN_AIR_AND_LAND);
CASE_FOR(TASK_SIMPLE_IN_AIR);
CASE_FOR(TASK_SIMPLE_LAND);
CASE_FOR(TASK_COMPLEX_BE_IN_GROUP);
CASE_FOR(TASK_COMPLEX_SEQUENCE);
CASE_FOR(TASK_SIMPLE_CALL_FOR_BACKUP);
CASE_FOR(TASK_COMPLEX_USE_PAIRED_ATTRACTOR);
CASE_FOR(TASK_COMPLEX_USE_ATTRACTOR_PARTNER);
CASE_FOR(TASK_COMPLEX_ATTRACTOR_PARTNER_WAIT);
CASE_FOR(TASK_COMPLEX_USE_SCRIPTED_ATTRACTOR);
CASE_FOR(TASK_COMPLEX_ON_FIRE);
CASE_FOR(TASK_SIMPLE_BE_DAMAGED);
CASE_FOR(TASK_SIMPLE_TRIGGER_EVENT);
CASE_FOR(TASK_SIMPLE_RAGDOLL);
CASE_FOR(TASK_SIMPLE_CLIMB);
CASE_FOR(TASK_SIMPLE_PLAYER_ON_FIRE);
CASE_FOR(TASK_COMPLEX_PARTNER);
CASE_FOR(TASK_COMPLEX_STARE_AT_PED);
CASE_FOR(TASK_COMPLEX_USE_CLOSEST_FREE_SCRIPTED_ATTRACTOR);
CASE_FOR(TASK_COMPLEX_USE_EFFECT_RUNNING);
CASE_FOR(TASK_COMPLEX_USE_EFFECT_SPRINTING);
CASE_FOR(TASK_COMPLEX_USE_CLOSEST_FREE_SCRIPTED_ATTRACTOR_RUN);
CASE_FOR(TASK_COMPLEX_USE_CLOSEST_FREE_SCRIPTED_ATTRACTOR_SPRINT);
CASE_FOR(TASK_SIMPLE_CHOKING);
CASE_FOR(TASK_SIMPLE_IK_CHAIN);
CASE_FOR(TASK_SIMPLE_IK_MANAGER);
CASE_FOR(TASK_SIMPLE_IK_LOOK_AT);
CASE_FOR(TASK_COMPLEX_CLIMB);
CASE_FOR(TASK_COMPLEX_IN_WATER);
CASE_FOR(TASK_SIMPLE_TRIGGER_LOOK_AT);
CASE_FOR(TASK_SIMPLE_CLEAR_LOOK_AT);
CASE_FOR(TASK_SIMPLE_SET_CHAR_DECISION_MAKER);
CASE_FOR(TASK_SIMPLE_IK_POINT_R_ARM);
CASE_FOR(TASK_SIMPLE_IK_POINT_L_ARM);
CASE_FOR(TASK_COMPLEX_BE_STILL);
CASE_FOR(TASK_COMPLEX_USE_SEQUENCE);
CASE_FOR(TASK_SIMPLE_SET_KINDA_STAY_IN_SAME_PLACE);
CASE_FOR(TASK_COMPLEX_FALL_TO_DEATH);
CASE_FOR(TASK_WAIT_FOR_MATCHING_LEADER_AREA_CODES);
CASE_FOR(TASK_SIMPLE_LOOK_AT_ENTITY_OR_COORD);
CASE_FOR(TASK_SIMPLE_SAY);
CASE_FOR(TASK_SIMPLE_SHAKE_FIST);
CASE_FOR(TASK_SIMPLE_FACIAL);
CASE_FOR(TASK_COMPLEX_CHAINED_FACIAL);
CASE_FOR(TASK_COMPLEX_FACIAL);
CASE_FOR(TASK_SIMPLE_AFFECT_SECONDARY_BEHAVIOUR);
CASE_FOR(TASK_SIMPLE_HOLD_ENTITY);
CASE_FOR(TASK_SIMPLE_PICKUP_ENTITY);
CASE_FOR(TASK_SIMPLE_PUTDOWN_ENTITY);
CASE_FOR(TASK_COMPLEX_GO_PICKUP_ENTITY);
CASE_FOR(TASK_SIMPLE_DUCK_WHILE_SHOTS_WHIZZING);
CASE_FOR(TASK_SIMPLE_ANIM);
CASE_FOR(TASK_SIMPLE_NAMED_ANIM);
CASE_FOR(TASK_SIMPLE_TIMED_ANIM);
CASE_FOR(TASK_SIMPLE_HIT_BACK);
CASE_FOR(TASK_SIMPLE_HIT_FRONT);
CASE_FOR(TASK_SIMPLE_HIT_LEFT);
CASE_FOR(TASK_SIMPLE_HIT_RIGHT);
CASE_FOR(TASK_SIMPLE_HIT_BY_GUN_BACK);
CASE_FOR(TASK_SIMPLE_HIT_BY_GUN_FRONT);
CASE_FOR(TASK_SIMPLE_HIT_BY_GUN_LEFT);
CASE_FOR(TASK_SIMPLE_HIT_BY_GUN_RIGHT);
CASE_FOR(TASK_SIMPLE_HIT_WALL);
CASE_FOR(TASK_SIMPLE_COWER);
CASE_FOR(TASK_SIMPLE_HANDS_UP);
CASE_FOR(TASK_SIMPLE_HIT_BEHIND);
CASE_FOR(TASK_SIMPLE_DUCK);
CASE_FOR(TASK_SIMPLE_CHAT);
CASE_FOR(TASK_COMPLEX_SUNBATHE);
CASE_FOR(TASK_SIMPLE_SUNBATHE);
CASE_FOR(TASK_SIMPLE_DETONATE);
CASE_FOR(TASK_SIMPLE_USE_ATM);
CASE_FOR(TASK_SIMPLE_SCRATCH_HEAD);
CASE_FOR(TASK_SIMPLE_LOOK_ABOUT);
CASE_FOR(TASK_SIMPLE_ABSEIL);
CASE_FOR(TASK_SIMPLE_ANIM_LOOPED_MIDDLE);
CASE_FOR(TASK_SIMPLE_HANDSIGNAL_ANIM);
CASE_FOR(TASK_COMPLEX_HANDSIGNAL_ANIM);
CASE_FOR(TASK_SIMPLE_DUCK_FOREVER);
CASE_FOR(TASK_SIMPLE_START_SUNBATHING);
CASE_FOR(TASK_SIMPLE_IDLE_SUNBATHING);
CASE_FOR(TASK_SIMPLE_STOP_SUNBATHING);
CASE_FOR(TASK_SIMPLE_HIT_HEAD);
CASE_FOR(TASK_SIMPLE_EVASIVE_STEP);
CASE_FOR(TASK_COMPLEX_EVASIVE_STEP);
CASE_FOR(TASK_SIMPLE_EVASIVE_DIVE);
CASE_FOR(TASK_COMPLEX_EVASIVE_DIVE_AND_GET_UP);
CASE_FOR(TASK_COMPLEX_HIT_PED_WITH_CAR);
CASE_FOR(TASK_SIMPLE_KILL_PED_WITH_CAR);
CASE_FOR(TASK_SIMPLE_HURT_PED_WITH_CAR);
CASE_FOR(TASK_COMPLEX_WALK_ROUND_CAR);
CASE_FOR(TASK_COMPLEX_WALK_ROUND_BUILDING_ATTEMPT);
CASE_FOR(TASK_COMPLEX_WALK_ROUND_OBJECT);
CASE_FOR(TASK_COMPLEX_MOVE_BACK_AND_JUMP);
CASE_FOR(TASK_COMPLEX_EVASIVE_COWER);
CASE_FOR(TASK_COMPLEX_DIVE_FROM_ATTACHED_ENTITY_AND_GET_UP);
CASE_FOR(TASK_COMPLEX_WALK_ROUND_FIRE);
CASE_FOR(TASK_COMPLEX_STUCK_IN_AIR);
CASE_FOR(TASK_COMPLEX_INVESTIGATE_DEAD_PED);
CASE_FOR(TASK_COMPLEX_REACT_TO_GUN_AIMED_AT);
CASE_FOR(TASK_COMPLEX_WAIT_FOR_BACKUP);
CASE_FOR(TASK_COMPLEX_GET_OUT_OF_WAY_OF_CAR);
CASE_FOR(TASK_COMPLEX_EXTINGUISH_FIRES);
CASE_FOR(TASK_COMPLEX_ENTER_CAR_AS_PASSENGER);
CASE_FOR(TASK_COMPLEX_ENTER_CAR_AS_DRIVER);
CASE_FOR(TASK_COMPLEX_STEAL_CAR);
CASE_FOR(TASK_COMPLEX_DRAG_PED_FROM_CAR);
CASE_FOR(TASK_COMPLEX_LEAVE_CAR);
CASE_FOR(TASK_COMPLEX_LEAVE_CAR_AND_DIE);
CASE_FOR(TASK_COMPLEX_LEAVE_CAR_AND_FLEE);
CASE_FOR(TASK_COMPLEX_LEAVE_CAR_AND_WANDER);
CASE_FOR(TASK_COMPLEX_SCREAM_IN_CAR_THEN_LEAVE);
CASE_FOR(TASK_SIMPLE_CAR_DRIVE);
CASE_FOR(TASK_COMPLEX_CAR_DRIVE_TO_POINT);
CASE_FOR(TASK_COMPLEX_CAR_DRIVE_WANDER);
CASE_FOR(TASK_COMPLEX_ENTER_CAR_AS_PASSENGER_TIMED);
CASE_FOR(TASK_COMPLEX_ENTER_CAR_AS_DRIVER_TIMED);
CASE_FOR(TASK_COMPLEX_LEAVE_ANY_CAR);
CASE_FOR(TASK_COMPLEX_ENTER_BOAT_AS_DRIVER);
CASE_FOR(TASK_COMPLEX_LEAVE_BOAT);
CASE_FOR(TASK_COMPLEX_ENTER_ANY_CAR_AS_DRIVER);
CASE_FOR(TASK_COMPLEX_ENTER_CAR_AS_PASSENGER_WAIT);
CASE_FOR(TASK_SIMPLE_CAR_DRIVE_TIMED);
CASE_FOR(TASK_COMPLEX_SHUFFLE_SEATS);
CASE_FOR(TASK_COMPLEX_CAR_DRIVE_POINT_ROUTE);
CASE_FOR(TASK_COMPLEX_CAR_OPEN_DRIVER_DOOR);
CASE_FOR(TASK_SIMPLE_CAR_SET_TEMP_ACTION);
CASE_FOR(TASK_COMPLEX_CAR_DRIVE_MISSION);
CASE_FOR(TASK_COMPLEX_CAR_DRIVE);
CASE_FOR(TASK_COMPLEX_CAR_DRIVE_MISSION_FLEE_SCENE);
CASE_FOR(TASK_COMPLEX_ENTER_LEADER_CAR_AS_PASSENGER);
CASE_FOR(TASK_COMPLEX_CAR_OPEN_PASSENGER_DOOR);
CASE_FOR(TASK_COMPLEX_CAR_DRIVE_MISSION_KILL_PED);
CASE_FOR(TASK_COMPLEX_LEAVE_CAR_AS_PASSENGER_WAIT);
CASE_FOR(TASK_COMPLEX_GO_TO_CAR_DOOR_AND_STAND_STILL);
CASE_FOR(TASK_SIMPLE_CAR_ALIGN);
CASE_FOR(TASK_SIMPLE_CAR_OPEN_DOOR_FROM_OUTSIDE);
CASE_FOR(TASK_SIMPLE_CAR_OPEN_LOCKED_DOOR_FROM_OUTSIDE);
CASE_FOR(TASK_SIMPLE_BIKE_PICK_UP);
CASE_FOR(TASK_SIMPLE_CAR_CLOSE_DOOR_FROM_INSIDE);
CASE_FOR(TASK_SIMPLE_CAR_CLOSE_DOOR_FROM_OUTSIDE);
CASE_FOR(TASK_SIMPLE_CAR_GET_IN);
CASE_FOR(TASK_SIMPLE_CAR_SHUFFLE);
CASE_FOR(TASK_SIMPLE_CAR_WAIT_TO_SLOW_DOWN);
CASE_FOR(TASK_SIMPLE_CAR_WAIT_FOR_DOOR_NOT_TO_BE_IN_USE);
CASE_FOR(TASK_SIMPLE_CAR_SET_PED_IN_AS_PASSENGER);
CASE_FOR(TASK_SIMPLE_CAR_SET_PED_IN_AS_DRIVER);
CASE_FOR(TASK_SIMPLE_CAR_GET_OUT);
CASE_FOR(TASK_SIMPLE_CAR_JUMP_OUT);
CASE_FOR(TASK_SIMPLE_CAR_FORCE_PED_OUT);
CASE_FOR(TASK_SIMPLE_CAR_SET_PED_OUT);
CASE_FOR(TASK_SIMPLE_CAR_QUICK_DRAG_PED_OUT);
CASE_FOR(TASK_SIMPLE_CAR_QUICK_BE_DRAGGED_OUT);
CASE_FOR(TASK_SIMPLE_CAR_SET_PED_QUICK_DRAGGED_OUT);
CASE_FOR(TASK_SIMPLE_CAR_SLOW_DRAG_PED_OUT);
CASE_FOR(TASK_SIMPLE_CAR_SLOW_BE_DRAGGED_OUT);
CASE_FOR(TASK_SIMPLE_CAR_SET_PED_SLOW_DRAGGED_OUT);
CASE_FOR(TASK_COMPLEX_CAR_SLOW_BE_DRAGGED_OUT);
CASE_FOR(TASK_COMPLEX_CAR_SLOW_BE_DRAGGED_OUT_AND_STAND_UP);
CASE_FOR(TASK_COMPLEX_CAR_QUICK_BE_DRAGGED_OUT);
CASE_FOR(TASK_SIMPLE_BIKE_JACKED);
CASE_FOR(TASK_SIMPLE_SET_PED_AS_AUTO_DRIVER);
CASE_FOR(TASK_SIMPLE_GO_TO_POINT_NEAR_CAR_DOOR_UNTIL_DOOR_NOT_IN_USE);
CASE_FOR(TASK_SIMPLE_WAIT_UNTIL_PED_OUT_CAR);
CASE_FOR(TASK_COMPLEX_GO_TO_BOAT_STEERING_WHEEL);
CASE_FOR(TASK_COMPLEX_GET_ON_BOAT_SEAT);
CASE_FOR(TASK_SIMPLE_CREATE_CAR_AND_GET_IN);
CASE_FOR(TASK_SIMPLE_WAIT_UNTIL_PED_IN_CAR);
CASE_FOR(TASK_SIMPLE_CAR_FALL_OUT);
CASE_FOR(TASK_SIMPLE_GO_TO_POINT);
CASE_FOR(TASK_COMPLEX_GO_TO_POINT_SHOOTING);
CASE_FOR(TASK_SIMPLE_ACHIEVE_HEADING);
CASE_FOR(TASK_COMPLEX_GO_TO_POINT_AND_STAND_STILL);
CASE_FOR(TASK_COMPLEX_GO_TO_POINT_AND_STAND_STILL_AND_ACHIEVE_HEADING);
CASE_FOR(TASK_COMPLEX_FOLLOW_POINT_ROUTE);
CASE_FOR(TASK_COMPLEX_FOLLOW_NODE_ROUTE);
CASE_FOR(TASK_COMPLEX_SEEK_ENTITY);
CASE_FOR(TASK_COMPLEX_FLEE_POINT);
CASE_FOR(TASK_COMPLEX_FLEE_ENTITY);
CASE_FOR(TASK_COMPLEX_SMART_FLEE_POINT);
CASE_FOR(TASK_COMPLEX_SMART_FLEE_ENTITY);
CASE_FOR(TASK_COMPLEX_WANDER);
CASE_FOR(TASK_COMPLEX_FOLLOW_LEADER_IN_FORMATION);
CASE_FOR(TASK_COMPLEX_FOLLOW_SEXY_PED);
CASE_FOR(TASK_COMPLEX_GO_TO_ATTRACTOR);
CASE_FOR(TASK_COMPLEX_LEAVE_ATTRACTOR);
CASE_FOR(TASK_COMPLEX_AVOID_OTHER_PED_WHILE_WANDERING);
CASE_FOR(TASK_COMPLEX_GO_TO_POINT_ANY_MEANS);
CASE_FOR(TASK_COMPLEX_WALK_ROUND_SHOP);
CASE_FOR(TASK_COMPLEX_TURN_TO_FACE_ENTITY);
CASE_FOR(TASK_COMPLEX_AVOID_BUILDING);
CASE_FOR(TASK_COMPLEX_SEEK_ENTITY_ANY_MEANS);
CASE_FOR(TASK_COMPLEX_FOLLOW_LEADER_ANY_MEANS);
CASE_FOR(TASK_COMPLEX_GO_TO_POINT_AIMING);
CASE_FOR(TASK_COMPLEX_TRACK_ENTITY);
CASE_FOR(TASK_SIMPLE_GO_TO_POINT_FINE);
CASE_FOR(TASK_COMPLEX_FLEE_ANY_MEANS);
CASE_FOR(TASK_COMPLEX_FLEE_SHOOTING);
CASE_FOR(TASK_COMPLEX_SEEK_ENTITY_SHOOTING);
CASE_FOR(TASK_UNUSED1);
CASE_FOR(TASK_COMPLEX_FOLLOW_PATROL_ROUTE);
CASE_FOR(TASK_COMPLEX_GOTO_DOOR_AND_OPEN);
CASE_FOR(TASK_COMPLEX_SEEK_ENTITY_AIMING);
CASE_FOR(TASK_SIMPLE_SLIDE_TO_COORD);
CASE_FOR(TASK_COMPLEX_INVESTIGATE_DISTURBANCE);
CASE_FOR(TASK_COMPLEX_FOLLOW_PED_FOOTSTEPS);
CASE_FOR(TASK_COMPLEX_FOLLOW_NODE_ROUTE_SHOOTING);
CASE_FOR(TASK_COMPLEX_USE_ENTRYEXIT);
CASE_FOR(TASK_COMPLEX_AVOID_ENTITY);
CASE_FOR(TASK_SMART_FLEE_ENTITY_WALKING);
CASE_FOR(TASK_COMPLEX_KILL_PED_ON_FOOT);
CASE_FOR(TASK_COMPLEX_KILL_PED_ON_FOOT_MELEE);
CASE_FOR(TASK_COMPLEX_KILL_PED_ON_FOOT_ARMED);
CASE_FOR(TASK_COMPLEX_DESTROY_CAR);
CASE_FOR(TASK_COMPLEX_DESTROY_CAR_MELEE);
CASE_FOR(TASK_COMPLEX_DESTROY_CAR_ARMED);
ECASE(TASK_SIMPLE_PLAYER_ON_FOOT);
ECASE(TASK_SIMPLE_PLAYER_IN_CAR);
ECASE(TASK_COMPLEX_MEDIC_TREAT_INJURED_PED);
ECASE(TASK_COMPLEX_TREAT_ACCIDENT);
ECASE(TASK_SIMPLE_GIVE_CPR);
ECASE(TASK_COMPLEX_COP_ARREST_PED);
ECASE(TASK_COMPLEX_COP_HASSLE_PED);
ECASE(TASK_COMPLEX_HASSLED_BY_COP);
ECASE(TASK_COMPLEX_PRESENT_ID_TO_COP);
ECASE(TASK_COMPLEX_DRIVE_FIRE_TRUCK);
ECASE(TASK_COMPLEX_USE_SWAT_ROPE);
ECASE(TASK_COMPLEX_USE_WATER_CANNON);
ECASE(TASK_COMPLEX_EXTINGUISH_FIRE_ON_FOOT);
ECASE(TASK_NONE);
ECASE(TASK_SIMPLE_UNINTERRUPTABLE);
ECASE(TASK_SIMPLE_PAUSE);
ECASE(TASK_SIMPLE_STAND_STILL);
ECASE(TASK_SIMPLE_SET_STAY_IN_SAME_PLACE);
ECASE(TASK_SIMPLE_GET_UP);
ECASE(TASK_COMPLEX_GET_UP_AND_STAND_STILL);
ECASE(TASK_SIMPLE_FALL);
ECASE(TASK_COMPLEX_FALL_AND_GET_UP);
ECASE(TASK_COMPLEX_FALL_AND_STAY_DOWN);
ECASE(TASK_SIMPLE_JUMP);
ECASE(TASK_COMPLEX_JUMP);
ECASE(TASK_SIMPLE_DIE);
ECASE(TASK_SIMPLE_DROWN);
ECASE(TASK_SIMPLE_DIE_IN_CAR);
ECASE(TASK_COMPLEX_DIE_IN_CAR);
ECASE(TASK_SIMPLE_DROWN_IN_CAR);
ECASE(TASK_COMPLEX_DIE);
ECASE(TASK_SIMPLE_DEAD);
ECASE(TASK_SIMPLE_TIRED);
ECASE(TASK_SIMPLE_SIT_DOWN);
ECASE(TASK_SIMPLE_SIT_IDLE);
ECASE(TASK_SIMPLE_STAND_UP);
ECASE(TASK_COMPLEX_SIT_DOWN_THEN_IDLE_THEN_STAND_UP);
ECASE(TASK_COMPLEX_OBSERVE_TRAFFIC_LIGHTS);
ECASE(TASK_COMPLEX_OBSERVE_TRAFFIC_LIGHTS_AND_ACHIEVE_HEADING);
ECASE(TASK_NOT_USED);
ECASE(TASK_COMPLEX_CROSS_ROAD_LOOK_AND_ACHIEVE_HEADING);
ECASE(TASK_SIMPLE_TURN_180);
ECASE(TASK_SIMPLE_HAIL_TAXI);
ECASE(TASK_COMPLEX_HIT_RESPONSE);
ECASE(TASK_COMPLEX_HIT_BY_GUN_RESPONSE);
ECASE(TASK_UNUSED_SLOT);
ECASE(TASK_COMPLEX_USE_EFFECT);
ECASE(TASK_COMPLEX_WAIT_AT_ATTRACTOR);
ECASE(TASK_COMPLEX_USE_ATTRACTOR);
ECASE(TASK_COMPLEX_WAIT_FOR_DRY_WEATHER);
ECASE(TASK_COMPLEX_WAIT_FOR_BUS);
ECASE(TASK_SIMPLE_WAIT_FOR_BUS);
ECASE(TASK_SIMPLE_WAIT_FOR_PIZZA);
ECASE(TASK_COMPLEX_IN_AIR_AND_LAND);
ECASE(TASK_SIMPLE_IN_AIR);
ECASE(TASK_SIMPLE_LAND);
ECASE(TASK_COMPLEX_BE_IN_GROUP);
ECASE(TASK_COMPLEX_SEQUENCE);
ECASE(TASK_SIMPLE_CALL_FOR_BACKUP);
ECASE(TASK_COMPLEX_USE_PAIRED_ATTRACTOR);
ECASE(TASK_COMPLEX_USE_ATTRACTOR_PARTNER);
ECASE(TASK_COMPLEX_ATTRACTOR_PARTNER_WAIT);
ECASE(TASK_COMPLEX_USE_SCRIPTED_ATTRACTOR);
ECASE(TASK_COMPLEX_ON_FIRE);
ECASE(TASK_SIMPLE_BE_DAMAGED);
ECASE(TASK_SIMPLE_TRIGGER_EVENT);
ECASE(TASK_SIMPLE_RAGDOLL);
ECASE(TASK_SIMPLE_CLIMB);
ECASE(TASK_SIMPLE_PLAYER_ON_FIRE);
ECASE(TASK_COMPLEX_PARTNER);
ECASE(TASK_COMPLEX_STARE_AT_PED);
ECASE(TASK_COMPLEX_USE_CLOSEST_FREE_SCRIPTED_ATTRACTOR);
ECASE(TASK_COMPLEX_USE_EFFECT_RUNNING);
ECASE(TASK_COMPLEX_USE_EFFECT_SPRINTING);
ECASE(TASK_COMPLEX_USE_CLOSEST_FREE_SCRIPTED_ATTRACTOR_RUN);
ECASE(TASK_COMPLEX_USE_CLOSEST_FREE_SCRIPTED_ATTRACTOR_SPRINT);
ECASE(TASK_SIMPLE_CHOKING);
ECASE(TASK_SIMPLE_IK_CHAIN);
ECASE(TASK_SIMPLE_IK_MANAGER);
ECASE(TASK_SIMPLE_IK_LOOK_AT);
ECASE(TASK_COMPLEX_CLIMB);
ECASE(TASK_COMPLEX_IN_WATER);
ECASE(TASK_SIMPLE_TRIGGER_LOOK_AT);
ECASE(TASK_SIMPLE_CLEAR_LOOK_AT);
ECASE(TASK_SIMPLE_SET_CHAR_DECISION_MAKER);
ECASE(TASK_SIMPLE_IK_POINT_R_ARM);
ECASE(TASK_SIMPLE_IK_POINT_L_ARM);
ECASE(TASK_COMPLEX_BE_STILL);
ECASE(TASK_COMPLEX_USE_SEQUENCE);
ECASE(TASK_SIMPLE_SET_KINDA_STAY_IN_SAME_PLACE);
ECASE(TASK_COMPLEX_FALL_TO_DEATH);
ECASE(TASK_WAIT_FOR_MATCHING_LEADER_AREA_CODES);
ECASE(TASK_SIMPLE_LOOK_AT_ENTITY_OR_COORD);
ECASE(TASK_SIMPLE_SAY);
ECASE(TASK_SIMPLE_SHAKE_FIST);
ECASE(TASK_SIMPLE_FACIAL);
ECASE(TASK_COMPLEX_CHAINED_FACIAL);
ECASE(TASK_COMPLEX_FACIAL);
ECASE(TASK_SIMPLE_AFFECT_SECONDARY_BEHAVIOUR);
ECASE(TASK_SIMPLE_HOLD_ENTITY);
ECASE(TASK_SIMPLE_PICKUP_ENTITY);
ECASE(TASK_SIMPLE_PUTDOWN_ENTITY);
ECASE(TASK_COMPLEX_GO_PICKUP_ENTITY);
ECASE(TASK_SIMPLE_DUCK_WHILE_SHOTS_WHIZZING);
ECASE(TASK_SIMPLE_ANIM);
ECASE(TASK_SIMPLE_NAMED_ANIM);
ECASE(TASK_SIMPLE_TIMED_ANIM);
ECASE(TASK_SIMPLE_HIT_BACK);
ECASE(TASK_SIMPLE_HIT_FRONT);
ECASE(TASK_SIMPLE_HIT_LEFT);
ECASE(TASK_SIMPLE_HIT_RIGHT);
ECASE(TASK_SIMPLE_HIT_BY_GUN_BACK);
ECASE(TASK_SIMPLE_HIT_BY_GUN_FRONT);
ECASE(TASK_SIMPLE_HIT_BY_GUN_LEFT);
ECASE(TASK_SIMPLE_HIT_BY_GUN_RIGHT);
ECASE(TASK_SIMPLE_HIT_WALL);
ECASE(TASK_SIMPLE_COWER);
ECASE(TASK_SIMPLE_HANDS_UP);
ECASE(TASK_SIMPLE_HIT_BEHIND);
ECASE(TASK_SIMPLE_DUCK);
ECASE(TASK_SIMPLE_CHAT);
ECASE(TASK_COMPLEX_SUNBATHE);
ECASE(TASK_SIMPLE_SUNBATHE);
ECASE(TASK_SIMPLE_DETONATE);
ECASE(TASK_SIMPLE_USE_ATM);
ECASE(TASK_SIMPLE_SCRATCH_HEAD);
ECASE(TASK_SIMPLE_LOOK_ABOUT);
ECASE(TASK_SIMPLE_ABSEIL);
ECASE(TASK_SIMPLE_ANIM_LOOPED_MIDDLE);
ECASE(TASK_SIMPLE_HANDSIGNAL_ANIM);
ECASE(TASK_COMPLEX_HANDSIGNAL_ANIM);
ECASE(TASK_SIMPLE_DUCK_FOREVER);
ECASE(TASK_SIMPLE_START_SUNBATHING);
ECASE(TASK_SIMPLE_IDLE_SUNBATHING);
ECASE(TASK_SIMPLE_STOP_SUNBATHING);
ECASE(TASK_SIMPLE_HIT_HEAD);
ECASE(TASK_SIMPLE_EVASIVE_STEP);
ECASE(TASK_COMPLEX_EVASIVE_STEP);
ECASE(TASK_SIMPLE_EVASIVE_DIVE);
ECASE(TASK_COMPLEX_EVASIVE_DIVE_AND_GET_UP);
ECASE(TASK_COMPLEX_HIT_PED_WITH_CAR);
ECASE(TASK_SIMPLE_KILL_PED_WITH_CAR);
ECASE(TASK_SIMPLE_HURT_PED_WITH_CAR);
ECASE(TASK_COMPLEX_WALK_ROUND_CAR);
ECASE(TASK_COMPLEX_WALK_ROUND_BUILDING_ATTEMPT);
ECASE(TASK_COMPLEX_WALK_ROUND_OBJECT);
ECASE(TASK_COMPLEX_MOVE_BACK_AND_JUMP);
ECASE(TASK_COMPLEX_EVASIVE_COWER);
ECASE(TASK_COMPLEX_DIVE_FROM_ATTACHED_ENTITY_AND_GET_UP);
ECASE(TASK_COMPLEX_WALK_ROUND_FIRE);
ECASE(TASK_COMPLEX_STUCK_IN_AIR);
ECASE(TASK_COMPLEX_INVESTIGATE_DEAD_PED);
ECASE(TASK_COMPLEX_REACT_TO_GUN_AIMED_AT);
ECASE(TASK_COMPLEX_WAIT_FOR_BACKUP);
ECASE(TASK_COMPLEX_GET_OUT_OF_WAY_OF_CAR);
ECASE(TASK_COMPLEX_EXTINGUISH_FIRES);
ECASE(TASK_COMPLEX_ENTER_CAR_AS_PASSENGER);
ECASE(TASK_COMPLEX_ENTER_CAR_AS_DRIVER);
ECASE(TASK_COMPLEX_STEAL_CAR);
ECASE(TASK_COMPLEX_DRAG_PED_FROM_CAR);
ECASE(TASK_COMPLEX_LEAVE_CAR);
ECASE(TASK_COMPLEX_LEAVE_CAR_AND_DIE);
ECASE(TASK_COMPLEX_LEAVE_CAR_AND_FLEE);
ECASE(TASK_COMPLEX_LEAVE_CAR_AND_WANDER);
ECASE(TASK_COMPLEX_SCREAM_IN_CAR_THEN_LEAVE);
ECASE(TASK_SIMPLE_CAR_DRIVE);
ECASE(TASK_COMPLEX_CAR_DRIVE_TO_POINT);
ECASE(TASK_COMPLEX_CAR_DRIVE_WANDER);
ECASE(TASK_COMPLEX_ENTER_CAR_AS_PASSENGER_TIMED);
ECASE(TASK_COMPLEX_ENTER_CAR_AS_DRIVER_TIMED);
ECASE(TASK_COMPLEX_LEAVE_ANY_CAR);
ECASE(TASK_COMPLEX_ENTER_BOAT_AS_DRIVER);
ECASE(TASK_COMPLEX_LEAVE_BOAT);
ECASE(TASK_COMPLEX_ENTER_ANY_CAR_AS_DRIVER);
ECASE(TASK_COMPLEX_ENTER_CAR_AS_PASSENGER_WAIT);
ECASE(TASK_SIMPLE_CAR_DRIVE_TIMED);
ECASE(TASK_COMPLEX_SHUFFLE_SEATS);
ECASE(TASK_COMPLEX_CAR_DRIVE_POINT_ROUTE);
ECASE(TASK_COMPLEX_CAR_OPEN_DRIVER_DOOR);
ECASE(TASK_SIMPLE_CAR_SET_TEMP_ACTION);
ECASE(TASK_COMPLEX_CAR_DRIVE_MISSION);
ECASE(TASK_COMPLEX_CAR_DRIVE);
ECASE(TASK_COMPLEX_CAR_DRIVE_MISSION_FLEE_SCENE);
ECASE(TASK_COMPLEX_ENTER_LEADER_CAR_AS_PASSENGER);
ECASE(TASK_COMPLEX_CAR_OPEN_PASSENGER_DOOR);
ECASE(TASK_COMPLEX_CAR_DRIVE_MISSION_KILL_PED);
ECASE(TASK_COMPLEX_LEAVE_CAR_AS_PASSENGER_WAIT);
ECASE(TASK_COMPLEX_GO_TO_CAR_DOOR_AND_STAND_STILL);
ECASE(TASK_SIMPLE_CAR_ALIGN);
ECASE(TASK_SIMPLE_CAR_OPEN_DOOR_FROM_OUTSIDE);
ECASE(TASK_SIMPLE_CAR_OPEN_LOCKED_DOOR_FROM_OUTSIDE);
ECASE(TASK_SIMPLE_BIKE_PICK_UP);
ECASE(TASK_SIMPLE_CAR_CLOSE_DOOR_FROM_INSIDE);
ECASE(TASK_SIMPLE_CAR_CLOSE_DOOR_FROM_OUTSIDE);
ECASE(TASK_SIMPLE_CAR_GET_IN);
ECASE(TASK_SIMPLE_CAR_SHUFFLE);
ECASE(TASK_SIMPLE_CAR_WAIT_TO_SLOW_DOWN);
ECASE(TASK_SIMPLE_CAR_WAIT_FOR_DOOR_NOT_TO_BE_IN_USE);
ECASE(TASK_SIMPLE_CAR_SET_PED_IN_AS_PASSENGER);
ECASE(TASK_SIMPLE_CAR_SET_PED_IN_AS_DRIVER);
ECASE(TASK_SIMPLE_CAR_GET_OUT);
ECASE(TASK_SIMPLE_CAR_JUMP_OUT);
ECASE(TASK_SIMPLE_CAR_FORCE_PED_OUT);
ECASE(TASK_SIMPLE_CAR_SET_PED_OUT);
ECASE(TASK_SIMPLE_CAR_QUICK_DRAG_PED_OUT);
ECASE(TASK_SIMPLE_CAR_QUICK_BE_DRAGGED_OUT);
ECASE(TASK_SIMPLE_CAR_SET_PED_QUICK_DRAGGED_OUT);
ECASE(TASK_SIMPLE_CAR_SLOW_DRAG_PED_OUT);
ECASE(TASK_SIMPLE_CAR_SLOW_BE_DRAGGED_OUT);
ECASE(TASK_SIMPLE_CAR_SET_PED_SLOW_DRAGGED_OUT);
ECASE(TASK_COMPLEX_CAR_SLOW_BE_DRAGGED_OUT);
ECASE(TASK_COMPLEX_CAR_SLOW_BE_DRAGGED_OUT_AND_STAND_UP);
ECASE(TASK_COMPLEX_CAR_QUICK_BE_DRAGGED_OUT);
ECASE(TASK_SIMPLE_BIKE_JACKED);
ECASE(TASK_SIMPLE_SET_PED_AS_AUTO_DRIVER);
ECASE(TASK_SIMPLE_GO_TO_POINT_NEAR_CAR_DOOR_UNTIL_DOOR_NOT_IN_USE);
ECASE(TASK_SIMPLE_WAIT_UNTIL_PED_OUT_CAR);
ECASE(TASK_COMPLEX_GO_TO_BOAT_STEERING_WHEEL);
ECASE(TASK_COMPLEX_GET_ON_BOAT_SEAT);
ECASE(TASK_SIMPLE_CREATE_CAR_AND_GET_IN);
ECASE(TASK_SIMPLE_WAIT_UNTIL_PED_IN_CAR);
ECASE(TASK_SIMPLE_CAR_FALL_OUT);
ECASE(TASK_SIMPLE_GO_TO_POINT);
ECASE(TASK_COMPLEX_GO_TO_POINT_SHOOTING);
ECASE(TASK_SIMPLE_ACHIEVE_HEADING);
ECASE(TASK_COMPLEX_GO_TO_POINT_AND_STAND_STILL);
ECASE(TASK_COMPLEX_GO_TO_POINT_AND_STAND_STILL_AND_ACHIEVE_HEADING);
ECASE(TASK_COMPLEX_FOLLOW_POINT_ROUTE);
ECASE(TASK_COMPLEX_FOLLOW_NODE_ROUTE);
ECASE(TASK_COMPLEX_SEEK_ENTITY);
ECASE(TASK_COMPLEX_FLEE_POINT);
ECASE(TASK_COMPLEX_FLEE_ENTITY);
ECASE(TASK_COMPLEX_SMART_FLEE_POINT);
ECASE(TASK_COMPLEX_SMART_FLEE_ENTITY);
ECASE(TASK_COMPLEX_WANDER);
ECASE(TASK_COMPLEX_FOLLOW_LEADER_IN_FORMATION);
ECASE(TASK_COMPLEX_FOLLOW_SEXY_PED);
ECASE(TASK_COMPLEX_GO_TO_ATTRACTOR);
ECASE(TASK_COMPLEX_LEAVE_ATTRACTOR);
ECASE(TASK_COMPLEX_AVOID_OTHER_PED_WHILE_WANDERING);
ECASE(TASK_COMPLEX_GO_TO_POINT_ANY_MEANS);
ECASE(TASK_COMPLEX_WALK_ROUND_SHOP);
ECASE(TASK_COMPLEX_TURN_TO_FACE_ENTITY);
ECASE(TASK_COMPLEX_AVOID_BUILDING);
ECASE(TASK_COMPLEX_SEEK_ENTITY_ANY_MEANS);
ECASE(TASK_COMPLEX_FOLLOW_LEADER_ANY_MEANS);
ECASE(TASK_COMPLEX_GO_TO_POINT_AIMING);
ECASE(TASK_COMPLEX_TRACK_ENTITY);
ECASE(TASK_SIMPLE_GO_TO_POINT_FINE);
ECASE(TASK_COMPLEX_FLEE_ANY_MEANS);
ECASE(TASK_COMPLEX_FLEE_SHOOTING);
ECASE(TASK_COMPLEX_SEEK_ENTITY_SHOOTING);
ECASE(TASK_UNUSED1);
ECASE(TASK_COMPLEX_FOLLOW_PATROL_ROUTE);
ECASE(TASK_COMPLEX_GOTO_DOOR_AND_OPEN);
ECASE(TASK_COMPLEX_SEEK_ENTITY_AIMING);
ECASE(TASK_SIMPLE_SLIDE_TO_COORD);
ECASE(TASK_COMPLEX_INVESTIGATE_DISTURBANCE);
ECASE(TASK_COMPLEX_FOLLOW_PED_FOOTSTEPS);
ECASE(TASK_COMPLEX_FOLLOW_NODE_ROUTE_SHOOTING);
ECASE(TASK_COMPLEX_USE_ENTRYEXIT);
ECASE(TASK_COMPLEX_AVOID_ENTITY);
ECASE(TASK_SMART_FLEE_ENTITY_WALKING);
ECASE(TASK_COMPLEX_KILL_PED_ON_FOOT);
ECASE(TASK_COMPLEX_KILL_PED_ON_FOOT_MELEE);
ECASE(TASK_COMPLEX_KILL_PED_ON_FOOT_ARMED);
ECASE(TASK_COMPLEX_DESTROY_CAR);
ECASE(TASK_COMPLEX_DESTROY_CAR_MELEE);
ECASE(TASK_COMPLEX_DESTROY_CAR_ARMED);
//CASE_FOR(TASK_COMPLEX_FIGHT);
//CASE_FOR(TASK_SIMPLE_FIRE_RANGED);
//CASE_FOR(TASK_SIMPLE_FIRE_RANGED_CROUCHED);
@ -861,133 +861,126 @@ static const char* GetTaskTypeName(eTaskType taskType) {
//CASE_FOR(TASK_SIMPLE_ATTACK_UNARMED);
//CASE_FOR(TASK_COMPLEX_THROW_PROJECTILE);
//CASE_FOR(TASK_SIMPLE_THROW_WEAPON);
CASE_FOR(TASK_COMPLEX_REACT_TO_ATTACK);
CASE_FOR(TASK_SIMPLE_BE_KICKED_ON_GROUND);
CASE_FOR(TASK_SIMPLE_BE_HIT);
CASE_FOR(TASK_SIMPLE_BE_HIT_WHILE_MOVING);
CASE_FOR(TASK_COMPLEX_SIDE_STEP_AND_SHOOT);
CASE_FOR(TASK_SIMPLE_DRIVEBY_SHOOT);
CASE_FOR(TASK_SIMPLE_DRIVEBY_WATCH_FOR_TARGET);
CASE_FOR(TASK_COMPLEX_DO_DRIVEBY);
CASE_FOR(TASK_KILL_ALL_THREATS);
CASE_FOR(TASK_KILL_PED_GROUP_ON_FOOT);
CASE_FOR(TASK_SIMPLE_FIGHT);
CASE_FOR(TASK_SIMPLE_USE_GUN);
CASE_FOR(TASK_SIMPLE_THROW_PROJECTILE);
CASE_FOR(TASK_SIMPLE_FIGHT_CTRL);
CASE_FOR(TASK_SIMPLE_GUN_CTRL);
CASE_FOR(TASK_SIMPLE_THROW_CTRL);
CASE_FOR(TASK_SIMPLE_GANG_DRIVEBY);
CASE_FOR(TASK_COMPLEX_KILL_PED_ON_FOOT_TIMED);
CASE_FOR(TASK_COMPLEX_KILL_PED_ON_FOOT_STAND_STILL);
CASE_FOR(TASK_UNUSED2);
CASE_FOR(TASK_KILL_PED_ON_FOOT_WHILE_DUCKING);
CASE_FOR(TASK_SIMPLE_STEALTH_KILL);
CASE_FOR(TASK_COMPLEX_KILL_PED_ON_FOOT_STEALTH);
CASE_FOR(TASK_COMPLEX_KILL_PED_ON_FOOT_KINDA_STAND_STILL);
CASE_FOR(TASK_COMPLEX_KILL_PED_AND_REENTER_CAR);
CASE_FOR(TASK_COMPLEX_ROAD_RAGE);
CASE_FOR(TASK_KILL_PED_FROM_BOAT);
CASE_FOR(TASK_SIMPLE_SET_CHAR_IGNORE_WEAPON_RANGE_FLAG);
CASE_FOR(TASK_SEEK_COVER_UNTIL_TARGET_DEAD);
CASE_FOR(TASK_SIMPLE_ARREST_PED);
CASE_FOR(TASK_COMPLEX_ARREST_PED);
CASE_FOR(TASK_SIMPLE_BE_ARRESTED);
CASE_FOR(TASK_COMPLEX_POLICE_PURSUIT);
CASE_FOR(TASK_COMPLEX_BE_COP);
CASE_FOR(TASK_COMPLEX_KILL_CRIMINAL);
CASE_FOR(TASK_COMPLEX_COP_IN_CAR);
CASE_FOR(TASK_SIMPLE_INFORM_GROUP);
CASE_FOR(TASK_COMPLEX_GANG_LEADER);
CASE_FOR(TASK_COMPLEX_PARTNER_DEAL);
CASE_FOR(TASK_COMPLEX_PARTNER_GREET);
CASE_FOR(TASK_COMPLEX_PARTNER_CHAT);
CASE_FOR(TASK_COMPLEX_GANG_HASSLE_VEHICLE);
CASE_FOR(TASK_COMPLEX_WALK_WITH_PED);
CASE_FOR(TASK_COMPLEX_GANG_FOLLOWER);
CASE_FOR(TASK_COMPLEX_WALK_ALONGSIDE_PED);
CASE_FOR(TASK_COMPLEX_PARTNER_SHOVE);
CASE_FOR(TASK_COMPLEX_SIGNAL_AT_PED);
CASE_FOR(TASK_COMPLEX_PASS_OBJECT);
CASE_FOR(TASK_COMPLEX_GANG_HASSLE_PED);
CASE_FOR(TASK_COMPLEX_WAIT_FOR_PED);
CASE_FOR(TASK_SIMPLE_DO_HAND_SIGNAL);
ECASE(TASK_COMPLEX_REACT_TO_ATTACK);
ECASE(TASK_SIMPLE_BE_KICKED_ON_GROUND);
ECASE(TASK_SIMPLE_BE_HIT);
ECASE(TASK_SIMPLE_BE_HIT_WHILE_MOVING);
ECASE(TASK_COMPLEX_SIDE_STEP_AND_SHOOT);
ECASE(TASK_SIMPLE_DRIVEBY_SHOOT);
ECASE(TASK_SIMPLE_DRIVEBY_WATCH_FOR_TARGET);
ECASE(TASK_COMPLEX_DO_DRIVEBY);
ECASE(TASK_KILL_ALL_THREATS);
ECASE(TASK_KILL_PED_GROUP_ON_FOOT);
ECASE(TASK_SIMPLE_FIGHT);
ECASE(TASK_SIMPLE_USE_GUN);
ECASE(TASK_SIMPLE_THROW_PROJECTILE);
ECASE(TASK_SIMPLE_FIGHT_CTRL);
ECASE(TASK_SIMPLE_GUN_CTRL);
ECASE(TASK_SIMPLE_THROW_CTRL);
ECASE(TASK_SIMPLE_GANG_DRIVEBY);
ECASE(TASK_COMPLEX_KILL_PED_ON_FOOT_TIMED);
ECASE(TASK_COMPLEX_KILL_PED_ON_FOOT_STAND_STILL);
ECASE(TASK_UNUSED2);
ECASE(TASK_KILL_PED_ON_FOOT_WHILE_DUCKING);
ECASE(TASK_SIMPLE_STEALTH_KILL);
ECASE(TASK_COMPLEX_KILL_PED_ON_FOOT_STEALTH);
ECASE(TASK_COMPLEX_KILL_PED_ON_FOOT_KINDA_STAND_STILL);
ECASE(TASK_COMPLEX_KILL_PED_AND_REENTER_CAR);
ECASE(TASK_COMPLEX_ROAD_RAGE);
ECASE(TASK_KILL_PED_FROM_BOAT);
ECASE(TASK_SIMPLE_SET_CHAR_IGNORE_WEAPON_RANGE_FLAG);
ECASE(TASK_SEEK_COVER_UNTIL_TARGET_DEAD);
ECASE(TASK_SIMPLE_ARREST_PED);
ECASE(TASK_COMPLEX_ARREST_PED);
ECASE(TASK_SIMPLE_BE_ARRESTED);
ECASE(TASK_COMPLEX_POLICE_PURSUIT);
ECASE(TASK_COMPLEX_BE_COP);
ECASE(TASK_COMPLEX_KILL_CRIMINAL);
ECASE(TASK_COMPLEX_COP_IN_CAR);
ECASE(TASK_SIMPLE_INFORM_GROUP);
ECASE(TASK_COMPLEX_GANG_LEADER);
ECASE(TASK_COMPLEX_PARTNER_DEAL);
ECASE(TASK_COMPLEX_PARTNER_GREET);
ECASE(TASK_COMPLEX_PARTNER_CHAT);
ECASE(TASK_COMPLEX_GANG_HASSLE_VEHICLE);
ECASE(TASK_COMPLEX_WALK_WITH_PED);
ECASE(TASK_COMPLEX_GANG_FOLLOWER);
ECASE(TASK_COMPLEX_WALK_ALONGSIDE_PED);
ECASE(TASK_COMPLEX_PARTNER_SHOVE);
ECASE(TASK_COMPLEX_SIGNAL_AT_PED);
ECASE(TASK_COMPLEX_PASS_OBJECT);
ECASE(TASK_COMPLEX_GANG_HASSLE_PED);
ECASE(TASK_COMPLEX_WAIT_FOR_PED);
ECASE(TASK_SIMPLE_DO_HAND_SIGNAL);
//CASE_FOR(TASK_COMPLEX_THROW_OBJECT_BEING_HELD);
CASE_FOR(TASK_COMPLEX_BE_IN_COUPLE);
CASE_FOR(TASK_COMPLEX_GOTO_VEHICLE_AND_LEAN);
CASE_FOR(TASK_COMPLEX_LEAN_ON_VEHICLE);
CASE_FOR(TASK_COMPLEX_CHAT);
CASE_FOR(TASK_COMPLEX_GANG_JOIN_RESPOND);
CASE_FOR(TASK_ZONE_RESPONSE);
CASE_FOR(TASK_SIMPLE_TOGGLE_PED_THREAT_SCANNER);
CASE_FOR(TASK_FINISHED);
CASE_FOR(TASK_SIMPLE_JETPACK);
CASE_FOR(TASK_SIMPLE_SWIM);
CASE_FOR(TASK_COMPLEX_SWIM_AND_CLIMB_OUT);
CASE_FOR(TASK_SIMPLE_DUCK_TOGGLE);
CASE_FOR(TASK_WAIT_FOR_MATCHING_AREA_CODES);
CASE_FOR(TASK_SIMPLE_ON_ESCALATOR);
CASE_FOR(TASK_COMPLEX_PROSTITUTE_SOLICIT);
CASE_FOR(TASK_INTERIOR_USE_INFO);
CASE_FOR(TASK_INTERIOR_GOTO_INFO);
CASE_FOR(TASK_INTERIOR_BE_IN_HOUSE);
CASE_FOR(TASK_INTERIOR_BE_IN_OFFICE);
CASE_FOR(TASK_INTERIOR_BE_IN_SHOP);
CASE_FOR(TASK_INTERIOR_SHOPKEEPER);
CASE_FOR(TASK_INTERIOR_LIE_IN_BED);
CASE_FOR(TASK_INTERIOR_SIT_ON_CHAIR);
CASE_FOR(TASK_INTERIOR_SIT_AT_DESK);
CASE_FOR(TASK_INTERIOR_LEAVE);
CASE_FOR(TASK_INTERIOR_SIT_IN_RESTAURANT);
CASE_FOR(TASK_INTERIOR_RESERVED2);
CASE_FOR(TASK_INTERIOR_RESERVED3);
CASE_FOR(TASK_INTERIOR_RESERVED4);
CASE_FOR(TASK_INTERIOR_RESERVED5);
CASE_FOR(TASK_INTERIOR_RESERVED6);
CASE_FOR(TASK_INTERIOR_RESERVED7);
CASE_FOR(TASK_INTERIOR_RESERVED8);
CASE_FOR(TASK_GROUP_FOLLOW_LEADER_ANY_MEANS);
CASE_FOR(TASK_GROUP_FOLLOW_LEADER_WITH_LIMITS);
CASE_FOR(TASK_GROUP_KILL_THREATS_BASIC);
CASE_FOR(TASK_GROUP_KILL_PLAYER_BASIC);
CASE_FOR(TASK_GROUP_STARE_AT_PED);
CASE_FOR(TASK_GROUP_FLEE_THREAT);
CASE_FOR(TASK_GROUP_PARTNER_DEAL);
CASE_FOR(TASK_GROUP_PARTNER_GREET);
CASE_FOR(TASK_GROUP_HASSLE_SEXY_PED);
CASE_FOR(TASK_GROUP_HASSLE_THREAT);
CASE_FOR(TASK_GROUP_USE_MEMBER_DECISION);
CASE_FOR(TASK_GROUP_EXIT_CAR);
CASE_FOR(TASK_GROUP_ENTER_CAR);
CASE_FOR(TASK_GROUP_ENTER_CAR_AND_PERFORM_SEQUENCE);
CASE_FOR(TASK_GROUP_RESPOND_TO_LEADER_COMMAND);
CASE_FOR(TASK_GROUP_HAND_SIGNAL);
CASE_FOR(TASK_GROUP_DRIVEBY);
CASE_FOR(TASK_GROUP_HASSLE_THREAT_PASSIVE);
CASE_FOR(TASK_COMPLEX_USE_MOBILE_PHONE);
CASE_FOR(TASK_SIMPLE_PHONE_TALK);
CASE_FOR(TASK_SIMPLE_PHONE_IN);
CASE_FOR(TASK_SIMPLE_PHONE_OUT);
CASE_FOR(TASK_COMPLEX_USE_GOGGLES);
CASE_FOR(TASK_SIMPLE_GOGGLES_ON);
CASE_FOR(TASK_SIMPLE_GOGGLES_OFF);
CASE_FOR(TASK_SIMPLE_INFORM_RESPECTED_FRIENDS);
CASE_FOR(TASK_COMPLEX_USE_SCRIPTED_BRAIN);
CASE_FOR(TASK_SIMPLE_FINISH_BRAIN);
ECASE(TASK_COMPLEX_BE_IN_COUPLE);
ECASE(TASK_COMPLEX_GOTO_VEHICLE_AND_LEAN);
ECASE(TASK_COMPLEX_LEAN_ON_VEHICLE);
ECASE(TASK_COMPLEX_CHAT);
ECASE(TASK_COMPLEX_GANG_JOIN_RESPOND);
ECASE(TASK_ZONE_RESPONSE);
ECASE(TASK_SIMPLE_TOGGLE_PED_THREAT_SCANNER);
ECASE(TASK_FINISHED);
ECASE(TASK_SIMPLE_JETPACK);
ECASE(TASK_SIMPLE_SWIM);
ECASE(TASK_COMPLEX_SWIM_AND_CLIMB_OUT);
ECASE(TASK_SIMPLE_DUCK_TOGGLE);
ECASE(TASK_WAIT_FOR_MATCHING_AREA_CODES);
ECASE(TASK_SIMPLE_ON_ESCALATOR);
ECASE(TASK_COMPLEX_PROSTITUTE_SOLICIT);
ECASE(TASK_INTERIOR_USE_INFO);
ECASE(TASK_INTERIOR_GOTO_INFO);
ECASE(TASK_INTERIOR_BE_IN_HOUSE);
ECASE(TASK_INTERIOR_BE_IN_OFFICE);
ECASE(TASK_INTERIOR_BE_IN_SHOP);
ECASE(TASK_INTERIOR_SHOPKEEPER);
ECASE(TASK_INTERIOR_LIE_IN_BED);
ECASE(TASK_INTERIOR_SIT_ON_CHAIR);
ECASE(TASK_INTERIOR_SIT_AT_DESK);
ECASE(TASK_INTERIOR_LEAVE);
ECASE(TASK_INTERIOR_SIT_IN_RESTAURANT);
ECASE(TASK_INTERIOR_RESERVED2);
ECASE(TASK_INTERIOR_RESERVED3);
ECASE(TASK_INTERIOR_RESERVED4);
ECASE(TASK_INTERIOR_RESERVED5);
ECASE(TASK_INTERIOR_RESERVED6);
ECASE(TASK_INTERIOR_RESERVED7);
ECASE(TASK_INTERIOR_RESERVED8);
ECASE(TASK_GROUP_FOLLOW_LEADER_ANY_MEANS);
ECASE(TASK_GROUP_FOLLOW_LEADER_WITH_LIMITS);
ECASE(TASK_GROUP_KILL_THREATS_BASIC);
ECASE(TASK_GROUP_KILL_PLAYER_BASIC);
ECASE(TASK_GROUP_STARE_AT_PED);
ECASE(TASK_GROUP_FLEE_THREAT);
ECASE(TASK_GROUP_PARTNER_DEAL);
ECASE(TASK_GROUP_PARTNER_GREET);
ECASE(TASK_GROUP_HASSLE_SEXY_PED);
ECASE(TASK_GROUP_HASSLE_THREAT);
ECASE(TASK_GROUP_USE_MEMBER_DECISION);
ECASE(TASK_GROUP_EXIT_CAR);
ECASE(TASK_GROUP_ENTER_CAR);
ECASE(TASK_GROUP_ENTER_CAR_AND_PERFORM_SEQUENCE);
ECASE(TASK_GROUP_RESPOND_TO_LEADER_COMMAND);
ECASE(TASK_GROUP_HAND_SIGNAL);
ECASE(TASK_GROUP_DRIVEBY);
ECASE(TASK_GROUP_HASSLE_THREAT_PASSIVE);
ECASE(TASK_COMPLEX_USE_MOBILE_PHONE);
ECASE(TASK_SIMPLE_PHONE_TALK);
ECASE(TASK_SIMPLE_PHONE_IN);
ECASE(TASK_SIMPLE_PHONE_OUT);
ECASE(TASK_COMPLEX_USE_GOGGLES);
ECASE(TASK_SIMPLE_GOGGLES_ON);
ECASE(TASK_SIMPLE_GOGGLES_OFF);
ECASE(TASK_SIMPLE_INFORM_RESPECTED_FRIENDS);
ECASE(TASK_COMPLEX_USE_SCRIPTED_BRAIN);
ECASE(TASK_SIMPLE_FINISH_BRAIN);
//CASE_FOR(TASK_COMPLEX_A);
//CASE_FOR(TASK_COMPLEX_B);
//CASE_FOR(TASK_COMPLEX_C);
//CASE_FOR(TASK_COMPLEX_D);
//CASE_FOR(TASK_COMPLEX_E);
default:
NOTSA_UNREACHABLE("Invalid task type: {}", (int)taskType);
return std::nullopt;
}
#undef CASE_FOR
}
template <>
struct std::formatter<eTaskType> : std::formatter<std::string> {
auto format(eTaskType tt, format_context& ctx) const {
return formatter<string>::format(std::format("{} ({})", GetTaskTypeName(tt), (int)tt), ctx);
}
};

View File

@ -2757,7 +2757,7 @@ void CEventHandler::ComputeVehiclePotentialCollisionResponse(CEventPotentialGetR
return { new CTaskSimpleHandsUp{ 3000 }, nullptr }; // 0x4C117B
}
} else {
if (rndChance > chanceForHornNeeded && !e->m_Vehicle->m_nHornCounter) {
if (rndChance > chanceForHornNeeded && !e->m_Vehicle->m_HornCounter) {
return {};
}
if (rndChance > chanceToEvadeBack) {
@ -2767,7 +2767,7 @@ void CEventHandler::ComputeVehiclePotentialCollisionResponse(CEventPotentialGetR
return { new CTaskComplexEvasiveDiveAndGetUp{ e->m_Vehicle, 0, dirToAvoidVehicle, true }, nullptr }; // 0x4C11BA
} else if (e->m_Vehicle->GetStatus() == STATUS_PLAYER && m_Ped->IsCreatedBy(PED_GAME)) {
const auto currPedEvent = m_Ped->GetIntelligence()->GetEventHandler().GetHistory().GetCurrentEvent();
if (e->m_Vehicle->m_nHornCounter && (!currPedEvent || currPedEvent->GetEventType() != EVENT_POTENTIAL_GET_RUN_OVER)) { // 0x4C12A0
if (e->m_Vehicle->m_HornCounter && (!currPedEvent || currPedEvent->GetEventType() != EVENT_POTENTIAL_GET_RUN_OVER)) { // 0x4C12A0
const auto rndNum = CGeneral::GetRandomNumberInRange(0, 1000);
if (rndNum < 25 && !m_Ped->IsCop()) { // 0x4C12C0
return { new CTaskComplexFleeEntity{ e->m_Vehicle, false, 60.f, CGeneral::GetRandomNumberInRange(750, 1250)}, nullptr };

View File

@ -280,7 +280,7 @@ bool CEventKnockOffBike::SetPedSafePosition(CPed* ped)
{
if (m_vehicle->IsBike()) {
CBike* bike = m_vehicle->AsBike();
bike->m_RideAnimData.m_fAnimLean = 0.0f;
bike->m_RideAnimData.LeanAngle = 0.0f;
bike->m_bLeanMatrixCalculated = false;
ped->SetPedPositionInCar();
}

View File

@ -25,6 +25,6 @@ void FxInfoEmSpeed_c::GetValue(float currentTime, float mult, float totalTime, f
m_InterpInfo.GetVal(values, currentTime);
auto& emission = *static_cast<EmissionInfo_t*>(info);
emission.m_fSpeed = values[0];
emission.m_Speed = values[0];
emission.m_fSpeedBias = values[1];
}

View File

@ -9,7 +9,7 @@ struct EmissionInfo_t {
CVector m_SizeMin;
CVector m_SizeMax;
float m_fSpeed;
float m_Speed;
float m_fSpeedBias;
CVector m_Direction;
@ -33,7 +33,7 @@ struct EmissionInfo_t {
m_fLife = 1.0f;
m_fRadius = 0.0f;
m_fSpeed = 0.0f;
m_Speed = 0.0f;
m_fSpeedBias = 0.0f;
m_fAngleMin = 0.0f;

Some files were not shown because too many files have changed in this diff Show More