diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/animation/CutsceneMgr.cpp | 2 | ||||
-rw-r--r-- | src/animation/CutsceneMgr.h | 1 | ||||
-rw-r--r-- | src/audio/AudioLogic.cpp | 31 | ||||
-rw-r--r-- | src/audio/AudioManager.cpp | 16 | ||||
-rw-r--r-- | src/audio/AudioManager.h | 12 | ||||
-rw-r--r-- | src/audio/DMAudio.cpp | 114 | ||||
-rw-r--r-- | src/audio/DMAudio.h | 9 | ||||
-rw-r--r-- | src/audio/MusicManager.cpp | 1644 | ||||
-rw-r--r-- | src/audio/MusicManager.h | 70 | ||||
-rw-r--r-- | src/audio/audio_enums.h | 11 | ||||
-rw-r--r-- | src/audio/sampman.h | 12 | ||||
-rw-r--r-- | src/audio/sampman_miles.cpp | 75 | ||||
-rw-r--r-- | src/audio/sampman_null.cpp | 15 | ||||
-rw-r--r-- | src/audio/sampman_oal.cpp | 46 | ||||
-rw-r--r-- | src/audio/soundlist.h | 15 | ||||
-rw-r--r-- | src/control/Script.cpp | 12 | ||||
-rw-r--r-- | src/control/Script.h | 4 | ||||
-rw-r--r-- | src/core/EventList.h | 1 | ||||
-rw-r--r-- | src/core/Game.cpp | 3 | ||||
-rw-r--r-- | src/core/Stats.cpp | 22 | ||||
-rw-r--r-- | src/core/Stats.h | 2 | ||||
-rw-r--r-- | src/peds/Ped.cpp | 826 | ||||
-rw-r--r-- | src/peds/Ped.h | 17 | ||||
-rw-r--r-- | src/save/GenericGameStorage.cpp | 27 | ||||
-rw-r--r-- | src/save/GenericGameStorage.h | 3 |
25 files changed, 1976 insertions, 1014 deletions
diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp index 31128990..64951a87 100644 --- a/src/animation/CutsceneMgr.cpp +++ b/src/animation/CutsceneMgr.cpp @@ -657,7 +657,7 @@ CCutsceneMgr::RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver() for (int i = CPools::GetBuildingPool()->GetSize() - 1; i >= 0; i--) { CBuilding* pBuilding = CPools::GetBuildingPool()->GetSlot(i); - if (pBuilding && pBuilding->GetClump() != nil && pBuilding->bIsBIGBuilding && pBuilding->bStreamBIGBuilding) { + if (pBuilding && pBuilding->m_rwObject != nil && pBuilding->bIsBIGBuilding && pBuilding->bStreamBIGBuilding) { if (pBuilding->bIsBIGBuilding) CStreaming::RequestModel(pBuilding->GetModelIndex(), 0); if (!pBuilding->bImBeingRendered) diff --git a/src/animation/CutsceneMgr.h b/src/animation/CutsceneMgr.h index b4497b5b..51ef6c04 100644 --- a/src/animation/CutsceneMgr.h +++ b/src/animation/CutsceneMgr.h @@ -57,4 +57,5 @@ public: static void AttachObjectToFrame(CObject *pObject, CEntity *pAttachTo, const char *frame); static void AttachObjectToBone(CObject *pObject, CObject *pAttachTo, int frame); static void RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver(); + static void DisableCutsceneShadows() { ms_useCutsceneShadows = false; } }; diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp index 613d847c..2b9e622e 100644 --- a/src/audio/AudioLogic.cpp +++ b/src/audio/AudioLogic.cpp @@ -294,6 +294,18 @@ cAudioManager::CalculateDistance(bool &distCalculated, float dist) } } +CVehicle *cAudioManager::FindVehicleOfPlayer() +{ + CVehicle* vehicle = FindPlayerVehicle(); + CPlayerPed* ped = FindPlayerPed(); + if (vehicle == nil && ped != nil) { + CEntity *attachedTo = ped->m_attachedTo; + if (attachedTo && attachedTo->IsVehicle()) + vehicle = (CVehicle*)attachedTo; + } + return vehicle; +} + void cAudioManager::ProcessSpecial() { @@ -3977,6 +3989,25 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) } void +cAudioManager::SetPedTalkingStatus(CPed *ped, uint8 status) +{ + if (ped != nil) + ped->m_canTalk = status; +} + +void +cAudioManager::SetPlayersMood(uint8 mood, int32 time) +{ + if (!m_bIsInitialised) return; + + if (mood < MAX_PLAYER_MOODS) { + m_nPlayerMood = mood; + m_nPlayerMoodTimer = CTimer::GetTimeInMilliseconds() + time; + } + +} + +void cAudioManager::SetupPedComments(cPedParams *params, uint32 sound) { CPed *ped = params->m_pPed; diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index 5b0b4907..f5cd9361 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -217,6 +217,12 @@ cAudioManager::PlayOneShot(int32 index, int16 sound, float vol) } void +cAudioManager::SetMP3BoostVolume(uint8 volume) const +{ + SampleManager.SetMP3BoostVolume(volume); +} + +void cAudioManager::SetEffectsMasterVolume(uint8 volume) const { SampleManager.SetEffectsMasterVolume(volume); @@ -337,6 +343,15 @@ cAudioManager::GetCurrent3DProviderIndex() const } int8 +cAudioManager::AutoDetect3DProviders() const +{ + if (m_bIsInitialised) + return SampleManager.AutoDetect3DProviders(); + + return -1; +} + +int8 cAudioManager::SetCurrent3DProvider(uint8 which) { if (!m_bIsInitialised) @@ -420,6 +435,7 @@ cAudioManager::IsAudioInitialised() const void cAudioManager::ServiceSoundEffects() { + field_5554++; m_bFifthFrameFlag = (m_FrameCounter++ % 5) == 0; if (m_nUserPause && !m_nPreviousUserPause) { for (int32 i = 0; i < allChannels; i++) diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h index 2f76144b..2578e418 100644 --- a/src/audio/AudioManager.h +++ b/src/audio/AudioManager.h @@ -197,9 +197,9 @@ public: cAudioScriptObjectManager m_sAudioScriptObjectManager; // miami - uint8 field_4B30; - uint8 m_bPlayerMood; - uint32 field_4B34; + uint8 m_bIsPlayerShutUp; + uint8 m_nPlayerMood; + uint32 m_nPlayerMoodTimer; uint8 field_rest[4]; uint8 field_4B3C; @@ -270,6 +270,7 @@ public: char *Get3DProviderName(uint8 id) const; uint8 GetCDAudioDriveLetter() const; int8 GetCurrent3DProviderIndex() const; + int8 AutoDetect3DProviders() const; float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used float GetCollisionOneShotRatio(int32 a, float b) const; float GetCollisionRatio(float a, float b, float c, float d) const; @@ -388,6 +389,7 @@ public: void SetDynamicAcousticModelingStatus(uint8 status); void SetEffectsFadeVol(uint8 volume) const; void SetEffectsMasterVolume(uint8 volume) const; + void SetMP3BoostVolume(uint8 volume) const; void SetEntityStatus(int32 id, uint8 status); uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision); void SetMissionAudioLocation(uint8 slot, float x, float y, float z); @@ -416,6 +418,10 @@ public: bool UsesSiren(int32 model) const; bool UsesSirenSwitching(int32 model) const; + CVehicle *FindVehicleOfPlayer(); + void SetPedTalkingStatus(CPed *ped, uint8 status); + void SetPlayersMood(uint8 mood, int32 time); + #ifdef GTA_PC // only used in pc void AdjustSamplesVolume(); diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp index b3c16941..486daebf 100644 --- a/src/audio/DMAudio.cpp +++ b/src/audio/DMAudio.cpp @@ -65,6 +65,15 @@ cDMAudio::SetMonoMode(uint8 mono) } void +cDMAudio::SetMP3BoostVolume(uint8 volume) +{ + uint8 vol = volume; + if (vol > MAX_VOLUME) vol = MAX_VOLUME; + + AudioManager.SetMP3BoostVolume(vol); +} + +void cDMAudio::SetEffectsMasterVolume(uint8 volume) { uint8 vol = volume; @@ -112,70 +121,9 @@ cDMAudio::Get3DProviderName(uint8 id) return AudioManager.Get3DProviderName(id); } -// TODO(Miami): Content of this moved to cSampleManager or cAudioManager int8 cDMAudio::AutoDetect3DProviders(void) { - if (!AudioManager.IsAudioInitialised()) - return -1; - - int eax = -1, eax2 = -1, eax3 = -1, ds3dh = -1, ds3ds = -1; - - for ( int32 i = 0; i < GetNum3DProvidersAvailable(); i++ ) - { - char *providername = Get3DProviderName(i); - strupr(providername); - -#if defined(AUDIO_OAL) - if (!strcmp(providername, "OPENAL SOFT")) { - SetCurrent3DProvider(i); - if (GetCurrent3DProviderIndex() == i) - return i; - } -#else - if (!strcmp(providername, "CREATIVE LABS EAX 3 (TM)")) { - SetCurrent3DProvider(i); - if (GetCurrent3DProviderIndex() == i) { - eax3 = i; - } - } - - if (!strcmp(providername, "CREATIVE LABS EAX 2 (TM)")) { - SetCurrent3DProvider(i); - if (GetCurrent3DProviderIndex() == i) - eax2 = i; - } - - if (!strcmp(providername, "CREATIVE LABS EAX (TM)")) { - SetCurrent3DProvider(i); - if (GetCurrent3DProviderIndex() == i) - eax = i; - } - - if (!strcmp(providername, "DIRECTSOUND3D HARDWARE SUPPORT")) { - SetCurrent3DProvider(i); - if (GetCurrent3DProviderIndex() == i) - ds3dh = i; - } - - if (!strcmp(providername, "DIRECTSOUND3D SOFTWARE EMULATION")) { - SetCurrent3DProvider(i); - if (GetCurrent3DProviderIndex() == i) - ds3ds = i; - } -#endif - } - - if (eax3 != -1) - return eax3; - if (eax2 != -1) - return eax2; - if (eax != -1) - return eax; - if (ds3dh != -1) - return ds3dh; - if (ds3ds != -1) - return ds3ds; - return -1; + return AudioManager.AutoDetect3DProviders(); } int8 @@ -392,3 +340,45 @@ cDMAudio::SetRadioChannel(int8 radio, int32 pos) { MusicManager.SetRadioChannelByScript(radio, pos); } + +void +cDMAudio::SetStartingTrackPositions(uint8 isStartGame) +{ + MusicManager.SetStartingTrackPositions(isStartGame); +} + +float * +cDMAudio::GetListenTimeArray() +{ + return MusicManager.GetListenTimeArray(); +} + +uint32 +cDMAudio::GetFavouriteRadioStation() +{ + return MusicManager.GetFavouriteRadioStation(); +} + +int32 +cDMAudio::GetRadioPosition(uint32 station) +{ + return MusicManager.GetRadioPosition(station); +} + +void +cDMAudio::SetPedTalkingStatus(CPed *ped, uint8 status) +{ + return AudioManager.SetPedTalkingStatus(ped, status); +} + +void +cDMAudio::SetPlayersMood(uint8 mood, int32 time) +{ + return AudioManager.SetPlayersMood(mood, time); +} + +void +cDMAudio::ShutUpPlayerTalking(uint8 state) +{ + AudioManager.m_bIsPlayerShutUp = state; +}
\ No newline at end of file diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h index e7d3a23b..ef62294e 100644 --- a/src/audio/DMAudio.h +++ b/src/audio/DMAudio.h @@ -30,6 +30,7 @@ public: void DestroyAllGameCreatedEntities(void); void SetMonoMode(uint8 mono); + void SetMP3BoostVolume(uint8 volume); void SetEffectsMasterVolume(uint8 volume); void SetMusicMasterVolume(uint8 volume); void SetEffectsFadeVol(uint8 volume); @@ -90,5 +91,13 @@ public: uint8 GetRadioInCar(void); void SetRadioInCar(uint32 radio); void SetRadioChannel(int8 radio, int32 pos); + + void SetStartingTrackPositions(uint8 isStartGame); + float *GetListenTimeArray(); + uint32 GetFavouriteRadioStation(); + int32 GetRadioPosition(uint32 station); + void SetPedTalkingStatus(class CPed *ped, uint8 status); + void SetPlayersMood(uint8 mood, int32 time); + void ShutUpPlayerTalking(uint8 state); }; extern cDMAudio DMAudio; diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp index ae2e97ac..51fd2d0b 100644 --- a/src/audio/MusicManager.cpp +++ b/src/audio/MusicManager.cpp @@ -14,179 +14,123 @@ #include "Timer.h" #include "World.h" #include "sampman.h" - +#include "Stats.h" +#include "Script.h" +#include "ZoneCull.h" +#include "Weather.h" +#include "DMAudio.h" +#include "GenericGameStorage.h" cMusicManager MusicManager; int32 gNumRetunePresses; int32 gRetuneCounter; -bool bHasStarted; +bool g_bAnnouncementReadPosAlready; +uint8 RadioStaticCounter; +uint32 RadioStaticTimer; + +CVector vecRiotPosition(300.7f, -322.0f, 12.0f); + +uint32 NewGameRadioTimers[10] = +{ + 948160, + 452150, + 2438150, + 3538230, + 3513100, + 4246050, + 1418050, + 3178240, + 471210, + 0 +}; cMusicManager::cMusicManager() { m_bIsInitialised = false; m_bDisabled = false; + m_nFrontendTrack = NO_TRACK; + m_nPlayingTrack = NO_TRACK; + m_nUpcomingMusicMode = MUSICMODE_DISABLED; m_nMusicMode = MUSICMODE_DISABLED; - m_nCurrentStreamedSound = NO_STREAMED_SOUND; - m_nPreviousStreamedSound = NO_STREAMED_SOUND; - m_bFrontendTrackFinished = false; - m_bPlayInFrontend = false; - m_bSetNextStation = false; - m_nAnnouncement = NO_STREAMED_SOUND; - m_bPreviousPlayerInCar = false; - m_bPlayerInCar = false; - m_bAnnouncementInProgress = false; - m_bDontServiceAmbienceTrack = false; - bHasStarted = false; -} - -bool -cMusicManager::PlayerInCar() -{ - if(!FindPlayerVehicle()) - return false; - - int32 State = FindPlayerPed()->m_nPedState; - - if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED) - return false; + field_2 = false; - if (!FindPlayerVehicle()) - return true; - - if (FindPlayerVehicle()->GetStatus() == STATUS_WRECKED) - return false; + for (int i = 0; i < NUM_RADIOS; i++) + aListenTimeArray[i] = 0.0f; - switch (FindPlayerVehicle()->GetModelIndex()) { - case MI_FIRETRUCK: - case MI_AMBULAN: - case MI_MRWHOOP: - case MI_PREDATOR: - case MI_TRAIN: - case MI_SPEEDER: - case MI_REEFER: -// case MI_GHOST: - return false; - default: return true; - } + m_nLastTrackServiceTime = 0.0f; + m_nVolumeLatency = 0; + m_nCurrentVolume = 0; + m_nMaxVolume = 0; + m_nAnnouncement = NO_TRACK; + m_bAnnouncementInProgress = false; } void -cMusicManager::DisplayRadioStationName() +cMusicManager::ResetMusicAfterReload() { - int8 pRetune; - int8 gStreamedSound; - int8 gRetuneCounter; - static wchar *pCurrentStation = nil; - static uint8 cDisplay = 0; - - if(!CTimer::GetIsPaused() && !TheCamera.m_WideScreenOn && PlayerInCar() && - !CReplay::IsPlayingBack()) { - if(m_bPlayerInCar && !m_bPreviousPlayerInCar) - pCurrentStation = nil; - - if(SampleManager.IsMP3RadioChannelAvailable()) { - gStreamedSound = m_nCurrentStreamedSound; + float afRadioTime[NUM_RADIOS]; - if(gStreamedSound == STREAMED_SOUND_CITY_AMBIENT || - gStreamedSound == STREAMED_SOUND_WATER_AMBIENT) { - gStreamedSound = STREAMED_SOUND_RADIO_POLICE; - } else { - - if(gStreamedSound > - STREAMED_SOUND_RADIO_MP3_PLAYER) - return; - } - - pRetune = gNumRetunePresses + gStreamedSound; - - if(pRetune == POLICE_RADIO) { - pRetune = RADIO_OFF; - } else if(pRetune > POLICE_RADIO) { - pRetune = pRetune - RADIO_OFF; - } - } else { - gStreamedSound = m_nCurrentStreamedSound; - pRetune = gNumRetunePresses + gStreamedSound; - - if(pRetune >= USERTRACK) { - gRetuneCounter = gNumRetunePresses; - pRetune = m_nCurrentStreamedSound; - - if(gStreamedSound == STREAMED_SOUND_WATER_AMBIENT) - pRetune = RADIO_OFF; + m_bRadioSetByScript = false; + m_nRadioStation = WILDSTYLE; + m_nRadioPosition = -1; + m_nAnnouncement = NO_TRACK; + m_bAnnouncementInProgress = false; + field_2 = false; + RadioStaticTimer = 0; + gNumRetunePresses = 0; + gRetuneCounter = 0; + m_nFrontendTrack = NO_TRACK; + m_nPlayingTrack = NO_TRACK; + field_398E = false; + field_398F = false; + m_nStreamedTrack = NO_TRACK; + field_3994 = false; + field_3995 = false; + field_3996 = false; + field_3997 = false; + field_3998 = -1; + field_3999 = false; + field_399A = false; + field_399C = false; + m_nVolumeLatency = 0; + m_nCurrentVolume = 0; + m_nMaxVolume = 0; + + bool bRadioWasEverListened = false; + + for (int i = 0; i < NUM_RADIOS; i++) { + afRadioTime[i] = CStats::GetFavoriteRadioStationList(i); + if (!bRadioWasEverListened && afRadioTime[i] != 0.0f) + bRadioWasEverListened = true; + } - while(gRetuneCounter) { - if(pRetune == RADIO_OFF) { - pRetune = WILDSTYLE; - } else if(pRetune < USERTRACK) { - pRetune = pRetune + 1; - } - if(pRetune == USERTRACK) pRetune = RADIO_OFF; + if (!bRadioWasEverListened) return; - --gRetuneCounter; - } + for (int i = 0; i < NUM_RADIOS; i++) { + aListenTimeArray[i] = afRadioTime[i]; + uint32 trackPos = GetSavedRadioStationPosition(i); + if (trackPos != -1) { + if (trackPos > m_aTracks[i].m_nLength) { + debug("Radio Track %d saved position is %d, Length is only %d\n", i, trackPos, m_aTracks[i].m_nLength); + trackPos %= m_aTracks[i].m_nLength; } + m_aTracks[i].m_nPosition = trackPos; + m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); } - - wchar *string = nil; - - switch(pRetune) { - case WILDSTYLE: string = TheText.Get("FEA_FM0"); break; - case FLASH_FM: string = TheText.Get("FEA_FM1"); break; - case KCHAT: string = TheText.Get("FEA_FM2"); break; - case FEVER: string = TheText.Get("FEA_FM3"); break; - case V_ROCK: string = TheText.Get("FEA_FM4"); break; - case VCPR: string = TheText.Get("FEA_FM5"); break; - case RADIO_ESPANTOSO: string = TheText.Get("FEA_FM6"); break; - case EMOTION: string = TheText.Get("FEA_FM7"); break; - case WAVE: string = TheText.Get("FEA_FM8"); break; - case USERTRACK: string = TheText.Get("FEA_FM9"); break; - default: return; - }; - - if(pRetune > WAVE && !SampleManager.IsMP3RadioChannelAvailable()) { return; } - - if(string && pCurrentStation != string || - m_nCurrentStreamedSound == STREAMED_SOUND_RADIO_MP3_PLAYER && - m_nPreviousStreamedSound != STREAMED_SOUND_RADIO_MP3_PLAYER) { - pCurrentStation = string; - cDisplay = 60; - } else { - if(cDisplay == 0) return; - cDisplay--; - } - - CFont::SetJustifyOff(); - CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); - CFont::SetPropOn(); - CFont::SetFontStyle(FONT_STANDARD); - CFont::SetCentreOn(); - CFont::SetCentreSize(SCREEN_SCALE_X(640.0f)); - CFont::SetColor(CRGBA(0, 0, 0, 255)); - CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), pCurrentStation); - - if(gNumRetunePresses) - CFont::SetColor(CRGBA(102, 133, 143, 255)); - else - CFont::SetColor(CRGBA(147, 196, 211, 255)); - - CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_Y(22.0f), pCurrentStation); - CFont::DrawFonts(); } } -bool -cMusicManager::Initialise() +void +cMusicManager::SetStartingTrackPositions(uint8 isNewGameTimer) { int pos; - if (!IsInitialised()) { + if (IsInitialised()) { time_t timevalue = time(0); if (timevalue == -1) { pos = AudioManager.GetRandomNumber(0); } else { - tm *pTm = localtime(&timevalue); + tm* pTm = localtime(&timevalue); if (pTm->tm_sec == 0) pTm->tm_sec = AudioManager.GetRandomNumber(0); if (pTm->tm_min == 0) @@ -213,22 +157,52 @@ cMusicManager::Initialise() for (int i = 0; i < TOTAL_STREAMED_SOUNDS; i++) { m_aTracks[i].m_nLength = SampleManager.GetStreamedFileLength(i); - m_aTracks[i].m_nPosition = pos * AudioManager.GetRandomNumber(i % 5) % m_aTracks[i].m_nLength; + + if (i < STREAMED_SOUND_CITY_AMBIENT && isNewGameTimer) + m_aTracks[i].m_nPosition = NewGameRadioTimers[i]; + else if (i < STREAMED_SOUND_ANNOUNCE_BRIDGE_CLOSED) + m_aTracks[i].m_nPosition = pos * AudioManager.GetRandomNumber(i % 5) % m_aTracks[i].m_nLength; + else + m_aTracks[i].m_nPosition = 0; + m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); } + } +} +bool +cMusicManager::Initialise() +{ + if (!IsInitialised()) { + m_bIsInitialised = true; + SetStartingTrackPositions(false); m_bResetTimers = false; m_nResetTime = 0; - m_nTimer = m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode(); - m_bDoTrackService = false; - m_bIgnoreTimeDelay = false; m_bRadioSetByScript = false; m_nRadioStation = WILDSTYLE; m_nRadioPosition = -1; - m_nRadioInCar = NO_STREAMED_SOUND; - gNumRetunePresses = 0; + m_nRadioInCar = NO_TRACK; gRetuneCounter = 0; - m_bIsInitialised = true; + gNumRetunePresses = 0; + m_nFrontendTrack = NO_TRACK; + m_nPlayingTrack = NO_TRACK; + m_nUpcomingMusicMode = MUSICMODE_DISABLED; + m_nMusicMode = MUSICMODE_DISABLED; + field_398E = false; + field_398F = false; + m_nStreamedTrack = NO_TRACK; + field_3994 = false; + field_3995 = false; + field_3996 = false; + field_3997 = false; + field_3998 = -1; + field_3999 = false; + field_399A = false; + m_nMusicModeToBeSet = MUSICMODE_DISABLED; + field_399C = false; + m_nVolumeLatency = 0; + m_nCurrentVolume = 0; + m_nMaxVolume = 0; } return m_bIsInitialised; } @@ -240,76 +214,60 @@ cMusicManager::Terminate() if (SampleManager.IsStreamPlaying(0)) { SampleManager.StopStreamedFile(0); - m_nCurrentStreamedSound = NO_STREAMED_SOUND; - m_nPreviousStreamedSound = NO_STREAMED_SOUND; + m_nPlayingTrack = NO_TRACK; } m_bIsInitialised = false; } void -cMusicManager::ChangeMusicMode(uint8 mode) +cMusicManager::SetRadioChannelByScript(uint32 station, int32 pos) { - if (!IsInitialised()) return; - - uint8 mode2; - switch (mode) - { - case MUSICMODE_FRONTEND: mode2 = MUSICMODE_FRONTEND; break; - case MUSICMODE_GAME: mode2 = MUSICMODE_GAME; break; - case MUSICMODE_CUTSCENE: mode2 = MUSICMODE_CUTSCENE; break; - case MUSICMODE_DISABLE: mode2 = MUSICMODE_DISABLED; break; - default: return; - } - - if (mode2 != m_nMusicMode || mode == MUSICMODE_FRONTEND && mode2 == MUSICMODE_FRONTEND) { - switch (mode) - { - case MUSICMODE_FRONTEND: - case MUSICMODE_GAME: - case MUSICMODE_CUTSCENE: - case MUSICMODE_DISABLED: - if (SampleManager.IsStreamPlaying(0)) { - if (m_nCurrentStreamedSound < TOTAL_STREAMED_SOUNDS) { - m_aTracks[m_nCurrentStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0); - m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); - } - SampleManager.StopStreamedFile(0); - } - m_nCurrentStreamedSound = NO_STREAMED_SOUND; - m_nPreviousStreamedSound = NO_STREAMED_SOUND; - m_bFrontendTrackFinished = false; - m_bPlayInFrontend = false; - m_bSetNextStation = false; - m_bPreviousPlayerInCar = false; - m_bPlayerInCar = false; - m_bAnnouncementInProgress = false; - m_nTimer = m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode(); - m_bDoTrackService = false; - m_bIgnoreTimeDelay = true; - m_bDontServiceAmbienceTrack = false; - m_nMusicMode = mode2; - break; - default: return; + if (m_bIsInitialised) { + if (station == USERTRACK) + station = RADIO_OFF; + if (station <= STREAMED_SOUND_RADIO_POLICE) { + m_bRadioSetByScript = true; + m_nRadioStation = station; + m_nRadioPosition = pos == -1 ? -1 : pos % m_aTracks[station].m_nLength; } } } -uint8 +bool +cMusicManager::PlayerInCar() +{ + CVehicle *vehicle = AudioManager.FindVehicleOfPlayer(); + if(!vehicle) + return false; + + int32 State = FindPlayerPed()->m_nPedState; + + if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED) + return false; + + if (vehicle->GetStatus() == STATUS_WRECKED) + return false; + + return true; +} + +uint32 cMusicManager::GetRadioInCar(void) { if (!m_bIsInitialised) return WILDSTYLE; if (PlayerInCar()) { - CVehicle *veh = FindPlayerVehicle(); - if (veh != nil){ - if (UsesPoliceRadio(veh)) { - if (m_nRadioInCar == NO_STREAMED_SOUND || (CReplay::IsPlayingBack() && AudioManager.m_nUserPause == 0)) - return POLICE_RADIO; + CVehicle* veh = AudioManager.FindVehicleOfPlayer(); + if (veh != nil) { + if (UsesPoliceRadio(veh) || UsesTaxiRadio(veh)) { + if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && AudioManager.m_nUserPause == 0)) + return STREAMED_SOUND_RADIO_POLICE; return m_nRadioInCar; - } else return veh->m_nRadioStation; + } + else return veh->m_nRadioStation; } } - if (m_nRadioInCar == NO_STREAMED_SOUND || (CReplay::IsPlayingBack() && AudioManager.m_nUserPause == 0)) + if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && AudioManager.m_nUserPause == 0)) return RADIO_OFF; return m_nRadioInCar; } @@ -322,9 +280,9 @@ cMusicManager::SetRadioInCar(uint32 station) m_nRadioInCar = station; return; } - CVehicle *veh = FindPlayerVehicle(); + CVehicle* veh = AudioManager.FindVehicleOfPlayer(); if (veh == nil) return; - if (UsesPoliceRadio(veh)) + if (UsesPoliceRadio(veh) || UsesTaxiRadio(veh)) m_nRadioInCar = station; else veh->m_nRadioStation = station; @@ -332,29 +290,52 @@ cMusicManager::SetRadioInCar(uint32 station) } void -cMusicManager::SetRadioChannelByScript(uint8 station, int32 pos) +cMusicManager::RecordRadioStats() { - if (m_bIsInitialised && station < RADIO_OFF) { - m_bRadioSetByScript = true; - m_nRadioStation = station; - m_nRadioPosition = pos == -1 ? -1 : pos % m_aTracks[station].m_nLength; + if (m_nPlayingTrack < STREAMED_SOUND_CITY_AMBIENT) { + double time /*Rusty*/ = CTimer::GetTimeInMillisecondsPauseMode(); + if (time > m_nLastTrackServiceTime) + aListenTimeArray[m_nPlayingTrack] += time - m_nLastTrackServiceTime; } } - void -cMusicManager::ResetMusicAfterReload() +cMusicManager::ChangeMusicMode(uint8 mode) { - m_bRadioSetByScript = false; - m_nRadioStation = 0; - m_nRadioPosition = -1; - m_nAnnouncement = NO_STREAMED_SOUND; - m_bAnnouncementInProgress = false; - m_bSetNextStation = false; - gRetuneCounter = 0; - gNumRetunePresses = 0; -} + if (!IsInitialised()) return; + switch (mode) + { + case MUSICMODE_FRONTEND: m_nUpcomingMusicMode = MUSICMODE_FRONTEND; break; + case MUSICMODE_GAME: m_nUpcomingMusicMode = MUSICMODE_GAME; break; + case MUSICMODE_CUTSCENE: + m_nUpcomingMusicMode = MUSICMODE_CUTSCENE; + if (SampleManager.IsStreamPlaying(0)) { + if (m_nPlayingTrack != NO_TRACK) { + RecordRadioStats(); + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + } + SampleManager.StopStreamedFile(0); + while (SampleManager.IsStreamPlaying(0)) + SampleManager.StopStreamedFile(0); + m_nMusicMode = m_nUpcomingMusicMode; + field_399A = false; + field_398F = false; + m_nStreamedTrack = NO_TRACK; + field_3994 = false; + field_3995 = false; + m_nPlayingTrack = NO_TRACK; + m_nFrontendTrack = NO_TRACK; + m_bAnnouncementInProgress = false; + m_nAnnouncement = NO_TRACK; + g_bAnnouncementReadPosAlready = false; + break; + case MUSICMODE_DISABLE: m_nUpcomingMusicMode = MUSICMODE_DISABLED; break; + default: return; + } +} void cMusicManager::ResetTimers(int32 time) @@ -371,297 +352,677 @@ cMusicManager::Service() m_nLastTrackServiceTime = m_nResetTime; } - if (!m_bIsInitialised || m_bDisabled) return; - - if (m_nMusicMode == MUSICMODE_CUTSCENE) { - SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0); - return; - } + static bool bRadioStatsRecorded = false; - m_nTimer = CTimer::GetTimeInMillisecondsPauseMode(); - if (m_nTimer > (m_nLastTrackServiceTime + 2000) || m_bIgnoreTimeDelay) { - m_bIgnoreTimeDelay = false; - m_bDoTrackService = true; - m_nLastTrackServiceTime = m_nTimer; - } else m_bDoTrackService = false; + if (!m_bIsInitialised || m_bDisabled) return; - if (m_nCurrentStreamedSound == NO_STREAMED_SOUND && SampleManager.IsStreamPlaying(0)) - SampleManager.StopStreamedFile(0); - else switch (m_nMusicMode) { - case MUSICMODE_FRONTEND: ServiceFrontEndMode(); break; - case MUSICMODE_GAME: ServiceGameMode(); break; + if (!field_399A) + m_nMusicModeToBeSet = m_nUpcomingMusicMode; + if (m_nMusicModeToBeSet == m_nMusicMode) { + if (!AudioManager.m_nUserPause || AudioManager.m_nPreviousUserPause || m_nMusicMode != MUSICMODE_FRONTEND) + { + switch (m_nMusicMode) + { + case MUSICMODE_FRONTEND: ServiceFrontEndMode(); break; + case MUSICMODE_GAME: ServiceGameMode(); break; + case MUSICMODE_CUTSCENE: SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0); break; + } + } + else + m_nMusicMode = MUSICMODE_DISABLED; + } else { + field_399A = true; + if (!field_3999 && !AudioManager.m_nUserPause && AudioManager.m_nPreviousUserPause) + field_3999 = true; + if (AudioManager.field_5554 % 4 == 0) { + gNumRetunePresses = 0; + gRetuneCounter = 0; + field_2 = false; + if (SampleManager.IsStreamPlaying(0)) { + if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) + { + RecordRadioStats(); + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + bRadioStatsRecorded = true; + } + SampleManager.StopStreamedFile(0); + } else { + bRadioStatsRecorded = false; + m_nMusicMode = m_nMusicModeToBeSet; + field_399A = false; + field_398F = false; + m_nStreamedTrack = NO_TRACK; + field_3994 = false; + field_3995 = false; + m_nPlayingTrack = NO_TRACK; + if (field_399C) + field_399C = false; + else + m_nFrontendTrack = NO_TRACK; + } } + } } void cMusicManager::ServiceFrontEndMode() { - if (m_nCurrentStreamedSound < TOTAL_STREAMED_SOUNDS) { - if (m_bFrontendTrackFinished) { - if (!SampleManager.IsStreamPlaying(0)) { - switch (m_nCurrentStreamedSound) - { - case STREAMED_SOUND_MISSION_COMPLETED: - if (!AudioManager.m_nUserPause) - ChangeMusicMode(MUSICMODE_GAME); - break; - default: - break; + static bool bRadioStatsRecorded = false; + + if (m_bAnnouncementInProgress) { + SampleManager.StopStreamedFile(0); + if (SampleManager.IsStreamPlaying(0)) + return; + g_bAnnouncementReadPosAlready = false; + m_nAnnouncement = NO_TRACK; + m_bAnnouncementInProgress = false; + m_nStreamedTrack = NO_TRACK; + m_nFrontendTrack = NO_TRACK; + m_nPlayingTrack = NO_TRACK; + } + + if (AudioManager.field_5554 % 4 != 0) return; + + if (!field_398F && !field_3995) { + m_nStreamedTrack = m_nFrontendTrack; + field_3994 = field_398E; + } + + if (m_nStreamedTrack == m_nPlayingTrack) { + if (SampleManager.IsStreamPlaying(0)) { + if (m_nVolumeLatency > 0) m_nVolumeLatency--; + else { + if (m_nCurrentVolume < m_nMaxVolume) + m_nCurrentVolume = Min(m_nMaxVolume, m_nCurrentVolume + 6); + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63u, 0, 0); + } + } else { + if (m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER) + SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0, 0); + else if (m_nPlayingTrack == STREAMED_SOUND_MISSION_COMPLETED && AudioManager.m_nUserPause == 0) + ChangeMusicMode(MUSICMODE_GAME); + } + } else { + field_398F = true; + if (field_3995 || !SampleManager.IsStreamPlaying(0)) { + bRadioStatsRecorded = false; + if (SampleManager.IsStreamPlaying(0) || m_nStreamedTrack == NO_TRACK) { + m_nPlayingTrack = m_nStreamedTrack; + field_3995 = false; + field_398F = false; + } else { + uint32 trackStartPos = (m_nStreamedTrack > STREAMED_SOUND_RADIO_POLICE) ? 0 : GetTrackStartPos(m_nStreamedTrack); + if (m_nStreamedTrack != NO_TRACK) { + SampleManager.SetStreamedFileLoopFlag(field_3994, 0); + SampleManager.StartStreamedFile(m_nStreamedTrack, trackStartPos, 0); + m_nVolumeLatency = 3; + m_nCurrentVolume = 0; + m_nMaxVolume = 100; + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0); + if (m_nStreamedTrack < STREAMED_SOUND_CITY_AMBIENT) + m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode(); + field_3995 = true; } - m_nCurrentStreamedSound = NO_STREAMED_SOUND; - m_nPreviousStreamedSound = NO_STREAMED_SOUND; } - } else if (bHasStarted) { - if (!SampleManager.IsStreamPlaying(0)) - SampleManager.StartStreamedFile(m_nCurrentStreamedSound, 0, 0); } else { + if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) { + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + RecordRadioStats(); + bRadioStatsRecorded = true; + } SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); - if (!SampleManager.StartStreamedFile(m_nCurrentStreamedSound, m_nCurrentStreamedSound < STREAMED_SOUND_RADIO_POLICE ? GetTrackStartPos(m_nCurrentStreamedSound) : 0, 0)) - return; - SampleManager.SetStreamedVolumeAndPan(100, 63, 0, 0); - if (m_bPlayInFrontend) bHasStarted = true; - else m_bFrontendTrackFinished = true; + SampleManager.StopStreamedFile(0); } } - if (SampleManager.IsStreamPlaying(0)) - SampleManager.SetStreamedVolumeAndPan((CPad::GetPad(0)->bDisplayNoControllerMessage || CPad::GetPad(0)->bObsoleteControllerMessage) ? 0 : 100, 63, 0, 0); } void cMusicManager::ServiceGameMode() { - bool bRadioOff = false; - static int8 nFramesSinceCutsceneEnded = -1; - - m_bPreviousPlayerInCar = m_bPlayerInCar; - m_bPlayerInCar = PlayerInCar(); - m_nPreviousStreamedSound = m_nCurrentStreamedSound; - if (m_bPlayerInCar) { - if (FindPlayerPed() != nil - && !FindPlayerPed()->DyingOrDead() - && CPad::GetPad(0)->ChangeStationJustDown() - && !CReplay::IsPlayingBack() - && FindPlayerVehicle() != nil - && !UsesPoliceRadio(FindPlayerVehicle())) { - gRetuneCounter = 30; - gNumRetunePresses++; - AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 1.0f); - if (SampleManager.IsMP3RadioChannelAvailable()) { - if (gNumRetunePresses > RADIO_OFF) - gNumRetunePresses -= RADIO_OFF; + CPed *ped = FindPlayerPed(); + CVehicle *vehicle = AudioManager.FindVehicleOfPlayer(); + field_3997 = field_3996; + field_3996 = false; + + switch (CGame::currArea) + { + case AREA_HOTEL: + case AREA_MALL: + case AREA_STRIP_CLUB: + case AREA_DIRT: + case AREA_BLOOD: + case AREA_OVALRING: + case AREA_MALIBU_CLUB: + field_3996 = false; + break; + default: + if (SampleManager.GetMusicVolume()) { + if (PlayerInCar()) + field_3996 = true; + } else + field_3996 = false; + break; + } + + if (!field_3996) { + field_3998 = -1; + gNumRetunePresses = 0; + gRetuneCounter = 0; + field_2 = false; + } else if (ped) { + if (ped->m_objective != OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN && ped->m_objective != OBJ_55) { +#ifdef GTA_PC + if (SampleManager.IsMP3RadioChannelAvailable() + && vehicle->m_nRadioStation < USERTRACK + && ControlsManager.GetIsKeyboardKeyJustDown(rsF9) + && vehicle) + { + if (!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) { + gNumRetunePresses = 0; + gRetuneCounter = 20; + RadioStaticCounter = 0; + if (vehicle->m_nRadioStation < USERTRACK) + { + do + ++gNumRetunePresses; + while (gNumRetunePresses + vehicle->m_nRadioStation < USERTRACK); + } + } + } +#endif + if (CPad::GetPad(0)->ChangeStationJustDown() && vehicle) + { + if (!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) { + gNumRetunePresses++; + gRetuneCounter = 20; + RadioStaticCounter = 0; } + } + } - } else { - nFramesSinceCutsceneEnded = -1; } - if (AudioManager.m_nPreviousUserPause) - m_bPreviousPlayerInCar = false; - if (!m_bPlayerInCar) { - if (m_bPreviousPlayerInCar) { - if (m_nCurrentStreamedSound != STREAMED_SOUND_RADIO_POLICE) - m_nRadioInCar = m_nCurrentStreamedSound; - } - ServiceAmbience(); - return; + if (field_3999) + { + field_3997 = false; + field_3999 = false; } + if (m_nPlayingTrack == NO_TRACK && m_nFrontendTrack == NO_TRACK) + field_3997 = false; - if (m_bPreviousPlayerInCar) { - if (m_nAnnouncement < TOTAL_STREAMED_SOUNDS - && (m_nCurrentStreamedSound < STREAMED_SOUND_CITY_AMBIENT || m_bAnnouncementInProgress) - && ServiceAnnouncement()) + if (field_3996) + { + if (field_3997) { - if (m_bAnnouncementInProgress) { - m_bSetNextStation = false; - return; + if (m_nAnnouncement < NO_TRACK) { + if ((m_bAnnouncementInProgress || m_nFrontendTrack == m_nPlayingTrack) && ServiceAnnouncement()) { + if (m_bAnnouncementInProgress) { + field_2 = false; + gNumRetunePresses = 0; + gRetuneCounter = 0; + return; + } + if (m_nAnnouncement == NO_TRACK) + { + m_nFrontendTrack = GetCarTuning(); + field_2 = false; + gRetuneCounter = 0; + gNumRetunePresses = 0; + } + } } - m_nPreviousStreamedSound = m_nCurrentStreamedSound; - m_nCurrentStreamedSound = GetCarTuning(); - } - if (SampleManager.IsMP3RadioChannelAvailable() - && m_nCurrentStreamedSound != STREAMED_SOUND_RADIO_MP3_PLAYER - && ControlsManager.GetIsKeyboardKeyJustDown(rsF9)) - { - m_nPreviousStreamedSound = m_nCurrentStreamedSound; - m_nCurrentStreamedSound = STREAMED_SOUND_RADIO_MP3_PLAYER; - if (FindPlayerVehicle() != nil) - FindPlayerVehicle()->m_nRadioStation = STREAMED_SOUND_RADIO_MP3_PLAYER; - AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 1.0f); - gRetuneCounter = 0; - gNumRetunePresses = 0; - m_bSetNextStation = false; - } - if (gNumRetunePresses) { - if (gRetuneCounter != 0) gRetuneCounter--; - else m_bSetNextStation = true; - } - if (gRetuneCounter) - AudioManager.DoPoliceRadioCrackle(); - if (m_bSetNextStation) { - m_bSetNextStation = false; - m_nPreviousStreamedSound = m_nCurrentStreamedSound; - m_nCurrentStreamedSound = GetNextCarTuning(); - if (m_nCurrentStreamedSound == STREAMED_SOUND_CITY_AMBIENT || m_nCurrentStreamedSound == STREAMED_SOUND_WATER_AMBIENT) - bRadioOff = true; - - if (m_nPreviousStreamedSound == STREAMED_SOUND_CITY_AMBIENT || m_nPreviousStreamedSound == STREAMED_SOUND_WATER_AMBIENT) - AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 0.0f); - } - if (m_nCurrentStreamedSound < STREAMED_SOUND_CITY_AMBIENT) { - if (ChangeRadioChannel()) { - ServiceTrack(); - } else { - m_bPlayerInCar = false; - if (FindPlayerVehicle()) - FindPlayerVehicle()->m_nRadioStation = m_nCurrentStreamedSound; - m_nCurrentStreamedSound = NO_STREAMED_SOUND; + if (!m_bAnnouncementInProgress + && m_nAnnouncement == NO_TRACK + && m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER + && !SampleManager.IsStreamPlaying(0)) + { + SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0, 0); } - if (CTimer::GetIsSlowMotionActive()) { - if (TheCamera.pTargetEntity != nil) { - float dist = (TheCamera.pTargetEntity->GetPosition() - TheCamera.GetPosition()).MagnitudeSqr(); - if (dist >= 3025.0f) { - SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); - } else if (dist >= 100.0f) { - int8 volume = ((45.0f - (Sqrt(dist) - 10.0f)) / 45.0f * 100.0f); - int8 pan; - if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) - volume /= 4; - if (volume != 0) { - CVector trVec; - AudioManager.TranslateEntity(&TheCamera.pTargetEntity->GetPosition(), &trVec); - pan = AudioManager.ComputePan(55.0f, &trVec); - } else { - pan = 0; - } - if (gRetuneCounter) - volume /= 4; - SampleManager.SetStreamedVolumeAndPan(volume, pan, 0, 0); - } else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) { - SampleManager.SetStreamedVolumeAndPan(25, 63, 0, 0); - } else if (gRetuneCounter) { - SampleManager.SetStreamedVolumeAndPan(25, 63, 0, 0); - } else { - SampleManager.SetStreamedVolumeAndPan(100, 63, 0, 0); + + if (!m_bRadioSetByScript) + { + if (gNumRetunePresses != 0) + { + if (--gRetuneCounter == 0) + { + field_2 = true; + gRetuneCounter = 0; } } - } else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) { - SampleManager.SetStreamedVolumeAndPan(25, 63, 0, 0); - nFramesSinceCutsceneEnded = 0; - } else { - int8 volume; - if (nFramesSinceCutsceneEnded == -1) { - volume = 100; - } else if (nFramesSinceCutsceneEnded >= 20) { - if (nFramesSinceCutsceneEnded >= 40) { - nFramesSinceCutsceneEnded = -1; - volume = 100; - } else { - volume = 3 * (nFramesSinceCutsceneEnded - 20) + 25; - nFramesSinceCutsceneEnded++; + if (gRetuneCounter) + { + int32 station = gNumRetunePresses + vehicle->m_nRadioStation; + while (station >= RADIO_OFF) station -= RADIO_OFF; + + if (!DMAudio.IsMP3RadioChannelAvailable() && station == USERTRACK) + { + ++gNumRetunePresses; + station = NUM_RADIOS; } - } else { - nFramesSinceCutsceneEnded++; - volume = 25; + if (station == NUM_RADIOS) + { + if (gRetuneCounter == NUM_RADIOS + 9) + { + AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_NO_RADIO, 0.0f); + RadioStaticCounter = 5; + } + } + else + { + if (station == WILDSTYLE && gRetuneCounter == NUM_RADIOS + 9) + AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 0.0f); + AudioManager.DoPoliceRadioCrackle(); + } + } + if (RadioStaticCounter < 2 && CTimer::GetTimeInMilliseconds() > RadioStaticTimer + 800) + { + AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_194, 0.0f); + RadioStaticCounter++; + RadioStaticTimer = CTimer::GetTimeInMilliseconds(); } - if (gRetuneCounter) volume /= 4; - SampleManager.SetStreamedVolumeAndPan(volume, 63, 0, 0); + if (field_2) + m_nFrontendTrack = GetNextCarTuning(); + if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT) + SetUpCorrectAmbienceTrack(); + ServiceTrack(vehicle, ped); + if (field_2) + field_2 = false; + return; + } + if (UsesPoliceRadio(vehicle)) + m_nFrontendTrack = STREAMED_SOUND_RADIO_POLICE; + else if (UsesTaxiRadio(vehicle)) + m_nFrontendTrack = STREAMED_SOUND_RADIO_TAXI; + else { + m_nFrontendTrack = m_nRadioStation; + vehicle->m_nRadioStation = m_nRadioStation; + } + + if (m_nRadioPosition != -1) { + m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition; + m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); } + + gRetuneCounter = 0; + gNumRetunePresses = 0; + field_2 = false; + m_bRadioSetByScript = false; + if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT) + SetUpCorrectAmbienceTrack(); + ServiceTrack(vehicle, ped); + if (field_2) + field_2 = false; return; } - if (bRadioOff) { - m_nCurrentStreamedSound = m_nPreviousStreamedSound; - if (FindPlayerVehicle() != nil) - FindPlayerVehicle()->m_nRadioStation = RADIO_OFF; - AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_NO_RADIO, 0.0f); + if (vehicle == nil) + { + m_nFrontendTrack = STREAMED_SOUND_RADIO_WAVE; // huh? + return; } - ServiceAmbience(); - return; - } - if (m_bRadioSetByScript) { - if (UsesPoliceRadio(FindPlayerVehicle())) { - m_nCurrentStreamedSound = STREAMED_SOUND_RADIO_POLICE; - } else { - m_nCurrentStreamedSound = m_nRadioStation; - if (FindPlayerVehicle()->m_nRadioStation == m_nCurrentStreamedSound) { - m_nPreviousStreamedSound = NO_STREAMED_SOUND; - SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); - SampleManager.StopStreamedFile(0); + if (m_bRadioSetByScript) + { + if (UsesPoliceRadio(vehicle)) + m_nFrontendTrack = STREAMED_SOUND_RADIO_POLICE; + else if (UsesTaxiRadio(vehicle)) + m_nFrontendTrack = STREAMED_SOUND_RADIO_TAXI; + else { + m_nFrontendTrack = m_nRadioStation; + vehicle->m_nRadioStation = m_nRadioStation; } - if (m_nRadioPosition != -1) { - m_aTracks[m_nCurrentStreamedSound].m_nPosition = m_nRadioPosition; - m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + if (m_nRadioPosition != -1) + { + m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition; + m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); } + m_bRadioSetByScript = false; + return; } - } else { - m_nCurrentStreamedSound = GetCarTuning(); - } - if (m_nCurrentStreamedSound >= RADIO_OFF) { - ServiceAmbience(); + + m_nFrontendTrack = GetCarTuning(); return; } - if (ChangeRadioChannel()) { - if (m_bRadioSetByScript) { - m_bRadioSetByScript = false; - FindPlayerVehicle()->m_nRadioStation = m_nCurrentStreamedSound; - } - } else { - m_bPlayerInCar = false; - m_nCurrentStreamedSound = NO_STREAMED_SOUND; + + if (m_bAnnouncementInProgress) + { + SampleManager.StopStreamedFile(0); + if (SampleManager.IsStreamPlaying(0)) + return; + g_bAnnouncementReadPosAlready = false; + m_nAnnouncement = NO_TRACK; + m_bAnnouncementInProgress = false; + m_nStreamedTrack = NO_TRACK; + m_nFrontendTrack = NO_TRACK; + m_nPlayingTrack = NO_TRACK; } + SetUpCorrectAmbienceTrack(); + ServiceTrack(nil, ped); } void -cMusicManager::StopFrontEndTrack() +cMusicManager::SetUpCorrectAmbienceTrack() { - if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_FRONTEND && m_nCurrentStreamedSound != NO_STREAMED_SOUND) { - m_aTracks[m_nCurrentStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0); - m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); - SampleManager.StopStreamedFile(0); - m_nPreviousStreamedSound = NO_STREAMED_SOUND; - m_nCurrentStreamedSound = NO_STREAMED_SOUND; + switch (CGame::currArea) + { + case AREA_MAIN_MAP: + case AREA_EVERYWHERE: + if (CTheScripts::RiotIntensity != 0 && ((TheCamera.GetPosition() - vecRiotPosition).MagnitudeSqr() < SQR(65.0f))) + m_nFrontendTrack = STREAMED_SOUND_LAW4RIOT_AMBIENT; + else if (TheCamera.DistanceToWater <= 90.0f) { + if (CCullZones::bAtBeachForAudio) { + if (CWeather::OldWeatherType != WEATHER_HURRICANE && CWeather::NewWeatherType != WEATHER_HURRICANE || CWeather::Wind <= 1.0f) + m_nFrontendTrack = STREAMED_SOUND_BEACH_AMBIENT; + else + m_nFrontendTrack = STREAMED_SOUND_HAVANA_BEACH_AMBIENT; + } + else if (CWeather::OldWeatherType != WEATHER_HURRICANE && CWeather::NewWeatherType != WEATHER_HURRICANE || CWeather::Wind <= 1.0f) + m_nFrontendTrack = STREAMED_SOUND_WATER_AMBIENT; + else + m_nFrontendTrack = STREAMED_SOUND_HAVANA_WATER_AMBIENT; + } + else if (CWeather::OldWeatherType != WEATHER_HURRICANE && CWeather::NewWeatherType != WEATHER_HURRICANE || CWeather::Wind <= 1.0f) + m_nFrontendTrack = STREAMED_SOUND_CITY_AMBIENT; + else + m_nFrontendTrack = STREAMED_SOUND_HAVANA_CITY_AMBIENT; + break; + case AREA_HOTEL: + m_nFrontendTrack = STREAMED_SOUND_HOTEL_AMBIENT; + break; + case AREA_MALL: + m_nFrontendTrack = STREAMED_SOUND_MALL_AMBIENT; + break; + case AREA_STRIP_CLUB: + m_nFrontendTrack = STREAMED_SOUND_STRIPCLUB_AMBIENT; + break; + case AREA_DIRT: + case AREA_BLOOD: + case AREA_OVALRING: + m_nFrontendTrack = STREAMED_SOUND_DIRTRING_AMBIENT; + break; + case AREA_MALIBU_CLUB: + m_nFrontendTrack = STREAMED_SOUND_MALIBU_AMBIENT; + break; + case AREA_MANSION: + case AREA_BANK: + case AREA_LAWYERS: + case AREA_COFFEE_SHOP: + case AREA_CONCERT_HALL: + case AREA_STUDIO: + case AREA_RIFLE_RANGE: + case AREA_BIKER_BAR: + case AREA_POLICE_STATION: + m_nFrontendTrack = STREAMED_SOUND_AMBSIL_AMBIENT; + break; + } +} + +float +GetHeightScale() +{ + if (TheCamera.GetPosition().z > 20.0f) { + if (TheCamera.GetPosition().z < 50.0f) + return 1.0f - (TheCamera.GetPosition().z - 20.0f) / 30.0f; + return 0.0f; } + return 1.0f; } void -cMusicManager::PlayAnnouncement(uint32 announcement) +cMusicManager::ComputeAmbienceVol(uint8 reset, uint8& outVolume) { - if (IsInitialised() && !m_bDisabled && !m_bAnnouncementInProgress) - m_nAnnouncement = announcement; + static float fVol = 0.0f; + + float fHeightScale = GetHeightScale(); + + if (CTheScripts::RiotIntensity > 0) { + float distToRiotSq = (TheCamera.GetPosition() - vecRiotPosition).MagnitudeSqr(); + if (distToRiotSq < SQR(100.0f)) { + if (distToRiotSq >= SQR(65.0f)) + outVolume = (Sqrt(distToRiotSq) - 65.0f) / 35.0f * (127.0f * fHeightScale); + else if (distToRiotSq >= SQR(20.0f)) + outVolume = (CTheScripts::RiotIntensity * (1.0f - (Sqrt(distToRiotSq) - 20.0f) / 45.0f) * (127.0f * fHeightScale)) / MAX_VOLUME; + else + outVolume = (CTheScripts::RiotIntensity * (127.0f * fHeightScale)) / MAX_VOLUME; + return; + } + } + + if (reset) + fVol = 0.0f; + else if (fVol < 60.0f) { + if ((m_nPlayingTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT) && (m_nPlayingTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT)) + fVol += 20.0f; + else + fVol += 1.0f; + fVol = Min(fVol, 60.0f); + } + + if ((m_nPlayingTrack >= STREAMED_SOUND_MALL_AMBIENT) && (m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)) { + outVolume = fVol; + return; + } + + if (CWeather::OldWeatherType == WEATHER_HURRICANE || CWeather::NewWeatherType == WEATHER_HURRICANE) { + if (CWeather::Wind > 1.0f) { + outVolume = (CWeather::Wind - 1.0f) * fVol; + return; + } + fVol = (1.0f - CWeather::Wind) * fVol; + } + + if (TheCamera.DistanceToWater > 140.0f) { + outVolume = fVol; + return; + } + + if (TheCamera.DistanceToWater > 90.0f) { + outVolume = ((TheCamera.DistanceToWater - 90.0f) / 50.0f * fVol * fHeightScale); + return; + } + + if (TheCamera.DistanceToWater > 40.0f) { + outVolume = fVol; + return; + } + + outVolume = (90.0f - fHeightScale) / 50.0f * fVol; +} + +bool +cMusicManager::ServiceAnnouncement() +{ + if (m_bAnnouncementInProgress) { + if (SampleManager.IsStreamPlaying(0)) + m_nPlayingTrack = m_nStreamedTrack; + else if (m_nPlayingTrack != NO_TRACK) { + m_nAnnouncement = NO_TRACK; + m_bAnnouncementInProgress = false; + m_nPlayingTrack = NO_TRACK; + } + return true; + } else if (SampleManager.IsStreamPlaying(0)) { + if (m_nPlayingTrack != NO_TRACK && !g_bAnnouncementReadPosAlready) { + RecordRadioStats(); + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + g_bAnnouncementReadPosAlready = true; + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + SampleManager.StopStreamedFile(0); + } else { + g_bAnnouncementReadPosAlready = false; + m_nPlayingTrack = NO_TRACK; + m_nStreamedTrack = m_nAnnouncement; + SampleManager.SetStreamedFileLoopFlag(0, false); + SampleManager.StartStreamedFile(m_nStreamedTrack, 0, 0); + SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 0, 0); + m_bAnnouncementInProgress = true; + } + + return true; } void -cMusicManager::PlayFrontEndTrack(uint32 track, uint8 bPlayInFrontend) +cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped) { - if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS) { - if (m_nMusicMode == MUSICMODE_GAME) { - if (m_nCurrentStreamedSound != NO_STREAMED_SOUND) { - if (m_bAnnouncementInProgress) { - m_nAnnouncement = NO_STREAMED_SOUND; - m_bAnnouncementInProgress = false; - } - m_aTracks[m_nCurrentStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0); - m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + static bool bRadioStatsRecorded = false; + static bool bRadioStatsRecorded2 = false; + uint8 AmbienceVol; + if (!field_398F) + m_nStreamedTrack = m_nFrontendTrack; + if (gRetuneCounter != 0 || field_2) { + if (SampleManager.IsStreamPlaying(0)) { + if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) { + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + RecordRadioStats(); + bRadioStatsRecorded = true; } + SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); SampleManager.StopStreamedFile(0); - } else if (m_nMusicMode == MUSICMODE_FRONTEND) { - if (m_nCurrentStreamedSound != NO_STREAMED_SOUND) { - m_aTracks[m_nCurrentStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0); - m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + return; + } + + if (bRadioStatsRecorded) { + bRadioStatsRecorded = false; + m_nPlayingTrack = NO_TRACK; + } + + if (m_nStreamedTrack != m_nPlayingTrack) + { + field_398F = true; + SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); + if (!(AudioManager.field_5554 & 1)) { + if (field_3995 || !SampleManager.IsStreamPlaying(0)) { + bRadioStatsRecorded2 = false; + if (SampleManager.IsStreamPlaying(0)) { + m_nPlayingTrack = m_nStreamedTrack; + field_3995 = false; + field_398F = false; + if (veh) { + if (veh->m_nRadioStation < STREAMED_SOUND_CITY_AMBIENT || veh->m_nRadioStation > STREAMED_SOUND_AMBSIL_AMBIENT) + veh->m_nRadioStation = m_nPlayingTrack; + else + veh->m_nRadioStation = STREAMED_SOUND_CITY_AMBIENT; + } + } else { + uint32 pos = GetTrackStartPos(m_nStreamedTrack); + if (m_nStreamedTrack != NO_TRACK) { + SampleManager.SetStreamedFileLoopFlag(1, 0); + SampleManager.StartStreamedFile(m_nStreamedTrack, pos, 0); + if (m_nFrontendTrack < STREAMED_SOUND_CITY_AMBIENT || m_nFrontendTrack > STREAMED_SOUND_AMBSIL_AMBIENT) + { + m_nVolumeLatency = 10; + m_nCurrentVolume = 0; + m_nMaxVolume = 100; + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0); + } + else + { + ComputeAmbienceVol(true, AmbienceVol); + SampleManager.SetStreamedVolumeAndPan(AmbienceVol, 63, 1, 0); + } + if (m_nStreamedTrack < STREAMED_SOUND_CITY_AMBIENT) + m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode(); + field_3995 = true; + } + } + } else { + if (m_nPlayingTrack == NO_TRACK) + debug("m_nPlayingTrack == NO_TRACK, yet track playing - tidying up\n"); + else if (!bRadioStatsRecorded2) + { + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + bRadioStatsRecorded2 = true; + RecordRadioStats(); + if (m_nPlayingTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT) + { + if (m_nStreamedTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT && m_nStreamedTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT) + AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE_2, 0.0); + } + } + SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); + SampleManager.StopStreamedFile(0); } - SampleManager.StopStreamedFile(0); } + return; + } - m_nPreviousStreamedSound = m_nCurrentStreamedSound; - m_nCurrentStreamedSound = track; - m_bPlayInFrontend = !!bPlayInFrontend; - m_bFrontendTrackFinished = false; - m_bDoTrackService = true; - bHasStarted = false; - if (m_nCurrentStreamedSound < STREAMED_SOUND_RADIO_POLICE) { - gRetuneCounter = 0; - gNumRetunePresses = 0; + if (m_nPlayingTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT) + { + ComputeAmbienceVol(false, AmbienceVol); + SampleManager.SetStreamedVolumeAndPan(AmbienceVol, 63, 1, 0); + return; + } + if (CTimer::GetIsSlowMotionActive()) + { + if (TheCamera.pTargetEntity) + { + float DistToTargetSq = (TheCamera.pTargetEntity->GetPosition() - TheCamera.GetPosition()).MagnitudeSqr(); + if (DistToTargetSq >= SQR(55.0f)) + { + SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); + } + else if (DistToTargetSq >= SQR(10.0f)) + { + AmbienceVol = (45.0f - (Sqrt(DistToTargetSq) - 10.0f)) / 45.0f * m_nCurrentVolume; + if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) + AmbienceVol /= 4; + + uint8 pan = 0; + if (AmbienceVol > 0) + { + CVector panVec; + AudioManager.TranslateEntity(&TheCamera.pTargetEntity->GetPosition(), &panVec); + pan = AudioManager.ComputePan(55.0f, &panVec); + } + if (gRetuneCounter != 0) + AmbienceVol = 0; + SampleManager.SetStreamedVolumeAndPan(AmbienceVol, pan, 0, 0); + } + else if (!AudioManager.ShouldDuckMissionAudio(0) && !AudioManager.ShouldDuckMissionAudio(1)) + { + if (gRetuneCounter == 0) + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0); + else + SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); + } + else + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0); } } + else + { + if (!AudioManager.ShouldDuckMissionAudio(0) && !AudioManager.ShouldDuckMissionAudio(1)) { + if (field_3998 == -1) + AmbienceVol = m_nCurrentVolume; + else if (field_3998 < 20) + { + AmbienceVol = Min(m_nCurrentVolume, 25); + field_3998++; + } + else if (field_3998 < 40) + { + AmbienceVol = Min(m_nCurrentVolume, 3 * (field_3998 - 20) + 25); + field_3998++; + } + else + { + AmbienceVol = m_nCurrentVolume; + field_3998 = -1; + } + if (gRetuneCounter != 0) + AmbienceVol = 0; + SampleManager.SetStreamedVolumeAndPan(AmbienceVol, 63, 0, 0); + } else + SampleManager.SetStreamedVolumeAndPan(Min(m_nCurrentVolume, 25), 63, 0, 0); + } + if (m_nVolumeLatency > 0) + m_nVolumeLatency--; + else if (m_nCurrentVolume < m_nMaxVolume) + m_nCurrentVolume = Min(m_nMaxVolume, m_nCurrentVolume + 6); } void @@ -673,7 +1034,7 @@ cMusicManager::PreloadCutSceneMusic(uint32 track) SampleManager.StopStreamedFile(0); SampleManager.PreloadStreamedFile(track, 0); SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0); - m_nCurrentStreamedSound = track; + m_nPlayingTrack = track; } } @@ -689,223 +1050,270 @@ cMusicManager::StopCutSceneMusic(void) { if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_CUTSCENE) { SampleManager.StopStreamedFile(0); - m_nCurrentStreamedSound = NO_STREAMED_SOUND; + m_nPlayingTrack = NO_TRACK; } } -uint32 -cMusicManager::GetTrackStartPos(uint8 track) +void +cMusicManager::PlayFrontEndTrack(uint32 track, uint8 bPlayInFrontend) { - uint32 result; - uint32 timer = m_aTracks[track].m_nLastPosCheckTimer; - if (CTimer::GetTimeInMillisecondsPauseMode() <= timer) { - result = m_aTracks[track].m_nPosition; - m_aTracks[track].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); - } else - result = Min(CTimer::GetTimeInMillisecondsPauseMode() - timer, 90000) + m_aTracks[track].m_nPosition; + if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS && (m_nUpcomingMusicMode == MUSICMODE_FRONTEND || m_nMusicMode == MUSICMODE_FRONTEND)) + { + m_nFrontendTrack = track; + field_398E = bPlayInFrontend; + if (m_nMusicMode != MUSICMODE_FRONTEND) + field_399C = true; + } +} - if (result > m_aTracks[track].m_nLength) result %= m_aTracks[track].m_nLength; - return result; +void +cMusicManager::StopFrontEndTrack() +{ + if (m_nUpcomingMusicMode == MUSICMODE_FRONTEND || m_nMusicMode == MUSICMODE_FRONTEND) + m_nFrontendTrack = NO_TRACK; } +void +cMusicManager::PlayAnnouncement(uint32 announcement) +{ + if (IsInitialised() && !m_bDisabled && !m_bAnnouncementInProgress) + m_nAnnouncement = announcement; +} -bool -cMusicManager::UsesPoliceRadio(CVehicle *veh) +uint32 +cMusicManager::GetNextCarTuning() { - switch (veh->GetModelIndex()) - { - case MI_VCNMAV: - case MI_POLMAV: - case MI_COASTG: - case MI_RHINO: - case MI_BARRACKS: - return true; - case MI_MRWHOOP: - case MI_HUNTER: - return false; + CVehicle *veh = AudioManager.FindVehicleOfPlayer(); + if (veh == nil) return STREAMED_SOUND_CITY_AMBIENT; + if (UsesPoliceRadio(veh)) return STREAMED_SOUND_RADIO_POLICE; + if (UsesTaxiRadio(veh)) return STREAMED_SOUND_RADIO_TAXI; + if (gNumRetunePresses != 0) { + veh->m_nRadioStation += gNumRetunePresses; + while (veh->m_nRadioStation >= RADIO_OFF) + veh->m_nRadioStation -= RADIO_OFF; + DMAudio.IsMP3RadioChannelAvailable(); // woof, just call and do nothing =P + gNumRetunePresses = 0; } - return veh->UsesSiren(); + return veh->m_nRadioStation; } -void -cMusicManager::ServiceAmbience() +uint32 +cMusicManager::GetCarTuning() { - uint8 volume; + CVehicle* veh = AudioManager.FindVehicleOfPlayer(); + if (veh == nil) return STREAMED_SOUND_CITY_AMBIENT; + if (UsesPoliceRadio(veh)) return STREAMED_SOUND_RADIO_POLICE; + if (UsesTaxiRadio(veh)) return STREAMED_SOUND_RADIO_TAXI; + if (veh->m_nRadioStation == USERTRACK && !SampleManager.IsMP3RadioChannelAvailable()) + veh->m_nRadioStation = AudioManager.GetRandomNumber(2) % USERTRACK; + return veh->m_nRadioStation; +} - if (m_bAnnouncementInProgress) { - m_nAnnouncement = NO_STREAMED_SOUND; - m_bAnnouncementInProgress = false; - } - if (m_nCurrentStreamedSound < STREAMED_SOUND_CITY_AMBIENT) { - if (SampleManager.IsStreamPlaying(0)) { - m_aTracks[m_nCurrentStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0); - m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); - SampleManager.StopStreamedFile(0); - m_nCurrentStreamedSound = NO_STREAMED_SOUND; - return; - } - m_nCurrentStreamedSound = STREAMED_SOUND_CITY_AMBIENT; - } - if (CWorld::Players[CWorld::PlayerInFocus].m_WBState != WBSTATE_PLAYING && !SampleManager.IsStreamPlaying(0)) { - m_nCurrentStreamedSound = NO_STREAMED_SOUND; - return; - } +float* +cMusicManager::GetListenTimeArray() +{ + return aListenTimeArray; +} - m_nPreviousStreamedSound = m_nCurrentStreamedSound; - m_nCurrentStreamedSound = TheCamera.DistanceToWater <= 45.0f ? STREAMED_SOUND_WATER_AMBIENT : STREAMED_SOUND_CITY_AMBIENT; +uint32 cMusicManager::GetTrackStartPos(uint32 track) +{ + if (!IsInitialised()) return 0; - if (m_nCurrentStreamedSound == m_nPreviousStreamedSound) { - ComputeAmbienceVol(false, volume); - SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0); - if (m_bDontServiceAmbienceTrack) { - if (SampleManager.IsStreamPlaying(0)) - m_bDontServiceAmbienceTrack = false; - } else ServiceTrack(); - } else { - if (m_nPreviousStreamedSound < TOTAL_STREAMED_SOUNDS) { - m_aTracks[m_nPreviousStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0); - m_aTracks[m_nPreviousStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); - SampleManager.StopStreamedFile(0); - } - uint32 pos = GetTrackStartPos(m_nCurrentStreamedSound); - SampleManager.SetStreamedVolumeAndPan(0, 63, 1, 0); - if (SampleManager.StartStreamedFile(m_nCurrentStreamedSound, pos, 0)) { - ComputeAmbienceVol(true, volume); - SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0); - m_bDontServiceAmbienceTrack = true; - } else - m_nCurrentStreamedSound = NO_STREAMED_SOUND; - } + uint32 pos = m_aTracks[track].m_nPosition; + if (CTimer::GetTimeInMillisecondsPauseMode() > m_aTracks[track].m_nLastPosCheckTimer) + pos += Min(CTimer::GetTimeInMillisecondsPauseMode() - m_aTracks[track].m_nLastPosCheckTimer, 270000); + else + m_aTracks[track].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + + if (pos > m_aTracks[track].m_nLength) + pos %= m_aTracks[track].m_nLength; + return pos; } -void -cMusicManager::ComputeAmbienceVol(uint8 reset, uint8 &outVolume) +uint32 +cMusicManager::GetRadioPosition(uint32 station) { - static float fVol = 0.0f; + if (station < STREAMED_SOUND_CITY_AMBIENT) + return GetTrackStartPos(station); + return 0; +} - if (reset) - fVol = 0.0f; - else if (fVol < 60.0f) - fVol += 1.0f; +uint32 +cMusicManager::GetFavouriteRadioStation() +{ + uint32 favstation = 0; - if (TheCamera.DistanceToWater > 70.0f) - outVolume = fVol; - else if (TheCamera.DistanceToWater > 45.0f) - outVolume = (TheCamera.DistanceToWater - 45.0f) / 25.0f * fVol; - else if (TheCamera.DistanceToWater > 20.0f) - outVolume = (45.0f - TheCamera.DistanceToWater) / 25.0f * fVol; - else - outVolume = fVol; + for (int i = 1; i < NUM_RADIOS; i++) { + if (aListenTimeArray[i] > aListenTimeArray[favstation]) + favstation = i; + } + + return favstation; +} + +bool +cMusicManager::CheckForMusicInterruptions() +{ + return (m_nPlayingTrack == STREAMED_SOUND_MISSION_COMPLETED) || (m_nPlayingTrack == STREAMED_SOUND_CUTSCENE_FINALE); } void -cMusicManager::ServiceTrack() +cMusicManager::SetMalibuClubTrackPos(uint8 scriptObject) { - if (m_bDoTrackService) { - if (!SampleManager.IsStreamPlaying(0)) - SampleManager.StartStreamedFile(m_nCurrentStreamedSound, 0, 0); + if (!IsInitialised()) + m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = 8640; + if (m_nStreamedTrack != STREAMED_SOUND_MALIBU_AMBIENT && m_nPlayingTrack != STREAMED_SOUND_MALIBU_AMBIENT) { + switch (scriptObject) + { + case SCRIPT_SOUND_MALIBU_1: + m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 8640; + break; + case SCRIPT_SOUND_MALIBU_2: + m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 286720; + break; + case SCRIPT_SOUND_MALIBU_3: + m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 509120; + break; + } + m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); } } -bool -cMusicManager::ServiceAnnouncement() +void +cMusicManager::SetStripClubTrackPos(uint8 scriptObject) { - static int8 cCheck = 0; - if (m_bAnnouncementInProgress) { - if (!SampleManager.IsStreamPlaying(0)) { - m_nAnnouncement = NO_STREAMED_SOUND; - m_bAnnouncementInProgress = false; + if (!IsInitialised()) + m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = 0; + if (m_nStreamedTrack != STREAMED_SOUND_STRIPCLUB_AMBIENT && m_nPlayingTrack != STREAMED_SOUND_STRIPCLUB_AMBIENT) + { + switch (scriptObject) + { + case SCRIPT_SOUND_STRIPCLUB_1: + m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = AudioManager.m_anRandomTable[0] % 128; + break; + case SCRIPT_SOUND_STRIPCLUB_2: + m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 320200; + break; + case SCRIPT_SOUND_STRIPCLUB_3: + m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 672000; + break; } - return true; + m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); } +} - if (++cCheck >= 30) { - cCheck = 0; - int pos = SampleManager.GetStreamedFilePosition(0); - if (SampleManager.IsStreamPlaying(0)) { - if (m_nCurrentStreamedSound != NO_STREAMED_SOUND) { - m_aTracks[m_nCurrentStreamedSound].m_nPosition = pos; - m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); - SampleManager.StopStreamedFile(0); +void +cMusicManager::DisplayRadioStationName() +{ + int8 gStreamedSound; + static wchar *pCurrentStation = nil; + static uint8 cDisplay = 0; + + if(!CTimer::GetIsPaused() && !TheCamera.m_WideScreenOn && PlayerInCar() && + !CReplay::IsPlayingBack()) { + CVehicle *vehicle = AudioManager.FindVehicleOfPlayer(); + + if (vehicle) + { + uint8 track; + gStreamedSound = vehicle->m_nRadioStation; + if (gStreamedSound >= STREAMED_SOUND_CITY_AMBIENT && gStreamedSound <= STREAMED_SOUND_AMBSIL_AMBIENT) + gStreamedSound = STREAMED_SOUND_CITY_AMBIENT; + if (gNumRetunePresses != 0) + { + track = gNumRetunePresses + gStreamedSound; + while (track >= RADIO_OFF) track -= RADIO_OFF; + if (!DMAudio.IsMP3RadioChannelAvailable() && track == USERTRACK) + gNumRetunePresses++; } - } + else + track = m_nFrontendTrack; + + + wchar* string = nil; + switch (track) { + case WILDSTYLE: string = TheText.Get("FEA_FM0"); break; + case FLASH_FM: string = TheText.Get("FEA_FM1"); break; + case KCHAT: string = TheText.Get("FEA_FM2"); break; + case FEVER: string = TheText.Get("FEA_FM3"); break; + case V_ROCK: string = TheText.Get("FEA_FM4"); break; + case VCPR: string = TheText.Get("FEA_FM5"); break; + case RADIO_ESPANTOSO: string = TheText.Get("FEA_FM6"); break; + case EMOTION: string = TheText.Get("FEA_FM7"); break; + case WAVE: string = TheText.Get("FEA_FM8"); break; + case USERTRACK: + if (!SampleManager.IsMP3RadioChannelAvailable()) + return; + string = TheText.Get("FEA_MP3"); break; + default: return; + }; - SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); - if (SampleManager.StartStreamedFile(m_nAnnouncement, 0, 0)) { - SampleManager.SetStreamedVolumeAndPan((AudioManager.IsMissionAudioSamplePlaying(0) || AudioManager.IsMissionAudioSamplePlaying(1)) ? 25 : 100, 63, 0, 0); - m_bAnnouncementInProgress = true; - m_nPreviousStreamedSound = m_nCurrentStreamedSound; - m_nCurrentStreamedSound = m_nAnnouncement; - return true; + if (pCurrentStation != string) { + pCurrentStation = string; + cDisplay = 60; + } + else { + if (cDisplay == 0) return; + cDisplay--; + } + + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); + CFont::SetPropOn(); + CFont::SetFontStyle(FONT_STANDARD); + CFont::SetCentreOn(); + CFont::SetCentreSize(SCREEN_SCALE_X(640.0f)); + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), pCurrentStation); + + if (gNumRetunePresses) + CFont::SetColor(CRGBA(102, 133, 143, 255)); + else + CFont::SetColor(CRGBA(147, 196, 211, 255)); + + CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_Y(22.0f), pCurrentStation); + CFont::DrawFonts(); } + } +} - if (cCheck != 0) cCheck--; - else cCheck = 30; +bool +cMusicManager::UsesPoliceRadio(CVehicle *veh) +{ + switch (veh->GetModelIndex()) + { + case MI_VCNMAV: + case MI_POLMAV: + case MI_COASTG: + case MI_RHINO: + case MI_BARRACKS: + return true; + case MI_MRWHOOP: + case MI_HUNTER: return false; } - - return false; + return veh->UsesSiren(); } -uint32 -cMusicManager::GetCarTuning() +bool +cMusicManager::UsesTaxiRadio(CVehicle *veh) { - CVehicle *veh = FindPlayerVehicle(); - if (veh == nil) return RADIO_OFF; - if (UsesPoliceRadio(veh)) return POLICE_RADIO; - if (veh->m_nRadioStation == USERTRACK && !SampleManager.IsMP3RadioChannelAvailable()) - veh->m_nRadioStation = AudioManager.GetRandomNumber(2) % USERTRACK; - return veh->m_nRadioStation; + if (veh->GetModelIndex() != MI_KAUFMAN) return false; + return CTheScripts::bPlayerHasMetDebbieHarry; } -uint32 -cMusicManager::GetNextCarTuning() +void +cMusicManager::ServiceAmbience() { - CVehicle *veh = FindPlayerVehicle(); - if (veh == nil) return RADIO_OFF; - if (UsesPoliceRadio(veh)) return STREAMED_SOUND_RADIO_POLICE; - if (gNumRetunePresses != 0) { - if (SampleManager.IsMP3RadioChannelAvailable()) { - if (veh->m_nRadioStation == RADIO_OFF) - veh->m_nRadioStation = POLICE_RADIO; - veh->m_nRadioStation += gNumRetunePresses; - if (veh->m_nRadioStation == POLICE_RADIO) - veh->m_nRadioStation = RADIO_OFF; - else if (veh->m_nRadioStation > POLICE_RADIO) - veh->m_nRadioStation -= RADIO_OFF; - } else if (gNumRetunePresses + veh->m_nRadioStation >= USERTRACK) { - while (gNumRetunePresses) { - if (veh->m_nRadioStation == RADIO_OFF) - veh->m_nRadioStation = WILDSTYLE; - else if (veh->m_nRadioStation < USERTRACK) - ++veh->m_nRadioStation; - - if (veh->m_nRadioStation == USERTRACK) - veh->m_nRadioStation = RADIO_OFF; - --gNumRetunePresses; - } - } else - veh->m_nRadioStation += gNumRetunePresses; - gNumRetunePresses = 0; - } - return veh->m_nRadioStation; } bool cMusicManager::ChangeRadioChannel() { - if (m_nCurrentStreamedSound != m_nPreviousStreamedSound) { - if (m_nPreviousStreamedSound < TOTAL_STREAMED_SOUNDS) { - m_aTracks[m_nPreviousStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0); - m_aTracks[m_nPreviousStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); - SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); - SampleManager.StopStreamedFile(0); - } - if (SampleManager.IsStreamPlaying(0)) - return false; - if (!SampleManager.StartStreamedFile(m_nCurrentStreamedSound, GetTrackStartPos(m_nCurrentStreamedSound), 0)) - return false; - SampleManager.SetStreamedVolumeAndPan((AudioManager.IsMissionAudioSamplePlaying(0) || AudioManager.IsMissionAudioSamplePlaying(1)) ? 25 : 100, 63, 0, 0); - } return true; } + +// these two are empty +void cMusicManager::Enable() {} +void cMusicManager::Disable() {}
\ No newline at end of file diff --git a/src/audio/MusicManager.h b/src/audio/MusicManager.h index 217b037b..e1bee497 100644 --- a/src/audio/MusicManager.h +++ b/src/audio/MusicManager.h @@ -11,41 +11,53 @@ public: }; class CVehicle; +class CPed; class cMusicManager { public: bool m_bIsInitialised; bool m_bDisabled; - uint8 m_nMusicMode; - uint32 m_nCurrentStreamedSound; - uint32 m_nPreviousStreamedSound; - bool m_bFrontendTrackFinished; - bool m_bPlayInFrontend; - bool m_bSetNextStation; + bool field_2; + uint8 m_nVolumeLatency; + uint8 m_nCurrentVolume; + uint8 m_nMaxVolume; uint32 m_nAnnouncement; - bool m_bPreviousPlayerInCar; - bool m_bPlayerInCar; bool m_bAnnouncementInProgress; tStreamedSample m_aTracks[TOTAL_STREAMED_SOUNDS]; bool m_bResetTimers; uint32 m_nResetTime; - uint32 m_nLastTrackServiceTime; - uint32 m_nTimer; - bool m_bDoTrackService; - bool m_bIgnoreTimeDelay; - bool m_bDontServiceAmbienceTrack; bool m_bRadioSetByScript; - uint32 m_nRadioStation; - int32 m_nRadioPosition; + uint8 m_nRadioStation; + uint32 m_nRadioPosition; uint32 m_nRadioInCar; + uint32 m_nFrontendTrack; + uint32 m_nPlayingTrack; + uint8 m_nUpcomingMusicMode; + uint8 m_nMusicMode; + bool field_398E; + bool field_398F; + uint32 m_nStreamedTrack; + bool field_3994; + bool field_3995; + bool field_3996; + bool field_3997; + int8 field_3998; + bool field_3999; + bool field_399A; + uint8 m_nMusicModeToBeSet; + bool field_399C; + float aListenTimeArray[NUM_RADIOS]; + float m_nLastTrackServiceTime; public: cMusicManager(); bool IsInitialised() { return m_bIsInitialised; } - uint32 GetMusicMode() { return m_nMusicMode; } - uint8 GetCurrentTrack() { return m_nCurrentStreamedSound; } + uint8 GetMusicMode() { return m_nMusicMode; } + uint32 GetCurrentTrack() { return m_nPlayingTrack; } + void ResetMusicAfterReload(); + void SetStartingTrackPositions(uint8 isNewGameTimer); bool Initialise(); void Terminate(); @@ -60,21 +72,20 @@ public: void PreloadCutSceneMusic(uint32); void PlayPreloadedCutSceneMusic(void); void StopCutSceneMusic(void); - uint8 GetRadioInCar(void); + uint32 GetRadioInCar(void); void SetRadioInCar(uint32); - void SetRadioChannelByScript(uint8, int32); - - void ResetMusicAfterReload(); + void SetRadioChannelByScript(uint32, int32); void ResetTimers(int32); void Service(); void ServiceFrontEndMode(); void ServiceGameMode(); void ServiceAmbience(); - void ServiceTrack(); + void ServiceTrack(CVehicle *veh, CPed *ped); bool UsesPoliceRadio(CVehicle *veh); - uint32 GetTrackStartPos(uint8); + bool UsesTaxiRadio(CVehicle *veh); + uint32 GetTrackStartPos(uint32 track); void ComputeAmbienceVol(uint8 reset, uint8& outVolume); bool ServiceAnnouncement(); @@ -82,8 +93,21 @@ public: uint32 GetCarTuning(); uint32 GetNextCarTuning(); bool ChangeRadioChannel(); + void RecordRadioStats(); + void SetUpCorrectAmbienceTrack(); + float *GetListenTimeArray(); + uint32 GetRadioPosition(uint32 station); + uint32 GetFavouriteRadioStation(); + void SetMalibuClubTrackPos(uint8 pos); + void SetStripClubTrackPos(uint8 pos); + bool CheckForMusicInterruptions(); + + void Enable(); + void Disable(); }; VALIDATE_SIZE(cMusicManager, 0x95C); extern cMusicManager MusicManager; +extern bool g_bAnnouncementReadPosAlready; // we have a symbol of this so it was declared in .h +float GetHeightScale();
\ No newline at end of file diff --git a/src/audio/audio_enums.h b/src/audio/audio_enums.h index 375c4a70..65094555 100644 --- a/src/audio/audio_enums.h +++ b/src/audio/audio_enums.h @@ -27,6 +27,15 @@ enum eMusicMode MUSICMODE_DISABLED, }; +enum ePlayerMood +{ + PLAYER_MOOD_CALM = 0, + PLAYER_MOOD_PISSED_OFF, + PLAYER_MOOD_ANGRY, + PLAYER_MOOD_WISECRACKING, + MAX_PLAYER_MOODS, +}; + enum eStreamedSounds { STREAMED_SOUND_RADIO_WILD, @@ -1254,7 +1263,7 @@ enum eStreamedSounds STREAMED_SOUND_MISSION_BUST_27, STREAMED_SOUND_MISSION_BUST_28, TOTAL_STREAMED_SOUNDS, - NO_STREAMED_SOUND, + NO_TRACK, }; enum AudioEntityHandle { diff --git a/src/audio/sampman.h b/src/audio/sampman.h index 773fbda1..a96704a1 100644 --- a/src/audio/sampman.h +++ b/src/audio/sampman.h @@ -117,15 +117,19 @@ class cSampleManager { uint8 m_nEffectsVolume; uint8 m_nMusicVolume; + uint8 m_nMP3BoostVolume; uint8 m_nEffectsFadeVolume; uint8 m_nMusicFadeVolume; uint8 m_nMonoMode; - char unk; char m_szCDRomRootPath[80]; bool m_bInitialised; uint8 m_nNumberOfProviders; char *m_aAudioProviders[MAXPROVIDERS]; tSample m_aSamples[TOTAL_AUDIO_SAMPLES]; + char m_MiscomPath[260]; + char m_SfxPath[260]; + char m_StreamedAudioPath[188]; + void *m_aChannels[18]; public: @@ -145,6 +149,8 @@ public: int8 GetCurrent3DProviderIndex(void); int8 SetCurrent3DProvider(uint8 which); + + int8 AutoDetect3DProviders(); bool IsMP3RadioChannelAvailable(void); @@ -165,6 +171,7 @@ public: void SetEffectsMasterVolume(uint8 nVolume); void SetMusicMasterVolume (uint8 nVolume); + void SetMP3BoostVolume (uint8 nVolume); void SetEffectsFadeVolume (uint8 nVolume); void SetMusicFadeVolume (uint8 nVolume); void SetMonoMode (uint8 nMode); @@ -213,6 +220,9 @@ public: void Service(void); #endif bool InitialiseSampleBanks(void); + + uint8 GetMusicVolume() const { return m_nMusicVolume; } + void SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nStream); }; extern cSampleManager SampleManager; diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp index d6bb1975..537c3aef 100644 --- a/src/audio/sampman_miles.cpp +++ b/src/audio/sampman_miles.cpp @@ -61,6 +61,7 @@ char _mp3DirectoryPath[MAX_PATH]; HSTREAM mp3Stream [MAX_STREAMS]; int8 nStreamPan [MAX_STREAMS]; int8 nStreamVolume[MAX_STREAMS]; +uint8 nStreamLoopedFlag[MAX_STREAMS]; uint32 _CurMP3Index; int32 _CurMP3Pos; bool _bIsMp3Active; @@ -407,6 +408,63 @@ cSampleManager::SetCurrent3DProvider(uint8 nProvider) return curprovider; } +int8 +cSampleManager::AutoDetect3DProviders() +{ + if (!AudioManager.IsAudioInitialised()) + return -1; + + int eax = -1, eax2 = -1, eax3 = -1, ds3dh = -1, ds3ds = -1; + + for (uint32 i = 0; i < GetNum3DProvidersAvailable(); i++) + { + char* providername = Get3DProviderName(i); + + if (!strcasecmp(providername, "CREATIVE LABS EAX (TM)")) { + AudioManager.SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) + eax = i; + } + + if (!strcasecmp(providername, "CREATIVE LABS EAX 2 (TM)")) { + AudioManager.SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) + eax2 = i; + } + + if (!strcasecmp(providername, "CREATIVE LABS EAX 3 (TM)")) { + AudioManager.SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) { + eax3 = i; + } + } + + if (!strcasecmp(providername, "DIRECTSOUND3D HARDWARE SUPPORT")) { + AudioManager.SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) + ds3dh = i; + } + + if (!strcasecmp(providername, "DIRECTSOUND3D SOFTWARE EMULATION")) { + AudioManager.SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) + ds3ds = i; + } + } + + if (eax3 != -1) + return eax3; + if (eax2 != -1) + return eax2; + if (eax != -1) + return eax; + if (ds3dh != -1) + return ds3dh; + if (ds3ds != -1) + return ds3ds; + return -1; +} + static bool _ResolveLink(char const *path, char *out) { @@ -1456,6 +1514,12 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume) } void +cSampleManager::SetMP3BoostVolume(uint8 nVolume) +{ + m_nMP3BoostVolume = nVolume; +} + +void cSampleManager::SetEffectsFadeVolume(uint8 nVolume) { m_nEffectsFadeVolume = nVolume; @@ -2132,7 +2196,8 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) AIL_open_stream(DIG, filename, 0); if(mp3Stream[nStream]) { AIL_set_stream_loop_count( - mp3Stream[nStream], 1); + mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1); + nStreamLoopedFlag[nStream] = true; AIL_set_stream_ms_position( mp3Stream[nStream], position); AIL_pause_stream(mp3Stream[nStream], @@ -2387,4 +2452,12 @@ cSampleManager::InitialiseSampleBanks(void) return true; } + +void +cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel) +{ + if (m_bInitialised) + nStreamLoopedFlag[nChannel] = nLoopFlag; +} + #endif
\ No newline at end of file diff --git a/src/audio/sampman_null.cpp b/src/audio/sampman_null.cpp index 3638e6fb..7aab0d09 100644 --- a/src/audio/sampman_null.cpp +++ b/src/audio/sampman_null.cpp @@ -114,6 +114,11 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume) } void +cSampleManager::SetMusicMasterVolume(uint8 nVolume) +{ +} + +void cSampleManager::SetEffectsFadeVolume(uint8 nVolume) { } @@ -365,4 +370,14 @@ cSampleManager::InitialiseSampleBanks(void) return true; } +void +cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel) +{ +} + +int8 cSampleManager::AutoDetect3DProviders() +{ + return -1; +} + #endif diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp index 1e9f60fd..0b59766f 100644 --- a/src/audio/sampman_oal.cpp +++ b/src/audio/sampman_oal.cpp @@ -131,6 +131,7 @@ uint32 nNumMP3s; CStream *aStream[MAX_STREAMS]; uint8 nStreamPan [MAX_STREAMS]; uint8 nStreamVolume[MAX_STREAMS]; +uint8 nStreamLoopedFlag[MAX_STREAMS]; /////////////////////////////////////////////////////////////// // Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS @@ -468,6 +469,38 @@ int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider) return curprovider; } +int8 +cSampleManager::AutoDetect3DProviders() +{ + if (!AudioManager.IsAudioInitialised()) + return -1; + + int eax = -1, eax2 = -1, eax3 = -1, ds3dh = -1, ds3ds = -1; + + for (uint32 i = 0; i < GetNum3DProvidersAvailable(); i++) + { + char* providername = Get3DProviderName(i); + + if (!strcasecmp(providername, "OPENAL SOFT")) { + SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) + return i; + } + } + + if (eax3 != -1) + return eax3; + if (eax2 != -1) + return eax2; + if (eax != -1) + return eax; + if (ds3dh != -1) + return ds3dh; + if (ds3ds != -1) + return ds3ds; + return -1; +} + bool cSampleManager::IsMP3RadioChannelAvailable(void) { @@ -730,6 +763,12 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume) } void +cSampleManager::SetMP3BoostVolume(uint8 nVolume) +{ + m_nMP3BoostVolume = nVolume; +} + +void cSampleManager::SetEffectsFadeVolume(uint8 nVolume) { m_nEffectsFadeVolume = nVolume; @@ -1468,4 +1507,11 @@ cSampleManager::InitialiseSampleBanks(void) return true; } +void +cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel) +{ + if (m_bInitialised) + nStreamLoopedFlag[nChannel] = nLoopFlag; +} + #endif diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h index bc9ac09a..bc5d3ba9 100644 --- a/src/audio/soundlist.h +++ b/src/audio/soundlist.h @@ -252,12 +252,15 @@ enum eScriptSounds : uint16 { SCRIPT_SOUND_SAWMILL_LOOP_L, SCRIPT_SOUND_38, SCRIPT_SOUND_39, - SCRIPT_SOUND_LAUNDERETTE_LOOP_S, - SCRIPT_SOUND_LAUNDERETTE_LOOP_L, - SCRIPT_SOUND_CHINATOWN_RESTAURANT_S, - SCRIPT_SOUND_CHINATOWN_RESTAURANT_L, - SCRIPT_SOUND_CIPRIANI_RESAURANT_S, - SCRIPT_SOUND_CIPRIANI_RESAURANT_L, + + // MIAMI: only these are true so far + SCRIPT_SOUND_MALIBU_1, + SCRIPT_SOUND_MALIBU_2, + SCRIPT_SOUND_MALIBU_3, + SCRIPT_SOUND_STRIPCLUB_1, + SCRIPT_SOUND_STRIPCLUB_2, + SCRIPT_SOUND_STRIPCLUB_3, + SCRIPT_SOUND_46_S, SCRIPT_SOUND_47_L, SCRIPT_SOUND_MARCO_BISTRO_S, diff --git a/src/control/Script.cpp b/src/control/Script.cpp index b313e308..c560e500 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -3773,7 +3773,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CPed* pNearPed = ped->m_nearPeds[i]; if (pNearPed->m_leader == ped) { pNearPed->Teleport(pos); - pNearPed->PositionPedOutOfCollision(); // TODO(MIAMI): this is PositionAnyPedOutOfCollision!!! + pNearPed->PositionAnyPedOutOfCollision(); } } } @@ -11936,7 +11936,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) return 0; case COMMAND_SHUT_CHAR_UP: CollectParameters(&m_nIp, 2); - debug("SHUT_CHAR_UP not implemented"); // TODO(MIAMI) + DMAudio.SetPedTalkingStatus(CPools::GetPedPool()->GetAt(ScriptParams[0]), ScriptParams[1] == 0); return 0; case COMMAND_SET_ENABLE_RC_DETONATE: CollectParameters(&m_nIp, 1); @@ -12563,13 +12563,13 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_SHUT_PLAYER_UP: { CollectParameters(&m_nIp, 2); - debug("SHUT_PLAYER_UP is not implemented\n"); // TODO(MIAMI) + DMAudio.ShutUpPlayerTalking(!!ScriptParams[1]); return 0; } case COMMAND_SET_PLAYER_MOOD: { CollectParameters(&m_nIp, 3); - debug("SET_PLAYER_MOOD is not implemented\n"); // TODO(MIAMI) + DMAudio.SetPlayersMood(ScriptParams[1], ScriptParams[2]); return 0; } case COMMAND_REQUEST_COLLISION: @@ -13001,7 +13001,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) } case COMMAND_DISABLE_CUTSCENE_SHADOWS: { - debug("DISABLE_CUTSCENE_SHADOWS not implemented, skipping\n"); // TODO(MIAMI) + CCutsceneMgr::DisableCutsceneShadows(); return 0; } case COMMAND_HAS_GLASS_BEEN_SHATTERED_NEARBY: @@ -13186,7 +13186,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) return 0; case COMMAND_REMOVE_EVERYTHING_FOR_HUGE_CUTSCENE: { - debug("REMOVE_EVERYTHING_FOR_HUGE_CUTSCENE not implemented, skipping\n"); + CCutsceneMgr::RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver(); return 0; } case COMMAND_IS_PLAYER_TOUCHING_VEHICLE: diff --git a/src/control/Script.h b/src/control/Script.h index 4493ade3..f3455797 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -282,12 +282,12 @@ class CTheScripts static uint8 UseTextCommands; static uint16 CommandsExecuted; static uint16 ScriptsUpdated; - static uint8 RiotIntensity; static uint32 LastMissionPassedTime; static uint16 NumberOfExclusiveMissionScripts; static bool bPlayerIsInTheStatium; +public: + static uint8 RiotIntensity; static bool bPlayerHasMetDebbieHarry; - public: static void Init(); static void Process(); diff --git a/src/core/EventList.h b/src/core/EventList.h index 0531aed7..dcca1270 100644 --- a/src/core/EventList.h +++ b/src/core/EventList.h @@ -24,6 +24,7 @@ enum eEventType EVENT_CAR_SET_ON_FIRE, EVENT_ASSAULT_NASTYWEAPON, EVENT_ASSAULT_NASTYWEAPON_POLICE, + EVENT_UNK, // Not on SA it seems EVENT_ICECREAM, EVENT_ATM, EVENT_SHOPSTALL, diff --git a/src/core/Game.cpp b/src/core/Game.cpp index d108c78d..6ba6b191 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -463,8 +463,7 @@ bool CGame::Initialise(const char* datFile) #ifdef USE_TEXTURE_POOL _TexturePoolsUnknown(true); #endif - // TODO(Miami) - // DMAudio.SetStartingTrackPositions(1); + DMAudio.SetStartingTrackPositions(true); DMAudio.ChangeMusicMode(MUSICMODE_GAME); return true; } diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp index 9c3ad084..373c295d 100644 --- a/src/core/Stats.cpp +++ b/src/core/Stats.cpp @@ -4,6 +4,7 @@ #include "Text.h" #include "World.h" #include "Pad.h" +#include "DMAudio.h" #include <climits> @@ -102,7 +103,7 @@ float CStats::LongestWheelieDist; float CStats::LongestStoppieDist; float CStats::Longest2WheelDist; -// --MIAMI: functions below are done except TODOs, but there are some to be moved from Frontend +// --MIAMI: functions below are done, but there are some to be moved from Frontend void CStats::Init() { @@ -198,9 +199,7 @@ void CStats::Init() NoMoreHurricanes = 0; ShowChaseStatOnScreen = 0; abSonyCDs[0] = 0; - // TODO(Miami): Change this with PopulateFavoriteRadioStationList(); !! - for (int i = 0; i < NUM_RADIOS; i++) - FavoriteRadioStationList[i] = 0.0f; + PopulateFavoriteRadioStationList(); NumPropertyOwned = 0; for (int i = 0; i < TOTAL_PROPERTIES; i++) @@ -471,6 +470,11 @@ void CStats::AddPropertyAsOwned(int32 id) } } +float CStats::GetFavoriteRadioStationList(int32 station) +{ + return FavoriteRadioStationList[station]; +} + void CStats::SaveStats(uint8 *buf, uint32 *size) { CheckPointReachedSuccessfully(); @@ -652,7 +656,7 @@ void CStats::SaveStats(uint8 *buf, uint32 *size) CopyToBuf(buf, TotalLegitimateKills); CopyToBuf(buf, LastMissionPassedName); CopyToBuf(buf, CheatedCount); - // TODO(Miami): Set favourite radio stations!! + PopulateFavoriteRadioStationList(); CopyToBuf(buf, FavoriteRadioStationList); assert(buf - buf_start == *size); @@ -757,3 +761,11 @@ void CStats::LoadStats(uint8 *buf, uint32 size) assert(buf - buf_start == size); #undef CopyFromBuf } + +void +CStats::PopulateFavoriteRadioStationList() +{ + float* pListenTimeArray = DMAudio.GetListenTimeArray(); + for (int i = 0; i < NUM_RADIOS; i++) + FavoriteRadioStationList[i] = pListenTimeArray[i]; +}
\ No newline at end of file diff --git a/src/core/Stats.h b/src/core/Stats.h index ad6fe516..49f84657 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -145,4 +145,6 @@ public: static void LongestTimeInBloodRing(int32); static void AddPropertyAsOwned(int32); + static void PopulateFavoriteRadioStationList(); + static float GetFavoriteRadioStationList(int32); }; diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index b5fc00e4..f197ae2c 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -65,6 +65,7 @@ #include "Bike.h" #include "WindModifiers.h" #include "CutsceneShadow.h" +#include "Clock.h" #define CAN_SEE_ENTITY_ANGLE_THRESHOLD DEGTORAD(60.0f) @@ -287,7 +288,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_fleeFromPosX = 0; m_fleeFromPosY = 0; m_fleeTimer = 0; - pThreatEx = nil; + m_threatEx = nil; m_vecSeekPosEx = CVector(0.0f, 0.0f, 0.0f); m_distanceToCountSeekDoneEx = 0.0f; m_nWaitState = WAITSTATE_FALSE; @@ -424,8 +425,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) bHasAlreadyUsedAttractor = false; b155_2 = false; bCarPassenger = false; - b155_8 = false; - b155_10 = false; + bFleeWhenStanding = false; + bGotUpOfMyOwnAccord = false; bMiamiViceCop = false; bMoneyHasBeenGivenByScript = false; bHasBeenPhotographed = false; @@ -446,7 +447,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) bDoomAim = true; bCanBeShotInVehicle = true; bPushedAlongByCar = false; - b157_40 = false; + bRemoveMeWhenIGotIntoCar = false; bIgnoreThreatsBehindObjects = false; bNeverEverTargetThisPed = false; @@ -455,7 +456,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) b158_8 = false; bCollectBusFare = false; bBoughtIceCream = false; - b158_40 = false; + bDonePositionOutOfCollision = false; b158_80 = false; if (CGeneral::GetRandomNumber() & 3) @@ -464,9 +465,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) bHasACamera = true; if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) <= 0.95f) - b157_8 = false; + bCanGiveUpSunbathing = false; else - b157_8 = true; + bCanGiveUpSunbathing = true; m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this); DMAudio.SetEntityStatus(m_audioEntityId, 1); @@ -2099,6 +2100,8 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) m_fRotationDest = veh->GetForward().Heading(); } else if (veh->bIsBus) { m_fRotationDest = 0.5f * PI + veh->GetForward().Heading(); + } else if (m_vehEnterType == CAR_WINDSCREEN) { + m_fRotationDest = veh->GetForward().Heading() + PI; } else { m_fRotationDest = veh->GetForward().Heading(); } @@ -2319,7 +2322,6 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) if (seatPosMult > 0.2f || vehIsUpsideDown || veh->IsBike()) { SetPosition(neededPos); - SetHeading(m_fRotationCur); } else { CMatrix vehDoorMat(veh->GetMatrix()); @@ -4084,7 +4086,7 @@ CPed::ClearAll(void) m_fleeFromPosY = 0.0f; m_fleeFrom = nil; m_fleeTimer = 0; - pThreatEx = nil; + m_threatEx = nil; bUsesCollision = true; ClearPointGunAt(); bIsPointingGunAt = false; @@ -4183,6 +4185,7 @@ CPed::SetStoredState(void) } } +// --MIAMI: Done void CPed::SetDie(AnimationId animId, float delta, float speed) { @@ -4198,6 +4201,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed) if (DyingOrDead()) return; + CAnimBlendAssociation *dieAssoc = nil; if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP) delta *= 0.5f; @@ -4205,7 +4209,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed) ClearAll(); m_fHealth = 0.0f; if (m_nPedState == PED_DRIVING) { - if (!IsPlayer()) + if (!IsPlayer() && (!m_pMyVehicle || !m_pMyVehicle->IsBike())) FlagToDestroyWhenNextProcessed(); } else if (bInVehicle) { if (m_pVehicleAnim) @@ -4214,11 +4218,11 @@ CPed::SetDie(AnimationId animId, float delta, float speed) QuitEnteringCar(); } - m_nPedState = PED_DIE; + SetPedState(PED_DIE); if (animId == NUM_STD_ANIMS) { bIsPedDieAnimPlaying = false; } else { - CAnimBlendAssociation *dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta); + dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta); if (speed > 0.0f) dieAssoc->speed = speed; @@ -4232,10 +4236,17 @@ CPed::SetDie(AnimationId animId, float delta, float speed) Say(SOUND_PED_DEATH); if (m_nLastPedState == PED_ENTER_CAR || m_nLastPedState == PED_CARJACK) QuitEnteringCar(); + if (!bInVehicle) StopNonPartialAnims(); m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds(); + if (!CGame::nastyGame && animId == ANIM_FLOOR_HIT) { + if (dieAssoc) { + dieAssoc->SetCurrentTime(dieAssoc->hierarchy->totalLength - 0.01f); + dieAssoc->SetRun(); + } + } } // --MIAMI: Done except commented things @@ -4789,6 +4800,7 @@ CPed::ClearFall(void) SetGetUp(); } +// --MIAMI: Done void CPed::SetGetUp(void) { @@ -4811,7 +4823,7 @@ CPed::SetGetUp(void) CVehicle *collidingVeh = (CVehicle*)m_pCollidingEntity; CVehicle *veh = (CVehicle*)CPedPlacement::IsPositionClearOfCars(&GetPosition()); - if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE || + if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE && veh != m_attachedTo || collidingVeh && collidingVeh->IsVehicle() && collidingVeh->m_vehType != VEHICLE_TYPE_BIKE && ((uint8)(CTimer::GetFrameCounter() + m_randomSeed + 5) % 8 || CCollision::ProcessColModels(GetMatrix(), *GetColModel(), collidingVeh->GetMatrix(), *collidingVeh->GetColModel(), @@ -4831,6 +4843,7 @@ CPed::SetGetUp(void) bGetUpAnimStarted = true; m_pCollidingEntity = nil; bKnockedUpIntoAir = false; + bKnockedOffBike = false; CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SPRINT); if (animAssoc) { if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN)) { @@ -4841,12 +4854,21 @@ CPed::SetGetUp(void) animAssoc->flags |= ASSOC_DELETEFADEDOUT; } - if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL)) + if (m_nWaitState == WAITSTATE_SUN_BATHE_IDLE) { + m_headingRate = 0.0f; + + // TODO(Miami): Looks like that should've been another getup anim but R* forgot it. Visit here later + if (bFleeWhenStanding && m_threatEx) + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f); + else + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f); + + } else if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL)) animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP_FRONT, 1000.0f); else animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f); - animAssoc->SetFinishCallback(PedGetupCB,this); + animAssoc->SetFinishCallback(PedGetupCB, this); } else { m_fHealth = 0.0f; SetDie(NUM_STD_ANIMS, 4.0f, 0.0f); @@ -6480,7 +6502,7 @@ CPed::SetFlee(CVector2D const &from, int time) } } -// --MIAMI: Only some part is done +// --MIAMI: Done void CPed::SetWaitState(eWaitState state, void *time) { @@ -6632,7 +6654,7 @@ CPed::SetWaitState(eWaitState state, void *time) case WAITSTATE_SIT_DOWN: animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_DOWN, 4.0f); animAssoc->SetFinishCallback(FinishedWaitCB, this); - m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 10000; + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000; break; case WAITSTATE_SIT_UP: animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_UP, 4.0f); @@ -6640,7 +6662,7 @@ CPed::SetWaitState(eWaitState state, void *time) m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000; break; case WAITSTATE_SIT_IDLE: - animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_IDLE, 5000.0f); + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_IDLE, 128.f); animAssoc->SetFinishCallback(FinishedWaitCB, this); if (time) m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; @@ -6648,13 +6670,19 @@ CPed::SetWaitState(eWaitState state, void *time) m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(25000, 30000); break; case WAITSTATE_USE_ATM: - animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ATM, 5000.0f); + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ATM, 4.0f); animAssoc->SetFinishCallback(FinishedWaitCB, this); if (time) m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; else m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000; break; + case WAITSTATE_SUN_BATHE_IDLE: + m_headingRate = 0.0f; + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_SUNBATHE, ANIM_SUNBATHE, 4.0f); + animAssoc->SetDeleteCallback(DeleteSunbatheIdleAnimCB, this); + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(50000, 100000); + break; case WAITSTATE_FAST_FALL: SetFall(-1, ANIM_KO_SKID_FRONT, true); break; @@ -6662,14 +6690,31 @@ CPed::SetWaitState(eWaitState state, void *time) CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_BOMBER, 4.0f); m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; break; + case WAITSTATE_GROUND_ATTACK: + { + CWeaponInfo* currentWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); + if (!currentWeapon) + break; + if (GetFireAnimGround(currentWeapon, false)) { + if (!RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(currentWeapon, false))) { + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000; + CAnimBlendAssociation* newAnim = CAnimManager::BlendAnimation(GetClump(), + currentWeapon->m_AnimToPlay, GetFireAnimGround(currentWeapon, false), 8.0f); + newAnim->SetDeleteCallback(FinishedWaitCB, this); + } + } + break; + } case WAITSTATE_LANCESITTING: CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_LANCE, ANIM_SUNBATHE, 4.0f); break; - case WAITSTATE_SUN_BATHE_PRE: - case WAITSTATE_SUN_BATHE_DOWN: - case WAITSTATE_SUN_BATHE_IDLE: - case WAITSTATE_GROUND_ATTACK: case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE: + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HANDSUP, 4.0f); + animAssoc->flags &= ~ASSOC_FADEOUTWHENDONE; + animAssoc->flags |= ASSOC_DELETEFADEDOUT; + animAssoc->SetDeleteCallback(FinishedWaitCB, this); + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; + break; default: ClearWaitState(); RestoreHeadingRate(); @@ -8376,7 +8421,7 @@ CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg) ped->Wait(); } -// --MIAMI: Some part is done +// --MIAMI: Done void CPed::Wait(void) { @@ -8577,28 +8622,24 @@ CPed::Wait(void) } else if (m_pedStats->m_fear <= 100 - pedWeLook->m_pedStats->m_temper) { if (GetWeapon()->IsTypeMelee()) { -#ifdef VC_PED_PORTS if(m_pedStats->m_flags & STAT_GUN_PANIC) { -#endif - SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, m_pLookTarget); - if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_FLEE_POS) { + SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, m_pLookTarget); + if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_FLEE_POS) { - bUsePedNodeSeek = true; - m_pNextPathNode = nil; - } - if (m_nMoveState != PEDMOVE_RUN) - SetMoveState(PEDMOVE_WALK); + bUsePedNodeSeek = true; + m_pNextPathNode = nil; + } + if (m_nMoveState != PEDMOVE_RUN) + SetMoveState(PEDMOVE_WALK); - if (m_nPedType != PEDTYPE_COP) { - ProcessObjective(); - SetMoveState(PEDMOVE_WALK); - } -#ifdef VC_PED_PORTS + if (m_nPedType != PEDTYPE_COP) { + ProcessObjective(); + SetMoveState(PEDMOVE_WALK); + } } else { SetObjective(OBJECTIVE_NONE); SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f)); } -#endif } else { SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_pLookTarget); SetObjectiveTimer(20000); @@ -8648,9 +8689,7 @@ CPed::Wait(void) bBoughtIceCream = true; } ClearWaitState(); - } -#ifdef VC_PED_PORTS - else if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI) { + } else if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI) { if (m_pedInObjective) { if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT) { @@ -8662,7 +8701,6 @@ CPed::Wait(void) } } } -#endif break; case WAITSTATE_FINISH_FLEE: @@ -8691,7 +8729,14 @@ CPed::Wait(void) if (m_attractor) GetPedAttractorManager()->BroadcastDeparture(this, m_attractor); ClearWaitState(); - //TODO(MIAMI): scan for threats! + if (bFleeWhenStanding) { + if (m_threatEx) { + SetFlee(m_threatEx, 10000); + bFleeWhenStanding = false; + m_threatEx = nil; + Say(SOUND_PED_FLEE_SPRINT); + } + } } break; case WAITSTATE_SIT_IDLE: @@ -8701,10 +8746,26 @@ CPed::Wait(void) m_fRotationDest = m_fRotationCur; bTurnedAroundOnAttractor = false; } - // TODO(MIAMI): scan for threats! if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { ClearWaitState(); SetWaitState(WAITSTATE_SIT_UP, 0); + } else { + if (m_fleeFrom && m_fleeFrom->IsVehicle()) { + m_pNextPathNode = nil; + m_threatEx = m_threatEntity; + bFleeWhenStanding = true; + ClearWaitState(); + SetWaitState(WAITSTATE_SIT_UP, 0); + } else { + uint32 threatFlag = ScanForThreats(); + if (threatFlag == PED_FLAG_GUN || threatFlag == PED_FLAG_EXPLOSION || threatFlag == PED_FLAG_DEADPEDS) { + m_pNextPathNode = nil; + m_threatEx = m_threatEntity; + bFleeWhenStanding = true; + ClearWaitState(); + SetWaitState(WAITSTATE_SIT_UP, 0); + } + } } break; case WAITSTATE_USE_ATM: @@ -8714,6 +8775,56 @@ CPed::Wait(void) ClearWaitState(); } break; + case WAITSTATE_SUN_BATHE_IDLE: + if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer && bCanGiveUpSunbathing) { + m_pNextPathNode = nil; + bGotUpOfMyOwnAccord = true; + SetGetUp(); + ClearWaitState(); + + } else if (CWeather::Rain <= 0.1f) { + if (CClock::GetHours() <= 18 || CGeneral::GetRandomNumberInRange(0.f, 1.0f) < 0.005f) { + uint32 threatFlag = ScanForThreats(); + if (threatFlag == PED_FLAG_GUN || threatFlag == PED_FLAG_EXPLOSION || threatFlag == PED_FLAG_DEADPEDS) { + // Get up in case of danger + m_pNextPathNode = nil; + m_threatEx = m_threatEntity; + bFleeWhenStanding = true; + SetGetUp(); + ClearWaitState(); + } + CPlayerPed *player = FindPlayerPed(); + if (player) { + // Get up if player coming towards us with a car + if (player->InVehicle()){ + CVector vehSpeedPerSec = player->m_pMyVehicle->m_vecMoveSpeed * GAME_SPEED_TO_METERS_PER_SECOND; + CVector vehPos = player->m_pMyVehicle->GetPosition(); + CVector ourPos = GetPosition(); + float timeUntilVehReachPed = DotProduct(ourPos - vehPos, vehSpeedPerSec) / vehSpeedPerSec.MagnitudeSqr(); + if (timeUntilVehReachPed > 0.0 && timeUntilVehReachPed < 8.0f) { + if ((ourPos - (timeUntilVehReachPed * vehSpeedPerSec + vehPos)).Magnitude() < 5.0f) { + m_pNextPathNode = nil; + m_threatEx = player; + bFleeWhenStanding = true; + SetGetUp(); + ClearWaitState(); + } + } + } + } + } else { + m_pNextPathNode = nil; + bGotUpOfMyOwnAccord = true; + SetGetUp(); + ClearWaitState(); + } + } else { + m_pNextPathNode = nil; + bGotUpOfMyOwnAccord = true; + SetGetUp(); + ClearWaitState(); + } + break; case WAITSTATE_RIOT: if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_ATTACK) { ClearWaitState(); @@ -8743,11 +8854,10 @@ CPed::Wait(void) case WAITSTATE_STRIPPER: PlayRandomAnimationsFromAnimBlock(this, ASSOCGRP_STRIP, ANIM_STRIP_A, ANIM_STRIP_G - ANIM_STRIP_A + 1); break; - case WAITSTATE_SUN_BATHE_PRE: - case WAITSTATE_SUN_BATHE_DOWN: - case WAITSTATE_SUN_BATHE_IDLE: case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE: - assert(0); + if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) + ClearWaitState(); + break; default: break; } @@ -9524,6 +9634,7 @@ CPed::SetLanding(void) bIsLanding = true; } +// --MIAMI: Done void CPed::Initialise(void) { @@ -9696,6 +9807,7 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void) CAnimManager::RemoveAnimBlockRef(bikedBlock); } +// --MIAMI: Done void CPed::InvestigateEvent(void) { @@ -9709,7 +9821,7 @@ CPed::InvestigateEvent(void) if (CTimer::GetTimeInMilliseconds() > m_standardTimer) { if (m_standardTimer) { - if (m_eventType < EVENT_ASSAULT_NASTYWEAPON) + if (m_eventType < EVENT_UNK) SetWaitState(WAITSTATE_TURN180, nil); m_standardTimer = 0; @@ -9763,13 +9875,14 @@ CPed::InvestigateEvent(void) animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE); if (animAssoc && animAssoc->animId == ANIM_IDLE_CAM) { - CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 14.0f); + CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f); SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500)); } else if (CGeneral::GetRandomNumber() & 3) { CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_CAM, 4.0f); SetLookTimer(CGeneral::GetRandomNumberInRange(2500, 5000)); - Say(SOUND_PED_CHAT_EVENT); + if (!CGame::germanGame) + Say(SOUND_PED_CHAT_EVENT); } else { m_standardTimer = 0; @@ -9790,7 +9903,7 @@ CPed::InvestigateEvent(void) animToPlay = ANIM_XPRESS_SCRATCH; CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f); - SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500)); + SetLookTimer(CGeneral::GetRandomNumberInRange(1500, 4000)); } else if (animAssoc && animAssoc->animId == ANIM_IDLE_HBHB) { animAssoc->blendDelta = -8.0f; @@ -9818,7 +9931,8 @@ CPed::InvestigateEvent(void) CAnimManager::BlendAnimation(GetClump(), animGroup, animToPlay, 4.0f); SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500)); } - Say(SOUND_PED_CHAT_EVENT); + if (!CGame::germanGame) + Say(SOUND_PED_CHAT_EVENT); } break; case EVENT_ICECREAM: @@ -9880,19 +9994,22 @@ CPed::InvestigateEvent(void) SetMoveState(PEDMOVE_WALK); return; } - if (distSqr > 1.44f) { + if (distSqr > sq(1.2f)) { SetMoveState(PEDMOVE_WALK); return; } + bool willStandStill = false; for (int i = 0; i < m_numNearPeds; i++) { if ((m_eventOrThreat - m_nearPeds[i]->GetPosition()).MagnitudeSqr() < sq(0.4f)) { SetMoveState(PEDMOVE_STILL); - return; + willStandStill = true; + break; } } - SetMoveState(PEDMOVE_WALK); + if (!willStandStill) + SetMoveState(PEDMOVE_WALK); } } @@ -10186,12 +10303,12 @@ CPed::Look(void) TurnBody(); } +// --MIAMI: Done bool CPed::LookForInterestingNodes(void) { CBaseModelInfo *model; CPtrNode *ptrNode; - CVector effectPos; CVector effectDist; C2dEffect *effect; CMatrix *objMat; @@ -10232,7 +10349,7 @@ CPed::LookForInterestingNodes(void) effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &veh->GetMatrix(); - effectPos = veh->GetMatrix() * effect->pos; + CVector effectPos = veh->GetMatrix() * effect->pos; effectDist = effectPos - GetPosition(); if (effectDist.MagnitudeSqr() < sq(8.0f)) { found = true; @@ -10250,7 +10367,7 @@ CPed::LookForInterestingNodes(void) effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &obj->GetMatrix(); - effectPos = obj->GetMatrix() * effect->pos; + CVector effectPos = obj->GetMatrix() * effect->pos; effectDist = effectPos - GetPosition(); if (effectDist.MagnitudeSqr() < sq(8.0f)) { found = true; @@ -10268,7 +10385,7 @@ CPed::LookForInterestingNodes(void) effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &building->GetMatrix(); - effectPos = building->GetMatrix() * effect->pos; + CVector effectPos = building->GetMatrix() * effect->pos; effectDist = effectPos - GetPosition(); if (effectDist.MagnitudeSqr() < sq(8.0f)) { found = true; @@ -10286,7 +10403,7 @@ CPed::LookForInterestingNodes(void) effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &building->GetMatrix(); - effectPos = building->GetMatrix() * effect->pos; + CVector effectPos = building->GetMatrix() * effect->pos; effectDist = effectPos - GetPosition(); if (effectDist.MagnitudeSqr() < sq(8.0f)) { found = true; @@ -10312,12 +10429,13 @@ CPed::LookForInterestingNodes(void) return false; } + CVector2D effectPos = *objMat * effect->pos; switch (effect->attractor.type) { case ATTRACTORTYPE_ICECREAM: - SetInvestigateEvent(EVENT_ICECREAM, CVector2D(effectPos), 0.1f, 15000, angleToFace); + SetInvestigateEvent(EVENT_ICECREAM, effectPos, 0.1f, 15000, angleToFace); break; case ATTRACTORTYPE_STARE: - SetInvestigateEvent(EVENT_SHOPSTALL, CVector2D(effectPos), 1.0f, + SetInvestigateEvent(EVENT_SHOPSTALL, effectPos, 1.0f, CGeneral::GetRandomNumberInRange(8000, 10 * effect->attractor.probability + 8500), angleToFace); break; @@ -10327,6 +10445,7 @@ CPed::LookForInterestingNodes(void) return true; } +// --MIAMI: Done void CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCountDone, uint16 time, float angle) { @@ -10335,7 +10454,7 @@ CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCount SetStoredState(); bFindNewNodeAfterStateRestore = false; - m_nPedState = PED_INVESTIGATE; + SetPedState(PED_INVESTIGATE); m_standardTimer = CTimer::GetTimeInMilliseconds() + time; m_eventType = event; m_eventOrThreat = pos; @@ -10863,7 +10982,7 @@ CPed::ProcessControl(void) CVisibilityPlugins::SetClumpAlpha(GetClump(), alpha); bIsShooting = false; - b158_40 = false; + bDonePositionOutOfCollision = false; BuildPedLists(); bIsInWater = false; bIsDrowning = false; @@ -13019,8 +13138,8 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) } } - if (ped->b157_40) { - ped->b157_40 = false; + if (ped->bRemoveMeWhenIGotIntoCar) { + ped->bRemoveMeWhenIGotIntoCar = false; ped->bRemoveFromWorld = true; } if (ped->bCollectBusFare) { @@ -13437,6 +13556,7 @@ CPed::ReactToPointGun(CEntity *entWithGun) } } +// --MIAMI: Done void CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -13460,8 +13580,17 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) } ped->bInVehicle = false; - if (veh && (veh->IsCar() || veh->IsBike()) && !veh->IsRoomForPedToLeaveCar(ped->m_vehEnterType, nil)) { - ped->PositionPedOutOfCollision(); + if (veh && (veh->IsCar() || veh->IsBike())) { + CWorld::pIgnoreEntity = veh; + if (CWorld::TestSphereAgainstWorld(ped->GetPosition() - CVector(0.f, 0.f, 0.2f), + 0.4f, veh, true, true, false, false, false, false) + || CWorld::TestSphereAgainstWorld(ped->GetPosition() + CVector(0.f, 0.f, 0.2f), + 0.4f, veh, true, true, false, false, false, false) + || !CWorld::GetIsLineOfSightClear(veh->GetPosition(), ped->GetPosition(), true, false, false, true, false, false, false)) { + CWorld::pIgnoreEntity = nil; + ped->PositionPedOutOfCollision(); + } + CWorld::pIgnoreEntity = nil; } if (ped->m_nPedState == PED_EXIT_CAR) { @@ -13545,6 +13674,7 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) } } } + // NB: Probably VC doesn't use a function for that, so it's GetBikeDoorFlag doesn't check for CAR_WINDSCREEN if (veh && veh->IsBike()) veh->m_nGettingOutFlags &= ~GetBikeDoorFlag(ped->m_vehEnterType); else @@ -13557,6 +13687,11 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) veh->m_nDoorLock = CARLOCK_UNLOCKED; if (ped->m_nPedType == PEDTYPE_COP && veh->IsLawEnforcementVehicle()) veh->ChangeLawEnforcerState(false); + if (veh->IsBike()) { + if (Abs(veh->m_vecMoveSpeed.x) < 0.1 && Abs(veh->m_vecMoveSpeed.y) < 0.1f) { + ((CBike*)veh)->bIsStanding = true; + } + } } else { veh->RemovePassenger(ped); } @@ -13820,6 +13955,146 @@ CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void bool CPed::PositionPedOutOfCollision(void) { + CVehicle *veh = m_pMyVehicle; + if (!veh) + return false; + + if (bDonePositionOutOfCollision) + return true; + + bool foundAPos = false; + CColModel *vehCol = veh->GetColModel(); + CVector vehPos = veh->GetPosition(); + CVector ourPos = GetPosition(); + CVector newPos = ourPos; + CWorld::pIgnoreEntity = veh; + bUsesCollision = false; + bJustCheckCollision = true; + m_vecMoveSpeed = CVector(0.f, 0.f, 0.f); + if (veh->IsOnItsSide()) { + // Top of the veh. + newPos = vehPos; + newPos.z = FEET_OFFSET + vehCol->boundingBox.max.x + vehPos.z; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + + } else if (m_vehEnterType != 0) { + // Try the normal way + CVector pos = GetPositionToOpenCarDoor(m_pMyVehicle, m_vehEnterType); + newPos = pos; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + + float vehRelativeExitX = vehCol->boundingBox.min.x - 0.355f; + if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) + vehRelativeExitX = 0.355f + vehCol->boundingBox.max.x; + + if (!foundAPos) { + // Check sides of veh., respective to seat column-veh. center difference(why?) + float exitOffset = vehRelativeExitX - DotProduct(ourPos - vehPos, veh->GetRight()); + newPos = exitOffset * veh->GetRight() + ourPos; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + if (!foundAPos) { + // Iterate through sections of veh. length + static offset on X + float minY = vehCol->boundingBox.min.y; + float ySection = (vehCol->boundingBox.max.y - minY) / 3.f; + for (int i = 0; i < 4; i++) { + float fwdMult = i * ySection + minY; + newPos = vehRelativeExitX * veh->GetRight() + fwdMult * veh->GetForward() + vehPos; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) { + foundAPos = true; + break; + } + } + } + } + if (!foundAPos) { + // Back of veh. + newPos = (vehCol->boundingBox.min.y - 0.355f) * veh->GetForward() + vehPos; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + if (!foundAPos) { + // Front of veh. + newPos = (0.355f + vehCol->boundingBox.max.y) * veh->GetForward() + vehPos; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + if (!foundAPos) { + // Opposite X side + back + newPos = vehCol->boundingBox.min.y * veh->GetForward() + vehPos - vehRelativeExitX * veh->GetRight(); + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + if (!foundAPos) { + // Opposite X side + front + newPos = vehCol->boundingBox.max.y * veh->GetForward() + vehPos - vehRelativeExitX * veh->GetRight(); + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + if (!foundAPos) { + // Top of veh. + if (veh->m_vehType == 0) { + newPos = vehCol->boundingBox.max.z * veh->GetUp() + vehPos; + newPos.z += FEET_OFFSET; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + } + m_vecMoveSpeed = CVector(0.f, 0.f, 0.f); + m_vecTurnSpeed = CVector(0.f, 0.f, 0.f); + veh->m_vecMoveSpeed = CVector(0.f, 0.f, 0.f); + veh->m_vecTurnSpeed = CVector(0.f, 0.f, 0.f); + CWorld::pIgnoreEntity = nil; + bUsesCollision = true; + bJustCheckCollision = false; + bDonePositionOutOfCollision = true; + if (foundAPos) + return true; + int foundNode = ThePaths.FindNodeClosestToCoors(vehPos, PATH_PED, 999999.9f, true, false, false, false); + if (foundNode < 0) + return false; + newPos = ThePaths.m_pathNodes[foundNode].GetPosition(); + CPedPlacement::FindZCoorForPed(&newPos); + GetMatrix().SetTranslate(newPos); + SetHeading(m_pMyVehicle->GetForward().Heading()); + return true; +} + +// --MIAMI: Done +// "Any" means he shouldn't have to be in vehicle. +bool +CPed::PositionAnyPedOutOfCollision(void) +{ CVehicle *veh; CVector posNearVeh; CVector posSomewhereClose; @@ -13828,9 +14103,6 @@ CPed::PositionPedOutOfCollision(void) int smallestDistNearVeh = 999; int smallestDistSomewhereClose = 999; - if (!m_pMyVehicle) - return false; - CVector vehPos = m_pMyVehicle->GetPosition(); CVector potentialPos; potentialPos.y = GetPosition().y - 3.5f; @@ -13841,15 +14113,7 @@ CPed::PositionPedOutOfCollision(void) for (int xTry = 0; xTry < 15; xTry++) { CPedPlacement::FindZCoorForPed(&potentialPos); - CVector distVec = potentialPos - vehPos; - float dist = distVec.Magnitude(); - - // Makes close distances bigger for some reason. - float mult = (0.6f + dist) / dist; - CVector adjustedPotentialPos = distVec * mult + vehPos; - if (CWorld::GetIsLineOfSightClear(vehPos, adjustedPotentialPos, true, false, false, true, false, false, false) - && !CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, true, false, false, true, false, false)) { - + if (!CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, true, false, false, true, false, false)) { float potentialChangeSqr = (potentialPos - GetPosition()).MagnitudeSqr(); veh = (CVehicle*)CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, false, true, false, false, false, false); if (veh) { @@ -13883,6 +14147,7 @@ CPed::PositionPedOutOfCollision(void) return true; } +// --MIAMI: Done bool CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh) { @@ -14062,6 +14327,7 @@ CPed::Render(void) } } +// --MIAMI: Done void CPed::ProcessObjective(void) { @@ -14099,15 +14365,6 @@ CPed::ProcessObjective(void) } switch (m_objective) { - case OBJECTIVE_NONE: - case OBJECTIVE_GUARD_AREA: - case OBJECTIVE_FOLLOW_CAR_IN_CAR: - case OBJECTIVE_FIRE_AT_OBJECT_FROM_VEHICLE: - case OBJECTIVE_DESTROY_OBJECT: - case OBJECTIVE_GOTO_AREA_IN_CAR: - case OBJECTIVE_FOLLOW_CAR_ON_FOOT_WITH_OFFSET: - case OBJECTIVE_SET_LEADER: - break; case OBJECTIVE_WAIT_ON_FOOT: if (GetPedState() == PED_DRIVING) m_objective = OBJECTIVE_NONE; @@ -14192,7 +14449,7 @@ CPed::ProcessObjective(void) { if (m_pedInObjective) { if (m_pedInObjective->IsPlayer() && CharCreatedBy != MISSION_CHAR - && m_nPedType != PEDTYPE_COP && FindPlayerPed()->m_pWanted->m_CurrentCops + && m_nPedType != PEDTYPE_COP && FindPlayerPed()->m_pWanted->m_CurrentCops != 0 && !bKindaStayInSamePlace) { SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE); @@ -14232,7 +14489,7 @@ CPed::ProcessObjective(void) float closestVehDist = 60.0f; int16 lastVehicle; CEntity* vehicles[8]; - CWorld::FindObjectsInRange(GetPosition(), 30.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false); + CWorld::FindObjectsInRange(GetPosition(), ENTER_CAR_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false); CVehicle *foundVeh = nil; for(int i = 0; i < lastVehicle; i++) { CVehicle *nearVeh = (CVehicle*)vehicles[i]; @@ -14305,7 +14562,6 @@ CPed::ProcessObjective(void) SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle); break; } - if (!m_pedInObjective || m_pedInObjective->DyingOrDead()) { bObjectiveCompleted = true; ClearLookFlag(); @@ -14555,7 +14811,7 @@ CPed::ProcessObjective(void) if (m_carInObjective && m_carInObjective->m_fHealth > 0.0f) { distWithTarget = m_carInObjective->GetPosition() - GetPosition(); if (!bInVehicle) { - if (nEnterCarRangeMultiplier * 30.0f < distWithTarget.Magnitude()) { + if (nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST < distWithTarget.Magnitude()) { if (!m_carInObjective->pDriver && !m_carInObjective->GetIsOnScreen() && !GetIsOnScreen()) WarpPedToNearEntityOffScreen(m_carInObjective); @@ -14581,6 +14837,15 @@ CPed::ProcessObjective(void) } break; } + case OBJECTIVE_DESTROY_OBJECT: + if (m_pPointGunAt) { + if (m_nPedState != PED_ATTACK) + SetAttack(m_pPointGunAt); + } else { + bScriptObjectiveCompleted = true; + RestorePreviousObjective(); + } + break; case OBJECTIVE_DESTROY_CAR: { if (!m_carInObjective) { @@ -14604,9 +14869,7 @@ CPed::ProcessObjective(void) break; } - if (m_attackTimer < CTimer::GetTimeInMilliseconds() && wepInfo->m_eWeaponFire != WEAPON_FIRE_MELEE - && distWithTargetSc < wepRange) { - + if (m_attackTimer < CTimer::GetTimeInMilliseconds() && distWithTargetSc < wepRange) { // I hope so CVector ourHead = GetMatrix() * CVector(0.5f, 0.0f, 0.6f); CVector maxShotPos = m_carInObjective->GetPosition() - ourHead; @@ -14621,6 +14884,8 @@ CPed::ProcessObjective(void) CWorld::bIncludeDeadPeds = false; if (foundEnt == m_carInObjective) { SetAttack(m_carInObjective); + if (m_pPointGunAt) + m_pPointGunAt->CleanUpOldReference((CEntity**)&m_pPointGunAt); m_pPointGunAt = m_carInObjective; if (m_pPointGunAt) m_pPointGunAt->RegisterReference((CEntity **) &m_pPointGunAt); @@ -14634,75 +14899,30 @@ CPed::ProcessObjective(void) } } } else if (m_nPedState != PED_ATTACK && !bKindaStayInSamePlace) { + if (wepRange <= 5.0f) { + if (Abs(distWithTarget.x) > wepRange || Abs(distWithTarget.y) > wepRange || + (distWithTarget.z > -1.0f && distWithTarget.z < 0.3)) { + SetSeek(m_carInObjective, 3.0f); + SetMoveState(PEDMOVE_RUN); + } else { + SetIdle(); + } + } else { + float safeDistance = wepRange * 0.25f; - float safeDistance; - if (wepRange <= 5.0f) - safeDistance = 3.0f; - else - safeDistance = wepRange * 0.25f; - - SetSeek(m_carInObjective, safeDistance); - SetMoveState(PEDMOVE_RUN); + SetSeek(m_carInObjective, safeDistance); + SetMoveState(PEDMOVE_RUN); + } } SetLookFlag(m_carInObjective, false); TurnBody(); break; } - case OBJECTIVE_GOTO_AREA_ANY_MEANS: - { - distWithTarget = m_nextRoutePointPos - GetPosition(); - distWithTarget.z = 0.0f; - if (InVehicle()) { - CCarAI::GetCarToGoToCoors(m_pMyVehicle, &m_nextRoutePointPos); - CCarCtrl::RegisterVehicleOfInterest(m_pMyVehicle); - if (distWithTarget.MagnitudeSqr() < sq(20.0f)) { - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; - ForceStoredObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS); - SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle); - } - break; - } - if (distWithTarget.Magnitude() > 30.0f) { - if (m_pMyVehicle) { - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; - } else { - float closestVehDist = SQR(60.0f); - int16 lastVehicle; - CEntity* vehicles[8]; - CWorld::FindObjectsInRange(GetPosition(), 25.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false); - CVehicle* foundVeh = nil; - for (int i = 0; i < lastVehicle; i++) { - CVehicle* nearVeh = (CVehicle*)vehicles[i]; - /* - Not used. - CVector vehSpeed = nearVeh->GetSpeed(); - CVector ourSpeed = GetSpeed(); - */ - CVector vehDistVec = nearVeh->GetPosition() - GetPosition(); - if (vehDistVec.MagnitudeSqr() < closestVehDist - && m_pedInObjective->m_pMyVehicle != nearVeh) - { - foundVeh = nearVeh; - closestVehDist = vehDistVec.MagnitudeSqr(); - } - } - m_pMyVehicle = foundVeh; - if (m_pMyVehicle) { - m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle); - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; - SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle); - } - } - break; - } - // fall through - } case OBJECTIVE_GOTO_AREA_ON_FOOT: case OBJECTIVE_RUN_TO_AREA: case OBJECTIVE_SPRINT_TO_AREA: { - if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || m_objective == OBJECTIVE_SPRINT_TO_AREA) - && InVehicle()) { + if (InVehicle()) { SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle); } else { distWithTarget = m_nextRoutePointPos - GetPosition(); @@ -14719,7 +14939,6 @@ CPed::ProcessObjective(void) if (!m_pNextPathNode) { bool found = FindBestCoordsFromNodes(m_vecSeekPos, &bestCoords); if (m_pNextPathNode) { - // Because it already does that if it finds better coords. if (!found) { bestCoords = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed); @@ -14733,6 +14952,7 @@ CPed::ProcessObjective(void) if (m_pNextPathNode) m_vecSeekPos = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed); } + CVector seekPos = m_vecSeekPos; SetSeek(m_vecSeekPos, m_distanceToCountSeekDone); } } @@ -14769,7 +14989,8 @@ CPed::ProcessObjective(void) int nextPoint = GetNextPointOnRoute(); m_nextRoutePointPos = CRouteNode::GetPointPosition(nextPoint); } else { - SetSeek(m_nextRoutePointPos, 0.8f); + CVector seekPos = m_nextRoutePointPos; + SetSeek(seekPos, 0.8f); } break; case OBJECTIVE_SOLICIT_VEHICLE: @@ -14833,31 +15054,27 @@ CPed::ProcessObjective(void) } case OBJECTIVE_BUY_ICE_CREAM: if (m_carInObjective) { - if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_BUY_ICECREAM) + if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_BUY_ICECREAM && m_nPedState != PED_CHAT) SetSeekCar(m_carInObjective, 0); - } else { - RestorePreviousObjective(); - RestorePreviousState(); - if (IsPedInControl()) - m_pMyVehicle = nil; } break; case OBJECTIVE_STEAL_ANY_CAR: + case OBJECTIVE_STEAL_ANY_MISSION_CAR: { if (bInVehicle) { bScriptObjectiveCompleted = true; RestorePreviousObjective(); } else if (m_hitRecoverTimer < CTimer::GetTimeInMilliseconds()) { CVehicle *carToSteal = nil; - float closestCarDist = 30.0f; + float closestCarDist = nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST; CVector pos = GetPosition(); int16 lastVehicle; CEntity *vehicles[8]; - CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false); + CWorld::FindObjectsInRange(pos, closestCarDist, true, &lastVehicle, 6, vehicles, false, true, false, false, false); for(int i = 0; i < lastVehicle; i++) { CVehicle *nearVeh = (CVehicle*)vehicles[i]; - if (nearVeh->VehicleCreatedBy != MISSION_VEHICLE) { + if (m_objective == OBJECTIVE_STEAL_ANY_MISSION_CAR || nearVeh->VehicleCreatedBy != MISSION_VEHICLE) { if (nearVeh->m_vecMoveSpeed.Magnitude() <= 0.1f) { if (nearVeh->CanPedOpenLocks(this)) { CVector vehDistVec = GetPosition() - nearVeh->GetPosition(); @@ -14970,60 +15187,6 @@ CPed::ProcessObjective(void) CPed::SetWanderPath(m_nPathDir); } break; - case OBJECTIVE_FLEE_CAR: - if (!bInVehicle && m_nPedState != PED_FLEE_ENTITY && m_pMyVehicle) { - RestorePreviousObjective(); - SetFlee(m_pMyVehicle, 6000); - break; - } - // fall through - case OBJECTIVE_LEAVE_CAR: - if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) { - if (InVehicle() && - (FindPlayerPed() != this || !CPad::GetPad(0)->GetAccelerate() || bBusJacked)) { - - if (m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR && m_nPedState != PED_EXIT_TRAIN - && (m_nPedType != PEDTYPE_COP - || m_pMyVehicle->IsBoat() - || m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.005f))) { -#ifdef GTA_TRAIN - if (m_pMyVehicle->IsTrain()) - SetExitTrain(m_pMyVehicle); - else -#endif - if (m_pMyVehicle->IsBoat()) - SetExitBoat(m_pMyVehicle); - else - SetExitCar(m_pMyVehicle, 0); - } - } else { - RestorePreviousObjective(); - } - } - if (bHeldHostageInCar) { - if (CTheScripts::IsPlayerOnAMission()) { - CVehicle *playerVeh = FindPlayerVehicle(); - if (playerVeh && playerVeh->IsPassenger(this)) { - if (m_leaveCarTimer != 0) - m_leaveCarTimer = 0; - } - } - } - break; - case OBJECTIVE_AIM_GUN_AT: - if (m_pedInObjective) { - if (!bObstacleShowedUpDuringKillObjective) - SetPointGunAt(m_pedInObjective); - - if (m_nMoveState == PEDMOVE_STILL && IsPedInControl()) { - SetLookFlag(m_pedInObjective, false); - TurnBody(); - } - } else { - ClearObjective(); - } - break; -#ifdef VC_PED_PORTS case OBJECTIVE_LEAVE_CAR_AND_DIE: { if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) { @@ -15051,6 +15214,59 @@ CPed::ProcessObjective(void) } break; } + case OBJECTIVE_GOTO_AREA_ANY_MEANS: + { + distWithTarget = m_nextRoutePointPos - GetPosition(); + distWithTarget.z = 0.0f; + if (InVehicle()) { + CCarAI::GetCarToGoToCoors(m_pMyVehicle, &m_nextRoutePointPos); + CCarCtrl::RegisterVehicleOfInterest(m_pMyVehicle); + if (distWithTarget.MagnitudeSqr() < sq(20.0f)) { + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; + ForceStoredObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS); + SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle); + } + break; + } + if (distWithTarget.Magnitude() > 30.0f) { + if (m_pMyVehicle) { + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; + } else { + float closestVehDist = SQR(60.0f); + int16 lastVehicle; + CEntity* vehicles[8]; + // NB: 25.0f in here is prolly a forgotten setting, all other places now use 30.0f (ENTER_CAR_MAX_DIST) + CWorld::FindObjectsInRange(GetPosition(), 25.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false); + CVehicle* foundVeh = nil; + for (int i = 0; i < lastVehicle; i++) { + CVehicle* nearVeh = (CVehicle*)vehicles[i]; + /* + Not used. + CVector vehSpeed = nearVeh->GetSpeed(); + CVector ourSpeed = GetSpeed(); + */ + CVector vehDistVec = nearVeh->GetPosition() - GetPosition(); + if (vehDistVec.MagnitudeSqr() < closestVehDist && m_pedInObjective->m_pMyVehicle != nearVeh) { + foundVeh = nearVeh; + closestVehDist = vehDistVec.MagnitudeSqr(); + } + } + m_pMyVehicle = foundVeh; + if (m_pMyVehicle) { + m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle); + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; + SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle); + } + } + break; + } + // Falls to different objectives in III and VC +#ifdef FIX_BUGS + break; +#else + // fall through +#endif + } case OBJECTIVE_GOTO_SEAT_ON_FOOT: case OBJECTIVE_GOTO_ATM_ON_FOOT: case OBJECTIVE_GOTO_BUS_STOP_ON_FOOT: @@ -15061,8 +15277,7 @@ CPed::ProcessObjective(void) m_objectiveTimer = 0; if (m_attractor) GetPedAttractorManager()->DeRegisterPed(this, m_attractor); - } - else { + } else { CVector distance = m_nextRoutePointPos - GetPosition(); distance.z = 0.0f; if (m_objective == OBJECTIVE_GOTO_SHELTER_ON_FOOT) { @@ -15178,6 +15393,59 @@ CPed::ProcessObjective(void) } } return; + case OBJECTIVE_FLEE_CAR: + if (!bInVehicle && m_nPedState != PED_FLEE_ENTITY && m_pMyVehicle) { + RestorePreviousObjective(); + SetFlee(m_pMyVehicle, 6000); + break; + } + // fall through + case OBJECTIVE_LEAVE_CAR: + if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) { + if (InVehicle() && + (FindPlayerPed() != this || !CPad::GetPad(0)->GetAccelerate() || bBusJacked)) { + + if (m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR && m_nPedState != PED_EXIT_TRAIN + && (m_nPedType != PEDTYPE_COP + || m_pMyVehicle->IsBoat() + || m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.005f))) { +#ifdef GTA_TRAIN + if (m_pMyVehicle->IsTrain()) + SetExitTrain(m_pMyVehicle); + else +#endif + if (m_pMyVehicle->IsBoat()) + SetExitBoat(m_pMyVehicle); + else + SetExitCar(m_pMyVehicle, 0); + } + } else { + RestorePreviousObjective(); + } + } + if (bHeldHostageInCar) { + if (CTheScripts::IsPlayerOnAMission()) { + CVehicle *playerVeh = FindPlayerVehicle(); + if (playerVeh && playerVeh->IsPassenger(this)) { + if (m_leaveCarTimer != 0) + m_leaveCarTimer = 0; + } + } + } + break; + case OBJECTIVE_AIM_GUN_AT: + if (m_pedInObjective) { + if (!bObstacleShowedUpDuringKillObjective) + SetPointGunAt(m_pedInObjective); + + if (m_nMoveState == PEDMOVE_STILL && IsPedInControl()) { + SetLookFlag(m_pedInObjective, false); + TurnBody(); + } + } else { + ClearObjective(); + } + break; case OBJECTIVE_WAIT_ON_FOOT_AT_SHELTER: SetIdle(); if (m_attractor && CWeather::Rain < 0.2f) @@ -15209,8 +15477,8 @@ CPed::ProcessObjective(void) } else if (m_pedInObjective) { SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, m_pedInObjective); } - } else { SetMoveAnim(); + } else { ClearLookFlag(); SetMoveAnim(); if (m_pCurrentPhysSurface && m_pCurrentPhysSurface->IsVehicle()) @@ -15270,7 +15538,7 @@ CPed::ProcessObjective(void) GetPedAttractorManager()->DeRegisterPed(this, m_attractor); SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, pBus); bDontDragMeOutCar = true; - b157_40 = true; + bRemoveMeWhenIGotIntoCar = true; CPlayerPed *player = FindPlayerPed(); if (pBus->IsPassenger(player) || pBus->IsDriver(player)) { bCollectBusFare = true; @@ -15311,7 +15579,6 @@ CPed::ProcessObjective(void) } break; } -#endif } if (bObjectiveCompleted || m_objectiveTimer > 0 && CTimer::GetTimeInMilliseconds() > m_objectiveTimer) { @@ -15331,6 +15598,7 @@ CPed::ProcessObjective(void) } } +// --MIAMI: Done void CPed::SetShootTimer(uint32 time) { @@ -16585,15 +16853,14 @@ CPed::PreRender(void) } } +// --MIAMI: Done void CPed::ProcessBuoyancy(void) { + float buoyancyLevel = 1.1f; static uint32 nGenerateRaindrops = 0; static uint32 nGenerateWaterCircles = 0; - CRGBA color(((0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed()) * 127.5f), - ((0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue()) * 127.5f), - ((0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen()) * 127.5f), - (CGeneral::GetRandomNumber() % 256 * 48.0f) + 48); + CRGBA color; if (bInVehicle) return; @@ -16601,26 +16868,27 @@ CPed::ProcessBuoyancy(void) CVector buoyancyPoint; CVector buoyancyImpulse; -#ifndef VC_PED_PORTS - float buoyancyLevel = (m_nPedState == PED_DEAD ? 1.5f : 1.3f); -#else - float buoyancyLevel = (m_nPedState == PED_DEAD ? 1.8f : 1.1f); -#endif + if (DyingOrDead()) + buoyancyLevel = 1.8f; if (mod_Buoyancy.ProcessBuoyancy(this, GRAVITY * m_fMass * buoyancyLevel, &buoyancyPoint, &buoyancyImpulse)) { bTouchingWater = true; CEntity *entity; CColPoint point; if (CWorld::ProcessVerticalLine(GetPosition(), GetPosition().z - 3.0f, point, entity, false, true, false, false, false, false, nil) - && entity->IsVehicle() && ((CVehicle*)entity)->IsBoat()) { + && entity->IsVehicle() && ((CVehicle*)entity)->IsBoat() && !entity->bRenderScorched) { bIsInWater = false; return; } + color.r = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed()) * 127.5f; + color.g = (0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue()) * 127.5f; + color.b = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen()) * 127.5f; + color.a = (CGeneral::GetRandomNumber() % 256 * 48.0f) + 48; bIsInWater = true; ApplyMoveForce(buoyancyImpulse); if (!DyingOrDead()) { if (bTryingToReachDryLand) { - if (buoyancyImpulse.z / m_fMass > 0.0032f * CTimer::GetTimeStep()) { + if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.4f * CTimer::GetTimeStep()) { bTryingToReachDryLand = false; CVector pos = GetPosition(); if (PlacePedOnDryLand()) { @@ -16632,19 +16900,15 @@ CPed::ProcessBuoyancy(void) bIsInTheAir = false; } pos.z = pos.z - 0.8f; -#ifdef PC_PARTICLE CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, color, true); -#else - CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, CRGBA(0, 0, 0, 0), true); -#endif m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); return; } } } float speedMult = 0.0f; - if (buoyancyImpulse.z / m_fMass > 0.006f * CTimer::GetTimeStep() + if (buoyancyImpulse.z / m_fMass > GRAVITY * CTimer::GetTimeStep() || mod_Buoyancy.m_waterlevel > GetPosition().z) { speedMult = pow(0.9f, CTimer::GetTimeStep()); m_vecMoveSpeed.x *= speedMult; @@ -16654,7 +16918,7 @@ CPed::ProcessBuoyancy(void) bIsDrowning = true; InflictDamage(nil, WEAPONTYPE_DROWNING, 3.0f * CTimer::GetTimeStep(), PEDPIECE_TORSO, 0); } - if (buoyancyImpulse.z / m_fMass > 0.002f * CTimer::GetTimeStep()) { + if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.25f * CTimer::GetTimeStep()) { if (speedMult == 0.0f) { speedMult = pow(0.9f, CTimer::GetTimeStep()); } @@ -16666,7 +16930,6 @@ CPed::ProcessBuoyancy(void) } else { m_vecMoveSpeed.z = -0.01f; DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f); -#ifdef PC_PARTICLE CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition(); float level = 0.0f; if (CWaterLevel::GetWaterLevel(aBitForward, &level, false)) @@ -16675,18 +16938,6 @@ CPed::ProcessBuoyancy(void) CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, CVector(0.0f, 0.0f, 0.1f), 0.0f, 200, color, true); nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 80; nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 100; -#else - CVector aBitForward = 1.6f * m_vecMoveSpeed + GetPosition(); - float level = 0.0f; - if (CWaterLevel::GetWaterLevel(aBitForward, &level, false)) - aBitForward.z = level + 0.5f; - - CVector vel = m_vecMoveSpeed * 0.1f; - vel.z = 0.18f; - CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, vel, 0.0f, 350, CRGBA(0, 0, 0, 0), true); - nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 300; - nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 60; -#endif } } } else @@ -16703,15 +16954,9 @@ CPed::ProcessBuoyancy(void) if (pos.z != 0.0f) { nGenerateWaterCircles = 0; for(int i = 0; i < 4; i++) { -#ifdef PC_PARTICLE pos.x += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f); pos.y += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f); CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, 0, 0, 0, 0); -#else - pos.x += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f); - pos.y += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f); - CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos+CVector(0.0f, 0.0f, 1.0f), CVector(0.0f, 0.0f, 0.0f)); -#endif } } } @@ -16723,17 +16968,9 @@ CPed::ProcessBuoyancy(void) pos.z = level; if (pos.z >= 0.0f) { -#ifdef PC_PARTICLE pos.z += 0.25f; -#else - pos.z += 0.5f; -#endif nGenerateRaindrops = 0; -#ifdef PC_PARTICLE CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true); -#else - CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 2500, CRGBA(0,0,0,0), true); -#endif } } } @@ -19472,10 +19709,7 @@ CPed::Solicit(void) void CPed::SetExitBoat(CVehicle *boat) { - if (m_nPedState == PED_FOLLOW_PATH) { - ClearFollowPath(); - } - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); CVector newPos = GetPosition(); RemoveInCarAnims(); CColModel* boatCol = boat->GetColModel(); @@ -20946,6 +21180,46 @@ CPed::ScanForDelayedResponseThreats(void) // --MIAMI: Done void +CPed::DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg) +{ + CPed *ped = (CPed*) arg; + + if (CTimer::GetTimeInMilliseconds() <= ped->m_nWaitTimer + && !ped->bGotUpOfMyOwnAccord && !ped->bFleeWhenStanding && !ped->m_threatEx) { + ped->m_pNextPathNode = nil; + ped->bFleeWhenStanding = true; + ped->m_threatEx = FindPlayerPed(); + ped->SetGetUp(); + ped->ClearWaitState(); + } + ped->m_nWaitTimer = 0; + ped->RestoreHeadingRate(); + ped->Wait(); +} + +// --MIAMI: Done +void +CPed::PedSetPreviousStateCB(CAnimBlendAssociation* assoc, void* arg) +{ + CPed* ped = (CPed*)arg; + ped->RestorePreviousState(); + ped->m_pVehicleAnim = nil; +} + +// --MIAMI: Done +void +CPed::PedAnimShuffleCB(CAnimBlendAssociation* assoc, void* arg) +{ + CPed *ped = (CPed*)arg; + if (ped->EnteringCar()) { + PedSetInCarCB(nil, ped); + } else if (ped->m_nPedState != PED_DRIVING) { + ped->QuitEnteringCar(); + } +} + +// --MIAMI: Done +void PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 first, uint32 amount) { if (!ped->IsPedInControl()) diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 944c851e..752973bc 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -14,6 +14,7 @@ #define FEET_OFFSET 1.04f #define CHECK_NEARBY_THINGS_MAX_DIST 15.0f +#define ENTER_CAR_MAX_DIST 30.0f class CAccident; class CObject; @@ -459,8 +460,8 @@ public: uint32 bHasAlreadyUsedAttractor : 1; uint32 b155_2 : 1; uint32 bCarPassenger : 1; - uint32 b155_8 : 1; - uint32 b155_10 : 1; + uint32 bFleeWhenStanding : 1; + uint32 bGotUpOfMyOwnAccord : 1; uint32 bMiamiViceCop : 1; uint32 bMoneyHasBeenGivenByScript : 1; // uint32 bHasBeenPhotographed : 1; // @@ -477,10 +478,10 @@ public: uint32 bDontFight : 1; uint32 bDoomAim : 1; uint32 bCanBeShotInVehicle : 1; - uint32 b157_8 : 1; + uint32 bCanGiveUpSunbathing : 1; uint32 bMakeFleeScream : 1; uint32 bPushedAlongByCar : 1; - uint32 b157_40 : 1; + uint32 bRemoveMeWhenIGotIntoCar : 1; uint32 bIgnoreThreatsBehindObjects : 1; uint32 bNeverEverTargetThisPed : 1; @@ -489,7 +490,7 @@ public: uint32 b158_8 : 1; uint32 bCollectBusFare : 1; uint32 bBoughtIceCream : 1; - uint32 b158_40 : 1; + uint32 bDonePositionOutOfCollision : 1; uint32 b158_80 : 1; // our own flags @@ -582,7 +583,7 @@ public: float m_fleeFromPosY; CEntity *m_fleeFrom; uint32 m_fleeTimer; - CEntity* pThreatEx; // TODO(Miami): What is this? + CEntity* m_threatEx; // TODO(Miami): What is this? CEntity* m_collidingEntityWhileFleeing; uint32 m_collidingThingTimer; CEntity *m_pCollidingEntity; @@ -833,6 +834,7 @@ public: void ReactToPointGun(CEntity*); void SeekCar(void); bool PositionPedOutOfCollision(void); + bool PositionAnyPedOutOfCollision(void); bool RunToReportCrime(eCrimeType); bool PlacePedOnDryLand(void); bool PossiblyFindBetterPosToSeekCar(CVector*, CVehicle*); @@ -907,6 +909,9 @@ public: static void RestoreHeadingRateCB(CAnimBlendAssociation *assoc, void *arg); static void PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *assoc, void *arg); static void PedSetDraggedOutCarPositionCB(CAnimBlendAssociation *assoc, void *arg); + static void DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg); + static void PedSetPreviousStateCB(CAnimBlendAssociation *assoc, void *arg); + static void PedAnimShuffleCB(CAnimBlendAssociation *assoc, void *arg); bool IsPlayer(void); bool IsFemale(void) { return m_nPedType == PEDTYPE_CIVFEMALE || m_nPedType == PEDTYPE_PROSTITUTE; } diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index 90e7e122..b38f1bd9 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -41,7 +41,7 @@ #include "Fluff.h" #define BLOCK_COUNT 20 -#define SIZE_OF_SIMPLEVARS 0xD4 +#define SIZE_OF_SIMPLEVARS 0xFC const uint32 SIZE_OF_ONE_GAME_IN_BYTES = 201729; @@ -67,6 +67,28 @@ bool StillToFadeOut; uint32 TimeStartedCountingForFade; uint32 TimeToStayFadedBeforeFadeOut = 1750; +uint32 RadioStationPosition[NUM_RADIOS]; + +void +InitRadioStationPositionList() +{ + for (int i = 0; i < NUM_RADIOS; i++) + RadioStationPosition[i] = 0; +} + +uint32 +GetSavedRadioStationPosition(int32 station) +{ + return RadioStationPosition[station]; +} + +void +PopulateRadioStationPositionList() +{ + for (int i = 0; i < NUM_RADIOS; i++) + RadioStationPosition[i] = DMAudio.GetRadioPosition(i); +} + #define ReadDataFromBufferPointer(buf, to) memcpy(&to, buf, sizeof(to)); buf += align4bytes(sizeof(to)); #define WriteDataToBufferPointer(buf, from) memcpy(buf, &from, sizeof(from)); buf += align4bytes(sizeof(from)); @@ -197,6 +219,8 @@ GenericSave(int file) WriteDataToBufferPointer(buf, CTimeCycle::m_ExtraColour); WriteDataToBufferPointer(buf, CTimeCycle::m_bExtraColourOn); WriteDataToBufferPointer(buf, CTimeCycle::m_ExtraColourInter); + PopulateRadioStationPositionList(); + WriteDataToBufferPointer(buf, RadioStationPosition); assert(buf - work_buff == SIZE_OF_SIMPLEVARS); // Save scripts, block is nested within the same block as simple vars for some reason @@ -334,6 +358,7 @@ GenericLoad() ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColour); ReadDataFromBufferPointer(buf, CTimeCycle::m_bExtraColourOn); ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColourInter); + ReadDataFromBufferPointer(buf, RadioStationPosition); assert(buf - work_buff == SIZE_OF_SIMPLEVARS); #ifdef MISSION_REPLAY WaitForSave = 0; diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h index 630b3b50..236e34f5 100644 --- a/src/save/GenericGameStorage.h +++ b/src/save/GenericGameStorage.h @@ -5,6 +5,9 @@ #define SLOT_COUNT (8) +void InitRadioStationPositionList(); +uint32 GetSavedRadioStationPosition(int32 station); +void PopulateRadioStationPositionList(); bool GenericSave(int file); bool GenericLoad(); bool ReadInSizeofSaveFileBuffer(int32 &file, uint32 &size); |