diff options
-rw-r--r-- | src/audio/AudioManager.cpp | 357 | ||||
-rw-r--r-- | src/control/AutoPilot.cpp | 81 | ||||
-rw-r--r-- | src/control/AutoPilot.h | 5 | ||||
-rw-r--r-- | src/core/Frontend.cpp | 8 | ||||
-rw-r--r-- | src/core/Pools.cpp | 78 | ||||
-rw-r--r-- | src/core/config.h | 4 | ||||
-rw-r--r-- | src/entities/Entity.cpp | 105 | ||||
-rw-r--r-- | src/entities/Entity.h | 5 | ||||
-rw-r--r-- | src/peds/Ped.cpp | 42 | ||||
-rw-r--r-- | src/peds/Ped.h | 5 | ||||
-rw-r--r-- | src/peds/PlayerPed.cpp | 37 | ||||
-rw-r--r-- | src/peds/PlayerPed.h | 7 | ||||
-rw-r--r-- | src/render/Hud.cpp | 8 | ||||
-rw-r--r-- | src/vehicles/Automobile.cpp | 26 | ||||
-rw-r--r-- | src/vehicles/Automobile.h | 6 | ||||
-rw-r--r-- | src/vehicles/Boat.cpp | 23 | ||||
-rw-r--r-- | src/vehicles/Boat.h | 7 | ||||
-rw-r--r-- | src/vehicles/Vehicle.cpp | 125 | ||||
-rw-r--r-- | src/vehicles/Vehicle.h | 6 | ||||
-rw-r--r-- | src/weapons/Weapon.cpp | 28 | ||||
-rw-r--r-- | src/weapons/Weapon.h | 5 |
21 files changed, 800 insertions, 168 deletions
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index 28ddfeee..523092fd 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -7910,11 +7910,13 @@ cAudioManager::ProcessSpecial() bool cAudioManager::ProcessTrainNoise(cVehicleParams *params) { + const float SOUND_INTENSITY = 300.0f; + CTrain *train; uint8 emittingVol; float speedMultipler; - if (params->m_fDistance >= 90000.f) + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) return false; if (params->m_fVelocityChange > 0.0f) { @@ -7923,8 +7925,8 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params) speedMultipler = Min(1.0f, train->m_fSpeed * 250.f / 51.f); emittingVol = (75.f * speedMultipler); if (train->m_fWagonPosition == 0.0f) { - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 300.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 32; m_sQueueSample.m_nSampleIndex = SFX_TRAIN_FAR; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; @@ -7936,7 +7938,7 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 3.0f; - m_sQueueSample.m_fSoundIntensity = 300.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 3; m_sQueueSample.m_bReverbFlag = true; @@ -7944,9 +7946,10 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params) AddSampleToRequestedQueue(); } } - if (params->m_fDistance < 4900.f) { - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 70.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { + const float SOUND_INTENSITY = 70.0f; + if (params->m_fDistance < SQR(SOUND_INTENSITY)) { + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 33; m_sQueueSample.m_nSampleIndex = SFX_TRAIN_NEAR; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; @@ -7958,7 +7961,7 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = 70.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 3; m_sQueueSample.m_bReverbFlag = true; @@ -8070,12 +8073,14 @@ cAudioManager::ProcessVehicle(CVehicle *veh) bool cAudioManager::ProcessVehicleDoors(cVehicleParams *params) { + const float SOUND_INTENSITY = 40.0f; + CAutomobile *automobile; int8 doorState; int32 emittingVol; float velocity; - if (params->m_fDistance >= 1600.f) + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) return false; automobile = (CAutomobile *)params->m_pVehicle; @@ -8087,7 +8092,7 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams *params) velocity = Min(0.3f, Abs(automobile->Doors[i].m_fAngVel)); if (velocity > 0.0035f) { emittingVol = (100.f * velocity * 10.f / 3.f); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 40.f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume) { m_sQueueSample.m_nCounter = i + 6; m_sQueueSample.m_nSampleIndex = m_anRandomTable[1] % 6 + SFX_COL_CAR_PANEL_1; @@ -8100,7 +8105,7 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams *params) m_sQueueSample.m_nLoopStart = 0; m_sQueueSample.m_nLoopEnd = -1; m_sQueueSample.m_fSpeedMultiplier = 1.0f; - m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = true; m_sQueueSample.m_bReverbFlag = true; m_sQueueSample.m_bRequireReflection = true; @@ -8116,13 +8121,14 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams *params) void cAudioManager::ProcessVehicleEngine(cVehicleParams *params) { + const float SOUND_INTENSITY = 50.0f; + CVehicle *playerVeh; CVehicle *veh; CAutomobile *automobile; float relativeGearChange; float relativeChange; uint8 volume; - eSfxSample accelerationSample; int32 freq = 0; // uinitialized variable uint8 emittingVol; cTransmission *transmission; @@ -8130,7 +8136,7 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams *params) float modificator; float traction = 0.f; - if (params->m_fDistance < SQR(50.f)) { + if (params->m_fDistance < SQR(SOUND_INTENSITY)) { playerVeh = FindPlayerVehicle(); veh = params->m_pVehicle; if (playerVeh == veh && veh->GetStatus() == STATUS_WRECKED) { @@ -8204,72 +8210,37 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams *params) freq = 13000.f * modificator + 14000; if (modificator >= 0.75f) { emittingVol = 120; - volume = ComputeVolume(120, 50.f, m_sQueueSample.m_fDistance); + volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); } else { emittingVol = modificator * 4.0f / 3.0f * 40.f + 80.f; - volume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance); + volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); } } else { modificator = 0.f; emittingVol = 80; - volume = ComputeVolume(80, 50.f, m_sQueueSample.m_fDistance); + volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); } m_sQueueSample.m_nVolume = volume; if (m_sQueueSample.m_nVolume) { if (automobile->GetStatus() == STATUS_SIMPLE) { if (modificator < 0.02f) { - m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_bEngineSoundType + SFX_CAR_REV_10; - freq = 10000.f * modificator + 22050; + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_bEngineSoundType - 1 + SFX_CAR_IDLE_1; + freq = modificator * 10000 + 22050; m_sQueueSample.m_nCounter = 52; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nFrequency = freq + 100 * m_sQueueSample.m_nEntityIndex % 1000; - if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_6 || m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6) - m_sQueueSample.m_nFrequency /= 2; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 8; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - return; + } else { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nAccelerationSampleIndex; + m_sQueueSample.m_nCounter = 2; } - accelerationSample = aVehicleSettings[params->m_nIndex].m_nAccelerationSampleIndex; } else { if (automobile->m_fGasPedal < 0.05f) { - m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_bEngineSoundType + SFX_CAR_REV_10; // to recheck idle sounds start - // 1 postion later - freq = 10000.f * modificator + 22050; + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_bEngineSoundType - 1 + SFX_CAR_IDLE_1; + freq = modificator * 10000 + 22050; m_sQueueSample.m_nCounter = 52; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nFrequency = freq + 100 * m_sQueueSample.m_nEntityIndex % 1000; - if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_6 || m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6) - m_sQueueSample.m_nFrequency /= 2; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 8; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - return; + } else { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nAccelerationSampleIndex; + m_sQueueSample.m_nCounter = 2; } - accelerationSample = aVehicleSettings[params->m_nIndex].m_nAccelerationSampleIndex; } - m_sQueueSample.m_nSampleIndex = accelerationSample; - m_sQueueSample.m_nCounter = 2; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_nReleasingVolumeModificator = 3; @@ -8281,13 +8252,12 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams *params) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 8; m_sQueueSample.m_bReverbFlag = true; m_sQueueSample.m_bRequireReflection = false; AddSampleToRequestedQueue(); - return; } } } @@ -8296,23 +8266,24 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams *params) void cAudioManager::ProcessVehicleHorn(cVehicleParams *params) { + const float SOUND_INTENSITY = 40.0f; + CAutomobile *automobile; - if (params->m_fDistance < 1600.f) { + if (params->m_fDistance < SQR(SOUND_INTENSITY)) { automobile = (CAutomobile *)params->m_pVehicle; if ((!automobile->m_bSirenOrAlarm || !UsesSirenSwitching(params->m_nIndex)) && automobile->m_modelIndex != MI_MRWHOOP) { if (automobile->m_nCarHornTimer) { if (params->m_pVehicle->GetStatus() != STATUS_PLAYER) { - if (automobile->m_nCarHornTimer > 44) - automobile->m_nCarHornTimer = 44; + automobile->m_nCarHornTimer = Min(44, automobile->m_nCarHornTimer); if (automobile->m_nCarHornTimer == 44) - automobile->field_22D = (uint8(m_FrameCounter) + uint8(m_sQueueSample.m_nEntityIndex)) & 7; + automobile->field_22D = (m_FrameCounter + m_sQueueSample.m_nEntityIndex) & 7; if (!hornPatternsArray[automobile->field_22D][44 - automobile->m_nCarHornTimer]) return; } CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(80, 40.f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(80, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume) { m_sQueueSample.m_nCounter = 4; m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nHornSample; @@ -8325,7 +8296,7 @@ cAudioManager::ProcessVehicleHorn(cVehicleParams *params) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 5.0f; - m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 3; m_sQueueSample.m_bReverbFlag = true; @@ -8364,7 +8335,9 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) case SOUND_CAR_DOOR_CLOSE_FRONT_RIGHT: case SOUND_CAR_DOOR_CLOSE_BACK_LEFT: case SOUND_CAR_DOOR_CLOSE_BACK_RIGHT: - maxDist = 2500.f; + { + const float SOUND_INTENSITY = 50.0f; + maxDist = SQR(SOUND_INTENSITY); emittingVol = m_anRandomTable[2] % 5 + 122; switch (aVehicleSettings[params->m_nIndex].m_bDoorType) { case 0: @@ -8386,16 +8359,19 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bRequireReflection = true; break; + } case SOUND_CAR_DOOR_OPEN_BONNET: case SOUND_CAR_DOOR_OPEN_BUMPER: case SOUND_CAR_DOOR_OPEN_FRONT_LEFT: case SOUND_CAR_DOOR_OPEN_FRONT_RIGHT: case SOUND_CAR_DOOR_OPEN_BACK_LEFT: case SOUND_CAR_DOOR_OPEN_BACK_RIGHT: - maxDist = 2500.f; + { + const float SOUND_INTENSITY = 50.0f; + maxDist = SQR(SOUND_INTENSITY); emittingVol = m_anRandomTable[1] % 10 + 117; switch (aVehicleSettings[params->m_nIndex].m_bDoorType) { case 0: @@ -8417,11 +8393,14 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bRequireReflection = true; break; + } case SOUND_CAR_WINDSHIELD_CRACK: - maxDist = 900.f; + { + const float SOUND_INTENSITY = 30.0f; + maxDist = SQR(SOUND_INTENSITY); m_sQueueSample.m_nSampleIndex = SFX_GLASS_CRACK; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 68; @@ -8429,11 +8408,13 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_CRACK); m_sQueueSample.m_nReleasingVolumeModificator = 5; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - break; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + } break; case SOUND_CAR_JUMP: + { + const float SOUND_INTENSITY = 35.0f; emittingVol = Max(80.f, 2 * (100.f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i])); - maxDist = 1225.f; + maxDist = SQR(SOUND_INTENSITY); m_sQueueSample.m_nSampleIndex = SFX_TYRE_BUMP; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = iWheelIndex++; @@ -8447,21 +8428,27 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) } m_sQueueSample.m_nReleasingVolumeModificator = 6; m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = 35.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; break; + } case SOUND_CAR_ENGINE_START: + { + const float SOUND_INTENSITY = 40.0f; emittingVol = 60; - maxDist = 1600.f; + maxDist = SQR(SOUND_INTENSITY); m_sQueueSample.m_nSampleIndex = SFX_CAR_STARTER; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 33; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_STARTER); m_sQueueSample.m_nReleasingVolumeModificator = 1; m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bRequireReflection = true; break; + } case SOUND_CAR_LIGHT_BREAK: + { + const float SOUND_INTENSITY = 30.0f; m_sQueueSample.m_nSampleIndex = SFX_GLASS_SHARD_1; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 37; @@ -8469,12 +8456,15 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); m_sQueueSample.m_nReleasingVolumeModificator = 5; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = 900.f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); emittingVol = m_anRandomTable[4] % 10 + 30; break; + } case SOUND_CAR_HYDRAULIC_1: case SOUND_CAR_HYDRAULIC_2: + { + const float SOUND_INTENSITY = 35.0f; if (event == MOONBEAM) // todo check m_sQueueSample.m_nFrequency = 15600; else @@ -8485,24 +8475,30 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); m_sQueueSample.m_nReleasingVolumeModificator = 5; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 35.0f; - maxDist = 1225.f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); emittingVol = m_anRandomTable[0] % 15 + 55; break; + } case SOUND_CAR_HYDRAULIC_3: + { + const float SOUND_INTENSITY = 35.0f; m_sQueueSample.m_nSampleIndex = SFX_SUSPENSION_SLOW_MOVE_LOOP; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 86; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SUSPENSION_SLOW_MOVE_LOOP); m_sQueueSample.m_nReleasingVolumeModificator = 5; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 35.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_nReleasingVolumeDivider = 7; noReflections = true; - maxDist = 1225.f; + maxDist = SQR(SOUND_INTENSITY); emittingVol = m_anRandomTable[0] % 15 + 55; break; + } case SOUND_CAR_JERK: + { + const float SOUND_INTENSITY = 35.0f; m_sQueueSample.m_nSampleIndex = SFX_SHAG_SUSPENSION; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 87; @@ -8510,11 +8506,14 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); m_sQueueSample.m_nReleasingVolumeModificator = 5; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 35.0f; - maxDist = 1225.f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); emittingVol = m_anRandomTable[1] % 15 + 55; break; + } case SOUND_CAR_SPLASH: + { + const float SOUND_INTENSITY = 40.0f; vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; if (vol <= 300.f) continue; @@ -8529,75 +8528,93 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) m_sQueueSample.m_nFrequency = (7000.f * relVol) + 6000; m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; emittingVol = (55.f * relVol); - maxDist = 1600.f; + maxDist = SQR(SOUND_INTENSITY); break; + } case SOUND_17: + { + const float SOUND_INTENSITY = 50.0f; m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_THUMB_OFF; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 47; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_BOAT_THUMB_OFF) + RandomDisplacement(600); m_sQueueSample.m_nReleasingVolumeModificator = 2; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; emittingVol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; - maxDist = 2500.f; + maxDist = SQR(SOUND_INTENSITY); break; + } case SOUND_18: case SOUND_19: + { + const float SOUND_INTENSITY = 35.0f; m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 59; m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 11025; m_sQueueSample.m_nReleasingVolumeModificator = 5; m_sQueueSample.m_fSpeedMultiplier = 5.0f; - m_sQueueSample.m_fSoundIntensity = 35.0f; - maxDist = 1225.f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); emittingVol = m_anRandomTable[1] % 20 + 70; break; + } case SOUND_CAR_TANK_TURRET_ROTATE: + { + const float SOUND_INTENSITY = 40.0f; vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; - if (vol > 0.038400002f) - vol = 0.038400002f; + if (vol > 96.0f / 2500.0f) + vol = 96.0f / 2500.0f; m_sQueueSample.m_nSampleIndex = SFX_TANK_TURRET; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 79; - m_sQueueSample.m_nFrequency = (3000.f * vol * 26.041666f) + 9000; + m_sQueueSample.m_nFrequency = (3000.f * vol * 2500.0f / 96.0f) + 9000; m_sQueueSample.m_nReleasingVolumeModificator = 2; m_sQueueSample.m_fSpeedMultiplier = 2.0f; m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSoundIntensity = 40.0f; - emittingVol = (37.f * vol * 26.041666f) + 90; - maxDist = 1600.f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + emittingVol = (37.f * vol * 2500.0f / 96.0f) + 90; + maxDist = SQR(SOUND_INTENSITY); noReflections = true; break; + } case SOUND_CAR_BOMB_TICK: + { + const float SOUND_INTENSITY = 30.0f; m_sQueueSample.m_nSampleIndex = SFX_BOMB_BEEP; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 80; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BOMB_BEEP); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = 900.f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); m_sQueueSample.m_bRequireReflection = true; emittingVol = 60; break; + } case SOUND_PLANE_ON_GROUND: + { + const float SOUND_INTENSITY = 180.0f; m_sQueueSample.m_nSampleIndex = SFX_JUMBO_LAND_WHEELS; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 81; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_LAND_WHEELS); m_sQueueSample.m_nReleasingVolumeModificator = 2; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 180.0f; - maxDist = 32400.f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); emittingVol = m_anRandomTable[4] % 25 + 75; break; + } case SOUND_WEAPON_SHOT_FIRED: + { + const float SOUND_INTENSITY = 120.0f; emittingVol = m_anRandomTable[2]; - maxDist = 14400.f; + maxDist = SQR(SOUND_INTENSITY); m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = GunIndex++; @@ -8608,9 +8625,12 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 120.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; break; + } case SOUND_WEAPON_HIT_VEHICLE: + { + const float SOUND_INTENSITY = 40.0f; m_sQueueSample.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % ARRAY_SIZE(m_anRandomTable)] % 6 + SFX_BULLET_CAR_1; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 34; @@ -8618,25 +8638,29 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); m_sQueueSample.m_nReleasingVolumeModificator = 7; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 40.0f; - maxDist = 1600.f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); emittingVol = m_anRandomTable[3] % 20 + 90; break; + } case SOUND_BOMB_TIMED_ACTIVATED: case SOUND_55: case SOUND_BOMB_ONIGNITION_ACTIVATED: case SOUND_BOMB_TICK: + { + const float SOUND_INTENSITY = 50.0f; m_sQueueSample.m_nSampleIndex = SFX_ARM_BOMB; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 36; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ARM_BOMB); m_sQueueSample.m_nReleasingVolumeModificator = 0; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bRequireReflection = true; emittingVol = 50; - maxDist = 2500.f; + maxDist = SQR(SOUND_INTENSITY); break; + } case SOUND_PED_HELI_PLAYER_FOUND: pedParams.m_pPed = nil; pedParams.m_bDistanceCalculated = false; @@ -8654,18 +8678,23 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) SetupPedComments(&pedParams, SOUND_PED_BODYCAST_HIT); continue; case SOUND_WATER_FALL: + { + const float SOUND_INTENSITY = 40.0f; m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 15; m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 16000; m_sQueueSample.m_nReleasingVolumeModificator = 1; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 40.0f; - maxDist = 1600.f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); m_sQueueSample.m_bRequireReflection = true; emittingVol = m_anRandomTable[4] % 20 + 90; break; + } case SOUND_SPLATTER: + { + const float SOUND_INTENSITY = 40.0f; m_sQueueSample.m_nSampleIndex = CrunchOffset + SFX_PED_CRUNCH_1; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nCounter = 48; @@ -8674,15 +8703,16 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) m_sQueueSample.m_fSpeedMultiplier = 0.0f; m_sQueueSample.m_fSoundIntensity = 40.0f; ++CrunchOffset; - maxDist = 1600.f; + maxDist = SQR(SOUND_INTENSITY); emittingVol = m_anRandomTable[4] % 20 + 55; - CrunchOffset &= 1u; + CrunchOffset %= 2; m_sQueueSample.m_bRequireReflection = true; break; + } case SOUND_CAR_PED_COLLISION: - vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; - if (20.f < vol) - vol = 20.f; + { + const float SOUND_INTENSITY = 40.0f; + vol = Min(20.0f, m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]); emittingVol = (vol / 20.0f * 127.f); if (!emittingVol) continue; @@ -8693,16 +8723,17 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) / 2; m_sQueueSample.m_nReleasingVolumeModificator = 1; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 40.0f; - maxDist = 1600.f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); break; + } default: continue; } if (params->m_fDistance < maxDist) { CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { + if (m_sQueueSample.m_nVolume != 0) { if (noReflections) { m_sQueueSample.m_nLoopCount = 0; m_sQueueSample.m_bReleasingSoundFlag = false; @@ -8724,14 +8755,16 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) bool cAudioManager::ProcessVehicleReverseWarning(cVehicleParams *params) { + const float SOUND_INTENSITY = 50.0f; + CVehicle *veh = params->m_pVehicle; - if (params->m_fDistance >= 2500.f) + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) return false; if (veh->bEngineOn && veh->m_fGasPedal < 0.0f) { CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(60, 50.f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(60, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume) { m_sQueueSample.m_nCounter = 12; m_sQueueSample.m_nSampleIndex = SFX_REVERSE_WARNING; @@ -8744,7 +8777,7 @@ cAudioManager::ProcessVehicleReverseWarning(cVehicleParams *params) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 3.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 3; m_sQueueSample.m_bReverbFlag = true; @@ -8758,13 +8791,15 @@ cAudioManager::ProcessVehicleReverseWarning(cVehicleParams *params) bool cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params) { + const float SOUND_INTENSITY = 95.0f; + int32 emittingVol; uint32 freq; float modificator; int sampleFreq; float velocity; - if (params->m_fDistance >= 9025.f) + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) return false; if (params->m_pTransmission) { if (params->m_pVehicle->m_vecMoveSpeed.z) { @@ -8772,7 +8807,7 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params) if (velocity > 0.0f) { CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); emittingVol = 30.f * Min(1.f, velocity / (0.5f * params->m_pTransmission->fMaxVelocity)); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 95.f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume) { m_sQueueSample.m_nCounter = 0; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; @@ -8793,7 +8828,7 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = 95.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 4; m_sQueueSample.m_bReverbFlag = true; @@ -8809,7 +8844,9 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params) void cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params) { - if (params->m_fDistance < 12100.f) { + const float SOUND_INTENSITY = 110.0f; + + if (params->m_fDistance < SQR(SOUND_INTENSITY)) { CVehicle *veh = params->m_pVehicle; if (veh->m_bSirenOrAlarm == 0 && veh->m_nAlarmState <= 0) return; @@ -8819,7 +8856,7 @@ cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params) return; #endif CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(80, 110.f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(80, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume) { m_sQueueSample.m_nCounter = 5; if (UsesSiren(params->m_nIndex)) { @@ -8848,7 +8885,7 @@ cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 7.0f; - m_sQueueSample.m_fSoundIntensity = 110.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 5; m_sQueueSample.m_bReverbFlag = true; @@ -8862,13 +8899,15 @@ cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params) void cAudioManager::ProcessVehicleSkidding(cVehicleParams *params) { + const float SOUND_INTENSITY = 40.0f; + CAutomobile *automobile; cTransmission *transmission; int32 emittingVol; float newSkidVal = 0.0f; float skidVal = 0.0f; - if (params->m_fDistance >= 1600.f) + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) return; automobile = (CAutomobile *)params->m_pVehicle; if (!automobile->m_nWheelsOnGround) @@ -8903,7 +8942,7 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params) if (skidVal > 0.0f) { emittingVol = 50.f * skidVal; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 40.f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 3; switch (params->m_pVehicle->m_nSurfaceTouched) { @@ -8936,7 +8975,7 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 3.0f; - m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 3; m_sQueueSample.m_bReverbFlag = true; @@ -8948,15 +8987,17 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params) void cAudioManager::ProcessWaterCannon(int32) { + const float SOUND_INTENSITY = 900.0f; + for (int32 i = 0; i < NUM_WATERCANNONS; i++) { if (CWaterCannons::aCannons[i].m_nId) { m_sQueueSample.m_vecPos = CWaterCannons::aCannons[0].m_avecPos[CWaterCannons::aCannons[i].m_nCur]; float distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos); - if (distSquared < 900.f) { + if (distSquared < SOUND_INTENSITY) { m_sQueueSample.m_fDistance = Sqrt(distSquared); m_sQueueSample.m_nVolume = ComputeVolume(50, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_fSoundIntensity = 900.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_nFrequency = 15591; @@ -9039,13 +9080,15 @@ cAudioManager::ProcessWeather(int32 id) bool cAudioManager::ProcessWetRoadNoise(cVehicleParams *params) { + const float SOUND_INTENSITY = 30.0f; + float relativeVelocity; int32 emittingVol; float modificator; int freq; float velChange; - if (params->m_fDistance >= 900.f) + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) return false; if (params->m_pTransmission) { if (params->m_pVehicle->m_vecMoveSpeed.z) { @@ -9054,7 +9097,7 @@ cAudioManager::ProcessWetRoadNoise(cVehicleParams *params) CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); relativeVelocity = Min(1.0f, velChange / (0.5f * params->m_pTransmission->fMaxVelocity)); emittingVol = 23.0f * relativeVelocity * CWeather::WetRoads; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 30.f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume) { m_sQueueSample.m_nCounter = 1; m_sQueueSample.m_nSampleIndex = SFX_ROAD_NOISE; @@ -9069,7 +9112,7 @@ cAudioManager::ProcessWetRoadNoise(cVehicleParams *params) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 4; m_sQueueSample.m_bReverbFlag = true; @@ -9350,11 +9393,12 @@ cAudioManager::SetSpeakerConfig(int32 conf) const bool cAudioManager::SetupJumboEngineSound(uint8 vol, int32 freq) { - if (m_sQueueSample.m_fDistance >= 180.f) + const float SOUND_INTENSITY = 180.0f; + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) return false; uint8 emittingVol = vol - gJumboVolOffsetPercentage / 100; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 180.f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 3; m_sQueueSample.m_nSampleIndex = SFX_JUMBO_ENGINE; @@ -9367,7 +9411,7 @@ cAudioManager::SetupJumboEngineSound(uint8 vol, int32 freq) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = 180.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 4; m_sQueueSample.m_bReverbFlag = true; @@ -9380,10 +9424,11 @@ cAudioManager::SetupJumboEngineSound(uint8 vol, int32 freq) bool cAudioManager::SetupJumboFlySound(uint8 emittingVol) { - if (m_sQueueSample.m_fDistance >= 440.0f) + const float SOUND_INTENSITY = 440.0f; + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) return false; - int32 vol = ComputeVolume(emittingVol, 440.0f, m_sQueueSample.m_fDistance); + int32 vol = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); m_sQueueSample.m_nVolume = vol; if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nSampleIndex = SFX_JUMBO_DIST_FLY; @@ -9395,7 +9440,7 @@ cAudioManager::SetupJumboFlySound(uint8 emittingVol) m_sQueueSample.m_nLoopCount = 0; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_DIST_FLY); m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSoundIntensity = 440.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_fSpeedMultiplier = 4.0f; m_sQueueSample.m_bReverbFlag = true; @@ -9409,10 +9454,11 @@ cAudioManager::SetupJumboFlySound(uint8 emittingVol) bool cAudioManager::SetupJumboRumbleSound(uint8 emittingVol) { - if (m_sQueueSample.m_fDistance >= 240.f) + const float SOUND_INTENSITY = 240.0f; + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) return false; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 240.0f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 5; @@ -9426,7 +9472,7 @@ cAudioManager::SetupJumboRumbleSound(uint8 emittingVol) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = 240.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 12; m_sQueueSample.m_nOffset = 0; @@ -9445,14 +9491,15 @@ cAudioManager::SetupJumboRumbleSound(uint8 emittingVol) bool cAudioManager::SetupJumboTaxiSound(uint8 vol) { - if (m_sQueueSample.m_fDistance >= 180.f) + const float SOUND_INTENSITY = 180.0f; + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) return false; - uint8 emittingVol = (vol / 2) + ((vol / 2) * m_sQueueSample.m_fDistance / 180); + uint8 emittingVol = (vol / 2) + ((vol / 2) * m_sQueueSample.m_fDistance / SOUND_INTENSITY); - if (m_sQueueSample.m_fDistance / 180 < 0.7f) + if (m_sQueueSample.m_fDistance / SOUND_INTENSITY < 0.7f) emittingVol -= emittingVol * gJumboVolOffsetPercentage / 100; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 180.f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 1; @@ -9466,7 +9513,7 @@ cAudioManager::SetupJumboTaxiSound(uint8 vol) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = 180.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 4; m_sQueueSample.m_bReverbFlag = true; @@ -9479,10 +9526,12 @@ cAudioManager::SetupJumboTaxiSound(uint8 vol) bool cAudioManager::SetupJumboWhineSound(uint8 emittingVol, int32 freq) { - if (m_sQueueSample.m_fDistance >= 170.f) + const float SOUND_INTENSITY = 170.0f; + + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) return false; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 170.f, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_nCounter = 2; @@ -9496,7 +9545,7 @@ cAudioManager::SetupJumboWhineSound(uint8 emittingVol, int32 freq) m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = 170.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 4; m_sQueueSample.m_bReverbFlag = true; diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp index 69511bc8..96a1fedf 100644 --- a/src/control/AutoPilot.cpp +++ b/src/control/AutoPilot.cpp @@ -44,4 +44,83 @@ void CAutoPilot::RemoveOnePathNode() --m_nPathFindNodesCount; for (int i = 0; i < m_nPathFindNodesCount; i++) m_aPathFindNodesInfo[i] = m_aPathFindNodesInfo[i + 1]; -}
\ No newline at end of file +} + +#ifdef COMPATIBLE_SAVES +void CAutoPilot::Save(uint8*& buf) +{ + WriteSaveBuf<int32>(buf, m_nCurrentRouteNode); + WriteSaveBuf<int32>(buf, m_nNextRouteNode); + WriteSaveBuf<int32>(buf, m_nPrevRouteNode); + WriteSaveBuf<uint32>(buf, m_nTimeEnteredCurve); + WriteSaveBuf<uint32>(buf, m_nTimeToSpendOnCurrentCurve); + WriteSaveBuf<uint32>(buf, m_nCurrentPathNodeInfo); + WriteSaveBuf<uint32>(buf, m_nNextPathNodeInfo); + WriteSaveBuf<uint32>(buf, m_nPreviousPathNodeInfo); + WriteSaveBuf<uint32>(buf, m_nAntiReverseTimer); + WriteSaveBuf<uint32>(buf, m_nTimeToStartMission); + WriteSaveBuf<int8>(buf, m_nPreviousDirection); + WriteSaveBuf<int8>(buf, m_nCurrentDirection); + WriteSaveBuf<int8>(buf, m_nNextDirection); + WriteSaveBuf<int8>(buf, m_nCurrentLane); + WriteSaveBuf<int8>(buf, m_nNextLane); + WriteSaveBuf<uint8>(buf, m_nDrivingStyle); + WriteSaveBuf<uint8>(buf, m_nCarMission); + WriteSaveBuf<uint8>(buf, m_nTempAction); + WriteSaveBuf<uint32>(buf, m_nTimeTempAction); + WriteSaveBuf<float>(buf, m_fMaxTrafficSpeed); + WriteSaveBuf<uint8>(buf, m_nCruiseSpeed); + uint8 flags = 0; + if (m_bSlowedDownBecauseOfCars) flags |= BIT(0); + if (m_bSlowedDownBecauseOfPeds) flags |= BIT(1); + if (m_bStayInCurrentLevel) flags |= BIT(2); + if (m_bStayInFastLane) flags |= BIT(3); + if (m_bIgnorePathfinding) flags |= BIT(4); + WriteSaveBuf<uint8>(buf, flags); + SkipSaveBuf(buf, 2); + WriteSaveBuf<float>(buf, m_vecDestinationCoors.x); + WriteSaveBuf<float>(buf, m_vecDestinationCoors.y); + WriteSaveBuf<float>(buf, m_vecDestinationCoors.z); + SkipSaveBuf(buf, 32); + WriteSaveBuf<int16>(buf, m_nPathFindNodesCount); + SkipSaveBuf(buf, 6); +} + +void CAutoPilot::Load(uint8*& buf) +{ + m_nCurrentRouteNode = ReadSaveBuf<int32>(buf); + m_nNextRouteNode = ReadSaveBuf<int32>(buf); + m_nPrevRouteNode = ReadSaveBuf<int32>(buf); + m_nTimeEnteredCurve = ReadSaveBuf<uint32>(buf); + m_nTimeToSpendOnCurrentCurve = ReadSaveBuf<uint32>(buf); + m_nCurrentPathNodeInfo = ReadSaveBuf<uint32>(buf); + m_nNextPathNodeInfo = ReadSaveBuf<uint32>(buf); + m_nPreviousPathNodeInfo = ReadSaveBuf<uint32>(buf); + m_nAntiReverseTimer = ReadSaveBuf<uint32>(buf); + m_nTimeToStartMission = ReadSaveBuf<uint32>(buf); + m_nPreviousDirection = ReadSaveBuf<int8>(buf); + m_nCurrentDirection = ReadSaveBuf<int8>(buf); + m_nNextDirection = ReadSaveBuf<int8>(buf); + m_nCurrentLane = ReadSaveBuf<int8>(buf); + m_nNextLane = ReadSaveBuf<int8>(buf); + m_nDrivingStyle = (eCarDrivingStyle)ReadSaveBuf<uint8>(buf); + m_nCarMission = (eCarMission)ReadSaveBuf<uint8>(buf); + m_nTempAction = (eCarTempAction)ReadSaveBuf<uint8>(buf); + m_nTimeTempAction = ReadSaveBuf<uint32>(buf); + m_fMaxTrafficSpeed = ReadSaveBuf<float>(buf); + m_nCruiseSpeed = ReadSaveBuf<uint8>(buf); + uint8 flags = ReadSaveBuf<uint8>(buf); + m_bSlowedDownBecauseOfCars = !!(flags & BIT(0)); + m_bSlowedDownBecauseOfPeds = !!(flags & BIT(1)); + m_bStayInCurrentLevel = !!(flags & BIT(2)); + m_bStayInFastLane = !!(flags & BIT(3)); + m_bIgnorePathfinding = !!(flags & BIT(4)); + SkipSaveBuf(buf, 2); + m_vecDestinationCoors.x = ReadSaveBuf<float>(buf); + m_vecDestinationCoors.y = ReadSaveBuf<float>(buf); + m_vecDestinationCoors.z = ReadSaveBuf<float>(buf); + SkipSaveBuf(buf, 32); + m_nPathFindNodesCount = ReadSaveBuf<int16>(buf); + SkipSaveBuf(buf, 6); +} +#endif
\ No newline at end of file diff --git a/src/control/AutoPilot.h b/src/control/AutoPilot.h index e1066071..4c356f96 100644 --- a/src/control/AutoPilot.h +++ b/src/control/AutoPilot.h @@ -120,5 +120,10 @@ public: void ModifySpeed(float); void RemoveOnePathNode(); +#ifdef COMPATIBLE_SAVES + void Save(uint8*& buf); + void Load(uint8*& buf); +#endif + }; static_assert(sizeof(CAutoPilot) == 0x70, "CAutoPilot: error"); diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index e078fe22..fc845a4c 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -5617,9 +5617,9 @@ CMenuManager::ConstructStatLine(int rowIdx) STAT_LINE("PER_COM", &percentCompleted, false, nil); STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil); - STAT_LINE("FEST_MP", &CStats::MissionsPassed, 0, &CStats::TotalNumberMissions); + STAT_LINE("FEST_MP", &CStats::MissionsPassed, false, &CStats::TotalNumberMissions); if (CGame::nastyGame) { - STAT_LINE("FEST_RP", &CStats::NumberKillFrenziesPassed, 0, &CStats::TotalNumberKillFrenzies); + STAT_LINE("FEST_RP", &CStats::NumberKillFrenziesPassed, false, &CStats::TotalNumberKillFrenzies); } CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus]; @@ -5628,8 +5628,8 @@ CMenuManager::ConstructStatLine(int rowIdx) packagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages; int nPackagesPercent = packagesPercent; - STAT_LINE("PERPIC", &nPackagesPercent, 0, &(nTemp = 100)); - STAT_LINE("NOUNIF", &CStats::TotalNumberOfUniqueJumps, 0, &CStats::NumberOfUniqueJumpsFound); + STAT_LINE("PERPIC", &nPackagesPercent, false, &(nTemp = 100)); + STAT_LINE("NOUNIF", &CStats::NumberOfUniqueJumpsFound, false, &CStats::TotalNumberOfUniqueJumps); STAT_LINE("DAYSPS", &CStats::DaysPassed, false, nil); if (CGame::nastyGame) { STAT_LINE("PE_WAST", &CStats::PeopleKilledByPlayer, false, nil); diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index e82fa6e2..4306cf09 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -110,13 +110,24 @@ INITSAVEBUF CStreaming::LoadAllRequestedModels(false); int32 slot = ReadSaveBuf<int32>(buf); CVehicle* pVehicle; - char* vbuf = new char[Max(sizeof(CAutomobile), sizeof(CBoat))]; +#ifdef COMPATIBLE_SAVES + if (type == VEHICLE_TYPE_BOAT) + pVehicle = new(slot) CBoat(model, RANDOM_VEHICLE); + else if (type == VEHICLE_TYPE_CAR) + pVehicle = new(slot) CAutomobile(model, RANDOM_VEHICLE); + else + assert(0); + --CCarCtrl::NumRandomCars; + pVehicle->Load(buf); + CWorld::Add(pVehicle); +#else + char* vbuf = new char[Max(CAutomobile::nSaveStructSize, CBoat::nSaveStructSize)]; if (type == VEHICLE_TYPE_BOAT) { memcpy(vbuf, buf, sizeof(CBoat)); SkipSaveBuf(buf, sizeof(CBoat)); CBoat* pBoat = new(slot) CBoat(model, RANDOM_VEHICLE); pVehicle = pBoat; - --CCarCtrl::NumRandomCars; // why? + --CCarCtrl::NumRandomCars; } else if (type == VEHICLE_TYPE_CAR) { memcpy(vbuf, buf, sizeof(CAutomobile)); @@ -168,6 +179,7 @@ INITSAVEBUF pVehicle->AutoPilot = pBufferVehicle->AutoPilot; CWorld::Add(pVehicle); delete[] vbuf; +#endif } VALIDATESAVEBUF(size) } @@ -184,7 +196,7 @@ INITSAVEBUF continue; bool bHasPassenger = false; for (int j = 0; j < ARRAY_SIZE(pVehicle->pPassengers); j++) { - if (pVehicle->pPassengers[i]) + if (pVehicle->pPassengers[j]) bHasPassenger = true; } if (!pVehicle->pDriver && !bHasPassenger) { @@ -194,8 +206,8 @@ INITSAVEBUF ++nNumBoats; } } - *size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + sizeof(CAutomobile)) + sizeof(int) + - nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + sizeof(CBoat)) + sizeof(int); + *size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CAutomobile::nSaveStructSize) + sizeof(int) + + nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CBoat::nSaveStructSize) + sizeof(int); WriteSaveBuf(buf, nNumCars); WriteSaveBuf(buf, nNumBoats); for (int i = 0; i < nPoolSize; i++) { @@ -208,6 +220,14 @@ INITSAVEBUF bHasPassenger = true; } if (!pVehicle->pDriver && !bHasPassenger) { +#ifdef COMPATIBLE_SAVES + if ((pVehicle->IsCar() || pVehicle->IsBoat()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { + WriteSaveBuf<uint32>(buf, pVehicle->m_vehType); + WriteSaveBuf<int16>(buf, pVehicle->m_modelIndex); + WriteSaveBuf<int32>(buf, GetVehicleRef(pVehicle)); + pVehicle->Save(buf); + } +#else if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { WriteSaveBuf(buf, (uint32)pVehicle->m_vehType); WriteSaveBuf(buf, pVehicle->m_modelIndex); @@ -222,6 +242,7 @@ INITSAVEBUF memcpy(buf, pVehicle, sizeof(CBoat)); SkipSaveBuf(buf, sizeof(CBoat)); } +#endif } } VALIDATESAVEBUF(*size) @@ -279,8 +300,12 @@ INITSAVEBUF WriteSaveBuf(buf, pObject->m_nCollisionDamageEffect); WriteSaveBuf(buf, pObject->m_nSpecialCollisionResponseCases); WriteSaveBuf(buf, pObject->m_nEndOfLifeTime); +#ifdef COMPATIBLE_SAVES + pObject->SaveEntityFlags(buf); +#else WriteSaveBuf(buf, (pObject->GetAddressOfEntityProperties())[0]); WriteSaveBuf(buf, (pObject->GetAddressOfEntityProperties())[1]); +#endif } } VALIDATESAVEBUF(*size) @@ -315,12 +340,17 @@ INITSAVEBUF pBufferObject->m_nCollisionDamageEffect = ReadSaveBuf<uint8>(buf); pBufferObject->m_nSpecialCollisionResponseCases = ReadSaveBuf<uint8>(buf); pBufferObject->m_nEndOfLifeTime = ReadSaveBuf<uint32>(buf); +#ifndef COMPATIBLE_SAVES (pBufferObject->GetAddressOfEntityProperties())[0] = ReadSaveBuf<uint32>(buf); (pBufferObject->GetAddressOfEntityProperties())[1] = ReadSaveBuf<uint32>(buf); +#endif if (GetObjectPool()->GetSlot(ref >> 8)) CPopulation::ConvertToDummyObject(GetObjectPool()->GetSlot(ref >> 8)); CObject* pObject = new(ref) CObject(mi, false); pObject->GetMatrix() = pBufferObject->GetMatrix(); +#ifdef COMPATIBLE_SAVES + pObject->LoadEntityFlags(buf); +#endif pObject->m_fUprootLimit = pBufferObject->m_fUprootLimit; pObject->m_objectMatrix = pBufferObject->m_objectMatrix; pObject->ObjectCreatedBy = pBufferObject->ObjectCreatedBy; @@ -335,8 +365,10 @@ INITSAVEBUF pObject->m_nCollisionDamageEffect = pBufferObject->m_nCollisionDamageEffect; pObject->m_nSpecialCollisionResponseCases = pBufferObject->m_nSpecialCollisionResponseCases; pObject->m_nEndOfLifeTime = pBufferObject->m_nEndOfLifeTime; +#ifndef COMPATIBLE_SAVES (pObject->GetAddressOfEntityProperties())[0] = (pBufferObject->GetAddressOfEntityProperties())[0]; (pObject->GetAddressOfEntityProperties())[1] = (pBufferObject->GetAddressOfEntityProperties())[1]; +#endif pObject->bHasCollided = false; CWorld::Add(pObject); delete[] obuf; @@ -356,7 +388,7 @@ INITSAVEBUF if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) nNumPeds++; } - *size = sizeof(int) + nNumPeds * (sizeof(uint32) + sizeof(int16) + sizeof(int) + sizeof(CPlayerPed) + + *size = sizeof(int) + nNumPeds * (sizeof(uint32) + sizeof(int16) + sizeof(int) + CPlayerPed::nSaveStructSize + sizeof(CWanted::MaximumWantedLevel) + sizeof(CWanted::nMaximumWantedLevel) + MAX_MODEL_NAME); WriteSaveBuf(buf, nNumPeds); for (int i = 0; i < nPoolSize; i++) { @@ -367,8 +399,12 @@ INITSAVEBUF WriteSaveBuf(buf, pPed->m_nPedType); WriteSaveBuf(buf, pPed->m_modelIndex); WriteSaveBuf(buf, GetPedRef(pPed)); +#ifdef COMPATIBLE_SAVES + pPed->Save(buf); +#else memcpy(buf, pPed, sizeof(CPlayerPed)); SkipSaveBuf(buf, sizeof(CPlayerPed)); +#endif WriteSaveBuf(buf, CWanted::MaximumWantedLevel); WriteSaveBuf(buf, CWanted::nMaximumWantedLevel); memcpy(buf, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetName(), MAX_MODEL_NAME); @@ -386,6 +422,34 @@ INITSAVEBUF uint32 pedtype = ReadSaveBuf<uint32>(buf); int16 model = ReadSaveBuf<int16>(buf); int ref = ReadSaveBuf<int>(buf); +#ifdef COMPATIBLE_SAVES + CPed* pPed; + + char name[MAX_MODEL_NAME]; + // Unfortunate hack: player model is stored after ped structure. + // It could be avoided by just using "player" because in practice it is always true. + memcpy(name, buf + CPlayerPed::nSaveStructSize + 2 * sizeof(int32), MAX_MODEL_NAME); + CStreaming::RequestSpecialModel(model, name, STREAMFLAGS_DONT_REMOVE); + CStreaming::LoadAllRequestedModels(false); + + if (pedtype == PEDTYPE_PLAYER1) + pPed = new(ref) CPlayerPed(); + else + assert(0); + + pPed->Load(buf); + if (pedtype == PEDTYPE_PLAYER1) { + CWanted::MaximumWantedLevel = ReadSaveBuf<int32>(buf); + CWanted::nMaximumWantedLevel = ReadSaveBuf<int32>(buf); + SkipSaveBuf(buf, MAX_MODEL_NAME); + } + + if (pedtype == PEDTYPE_PLAYER1) { + pPed->m_wepAccuracy = 100; + CWorld::Players[0].m_pPed = (CPlayerPed*)pPed; + } + CWorld::Add(pPed); +#else char* pbuf = new char[sizeof(CPlayerPed)]; CPlayerPed* pBufferPlayer = (CPlayerPed*)pbuf; CPed* pPed; @@ -416,12 +480,14 @@ INITSAVEBUF pPed->m_maxWeaponTypeAllowed = pBufferPlayer->m_maxWeaponTypeAllowed; for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) pPed->m_weapons[i] = pBufferPlayer->m_weapons[i]; + if (pedtype == PEDTYPE_PLAYER1) { pPed->m_wepAccuracy = 100; CWorld::Players[0].m_pPed = (CPlayerPed*)pPed; } CWorld::Add(pPed); delete[] pbuf; +#endif } VALIDATESAVEBUF(size) } diff --git a/src/core/config.h b/src/core/config.h index 40b51b4a..7c1fab5b 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -227,6 +227,8 @@ enum Config { #define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script #define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely +#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible + // Replay //#define DONT_FIX_REPLAY_BUGS // keeps various bugs in CReplay, some of which are fairly cool! //#define USE_BETA_REPLAY_MODE // adds another replay mode, a few seconds slomo (caution: buggy!) @@ -240,7 +242,7 @@ enum Config { #define CAMERA_PICKUP // Peds -//#define PED_SKIN // support for skinned geometry on peds +#define PED_SKIN // support for skinned geometry on peds #define ANIMATE_PED_COL_MODEL #define VC_PED_PORTS // various ports from VC's CPed, mostly subtle // #define NEW_WALK_AROUND_ALGORITHM // to make walking around vehicles/objects less awkward diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index ee4faa82..2a6211d6 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -920,3 +920,108 @@ CEntity::AddSteamsFromGround(CPtrList& list) pNode = pNode->next; } } + +#ifdef COMPATIBLE_SAVES +void +CEntity::SaveEntityFlags(uint8*& buf) +{ + uint32 tmp = 0; + tmp |= (m_type & (BIT(3) - 1)); + tmp |= (m_status & (BIT(5) - 1)) << 3; + + if (bUsesCollision) tmp |= BIT(8); + if (bCollisionProcessed) tmp |= BIT(9); + if (bIsStatic) tmp |= BIT(10); + if (bHasContacted) tmp |= BIT(11); + if (bPedPhysics) tmp |= BIT(12); + if (bIsStuck) tmp |= BIT(13); + if (bIsInSafePosition) tmp |= BIT(14); + if (bUseCollisionRecords) tmp |= BIT(15); + + if (bWasPostponed) tmp |= BIT(16); + if (bExplosionProof) tmp |= BIT(17); + if (bIsVisible) tmp |= BIT(18); + if (bHasCollided) tmp |= BIT(19); + if (bRenderScorched) tmp |= BIT(20); + if (bHasBlip) tmp |= BIT(21); + if (bIsBIGBuilding) tmp |= BIT(22); + if (bRenderDamaged) tmp |= BIT(23); + + if (bBulletProof) tmp |= BIT(24); + if (bFireProof) tmp |= BIT(25); + if (bCollisionProof) tmp |= BIT(26); + if (bMeleeProof) tmp |= BIT(27); + if (bOnlyDamagedByPlayer) tmp |= BIT(28); + if (bStreamingDontDelete) tmp |= BIT(29); + if (bZoneCulled) tmp |= BIT(30); + if (bZoneCulled2) tmp |= BIT(31); + + WriteSaveBuf<uint32>(buf, tmp); + + tmp = 0; + + if (bRemoveFromWorld) tmp |= BIT(0); + if (bHasHitWall) tmp |= BIT(1); + if (bImBeingRendered) tmp |= BIT(2); + if (bTouchingWater) tmp |= BIT(3); + if (bIsSubway) tmp |= BIT(4); + if (bDrawLast) tmp |= BIT(5); + if (bNoBrightHeadLights) tmp |= BIT(6); + if (bDoNotRender) tmp |= BIT(7); + + if (bDistanceFade) tmp |= BIT(8); + if (m_flagE2) tmp |= BIT(9); + + WriteSaveBuf<uint32>(buf, tmp); +} + +void +CEntity::LoadEntityFlags(uint8*& buf) +{ + uint32 tmp = ReadSaveBuf<uint32>(buf); + m_type = (tmp & ((BIT(3) - 1))); + m_status = ((tmp >> 3) & (BIT(5) - 1)); + + bUsesCollision = !!(tmp & BIT(8)); + bCollisionProcessed = !!(tmp & BIT(9)); + bIsStatic = !!(tmp & BIT(10)); + bHasContacted = !!(tmp & BIT(11)); + bPedPhysics = !!(tmp & BIT(12)); + bIsStuck = !!(tmp & BIT(13)); + bIsInSafePosition = !!(tmp & BIT(14)); + bUseCollisionRecords = !!(tmp & BIT(15)); + + bWasPostponed = !!(tmp & BIT(16)); + bExplosionProof = !!(tmp & BIT(17)); + bIsVisible = !!(tmp & BIT(18)); + bHasCollided = !!(tmp & BIT(19)); + bRenderScorched = !!(tmp & BIT(20)); + bHasBlip = !!(tmp & BIT(21)); + bIsBIGBuilding = !!(tmp & BIT(22)); + bRenderDamaged = !!(tmp & BIT(23)); + + bBulletProof = !!(tmp & BIT(24)); + bFireProof = !!(tmp & BIT(25)); + bCollisionProof = !!(tmp & BIT(26)); + bMeleeProof = !!(tmp & BIT(27)); + bOnlyDamagedByPlayer = !!(tmp & BIT(28)); + bStreamingDontDelete = !!(tmp & BIT(29)); + bZoneCulled = !!(tmp & BIT(30)); + bZoneCulled2 = !!(tmp & BIT(31)); + + tmp = ReadSaveBuf<uint32>(buf); + + bRemoveFromWorld = !!(tmp & BIT(0)); + bHasHitWall = !!(tmp & BIT(1)); + bImBeingRendered = !!(tmp & BIT(2)); + bTouchingWater = !!(tmp & BIT(3)); + bIsSubway = !!(tmp & BIT(4)); + bDrawLast = !!(tmp & BIT(5)); + bNoBrightHeadLights = !!(tmp & BIT(6)); + bDoNotRender = !!(tmp & BIT(7)); + + bDistanceFade = !!(tmp & BIT(8)); + m_flagE2 = !!(tmp & BIT(9)); +} + +#endif diff --git a/src/entities/Entity.h b/src/entities/Entity.h index 15a7a602..dbe2c08b 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -98,7 +98,12 @@ public: eEntityStatus GetStatus() const { return (eEntityStatus)m_status; } void SetStatus(eEntityStatus status) { m_status = status; } CColModel *GetColModel(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); } +#ifdef COMPATIBLE_SAVES + void SaveEntityFlags(uint8*& buf); + void LoadEntityFlags(uint8*& buf); +#else uint32* GetAddressOfEntityProperties() { /* AWFUL */ return (uint32*)((char*)&m_rwObject + sizeof(m_rwObject)); } +#endif CEntity(void); ~CEntity(void); diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 20fa93da..e7972541 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -17732,3 +17732,45 @@ CPed::SetExitBoat(CVehicle *boat) // Not there in VC. CWaterLevel::FreeBoatWakeArray(); } + +#ifdef COMPATIBLE_SAVES +void +CPed::Save(uint8*& buf) +{ + SkipSaveBuf(buf, 52); + WriteSaveBuf<float>(buf, GetPosition().x); + WriteSaveBuf<float>(buf, GetPosition().y); + WriteSaveBuf<float>(buf, GetPosition().z); + SkipSaveBuf(buf, 288); + WriteSaveBuf<uint8>(buf, CharCreatedBy); + SkipSaveBuf(buf, 351); + WriteSaveBuf<float>(buf, m_fHealth); + WriteSaveBuf<float>(buf, m_fArmour); + SkipSaveBuf(buf, 148); + for (int i = 0; i < 13; i++) // has to be hardcoded + m_weapons[i].Save(buf); + SkipSaveBuf(buf, 5); + WriteSaveBuf<uint8>(buf, m_maxWeaponTypeAllowed); + SkipSaveBuf(buf, 162); +} + +void +CPed::Load(uint8*& buf) +{ + SkipSaveBuf(buf, 52); + GetPosition().x = ReadSaveBuf<float>(buf); + GetPosition().y = ReadSaveBuf<float>(buf); + GetPosition().z = ReadSaveBuf<float>(buf); + SkipSaveBuf(buf, 288); + CharCreatedBy = ReadSaveBuf<uint8>(buf); + SkipSaveBuf(buf, 351); + m_fHealth = ReadSaveBuf<float>(buf); + m_fArmour = ReadSaveBuf<float>(buf); + SkipSaveBuf(buf, 148); + for (int i = 0; i < 13; i++) // has to be hardcoded + m_weapons[i].Load(buf); + SkipSaveBuf(buf, 5); + m_maxWeaponTypeAllowed = ReadSaveBuf<uint8>(buf); + SkipSaveBuf(buf, 162); +} +#endif diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 91322151..9f105e7a 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -886,6 +886,11 @@ public: #ifdef PED_SKIN void renderLimb(int node); #endif + +#ifdef COMPATIBLE_SAVES + virtual void Save(uint8*& buf); + virtual void Load(uint8*& buf); +#endif }; void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg); diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index dc44983d..6d0d394d 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -19,6 +19,13 @@ #define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f +const uint32 CPlayerPed::nSaveStructSize = +#ifdef COMPATIBLE_SAVES + 1520; +#else + sizeof(CPlayerPed); +#endif + CPlayerPed::~CPlayerPed() { delete m_pWanted; @@ -1504,3 +1511,33 @@ CPlayerPed::ProcessControl(void) UpdateRpHAnim(); #endif } + +#ifdef COMPATIBLE_SAVES +void +CPlayerPed::Save(uint8*& buf) +{ + CPed::Save(buf); + SkipSaveBuf(buf, 16); + WriteSaveBuf<float>(buf, m_fMaxStamina); + SkipSaveBuf(buf, 28); + WriteSaveBuf<int32>(buf, m_nTargettableObjects[0]); + WriteSaveBuf<int32>(buf, m_nTargettableObjects[1]); + WriteSaveBuf<int32>(buf, m_nTargettableObjects[2]); + WriteSaveBuf<int32>(buf, m_nTargettableObjects[3]); + SkipSaveBuf(buf, 116); +} + +void +CPlayerPed::Load(uint8*& buf) +{ + CPed::Load(buf); + SkipSaveBuf(buf, 16); + m_fMaxStamina = ReadSaveBuf<float>(buf); + SkipSaveBuf(buf, 28); + m_nTargettableObjects[0] = ReadSaveBuf<int32>(buf); + m_nTargettableObjects[1] = ReadSaveBuf<int32>(buf); + m_nTargettableObjects[2] = ReadSaveBuf<int32>(buf); + m_nTargettableObjects[3] = ReadSaveBuf<int32>(buf); + SkipSaveBuf(buf, 116); +} +#endif diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h index b8bd57e4..61b70f89 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -75,6 +75,13 @@ public: static void SetupPlayerPed(int32); static void DeactivatePlayerPed(int32); static void ReactivatePlayerPed(int32); + +#ifdef COMPATIBLE_SAVES + virtual void Save(uint8*& buf); + virtual void Load(uint8*& buf); +#endif + + static const uint32 nSaveStructSize; }; #ifndef PED_SKIN diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index 3707f51f..c3fcb7bf 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -336,7 +336,11 @@ void CHud::Draw() || FindPlayerPed()->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) { AsciiToUnicode("{", sPrintIcon); +#ifdef FIX_BUGS + sprintf(sTemp, "%03d", int32(FindPlayerPed()->m_fHealth + 0.5f)); +#else sprintf(sTemp, "%03d", (int32)FindPlayerPed()->m_fHealth); +#endif AsciiToUnicode(sTemp, sPrint); CFont::SetColor(CRGBA(0, 0, 0, 255)); @@ -362,7 +366,11 @@ void CHud::Draw() CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); if (FindPlayerPed()->m_fArmour > 1.0f) { AsciiToUnicode("[", sPrintIcon); +#ifdef FIX_BUGS + sprintf(sTemp, "%03d", int32(FindPlayerPed()->m_fArmour + 0.5f)); +#else sprintf(sTemp, "%03d", (int32)FindPlayerPed()->m_fArmour); +#endif AsciiToUnicode(sTemp, sPrint); CFont::SetColor(CRGBA(0, 0, 0, 255)); diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index e38c93ae..acca4d60 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -51,6 +51,13 @@ RwObject *GetCurrentAtomicObjectCB(RwObject *object, void *data); bool CAutomobile::m_sAllTaxiLights; +const uint32 CAutomobile::nSaveStructSize = +#ifdef COMPATIBLE_SAVES + 1448; +#else + sizeof(CAutomobile); +#endif + CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) : CVehicle(CreatedBy) { @@ -4580,3 +4587,22 @@ CAutomobile::SetAllTaxiLights(bool set) { m_sAllTaxiLights = set; } + +#ifdef COMPATIBLE_SAVES +void +CAutomobile::Save(uint8*& buf) +{ + CVehicle::Save(buf); + WriteSaveBuf<CDamageManager>(buf, Damage); + SkipSaveBuf(buf, 800 - sizeof(CDamageManager)); +} + +void +CAutomobile::Load(uint8*& buf) +{ + CVehicle::Load(buf); + Damage = ReadSaveBuf<CDamageManager>(buf); + SkipSaveBuf(buf, 800 - sizeof(CDamageManager)); + SetupDamageAfterLoad(); +} +#endif diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 2de85a99..041302bf 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -188,9 +188,15 @@ public: void HideAllComps(void); void ShowAllComps(void); void ReduceHornCounter(void); +#ifdef COMPATIBLE_SAVES + virtual void Save(uint8*& buf); + virtual void Load(uint8*& buf); +#endif + static const uint32 nSaveStructSize; static void SetAllTaxiLights(bool set); }; + static_assert(sizeof(CAutomobile) == 0x5A8, "CAutomobile: error"); inline uint8 GetCarDoorFlag(int32 carnode) { diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index 5e75dc21..1f80c43e 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -32,6 +32,13 @@ float WAKE_LIFETIME = 400.0f; CBoat *CBoat::apFrameWakeGeneratingBoats[4]; +const uint32 CBoat::nSaveStructSize = +#ifdef COMPATIBLE_SAVES + 1156; +#else + sizeof(CBoat); +#endif + CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner) { CVehicleModelInfo *minfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(mi); @@ -899,3 +906,19 @@ CBoat::AddWakePoint(CVector point) m_nNumWakePoints = 1; } } + +#ifdef COMPATIBLE_SAVES +void +CBoat::Save(uint8*& buf) +{ + CVehicle::Save(buf); + SkipSaveBuf(buf, 1156 - 648); +} + +void +CBoat::Load(uint8*& buf) +{ + CVehicle::Load(buf); + SkipSaveBuf(buf, 1156 - 648); +} +#endif diff --git a/src/vehicles/Boat.h b/src/vehicles/Boat.h index ba56e355..70407ab9 100644 --- a/src/vehicles/Boat.h +++ b/src/vehicles/Boat.h @@ -64,7 +64,14 @@ public: static float IsVertexAffectedByWake(CVector vecVertex, CBoat *pBoat); static void FillBoatList(void); +#ifdef COMPATIBLE_SAVES + virtual void Save(uint8*& buf); + virtual void Load(uint8*& buf); +#endif + static const uint32 nSaveStructSize; + }; + static_assert(sizeof(CBoat) == 0x484, "CBoat: error"); extern float MAX_WAKE_LENGTH; diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 590e68f2..75f43515 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -1222,3 +1222,128 @@ DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle) CWorld::Remove(pVehicle); delete pVehicle; } + +#ifdef COMPATIBLE_SAVES +void +CVehicle::Save(uint8*& buf) +{ + SkipSaveBuf(buf, 4); + WriteSaveBuf<float>(buf, GetRight().x); + WriteSaveBuf<float>(buf, GetRight().y); + WriteSaveBuf<float>(buf, GetRight().z); + SkipSaveBuf(buf, 4); + WriteSaveBuf<float>(buf, GetForward().x); + WriteSaveBuf<float>(buf, GetForward().y); + WriteSaveBuf<float>(buf, GetForward().z); + SkipSaveBuf(buf, 4); + WriteSaveBuf<float>(buf, GetUp().x); + WriteSaveBuf<float>(buf, GetUp().y); + WriteSaveBuf<float>(buf, GetUp().z); + SkipSaveBuf(buf, 4); + WriteSaveBuf<float>(buf, GetPosition().x); + WriteSaveBuf<float>(buf, GetPosition().y); + WriteSaveBuf<float>(buf, GetPosition().z); + SkipSaveBuf(buf, 16); + SaveEntityFlags(buf); + SkipSaveBuf(buf, 212); + AutoPilot.Save(buf); + WriteSaveBuf<int8>(buf, m_currentColour1); + WriteSaveBuf<int8>(buf, m_currentColour2); + SkipSaveBuf(buf, 2); + WriteSaveBuf<int16>(buf, m_nAlarmState); + SkipSaveBuf(buf, 43); + WriteSaveBuf<uint8>(buf, m_nNumMaxPassengers); + SkipSaveBuf(buf, 2); + WriteSaveBuf<float>(buf, field_1D0[0]); + WriteSaveBuf<float>(buf, field_1D0[1]); + WriteSaveBuf<float>(buf, field_1D0[2]); + WriteSaveBuf<float>(buf, field_1D0[3]); + SkipSaveBuf(buf, 8); + WriteSaveBuf<float>(buf, m_fSteerAngle); + WriteSaveBuf<float>(buf, m_fGasPedal); + WriteSaveBuf<float>(buf, m_fBrakePedal); + WriteSaveBuf<uint8>(buf, VehicleCreatedBy); + uint8 flags = 0; + if (bIsLawEnforcer) flags |= BIT(0); + if (bIsLocked) flags |= BIT(3); + if (bEngineOn) flags |= BIT(4); + if (bIsHandbrakeOn) flags |= BIT(5); + if (bLightsOn) flags |= BIT(6); + if (bFreebies) flags |= BIT(7); + WriteSaveBuf<uint8>(buf, flags); + SkipSaveBuf(buf, 10); + WriteSaveBuf<float>(buf, m_fHealth); + WriteSaveBuf<uint8>(buf, m_nCurrentGear); + SkipSaveBuf(buf, 3); + WriteSaveBuf<float>(buf, m_fChangeGearTime); + SkipSaveBuf(buf, 4); + WriteSaveBuf<uint32>(buf, m_nTimeOfDeath); + SkipSaveBuf(buf, 2); + WriteSaveBuf<int16>(buf, m_nBombTimer); + SkipSaveBuf(buf, 12); + WriteSaveBuf<int8>(buf, m_nDoorLock); + SkipSaveBuf(buf, 99); +} + +void +CVehicle::Load(uint8*& buf) +{ + CMatrix tmp; + SkipSaveBuf(buf, 4); + tmp.GetRight().x = ReadSaveBuf<float>(buf); + tmp.GetRight().y = ReadSaveBuf<float>(buf); + tmp.GetRight().z = ReadSaveBuf<float>(buf); + SkipSaveBuf(buf, 4); + tmp.GetForward().x = ReadSaveBuf<float>(buf); + tmp.GetForward().y = ReadSaveBuf<float>(buf); + tmp.GetForward().z = ReadSaveBuf<float>(buf); + SkipSaveBuf(buf, 4); + tmp.GetUp().x = ReadSaveBuf<float>(buf); + tmp.GetUp().y = ReadSaveBuf<float>(buf); + tmp.GetUp().z = ReadSaveBuf<float>(buf); + SkipSaveBuf(buf, 4); + tmp.GetPosition().x = ReadSaveBuf<float>(buf); + tmp.GetPosition().y = ReadSaveBuf<float>(buf); + tmp.GetPosition().z = ReadSaveBuf<float>(buf); + m_matrix = tmp; + SkipSaveBuf(buf, 16); + LoadEntityFlags(buf); + SkipSaveBuf(buf, 212); + AutoPilot.Load(buf); + m_currentColour1 = ReadSaveBuf<int8>(buf); + m_currentColour2 = ReadSaveBuf<int8>(buf); + SkipSaveBuf(buf, 2); + m_nAlarmState = ReadSaveBuf<int16>(buf); + SkipSaveBuf(buf, 43); + m_nNumMaxPassengers = ReadSaveBuf<int8>(buf); + SkipSaveBuf(buf, 2); + field_1D0[0] = ReadSaveBuf<float>(buf); + field_1D0[1] = ReadSaveBuf<float>(buf); + field_1D0[2] = ReadSaveBuf<float>(buf); + field_1D0[3] = ReadSaveBuf<float>(buf); + SkipSaveBuf(buf, 8); + m_fSteerAngle = ReadSaveBuf<float>(buf); + m_fGasPedal = ReadSaveBuf<float>(buf); + m_fBrakePedal = ReadSaveBuf<float>(buf); + VehicleCreatedBy = ReadSaveBuf<uint8>(buf); + uint8 flags = ReadSaveBuf<uint8>(buf); + bIsLawEnforcer = !!(flags & BIT(0)); + bIsLocked = !!(flags & BIT(3)); + bEngineOn = !!(flags & BIT(4)); + bIsHandbrakeOn = !!(flags & BIT(5)); + bLightsOn = !!(flags & BIT(6)); + bFreebies = !!(flags & BIT(7)); + SkipSaveBuf(buf, 10); + m_fHealth = ReadSaveBuf<float>(buf); + m_nCurrentGear = ReadSaveBuf<uint8>(buf); + SkipSaveBuf(buf, 3); + m_fChangeGearTime = ReadSaveBuf<float>(buf); + SkipSaveBuf(buf, 4); + m_nTimeOfDeath = ReadSaveBuf<uint32>(buf); + SkipSaveBuf(buf, 2); + m_nBombTimer = ReadSaveBuf<int16>(buf); + SkipSaveBuf(buf, 12); + m_nDoorLock = (eCarLock)ReadSaveBuf<int8>(buf); + SkipSaveBuf(buf, 99); +} +#endif diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index cb4ac2cf..d8f90d92 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -193,7 +193,7 @@ public: uint8 m_bRainAudioCounter; uint8 m_bRainSamplesCounter; uint8 m_nCarHornTimer; - int8 field_22D; // last horn? + uint8 field_22D; // last horn? bool m_bSirenOrAlarm; int8 m_comedyControlState; CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car @@ -231,6 +231,10 @@ public: virtual bool IsRoomForPedToLeaveCar(uint32 component, CVector *forcedDoorPos) { return false;} virtual float GetHeightAboveRoad(void); virtual void PlayCarHorn(void) {} +#ifdef COMPATIBLE_SAVES + virtual void Save(uint8*& buf); + virtual void Load(uint8*& buf); +#endif bool IsCar(void) { return m_vehType == VEHICLE_TYPE_CAR; } bool IsBoat(void) { return m_vehType == VEHICLE_TYPE_BOAT; } diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index 9897e73f..e9b917de 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -2257,4 +2257,30 @@ bool CWeapon::ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPoint &point, CEntity *&entity, eWeaponType type, CEntity *shooter, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects) { return CWorld::ProcessLineOfSight(point1, point2, point, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects); -}
\ No newline at end of file +} + +#ifdef COMPATIBLE_SAVES +void +CWeapon::Save(uint8*& buf) +{ + WriteSaveBuf<uint32>(buf, m_eWeaponType); + WriteSaveBuf<uint32>(buf, m_eWeaponState); + WriteSaveBuf<uint32>(buf, m_nAmmoInClip); + WriteSaveBuf<uint32>(buf, m_nAmmoTotal); + WriteSaveBuf<uint32>(buf, m_nTimer); + WriteSaveBuf<bool>(buf, m_bAddRotOffset); + SkipSaveBuf(buf, 3); +} + +void +CWeapon::Load(uint8*& buf) +{ + m_eWeaponType = (eWeaponType)ReadSaveBuf<uint32>(buf); + m_eWeaponState = (eWeaponState)ReadSaveBuf<uint32>(buf); + m_nAmmoInClip = ReadSaveBuf<uint32>(buf); + m_nAmmoTotal = ReadSaveBuf<uint32>(buf); + m_nTimer = ReadSaveBuf<uint32>(buf); + m_bAddRotOffset = ReadSaveBuf<bool>(buf); + SkipSaveBuf(buf, 3); +} +#endif diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h index 2c3a9657..1b2c0320 100644 --- a/src/weapons/Weapon.h +++ b/src/weapons/Weapon.h @@ -67,6 +67,11 @@ public: bool HasWeaponAmmoToBeUsed(void); static bool ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPoint &point, CEntity *&entity, eWeaponType type, CEntity *shooter, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects); + +#ifdef COMPATIBLE_SAVES + void Save(uint8*& buf); + void Load(uint8*& buf); +#endif }; VALIDATE_SIZE(CWeapon, 0x18); |