diff options
Diffstat (limited to '')
96 files changed, 4631 insertions, 2755 deletions
diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp index dcaf4dcb..b690882e 100644 --- a/src/audio/AudioLogic.cpp +++ b/src/audio/AudioLogic.cpp @@ -1,4 +1,4 @@ -#include "common.h" +#include "common.h" #include "AudioManager.h" #include "audio_enums.h" @@ -5079,8 +5079,12 @@ cAudioManager::ProcessWaterCannon(int32) if (distSquared < SQR(SOUND_INTENSITY)) { m_sQueueSample.m_fDistance = distSquared <= 0.0f ? 0.0f : Sqrt(distSquared); m_sQueueSample.m_nVolume = ComputeVolume(50, SOUND_INTENSITY, m_sQueueSample.m_fDistance); +#endif if (m_sQueueSample.m_nVolume != 0) { m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; //BUG IN III!!!! +#else + m_sQueueSample.m_fSoundIntensity = SQR(SOUND_INTENSITY); +#endif m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nFrequency = 15591; @@ -5220,7 +5224,7 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound) static uint8 iSound = 0; switch (sound) { - case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S: + /*case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S: case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L: male.m_pPed = nil; male.m_bDistanceCalculated = false; @@ -5248,7 +5252,7 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound) m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bRequireReflection = true; emittingVolume = RandomDisplacement(10) + 50; - break; + break;*/ case SCRIPT_SOUND_BULLET_HIT_GROUND_1: case SCRIPT_SOUND_BULLET_HIT_GROUND_2: case SCRIPT_SOUND_BULLET_HIT_GROUND_3: @@ -5463,7 +5467,7 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound) float distSquared; switch (sound) { - case SCRIPT_SOUND_PARTY_1_LOOP_S: + /*case SCRIPT_SOUND_PARTY_1_LOOP_S: m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; m_sQueueSample.m_nSampleIndex = SFX_CLUB_1; m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_1; @@ -5562,7 +5566,7 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound) m_sQueueSample.m_nReleasingVolumeModificator = 8; m_sQueueSample.m_nReleasingVolumeDivider = 10; m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; + break;*/ default: return; } diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index 338f33a4..d89f7891 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -329,8 +329,13 @@ cAudioManager::Get3DProviderName(uint8 id) const { if (!m_bIsInitialised) return nil; +#ifdef AUDIO_OAL + id = clamp(id, 0, SampleManager.GetNum3DProvidersAvailable() - 1); +#else + // We don't want that either since it will crash the game, but skipping for now if (id >= SampleManager.GetNum3DProvidersAvailable()) return nil; +#endif return SampleManager.Get3DProviderName(id); } @@ -619,29 +624,56 @@ cAudioManager::AddDetailsToRequestedOrderList(uint8 sample) m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = sample; } +// --MIAMI: Done void cAudioManager::AddReflectionsToRequestedQueue() { +#ifdef FIX_BUGS + uint32 oldFreq = 0; +#else + uint32 oldFreq; +#endif float reflectionDistance; int32 noise; - uint8 emittingVolume = (m_sQueueSample.m_nVolume / 2) + (m_sQueueSample.m_nVolume / 8); + uint8 emittingVolume; + + uint32 oldCounter = m_sQueueSample.m_nCounter; + float oldDist = m_sQueueSample.m_fDistance; + CVector oldPos = m_sQueueSample.m_vecPos; + if ( CTimer::GetIsSlowMotionActive() ) { + emittingVolume = m_sQueueSample.m_nVolume; + oldFreq = m_sQueueSample.m_nFrequency; + } else { + emittingVolume = (m_sQueueSample.m_nVolume / 2) + (m_sQueueSample.m_nVolume / 16); + } + m_sQueueSample.m_fSoundIntensity = m_sQueueSample.m_fSoundIntensity / 2.f; + + int halfOldFreq = oldFreq >> 1; for (uint32 i = 0; i < ARRAY_SIZE(m_afReflectionsDistances); i++) { + if ( CTimer::GetIsSlowMotionActive() ) + m_afReflectionsDistances[i] = GetRandomNumberInRange(i % 4, 0, 2) * 100.f / 8.f; + reflectionDistance = m_afReflectionsDistances[i]; if (reflectionDistance > 0.0f && reflectionDistance < 100.f && reflectionDistance < m_sQueueSample.m_fSoundIntensity) { - m_sQueueSample.m_nLoopsRemaining = (reflectionDistance * 500.f / 1029.f); - if (m_sQueueSample.m_nLoopsRemaining > 5) { + m_sQueueSample.m_nLoopsRemaining = CTimer::GetIsSlowMotionActive() ? (reflectionDistance * 800.f / 1029.f) : (reflectionDistance * 500.f / 1029.f); + if (m_sQueueSample.m_nLoopsRemaining > 3) { m_sQueueSample.m_fDistance = m_afReflectionsDistances[i]; m_sQueueSample.m_nEmittingVolume = emittingVolume; m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume > emittingVolume / 16) { - m_sQueueSample.m_nCounter += (i + 1) * 256; + m_sQueueSample.m_nCounter = oldCounter + (i + 1) * 256; if (m_sQueueSample.m_nLoopCount) { - noise = RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - if (noise <= 0) - m_sQueueSample.m_nFrequency += noise; - else - m_sQueueSample.m_nFrequency -= noise; + if ( CTimer::GetIsSlowMotionActive() ) { + m_sQueueSample.m_nFrequency = halfOldFreq + ((halfOldFreq * i) / ARRAY_SIZE(m_afReflectionsDistances)); + } else { + noise = RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + if (noise <= 0) + m_sQueueSample.m_nFrequency += noise; + else + m_sQueueSample.m_nFrequency -= noise; + } } m_sQueueSample.m_nReleasingVolumeModificator += 20; m_sQueueSample.m_vecPos = m_avecReflectionsPos[i]; @@ -650,50 +682,85 @@ cAudioManager::AddReflectionsToRequestedQueue() } } } + m_sQueueSample.m_vecPos = oldPos; + m_sQueueSample.m_fDistance = oldDist; } +// --MIAMI: Done void cAudioManager::UpdateReflections() { - const CVector &camPos = TheCamera.GetPosition(); + CVector camPos = TheCamera.GetPosition(); CColPoint colpoint; CEntity *ent; if (m_FrameCounter % 8 == 0) { m_avecReflectionsPos[0] = camPos; - m_avecReflectionsPos[0].y += 50.f; + m_avecReflectionsPos[0].y += 100.f; if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[0], colpoint, ent, true, false, false, true, false, true, true)) m_afReflectionsDistances[0] = Distance(camPos, colpoint.point); else - m_afReflectionsDistances[0] = 50.0f; + m_afReflectionsDistances[0] = 100.0f; + } else if ((m_FrameCounter + 1) % 8 == 0) { m_avecReflectionsPos[1] = camPos; - m_avecReflectionsPos[1].y -= 50.0f; + m_avecReflectionsPos[1].y -= 100.0f; if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[1], colpoint, ent, true, false, false, true, false, true, true)) m_afReflectionsDistances[1] = Distance(camPos, colpoint.point); else - m_afReflectionsDistances[1] = 50.0f; + m_afReflectionsDistances[1] = 100.0f; + } else if ((m_FrameCounter + 2) % 8 == 0) { m_avecReflectionsPos[2] = camPos; - m_avecReflectionsPos[2].x -= 50.0f; + m_avecReflectionsPos[2].x -= 100.0f; if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[2], colpoint, ent, true, false, false, true, false, true, true)) m_afReflectionsDistances[2] = Distance(camPos, colpoint.point); else - m_afReflectionsDistances[2] = 50.0f; + m_afReflectionsDistances[2] = 100.0f; + } else if ((m_FrameCounter + 3) % 8 == 0) { m_avecReflectionsPos[3] = camPos; - m_avecReflectionsPos[3].x += 50.0f; + m_avecReflectionsPos[3].x += 100.0f; if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[3], colpoint, ent, true, false, false, true, false, true, true)) m_afReflectionsDistances[3] = Distance(camPos, colpoint.point); else - m_afReflectionsDistances[3] = 50.0f; + m_afReflectionsDistances[3] = 100.0f; + } else if ((m_FrameCounter + 4) % 8 == 0) { + camPos.y += 1.0f; m_avecReflectionsPos[4] = camPos; - m_avecReflectionsPos[4].z += 50.0f; + m_avecReflectionsPos[4].z += 100.0f; if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[4].z, colpoint, ent, true, false, false, false, true, false, nil)) m_afReflectionsDistances[4] = colpoint.point.z - camPos.z; else - m_afReflectionsDistances[4] = 50.0f; + m_afReflectionsDistances[4] = 100.0f; + + } else if ((m_FrameCounter + 5) % 8 == 0) { + camPos.y -= 1.0f; + m_avecReflectionsPos[5] = camPos; + m_avecReflectionsPos[5].z += 100.0f; + if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[5].z, colpoint, ent, true, false, false, false, true, false, nil)) + m_afReflectionsDistances[5] = colpoint.point.z - camPos.z; + else + m_afReflectionsDistances[5] = 100.0f; + + } else if ((m_FrameCounter + 6) % 8 == 0) { + camPos.x -= 1.0f; + m_avecReflectionsPos[6] = camPos; + m_avecReflectionsPos[6].z += 100.0f; + if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[6].z, colpoint, ent, true, false, false, false, true, false, nil)) + m_afReflectionsDistances[6] = colpoint.point.z - camPos.z; + else + m_afReflectionsDistances[6] = 100.0f; + + } else if ((m_FrameCounter + 7) % 8 == 0) { + camPos.x += 1.0f; + m_avecReflectionsPos[7] = camPos; + m_avecReflectionsPos[7].z += 100.0f; + if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[7].z, colpoint, ent, true, false, false, false, true, false, nil)) + m_afReflectionsDistances[7] = colpoint.point.z - camPos.z; + else + m_afReflectionsDistances[7] = 100.0f; } } @@ -1010,4 +1077,4 @@ cAudioManager::ComputeEmittingVolume(uint8 emittingVolume, float intensity, floa return (quatIntensity - (dist - diffIntensity)) * (float)emittingVolume / quatIntensity; return emittingVolume; } -#endif
\ No newline at end of file +#endif diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h index 7b2e01ae..dbc58ac2 100644 --- a/src/audio/AudioManager.h +++ b/src/audio/AudioManager.h @@ -76,7 +76,8 @@ public: uint8 m_nIndexMap[NUM_PED_COMMENTS_BANKS][NUM_PED_COMMENTS_SLOTS]; uint8 m_nCommentsInBank[NUM_PED_COMMENTS_BANKS]; uint8 m_nActiveBank; - uint32 field_48C; + bool m_bDelay; + uint32 m_nDelayTimer; cPedComments() { @@ -157,19 +158,14 @@ public: VALIDATE_SIZE(cVehicleParams, 0x18); enum { - /* - REFLECTION_YMAX = 0, top - REFLECTION_YMIN = 1, bottom - REFLECTION_XMIN = 2, left - REFLECTION_XMAX = 3, right - REFLECTION_ZMAX = 4, - */ - - REFLECTION_TOP = 0, - REFLECTION_BOTTOM, - REFLECTION_LEFT, - REFLECTION_RIGHT, - REFLECTION_UP, + REFLECTION_NORTH = 0, + REFLECTION_SOUTH, + REFLECTION_WEST, + REFLECTION_EAST, + REFLECTION_CEIL_NORTH, + REFLECTION_CEIL_SOUTH, + REFLECTION_CEIL_WEST, + REFLECTION_CEIL_EAST, MAX_REFLECTIONS, }; @@ -385,7 +381,7 @@ public: void Service(); //done void ServiceCollisions(); //done void ServicePoliceRadio(); - void ServicePoliceRadioChannel(int32 wantedLevel); + void ServicePoliceRadioChannel(uint8 wantedLevel); void ServiceSoundEffects(); int8 SetCurrent3DProvider(uint8 which); void SetDynamicAcousticModelingStatus(uint8 status); diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp index a4db2862..ade53d9b 100644 --- a/src/audio/DMAudio.cpp +++ b/src/audio/DMAudio.cpp @@ -190,7 +190,7 @@ cDMAudio::IsAudioInitialised(void) void cDMAudio::ReportCrime(eCrimeType crime, const CVector &pos) { - AudioManager.ReportCrime(crime, &pos); + AudioManager.ReportCrime(crime, pos); } int32 diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp index 4653acb7..adae2708 100644 --- a/src/audio/MusicManager.cpp +++ b/src/audio/MusicManager.cpp @@ -1160,13 +1160,13 @@ cMusicManager::SetMalibuClubTrackPos(uint8 scriptObject) if (m_nStreamedTrack != STREAMED_SOUND_MALIBU_AMBIENT && m_nPlayingTrack != STREAMED_SOUND_MALIBU_AMBIENT) { switch (scriptObject) { - case SCRIPT_SOUND_MALIBU_1: + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_1: m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 8640; break; - case SCRIPT_SOUND_MALIBU_2: + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_2: m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 286720; break; - case SCRIPT_SOUND_MALIBU_3: + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_3: m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 509120; break; } @@ -1183,13 +1183,13 @@ cMusicManager::SetStripClubTrackPos(uint8 scriptObject) { switch (scriptObject) { - case SCRIPT_SOUND_STRIPCLUB_1: + case SCRIPT_SOUND_NEW_BUILDING_STRIP_1: m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = AudioManager.m_anRandomTable[0] % 128; break; - case SCRIPT_SOUND_STRIPCLUB_2: + case SCRIPT_SOUND_NEW_BUILDING_STRIP_2: m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 320200; break; - case SCRIPT_SOUND_STRIPCLUB_3: + case SCRIPT_SOUND_NEW_BUILDING_STRIP_3: m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 672000; break; } diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp index 15dafab1..2f0c7fc3 100644 --- a/src/audio/PoliceRadio.cpp +++ b/src/audio/PoliceRadio.cpp @@ -65,7 +65,7 @@ cAudioManager::InitialisePoliceRadio() m_sPoliceRadioQueue.policeChannelTimerSeconds = 0; m_sPoliceRadioQueue.policeChannelCounterSeconds = 0; for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) - m_sPoliceRadioQueue.crimes[i].type = 0; + m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE; SampleManager.SetChannelReverbFlag(policeChannel, 0); gSpecialSuspectLastSeenReport = false; @@ -128,20 +128,23 @@ cAudioManager::ServicePoliceRadio() if(!m_bIsInitialised) return; - if(!m_nUserPause) { + if(m_nUserPause == 0) { bool crimeReport = SetupCrimeReport(); #ifdef FIX_BUGS // Crash at 0x5fe6ef if(CReplay::IsPlayingBack() || !FindPlayerPed() || !FindPlayerPed()->m_pWanted) return; #endif - wantedLevel = FindPlayerPed()->m_pWanted->m_nWantedLevel; - if(!crimeReport) { - if(wantedLevel) { - if(nLastSeen) { - --nLastSeen; - } else { - nLastSeen = m_anRandomTable[1] % 1000 + 2000; - SetupSuspectLastSeenReport(); + CPlayerPed *playerPed = FindPlayerPed(); + if (playerPed) { + wantedLevel = playerPed->m_pWanted->m_nWantedLevel; + if (!crimeReport) { + if (wantedLevel != 0) { + if (nLastSeen != 0) + --nLastSeen; + else { + nLastSeen = m_anRandomTable[1] % 1000 + 2000; + SetupSuspectLastSeenReport(); + } } } } @@ -150,7 +153,7 @@ cAudioManager::ServicePoliceRadio() } void -cAudioManager::ServicePoliceRadioChannel(int32 wantedLevel) +cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel) { bool processed = false; uint32 sample; @@ -159,18 +162,18 @@ cAudioManager::ServicePoliceRadioChannel(int32 wantedLevel) static int cWait = 0; static bool bChannelOpen = false; static uint8 bMissionAudioPhysicalPlayingStatus = 0; - static int32 PoliceChannelFreq = 5500; + static int32 PoliceChannelFreq = 22050; if (!m_bIsInitialised) return; - if (m_nUserPause) { + if (m_nUserPause != 0) { if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel); - if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && bMissionAudioPhysicalPlayingStatus == 1 && + if (g_nMissionAudioSfx != NO_SAMPLE && bMissionAudioPhysicalPlayingStatus == 1 && SampleManager.IsStreamPlaying(1)) { SampleManager.PauseStream(1, 1); } } else { - if (m_nPreviousUserPause && g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && + if (m_nPreviousUserPause && g_nMissionAudioSfx != NO_SAMPLE && bMissionAudioPhysicalPlayingStatus == 1) { SampleManager.PauseStream(0, 1); } @@ -179,7 +182,7 @@ cAudioManager::ServicePoliceRadioChannel(int32 wantedLevel) --cWait; return; } - if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && !bChannelOpen) { + if (g_nMissionAudioSfx != NO_SAMPLE && !bChannelOpen) { if (g_nMissionAudioPlayingStatus) { if (g_nMissionAudioPlayingStatus == 1 && !bMissionAudioPhysicalPlayingStatus && SampleManager.IsStreamPlaying(1)) { @@ -191,7 +194,7 @@ cAudioManager::ServicePoliceRadioChannel(int32 wantedLevel) } else { bMissionAudioPhysicalPlayingStatus = 2; g_nMissionAudioPlayingStatus = 2; - g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES; + g_nMissionAudioSfx = NO_SAMPLE; cWait = 30; } return; @@ -206,24 +209,24 @@ cAudioManager::ServicePoliceRadioChannel(int32 wantedLevel) } } if (bChannelOpen) DoPoliceRadioCrackle(); - if ((g_nMissionAudioSfx == TOTAL_AUDIO_SAMPLES || g_nMissionAudioPlayingStatus != 1) && + if ((g_nMissionAudioSfx == NO_SAMPLE || g_nMissionAudioPlayingStatus != 1) && !SampleManager.GetChannelUsedFlag(policeChannel) && m_sPoliceRadioQueue.policeChannelTimer) { if (m_sPoliceRadioQueue.policeChannelTimer) { sample = m_sPoliceRadioQueue.crimesSamples[m_sPoliceRadioQueue.policeChannelCounterSeconds]; m_sPoliceRadioQueue.policeChannelTimer--; m_sPoliceRadioQueue.policeChannelCounterSeconds = (m_sPoliceRadioQueue.policeChannelCounterSeconds + 1) % 60; } else { - sample = TOTAL_AUDIO_SAMPLES; + sample = NO_SAMPLE; } - if (!wantedLevel) { + if (wantedLevel == 0) { if (gSpecialSuspectLastSeenReport) { gSpecialSuspectLastSeenReport = 0; - } else if (sample == SFX_POLICE_RADIO_MESSAGE_NOISE_1 || sample == TOTAL_AUDIO_SAMPLES) { + } else if (sample == SFX_POLICE_RADIO_MESSAGE_NOISE_1) { bChannelOpen = false; processed = true; } } - if (sample == TOTAL_AUDIO_SAMPLES) { + if (sample == NO_SAMPLE) { if (!processed) cWait = 30; } else { SampleManager.InitialiseChannel(policeChannel, sample, 0); @@ -281,17 +284,28 @@ cAudioManager::SetupCrimeReport() for (int j = 0; j < NUMAUDIOZONES; j++) { if (strcmp(zone->name, ZoneSfx[j].m_aName) == 0) { sampleIndex = ZoneSfx[j].m_nSampleIndex; - m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_WEVE_GOT); m_sPoliceRadioQueue.Add(SFX_A_10); switch (m_sPoliceRadioQueue.crimes[i].type) { - case CRIME_PED_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_PED; break; - case CRIME_COP_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_COP; break; + case CRIME_PED_BURNED: + case CRIME_HIT_PED_NASTYWEAPON: + m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_PED; + break; + case CRIME_COP_BURNED: + case CRIME_HIT_COP_NASTYWEAPON: + m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_COP; + break; case CRIME_VEHICLE_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_STEAL_CAR; break; case CRIME_DESTROYED_CESSNA: m_sPoliceRadioQueue.crimes[i].type = CRIME_SHOOT_HELI; break; + case CRIME_EXPLOSION: m_sPoliceRadioQueue.crimes[i].type = CRIME_STEAL_CAR; break; // huh? default: break; } +#ifdef FIX_BUGS m_sPoliceRadioQueue.Add(m_sPoliceRadioQueue.crimes[i].type + SFX_CRIME_1 - 1); +#else + m_sPoliceRadioQueue.Add(m_sPoliceRadioQueue.crimes[i].type + SFX_CRIME_1); +#endif m_sPoliceRadioQueue.Add(SFX_IN); rangeX = zone->maxx - zone->minx; rangeY = zone->maxy - zone->miny; @@ -316,8 +330,8 @@ cAudioManager::SetupCrimeReport() m_sPoliceRadioQueue.Add(SFX_CENTRAL); m_sPoliceRadioQueue.Add(sampleIndex); - m_sPoliceRadioQueue.Add(m_anRandomTable[2] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1); - m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(NO_SAMPLE); break; } } @@ -339,161 +353,105 @@ cAudioManager::SetupSuspectLastSeenReport() int32 color_post_modifier; const int32 gCarColourTable[][3] = { - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLACK, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_WHITE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_BRIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLACK, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_WHITE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {SFX_POLICE_RADIO_BRIGHT, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, SFX_POLICE_RADIO_GREY}, -#ifdef FIX_BUGS - {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, -#else - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, -#endif - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, -#ifdef FIX_BUGS - {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES}, -#else - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, -#endif - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES}, -#ifdef FIX_BUGS - {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES}, -#else - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, -#endif - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES}, -#ifdef FIX_BUGS - {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES}, -#else - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, -#endif - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES}, -#ifdef FIX_BUGS - {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, -#else - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, -#endif - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, -#ifdef FIX_BUGS - {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_BLUE}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES}, -#else - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, -#endif - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES}, -#ifdef FIX_BUGS - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_GREY}, -#else - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES}, -#endif - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES}, -#ifdef FIX_BUGS - {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES}, -#else - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, -#endif - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES}, - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES}, -#ifdef FIX_BUGS - {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES}, -#else - {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES}, -#endif - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}, - {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES} + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE} }; if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE) { - veh = FindPlayerVehicle(); + veh = FindVehicleOfPlayer(); if (veh != nil) { if (60 - m_sPoliceRadioQueue.policeChannelTimer > 9) { color1 = veh->m_currentColour1; @@ -504,156 +462,213 @@ cAudioManager::SetupSuspectLastSeenReport() color_pre_modifier = gCarColourTable[color1][0]; color_post_modifier = gCarColourTable[color1][2]; switch (veh->GetModelIndex()) { -// TODO(MIAMI): just making this compile -#ifdef FIX_BUGS - // case MI_COLUMB: - // main_color = SFX_POLICE_RADIO_BLUE; - // color_pre_modifier = color_post_modifier = TOTAL_AUDIO_SAMPLES; -#endif case MI_LANDSTAL: - // case MI_BLISTA: - sample = SFX_POLICE_RADIO_CRUISER; break; -#ifdef FIX_BUGS - // case MI_YARDIE: - // color_pre_modifier = TOTAL_AUDIO_SAMPLES; - // main_color = SFX_POLICE_RADIO_RED; - // color_post_modifier = SFX_POLICE_RADIO_YELLOW; - // sample = SFX_POLICE_RADIO_CONVERTIBLE; break; - // case MI_DIABLOS: - // main_color = SFX_POLICE_RADIO_BLACK; -#endif + case MI_PATRIOT: + case MI_RANCHER: + case MI_FBIRANCH: + case MI_SANDKING: + sample = SFX_POLICE_RADIO_OFFROAD; + break; case MI_IDAHO: - // case MI_STALLION: sample = SFX_POLICE_RADIO_CONVERTIBLE; break; -#ifdef FIX_BUGS - // case MI_YAKUZA: - // color_pre_modifier = TOTAL_AUDIO_SAMPLES; - // main_color = SFX_POLICE_RADIO_SILVER; - // color_post_modifier = SFX_POLICE_RADIO_RED; -#endif + case MI_MANANA: + case MI_ESPERANT: + case MI_CUBAN: + case MI_STALLION: + case MI_SABRE: + case MI_SABRETUR: + case MI_VIRGO: + case MI_BLISTAC: + sample = SFX_POLICE_RADIO_2_DOOR; + break; case MI_STINGER: case MI_INFERNUS: case MI_CHEETAH: - case MI_BANSHEE: sample = SFX_POLICE_RADIO_SPORTS_CAR; break; -#ifdef FIX_BUGS - // case MI_MAFIA: - // color_pre_modifier = color_post_modifier = TOTAL_AUDIO_SAMPLES; - // main_color = SFX_POLICE_RADIO_GREY; - case MI_WASHING: -#endif + case MI_BANSHEE: + case MI_PHEONIX: + case MI_COMET: + case MI_DELUXO: + case MI_HOTRING: + sample = SFX_POLICE_RADIO_SPORTS_CAR; + break; + case MI_LINERUN: + sample = SFX_POLICE_RADIO_RIG; + break; case MI_PEREN: + case MI_REGINA: + sample = SFX_POLICE_RADIO_STATION_WAGON; + break; case MI_SENTINEL: - // case MI_FBICAR: sample = SFX_POLICE_RADIO_SALOON; break; - case MI_PATRIOT: - case MI_BOBCAT: sample = SFX_POLICE_RADIO_PICKUP; break; - case MI_FIRETRUCK: sample = SFX_POLICE_RADIO_FIRE_TRUCK; break; -#ifdef FIX_BUGS - case MI_LINERUN: - case MI_FLATBED: -#endif + case MI_FBICAR: + case MI_WASHING: + case MI_SENTXS: + case MI_ADMIRAL: + case MI_GLENDALE: + case MI_OCEANIC: + case MI_HERMES: + case MI_GREENWOO: + sample = SFX_POLICE_RADIO_SEDAN; + break; + case MI_RIO: + sample = SFX_POLICE_RADIO_CRUISER; + break; + case MI_FIRETRUCK: + sample = SFX_POLICE_RADIO_FIRE_TRUCK; + break; case MI_TRASH: - case MI_BARRACKS: sample = SFX_POLICE_RADIO_TRUCK; break; - // case MI_STRETCH: sample = SFX_POLICE_RADIO_LIMO; break; - case MI_MANANA: - case MI_ESPERANT: sample = SFX_POLICE_RADIO_2_DOOR; break; -#ifdef FIX_BUGS - // case MI_HOODS: - // color_pre_modifier = TOTAL_AUDIO_SAMPLES; - // main_color = SFX_POLICE_RADIO_BLUE; - // color_post_modifier = SFX_POLICE_RADIO_GREEN; - // case MI_BELLYUP: - case MI_YANKEE: - case MI_TOPFUN: - // case MI_MRWONGS: - // case MI_PANLANT: -#endif + sample = SFX_POLICE_RADIO_GARBAGE_TRUCK; + break; + case MI_STRETCH: + case MI_LOVEFIST: + sample = SFX_POLICE_RADIO_STRETCH; + break; + case MI_VOODOO: + sample = SFX_POLICE_RADIO_LOWRIDER; + break; case MI_PONY: - case MI_MULE: case MI_MOONBEAM: - case MI_ENFORCER: case MI_SECURICA: - case MI_RUMPO: sample = SFX_POLICE_RADIO_VAN; break; - case MI_AMBULAN: sample = SFX_POLICE_RADIO_AMBULANCE; break; + case MI_RUMPO: + case MI_GANGBUR: + case MI_YANKEE: + case MI_TOPFUN: + case MI_BURRITO: + case MI_SPAND: + sample = SFX_POLICE_RADIO_VAN; + break; + case MI_MULE: + case MI_BARRACKS: + case MI_PACKER: + case MI_FLATBED: + sample = SFX_POLICE_RADIO_TRUCK; + break; + case MI_AMBULAN: + sample = SFX_POLICE_RADIO_AMBULANCE; + break; case MI_TAXI: case MI_CABBIE: - case MI_ZEBRA: sample = SFX_POLICE_RADIO_TAXI; break; - case MI_KAUFMAN: sample = SFX_POLICE_RADIO_TAXI; break; + case MI_ZEBRA: + case MI_KAUFMAN: + sample = SFX_POLICE_RADIO_TAXI; + break; + case MI_BOBCAT: + case MI_WALTON: + sample = SFX_POLICE_RADIO_PICKUP; + break; case MI_MRWHOOP: sample = SFX_POLICE_RADIO_ICE_CREAM_VAN; break; - case MI_BFINJECT: sample = SFX_POLICE_RADIO_BUGGY; break; - case MI_POLICE: sample = SFX_POLICE_RADIO_POLICE_CAR; break; -#ifdef FIX_BUGS + case MI_BFINJECT: + sample = SFX_POLICE_RADIO_BUGGY; + break; + case MI_HUNTER: + case MI_CHOPPER: + case MI_SEASPAR: + case MI_SPARROW: + case MI_MAVERICK: + case MI_VCNMAV: + case MI_POLMAV: + sample = SFX_POLICE_RADIO_HELICOPTER; + break; + case MI_POLICE: + sample = SFX_POLICE_RADIO_POLICE_CAR; + break; + case MI_ENFORCER: + sample = SFX_POLICE_RADIO_SWAT_VAN; + break; + case MI_PREDATOR: + case MI_SQUALO: case MI_SPEEDER: - case MI_REEFER: - // case MI_GHOST: -#endif - case MI_PREDATOR: sample = SFX_POLICE_RADIO_BOAT; break; + sample = SFX_POLICE_RADIO_SPEEDBOAT; + break; case MI_BUS: - case MI_COACH: sample = SFX_POLICE_RADIO_BUS; break; + sample = SFX_POLICE_RADIO_BUS; + break; case MI_RHINO: sample = SFX_POLICE_RADIO_TANK; - main_color = TOTAL_AUDIO_SAMPLES; - color_post_modifier = TOTAL_AUDIO_SAMPLES; break; - // case MI_TRAIN: - // sample = SFX_POLICE_RADIO_SUBWAY_CAR; - // main_color = TOTAL_AUDIO_SAMPLES; - // color_post_modifier = TOTAL_AUDIO_SAMPLES; - - // break; + case MI_ANGEL: + case MI_PCJ600: + case MI_FREEWAY: + case MI_SANCHEZ: + sample = SFX_POLICE_RADIO_MOTOBIKE; + break; + case MI_COACH: + sample = SFX_POLICE_RADIO_COACH; + break; + case MI_ROMERO: + sample = SFX_POLICE_RADIO_HEARSE; + break; + case MI_PIZZABOY: + case MI_FAGGIO: + sample = SFX_POLICE_RADIO_MOPED; + break; + case MI_DEADDODO: + case MI_SKIMMER: + sample = SFX_POLICE_RADIO_PLANE; + break; + case MI_REEFER: + case MI_TROPIC: + case MI_COASTG: + case MI_MARQUIS: + case MI_JETMAX: + sample = SFX_POLICE_RADIO_BOAT; + break; + case MI_CADDY: + sample = SFX_POLICE_RADIO_GOLF_CART; + break; + case MI_DINGHY: + sample = SFX_POLICE_RADIO_DINGHY; + break; default: - debug("\n *** UNKNOWN CAR MODEL INDEX %d *** ", veh->GetModelIndex()); + //debug("\n *** UNKNOWN CAR MODEL INDEX %d *** ", veh->GetModelIndex()); return; } - m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT); if (m_anRandomTable[3] % 2) m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_LAST_SEEN); m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_IN_A); - if (color_pre_modifier != TOTAL_AUDIO_SAMPLES) + if (color_pre_modifier != NO_SAMPLE) m_sPoliceRadioQueue.Add(color_pre_modifier); - if (main_color != TOTAL_AUDIO_SAMPLES) + if (main_color != NO_SAMPLE) m_sPoliceRadioQueue.Add(main_color); - if (color_post_modifier != TOTAL_AUDIO_SAMPLES) + if (color_post_modifier != NO_SAMPLE) m_sPoliceRadioQueue.Add(color_post_modifier); m_sPoliceRadioQueue.Add(sample); - m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1); - m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(NO_SAMPLE); } } } else if (60 - m_sPoliceRadioQueue.policeChannelTimer > 4) { m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT); m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_ON_FOOT); - m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1); - m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(NO_SAMPLE); } } } - - void -cAudioManager::ReportCrime(int32 type, const CVector *pos) +cAudioManager::ReportCrime(eCrimeType type, const CVector &pos) { int32 lastCrime = ARRAY_SIZE(m_sPoliceRadioQueue.crimes); if (m_bIsInitialised && MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0 && (type > CRIME_NONE || type < NUM_CRIME_TYPES) && m_FrameCounter >= gMinTimeToNextReport[type]) { for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) { - if (m_sPoliceRadioQueue.crimes[i].type) { + if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE) { if (m_sPoliceRadioQueue.crimes[i].type == type) { - m_sPoliceRadioQueue.crimes[i].position = *pos; + m_sPoliceRadioQueue.crimes[i].position = pos; m_sPoliceRadioQueue.crimes[i].timer = 0; return; } - } else { + } else lastCrime = i; - } } if (lastCrime < ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) { m_sPoliceRadioQueue.crimes[lastCrime].type = type; - m_sPoliceRadioQueue.crimes[lastCrime].position = *pos; + m_sPoliceRadioQueue.crimes[lastCrime].position = pos; m_sPoliceRadioQueue.crimes[lastCrime].timer = 0; gMinTimeToNextReport[type] = m_FrameCounter + 500; } @@ -682,6 +697,7 @@ cAudioManager::PlaySuspectLastSeen(float x, float y, float z) zone = CTheZones::GetAudioZone(audioZone); for (int i = 0; i < NUMAUDIOZONES; i++) { if (strcmp(zone->name, ZoneSfx[i].m_aName) == 0) { + sample = ZoneSfx[i].m_nSampleIndex; m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT); m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_LAST_SEEN); @@ -707,8 +723,7 @@ cAudioManager::PlaySuspectLastSeen(float x, float y, float z) m_sPoliceRadioQueue.Add(SFX_WEST); else if (!processed) m_sPoliceRadioQueue.Add(SFX_CENTRAL); - - m_sPoliceRadioQueue.Add(ZoneSfx[i].m_nSampleIndex); + m_sPoliceRadioQueue.Add(sample); m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); m_sPoliceRadioQueue.Add(NO_SAMPLE); gSpecialSuspectLastSeenReport = true; diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp index 2f392264..58b5dc02 100644 --- a/src/audio/oal/stream.cpp +++ b/src/audio/oal/stream.cpp @@ -377,8 +377,8 @@ CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUF #endif else m_pSoundFile = nil; - ASSERT(m_pSoundFile != nil); - if (m_pSoundFile && m_pSoundFile->IsOpened() ) + + if ( IsOpened() ) { m_pBuffer = malloc(m_pSoundFile->GetBufferSize()); ASSERT(m_pBuffer!=nil); @@ -425,14 +425,14 @@ bool CStream::HasSource() bool CStream::IsOpened() { - return m_pSoundFile->IsOpened(); + return m_pSoundFile && m_pSoundFile->IsOpened(); } bool CStream::IsPlaying() { if ( !HasSource() || !IsOpened() ) return false; - if ( m_pSoundFile->IsOpened() && !m_bPaused ) + if ( !m_bPaused ) { ALint sourceState; alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); @@ -500,7 +500,7 @@ void CStream::SetPan(uint8 nPan) void CStream::SetPosMS(uint32 nPos) { - if ( !m_pSoundFile->IsOpened() ) return; + if ( !IsOpened() ) return; m_pSoundFile->Seek(nPos); ClearBuffers(); } @@ -508,7 +508,7 @@ void CStream::SetPosMS(uint32 nPos) uint32 CStream::GetPosMS() { if ( !HasSource() ) return 0; - if ( !m_pSoundFile->IsOpened() ) return 0; + if ( !IsOpened() ) return 0; ALint offset; //alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset); @@ -521,7 +521,7 @@ uint32 CStream::GetPosMS() uint32 CStream::GetLengthMS() { - if ( !m_pSoundFile->IsOpened() ) return 0; + if ( !IsOpened() ) return 0; return m_pSoundFile->GetLength(); } @@ -529,7 +529,7 @@ bool CStream::FillBuffer(ALuint alBuffer) { if ( !HasSource() ) return false; - if ( !m_pSoundFile->IsOpened() ) + if ( !IsOpened() ) return false; if ( !(alBuffer != AL_NONE && alIsBuffer(alBuffer)) ) return false; @@ -571,7 +571,7 @@ void CStream::ClearBuffers() bool CStream::Setup() { - if ( m_pSoundFile->IsOpened() ) + if ( IsOpened() ) { m_pSoundFile->Seek(0); alSourcei(m_alSource, AL_SOURCE_RELATIVE, AL_TRUE); diff --git a/src/audio/sampman.h b/src/audio/sampman.h index dc4a8e3e..794db8e0 100644 --- a/src/audio/sampman.h +++ b/src/audio/sampman.h @@ -143,8 +143,8 @@ class cSampleManager char *m_aAudioProviders[MAXPROVIDERS]; tSample m_aSamples[TOTAL_AUDIO_SAMPLES]; char m_MiscomPath[260]; - char m_SfxPath[260]; - char m_StreamedAudioPath[188]; + char m_WavFilesPath[260]; + char m_MP3FilesPath[188]; void *m_aChannels[18]; public: diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp index 6a7850d8..f7c4d7a6 100644 --- a/src/audio/sampman_miles.cpp +++ b/src/audio/sampman_miles.cpp @@ -16,10 +16,12 @@ #include "MusicManager.h" #include "Frontend.h" #include "Timer.h" - +#include "crossplatform.h" #pragma comment( lib, "mss32.lib" ) +// --MIAMI: file done + cSampleManager SampleManager; uint32 BankStartOffset[MAX_SFX_BANKS]; /////////////////////////////////////////////////////////////// @@ -65,11 +67,6 @@ uint8 nStreamLoopedFlag[MAX_STREAMS]; uint32 _CurMP3Index; int32 _CurMP3Pos; bool _bIsMp3Active; - -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) -bool _bUseHDDAudio; -char _aHDDPath[MAX_PATH]; -#endif /////////////////////////////////////////////////////////////// @@ -560,15 +557,6 @@ _FindMP3s(void) FindClose(hFind); return; } - - FILE *f = fopen("MP3\\MP3Report.txt", "w"); - - if ( f ) - { - fprintf(f, "MP3 Report File\n\n"); - fprintf(f, "\"%s\"", fd.cFileName); - } - if ( filepathlen > 4 ) { @@ -578,12 +566,6 @@ _FindMP3s(void) { OutputDebugString("Resolving Link"); OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); } bShortcut = true; @@ -607,10 +589,6 @@ _FindMP3s(void) if ( _pMP3List == NULL ) { FindClose(hFind); - - if ( f ) - fclose(f); - return; } @@ -633,9 +611,6 @@ _FindMP3s(void) { _pMP3List->pLinkPath = NULL; } - - if ( f ) fprintf(f, " - OK\n"); - bInitFirstEntry = false; } else @@ -644,8 +619,6 @@ _FindMP3s(void) OutputDebugString(filepath); - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); - bInitFirstEntry = true; } @@ -661,8 +634,6 @@ _FindMP3s(void) int32 filepathlen = strlen(filepath); - if ( f ) fprintf(f, "\"%s\"", fd.cFileName); - if ( filepathlen > 0 ) { if ( filepathlen > 4 ) @@ -673,12 +644,6 @@ _FindMP3s(void) { OutputDebugString("Resolving Link"); OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); } bShortcut = true; @@ -689,8 +654,6 @@ _FindMP3s(void) if ( filepathlen > MAX_PATH ) { - if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath); - continue; } } @@ -729,17 +692,13 @@ _FindMP3s(void) } pList = _pMP3List; - - if ( f ) fprintf(f, " - OK\n"); - + bInitFirstEntry = false; } else { strcat(filepath, " - NOT A VALID MP3"); OutputDebugString(filepath); - - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); } } } @@ -752,8 +711,6 @@ _FindMP3s(void) if ( filepathlen > 0 ) { - if ( f ) fprintf(f, "\"%s\"", fd.cFileName); - if ( filepathlen > 4 ) { if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) @@ -762,12 +719,6 @@ _FindMP3s(void) { OutputDebugString("Resolving Link"); OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); } bShortcut = true; @@ -812,26 +763,16 @@ _FindMP3s(void) nNumMP3s++; OutputDebugString(fd.cFileName); - - if ( f ) fprintf(f, " - OK\n"); } else { strcat(filepath, " - NOT A VALID MP3"); OutputDebugString(filepath); - - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); } } } } - - if ( f ) - { - fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s); - fclose(f); - } - + FindClose(hFind); } @@ -1043,54 +984,37 @@ cSampleManager::Initialise(void) AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS); - DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0); - if ( DIG == NULL ) - { - OutputDebugString(AIL_last_error()); - Terminate(); - return false; - } - - add_providers(); - - if ( !InitialiseSampleBanks() ) - { - Terminate(); - return false; - } - - nSampleBankMemoryStartAddress[SFX_BANK_0] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SFX_BANK_0]); - if ( !nSampleBankMemoryStartAddress[SFX_BANK_0] ) - { - Terminate(); - return false; - } - - nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX); + DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0); } #ifdef AUDIO_CACHE TRACE("cache"); - FILE *cacheFile = fopen("audio\\sound.cache", "rb"); + FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb"); + bool CreateCache = false; if (cacheFile) { fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); fclose(cacheFile); - m_bInitialised = true; - }else { + }else + CreateCache = true; #endif - TRACE("cdrom"); - S32 tatalms; char filepath[MAX_PATH]; + bool bFileNotFound; + S32 tatalms; + TRACE("cdrom"); { m_bInitialised = false; + while (true) { + + // Find path of WAVs (originally in HDD) int32 drive = 'C'; +#ifndef NO_CDCHECK do { char latter[2]; @@ -1111,93 +1035,35 @@ cSampleManager::Initialise(void) if ( f ) { fclose(f); - - bool bFileNotFound = false; - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - { - strcpy(filepath, m_szCDRomRootPath); - strcat(filepath, StreamedNameTable[i]); - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - nStreamLength[i] = tatalms; - } - else - { - bFileNotFound = true; - break; - } - } - - if ( !bFileNotFound ) - { - m_bInitialised = true; - break; - } - else - { - m_bInitialised = false; - continue; - } + strcpy(m_MiscomPath, m_szCDRomRootPath); + break; } } - + } while ( ++drive <= 'Z' ); - - if ( !m_bInitialised ) - { -#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) - FrontEndMenuManager.WaitForUserCD(); - if ( FrontEndMenuManager.m_bQuitGameNoCD ) - { - Terminate(); - return false; - } - continue; #else - m_bInitialised = true; + m_MiscomPath[0] = '\0'; #endif + + if ( DIG == NULL ) + { + OutputDebugString(AIL_last_error()); + Terminate(); + return false; } - break; - } - } + add_providers(); -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) - // hddaudio - /** - Option for user to play audio files directly from hard disk. - Copy the contents of the PLAY discs Audio directory into your installed Grand Theft Auto III Audio directory. - Grand Theft Auto III still requires the presence of the PLAY disc when started. - This may give better performance on some machines (though worse on others). - **/ - TRACE("hddaudio 1.1 patch"); - { - int32 streamLength[TOTAL_STREAMED_SOUNDS]; - - bool bFileNotFound = false; - char rootpath[MAX_PATH]; - - strcpy(_aHDDPath, m_szCDRomRootPath); - rootpath[0] = '\0'; - - FILE *f = fopen(StreamedNameTable[0], "rb"); - - if ( f ) - { - fclose(f); - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + m_szCDRomRootPath[0] = '\0'; + + strcpy(m_WavFilesPath, m_szCDRomRootPath); + +#ifdef AUDIO_CACHE + if ( CreateCache ) +#endif + for ( int32 i = STREAMED_SOUND_MISSION_MOBR1; i < TOTAL_STREAMED_SOUNDS; i++ ) { - strcpy(filepath, rootpath); + strcpy(filepath, m_szCDRomRootPath); strcat(filepath, StreamedNameTable[i]); mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); @@ -1209,39 +1075,149 @@ cSampleManager::Initialise(void) AIL_close_stream(mp3Stream[0]); mp3Stream[0] = NULL; - streamLength[i] = tatalms; + nStreamLength[i] = tatalms; } else { - bFileNotFound = true; + m_bInitialised = false; + Terminate(); + return false; + } + } + + // Find path of MP3s (originally in CD-Rom) + // if NO_CDCHECK is NOT defined but AUDIO_CACHE is defined, we still need to find MP3s' path, but will exit after the first file +#ifndef NO_CDCHECK + int32 drive = 'C'; + do + { + latter[0] = drive; + latter[1] = '\0'; + + strcpy(m_szCDRomRootPath, latter); + strcat(m_szCDRomRootPath, ":"); + strcat(m_MP3FilesPath, m_szCDRomRootPath); +#else + m_MP3FilesPath[0] = '\0'; + { +#endif + + for (int32 i = 0; i < STREAMED_SOUND_MISSION_MOBR1; i++) + { + strcpy(filepath, m_MP3FilesPath); + strcat(filepath, StreamedNameTable[i]); + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + + if (mp3Stream[0]) + { + AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + bFileNotFound = false; +#ifdef AUDIO_CACHE + if (!CreateCache) + break; + else +#endif + nStreamLength[i] = tatalms; + + } + else + { + bFileNotFound = true; + break; + } + } + +#ifndef NO_CDCHECK + if (!bFileNotFound) // otherwise try next drive break; + + } + while (++drive <= 'Z'); +#else + } +#endif + + if ( !bFileNotFound ) { + +#ifdef AUDIO_CACHE + if ( CreateCache ) +#endif + for ( int32 i = STREAMED_SOUND_MISSION_COMPLETED4; i < STREAMED_SOUND_MISSION_PAGER; i++ ) + { + strcpy(filepath, m_MiscomPath); + strcat(filepath, StreamedNameTable[i]); + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + nStreamLength[i] = tatalms; + bFileNotFound = false; + } + else + { + bFileNotFound = true; + break; + } } } - - } - else - bFileNotFound = true; - - if ( !bFileNotFound ) - { - strcpy(m_szCDRomRootPath, rootpath); - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - nStreamLength[i] = streamLength[i]; + m_bInitialised = !bFileNotFound; + + if ( !m_bInitialised ) + { +#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) + FrontEndMenuManager.WaitForUserCD(); + if ( FrontEndMenuManager.m_bQuitGameNoCD ) + { + Terminate(); + return false; + } + continue; +#else + m_bInitialised = true; +#endif + } - _bUseHDDAudio = true; + break; } - else - _bUseHDDAudio = false; } -#endif + #ifdef AUDIO_CACHE - cacheFile = fopen("audio\\sound.cache", "wb"); - fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); - fclose(cacheFile); + if (CreateCache) { + cacheFile = fcaseopen("audio\\sound.cache", "wb"); + fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); + fclose(cacheFile); } #endif + if ( !InitialiseSampleBanks() ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SFX_BANK_0] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SFX_BANK_0]); + if ( !nSampleBankMemoryStartAddress[SFX_BANK_0] ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX); + + LoadSampleBank(SFX_BANK_0); + TRACE("stream"); { for ( int32 i = 0; i < MAX_STREAMS; i++ ) @@ -1270,7 +1246,7 @@ cSampleManager::Initialise(void) while ( n < m_nNumberOfProviders ) { - if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") ) + if ( !strcmp(strupr(providers[n].name), "DIRECTSOUND3D SOFTWARE EMULATION") ) { set_new_provider(n); break; @@ -1285,10 +1261,6 @@ cSampleManager::Initialise(void) } } - TRACE("bank"); - - LoadSampleBank(SFX_BANK_0); - // mp3 TRACE("mp3"); { @@ -1411,26 +1383,25 @@ cSampleManager::CheckForAnAudioFileOnCD(void) #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) char filepath[MAX_PATH]; -#if defined(GTA3_1_1_PATCH) - if (_bUseHDDAudio) - strcpy(filepath, _aHDDPath); - else - strcpy(filepath, m_szCDRomRootPath); -#else - strcpy(filepath, m_szCDRomRootPath); -#endif // #if defined(GTA3_1_1_PATCH) + strcpy(filepath, m_MiscomPath); + strcat(filepath, StreamedNameTable[STREAMED_SOUND_MISSION_COMPLETED4]); - strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]); - FILE *f = fopen(filepath, "rb"); - + if ( f ) { fclose(f); + DMAudio.SetMusicMasterVolume(FrontEndMenuManager.m_PrefsMusicVolume); + DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume); + DMAudio.Service(); return true; } - + + DMAudio.SetMusicMasterVolume(0); + DMAudio.SetEffectsMasterVolume(0); + DMAudio.Service(); + return false; #else @@ -1441,27 +1412,10 @@ cSampleManager::CheckForAnAudioFileOnCD(void) char cSampleManager::GetCDAudioDriveLetter(void) { -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) - if (_bUseHDDAudio) - { - if ( strlen(_aHDDPath) != 0 ) - return _aHDDPath[0]; - else - return '\0'; - } - else - { - if ( strlen(m_szCDRomRootPath) != 0 ) - return m_szCDRomRootPath[0]; - else - return '\0'; - } -#else - if ( strlen(m_szCDRomRootPath) != 0 ) - return m_szCDRomRootPath[0]; + if ( strlen(m_MiscomPath) != 0 ) + return m_MiscomPath[0]; else return '\0'; -#endif } void @@ -1629,14 +1583,6 @@ cSampleManager::LoadPedComment(uint32 nComment) break; } - - case MUSICMODE_FRONTEND: - { - if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE ) - return false; - - break; - } } } @@ -1699,69 +1645,45 @@ cSampleManager::UpdateReverb(void) if ( AudioManager.GetFrameCounter() & 15 ) return false; - - float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM); - float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT); - float z = AudioManager.GetReflectionsDistance(REFLECTION_UP); - - float normy = norm(y, 5.0f, 40.0f); - float normx = norm(x, 5.0f, 40.0f); - float normz = norm(z, 5.0f, 40.0f); - float fRatio; - - if ( normy == 0.0f ) - { - if ( normx == 0.0f ) - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = 0.5f; - } - else - { - fRatio = 0.3f; - } - } - else - { - if ( normx == 0.0f ) - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = 0.5f; - } - else - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = (normy+normx+normz) / 3.0f; - } - } + float fRatio = 0.0f; + +#define MIN_DIST 0.5f +#define CALCULATE_RATIO(value, maxDist, maxRatio) (value > MIN_DIST && value < maxDist ? value / maxDist * maxRatio : 0) + + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_NORTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_SOUTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_WEST), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_EAST), 10.0f, 1/2.f); + + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_NORTH) + AudioManager.GetReflectionsDistance(REFLECTION_SOUTH)) / 2.f, 4.0f, 1/3.f); + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_WEST) + AudioManager.GetReflectionsDistance(REFLECTION_EAST)) / 2.f, 4.0f, 1/3.f); + +#undef CALCULATE_RATIO +#undef MIN_DIST - fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f); + fRatio = clamp(fRatio, 0.0f, 0.6f); if ( fRatio == _fPrevEaxRatioDestination ) return false; if ( usingEAX3 ) { + fRatio = Min(fRatio * 1.67f, 1.0f); if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) { AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params); - _fEffectsLevel = 1.0f - fRatio * 0.5f; + _fEffectsLevel = fRatio * 0.75f; } } else { if ( _usingMilesFast2D ) - _fEffectsLevel = (1.0f - fRatio) * 0.4f; + _fEffectsLevel = fRatio * 0.8f; else - _fEffectsLevel = (1.0f - fRatio) * 0.7f; + _fEffectsLevel = fRatio * 0.22f; } + _fEffectsLevel = Min(_fEffectsLevel, 1.0f); _fPrevEaxRatioDestination = fRatio; @@ -1870,10 +1792,11 @@ cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) nChannelVolume[nChannel] = vol; // increase the volume for JB.MP3 and S4_BDBD.MP3 - if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_FINALE ) - { - nChannelVolume[nChannel] >>= 2; + if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) { + if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE) + nChannelVolume[nChannel] = 0; + else + nChannelVolume[nChannel] >>= 2; } if ( opened_samples[nChannel] ) @@ -2123,7 +2046,7 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream) char filepath[MAX_PATH]; - strcpy(filepath, m_szCDRomRootPath); + strcpy(filepath, nFile < STREAMED_SOUND_MISSION_COMPLETED4 ? m_MP3FilesPath : (nFile < STREAMED_SOUND_MISSION_MOBR1 ? m_MiscomPath : m_WavFilesPath)); strcat(filepath, StreamedNameTable[nFile]); mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0); @@ -2189,7 +2112,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) if(mp3 == NULL) { _bIsMp3Active = false; nFile = 0; - strcpy(filename, m_szCDRomRootPath); + strcpy(filename, m_MiscomPath); strcat(filename, StreamedNameTable[nFile]); mp3Stream[nStream] = @@ -2239,15 +2162,14 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) if ( e == NULL ) { nFile = 0; - strcpy(filename, m_szCDRomRootPath); + strcpy(filename, m_MiscomPath); strcat(filename, StreamedNameTable[nFile]); mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); if(mp3Stream[nStream]) { - AIL_set_stream_loop_count( - mp3Stream[nStream], 1); - AIL_set_stream_ms_position( - mp3Stream[nStream], position); + AIL_set_stream_loop_count(mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1); + nStreamLoopedFlag[nStream] = true; + AIL_set_stream_ms_position(mp3Stream[nStream], position); AIL_pause_stream(mp3Stream[nStream], 0); return true; } @@ -2285,13 +2207,14 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) nFile = 0; } - strcpy(filename, m_szCDRomRootPath); + strcpy(filename, m_MiscomPath); strcat(filename, StreamedNameTable[nFile]); mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); if ( mp3Stream[nStream] ) { - AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_set_stream_loop_count(mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1); + nStreamLoopedFlag[nStream] = true; AIL_set_stream_ms_position(mp3Stream[nStream], position); AIL_pause_stream(mp3Stream[nStream], 0); return true; @@ -2355,11 +2278,14 @@ void cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) { uint8 vol = nVolume; + float boostMult = 0.0f; if ( m_bInitialised ) { if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + if ( MusicManager.GetRadioInCar() == USERTRACK && !MusicManager.CheckForMusicInterruptions() ) + boostMult = m_nMP3BoostVolume / 64.f; nStreamVolume[nStream] = vol; nStreamPan[nStream] = nPan; @@ -2368,13 +2294,13 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect { if ( nEffectFlag ) { - if ( nStream == 1 ) // TODO(MIAMI): || nStream == 2 when we have second mission channel? + if ( nStream == 1 || nStream == 2 ) AIL_set_stream_volume(mp3Stream[nStream], 128*vol*m_nEffectsVolume >> 14); else AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); } else - AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14); + AIL_set_stream_volume(mp3Stream[nStream], (m_nMusicFadeVolume*vol*(uint32)(m_nMusicVolume * boostMult + m_nMusicVolume)) >> 14); AIL_set_stream_pan(mp3Stream[nStream], nPan); } @@ -2460,4 +2386,4 @@ cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel) nStreamLoopedFlag[nChannel] = nLoopFlag; } -#endif
\ No newline at end of file +#endif diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp index d0b88245..ce81439b 100644 --- a/src/audio/sampman_oal.cpp +++ b/src/audio/sampman_oal.cpp @@ -1,4 +1,3 @@ -#include "common.h" //#define JUICY_OAL #ifdef AUDIO_OAL @@ -9,6 +8,10 @@ #include "eax.h" #include "eax-util.h" +#define WITHWINDOWS +#include "common.h" +#include "crossplatform.h" + #ifdef _WIN32 #include <io.h> #include <AL/al.h> @@ -27,20 +30,27 @@ #include "MusicManager.h" #include "Frontend.h" #include "Timer.h" -#include "crossplatform.h" #ifdef AUDIO_OPUS #include <opusfile.h> #endif //TODO: fix eax3 reverb -//TODO: max channals +//TODO: max channels //TODO: loop count -//TODO: mp3 player #ifdef _WIN32 #pragma comment( lib, "OpenAL32.lib" ) #endif +// for user MP3s +#ifdef _WIN32 +#include <direct.h> +#include <shobjidl.h> +#include <shlguid.h> +#else +#define _getcwd getcwd +#endif + cSampleManager SampleManager; bool _bSampmanInitialised = false; @@ -128,12 +138,27 @@ struct } }ALBuffers[SAMPLEBANK_MAX]; -uint32 nNumMP3s; +struct tMP3Entry +{ + char aFilename[MAX_PATH]; + + uint32 nTrackLength; + uint32 nTrackStreamPos; + + tMP3Entry* pNext; + char* pLinkPath; +}; + +uint32 nNumMP3s; +tMP3Entry* _pMP3List; +char _mp3DirectoryPath[MAX_PATH]; CStream *aStream[MAX_STREAMS]; uint8 nStreamPan [MAX_STREAMS]; uint8 nStreamVolume[MAX_STREAMS]; uint8 nStreamLoopedFlag[MAX_STREAMS]; - +uint32 _CurMP3Index; +int32 _CurMP3Pos; +bool _bIsMp3Active; /////////////////////////////////////////////////////////////// // 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 EAXLISTENERPROPERTIES StartEAX3 = @@ -452,20 +477,14 @@ int8 cSampleManager::GetCurrent3DProviderIndex(void) int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider) { - if (nProvider >= m_nNumberOfProviders) - nProvider = 0; - ASSERT( nProvider < m_nNumberOfProviders ); int savedprovider = curprovider; - - if ( nProvider < m_nNumberOfProviders ) - { - if ( set_new_provider(nProvider) ) - return curprovider; - else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) ) - return curprovider; - else - return -1; - } + + nProvider = clamp(nProvider, 0, m_nNumberOfProviders - 1); + + if ( set_new_provider(nProvider) ) + return curprovider; + else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) ) + return curprovider; else return curprovider; } @@ -476,7 +495,10 @@ cSampleManager::AutoDetect3DProviders() if (!AudioManager.IsAudioInitialised()) return -1; - int eax = -1, eax2 = -1, eax3 = -1, ds3dh = -1, ds3ds = -1; + if (defaultProvider >= 0 && defaultProvider < m_nNumberOfProviders) { + if (set_new_provider(defaultProvider)) + return defaultProvider; + } for (uint32 i = 0; i < GetNum3DProvidersAvailable(); i++) { @@ -489,19 +511,412 @@ cSampleManager::AutoDetect3DProviders() } } - 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) +{ +#ifdef _WIN32 + size_t len = strlen(path); + if (len < 4 || strcmp(&path[len - 4], ".lnk") != 0) + return false; + + IShellLink* psl; + WIN32_FIND_DATA fd; + char filepath[MAX_PATH]; + + CoInitialize(NULL); + + if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) )) + { + IPersistFile *ppf; + + if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) + { + WCHAR wpath[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH); + + if (SUCCEEDED(ppf->Load(wpath, STGM_READ))) + { + /* Resolve the link */ + if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH))) + { + strcpy(filepath, path); + + if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY))) + { + OutputDebugString(fd.cFileName); + + strcpy(out, filepath); + // FIX: Release the objects. Taken from SA. +#ifdef FIX_BUGS + ppf->Release(); + psl->Release(); +#endif + return true; + } + } + } + + ppf->Release(); + } + psl->Release(); + } + + return false; +#else + struct stat sb; + + if (lstat(path, &sb) == -1) { + perror("lstat: "); + return false; + } + + if (S_ISLNK(sb.st_mode)) { + char* linkname = (char*)alloca(sb.st_size + 1); + if (linkname == NULL) { + fprintf(stderr, "insufficient memory\n"); + return false; + } + + if (readlink(path, linkname, sb.st_size + 1) < 0) { + perror("readlink: "); + return false; + } + linkname[sb.st_size] = '\0'; + strcpy(out, linkname); + return true; + } else { + return false; + } +#endif +} + +static void +_FindMP3s(void) +{ + tMP3Entry *pList; + bool bShortcut; + bool bInitFirstEntry; + HANDLE hFind; + char path[MAX_PATH]; + char filepath[MAX_PATH*2]; + int total_ms; + WIN32_FIND_DATA fd; + + if (getcwd(_mp3DirectoryPath, MAX_PATH) == NULL) { + perror("getcwd: "); + return; + } + + OutputDebugString("Finding MP3s..."); + strcpy(path, _mp3DirectoryPath); + strcat(path, "\\MP3\\"); + + strcpy(_mp3DirectoryPath, path); + OutputDebugString(_mp3DirectoryPath); + + strcat(path, "*"); + + hFind = FindFirstFile(path, &fd); + + if ( hFind == INVALID_HANDLE_VALUE ) + { + return; + } + + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + size_t filepathlen = strlen(filepath); + + if ( filepathlen <= 0) + { + FindClose(hFind); + return; + } + + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + bShortcut = true; + } else + bShortcut = false; + + aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]); + + if (aStream[0] && aStream[0]->IsOpened()) + { + total_ms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL ) + { + FindClose(hFind); + return; + } + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + + _pMP3List->pNext = NULL; + + pList = _pMP3List; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char[MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + + OutputDebugString(filepath); + + bInitFirstEntry = true; + } + + while ( true ) + { + if ( !FindNextFile(hFind, &fd) ) + break; + + if ( bInitFirstEntry ) + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + size_t filepathlen = strlen(filepath); + + if ( filepathlen > 0 ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + bShortcut = true; + } else { + bShortcut = false; + if (filepathlen > MAX_PATH) { + continue; + } + } + aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]); + + if (aStream[0] && aStream[0]->IsOpened()) + { + total_ms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL) + break; + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + _pMP3List->pNext = NULL; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char [MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + + pList = _pMP3List; + + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + } + } + } + else + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + size_t filepathlen = strlen(filepath); + + if ( filepathlen > 0 ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + bShortcut = true; + } else + bShortcut = false; + + aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]); + + if (aStream[0] && aStream[0]->IsOpened()) + { + total_ms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + OutputDebugString(fd.cFileName); + + pList->pNext = new tMP3Entry; + + tMP3Entry *e = pList->pNext; + + if ( e == NULL ) + break; + + pList = pList->pNext; + + strcpy(e->aFilename, fd.cFileName); + e->nTrackLength = total_ms; + e->pNext = NULL; + + if ( bShortcut ) + { + e->pLinkPath = new char [MAX_PATH*2]; + strcpy(e->pLinkPath, filepath); + } + else + { + e->pLinkPath = NULL; + } + + nNumMP3s++; + + OutputDebugString(fd.cFileName); + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + } + } + } + } + + FindClose(hFind); +} + +static void +_DeleteMP3Entries(void) +{ + tMP3Entry *e = _pMP3List; + + while ( e != NULL ) + { + tMP3Entry *next = e->pNext; + + if ( next == NULL ) + next = NULL; + + if ( e->pLinkPath != NULL ) + { +#ifndef FIX_BUGS + delete e->pLinkPath; // BUG: should be delete [] +#else + delete[] e->pLinkPath; +#endif + e->pLinkPath = NULL; + } + + delete e; + + if ( next ) + e = next; + else + e = NULL; + + nNumMP3s--; + } + + + if ( nNumMP3s != 0 ) + { + OutputDebugString("Not all MP3 entries were deleted"); + nNumMP3s = 0; + } + + _pMP3List = NULL; +} + +static tMP3Entry * +_GetMP3EntryByIndex(uint32 idx) +{ + uint32 n = ( idx < nNumMP3s ) ? idx : 0; + + if ( _pMP3List != NULL ) + { + tMP3Entry *e = _pMP3List; + + for ( uint32 i = 0; i < n; i++ ) + e = e->pNext; + + return e; + + } + + return NULL; +} + +static inline bool +_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry) +{ + _CurMP3Index = 0; + + for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext ) + { + if ( *pPosition >= (*pEntry)->nTrackStreamPos + && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos ) + { + *pPosition -= (*pEntry)->nTrackStreamPos; + _CurMP3Pos = *pPosition; + + return true; + } + + _CurMP3Index++; + } + + *pPosition = 0; + *pEntry = _pMP3List; + _CurMP3Pos = 0; + _CurMP3Index = 0; + + return false; +} + bool cSampleManager::IsMP3RadioChannelAvailable(void) { @@ -599,21 +1014,45 @@ cSampleManager::Initialise(void) nChannelVolume[i] = 0; } - { - for ( int32 i = 0; i < MAX_STREAMS; i++ ) - { - aStream[i] = NULL; - nStreamVolume[i] = 100; - nStreamPan[i] = 63; - } - + { for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) nStreamLength[i] = 0; } - { add_providers(); - + +#ifdef AUDIO_CACHE + FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb"); + if (cacheFile) { + fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); + fclose(cacheFile); + } else +#endif + { + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + { + aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0]); + + if ( aStream[0] && aStream[0]->IsOpened() ) + { + uint32 tatalms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + nStreamLength[i] = tatalms; + } + else + USERERROR("Can't open '%s'\n", StreamedNameTable[i]); + } +#ifdef AUDIO_CACHE + cacheFile = fcaseopen("audio\\sound.cache", "wb"); + fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); + fclose(cacheFile); +#endif + } + + { if ( !InitialiseSampleBanks() ) { Terminate(); @@ -631,13 +1070,23 @@ cSampleManager::Initialise(void) nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (uintptr)malloc(PED_BLOCKSIZE*MAX_PEDSFX); ASSERT(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] != 0); + + LoadSampleBank(SFX_BANK_0); } + { + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + aStream[i] = NULL; + nStreamVolume[i] = 100; + nStreamPan[i] = 63; + } + } { _bSampmanInitialised = true; - if ( 0 >= defaultProvider && defaultProvider < m_nNumberOfProviders ) + if ( defaultProvider >= 0 && defaultProvider < m_nNumberOfProviders ) { set_new_provider(defaultProvider); } @@ -647,38 +1096,66 @@ cSampleManager::Initialise(void) return false; } } -#ifdef AUDIO_CACHE - FILE *cacheFile = fopen("audio\\sound.cache", "rb"); - if (cacheFile) { - fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); - fclose(cacheFile); - } else -#endif + { - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - { - aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0]); + nNumMP3s = 0; + + _pMP3List = NULL; + + _FindMP3s(); + + if ( nNumMP3s != 0 ) + { + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0; - if ( aStream[0] && aStream[0]->IsOpened() ) + for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext ) { - uint32 tatalms = aStream[0]->GetLengthMS(); - delete aStream[0]; - aStream[0] = NULL; - - nStreamLength[i] = tatalms; + e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER]; + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength; } + + time_t t = time(NULL); + tm *localtm; + bool bUseRandomTable; + + if ( t == -1 ) + bUseRandomTable = true; else - USERERROR("Can't open '%s'\n", StreamedNameTable[i]); + { + bUseRandomTable = false; + localtm = localtime(&t); + } + + int32 randval; + if ( bUseRandomTable ) + randval = AudioManager.GetRandomNumber(1); + else + randval = localtm->tm_sec * localtm->tm_min; + + _CurMP3Index = randval % nNumMP3s; + + tMP3Entry *randmp3 = _pMP3List; + for ( int32 i = randval % nNumMP3s; i > 0; --i) + randmp3 = randmp3->pNext; + + if ( bUseRandomTable ) + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + else + { + if ( localtm->tm_sec > 0 ) + { + int32 s = localtm->tm_sec; + _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength; + } + else + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + } } -#ifdef AUDIO_CACHE - cacheFile = fopen("audio\\sound.cache", "wb"); - fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); - fclose(cacheFile); -#endif - } + else + _CurMP3Pos = 0; - LoadSampleBank(SFX_BANK_0); + _bIsMp3Active = false; + } return true; } @@ -686,8 +1163,6 @@ cSampleManager::Initialise(void) void cSampleManager::Terminate(void) { - release_existing(); - for (int32 i = 0; i < MAX_STREAMS; i++) { CStream *stream = aStream[i]; @@ -698,6 +1173,10 @@ cSampleManager::Terminate(void) } } + release_existing(); + + _DeleteMP3Entries(); + CStream::Terminate(); if ( nSampleBankMemoryStartAddress[SFX_BANK_0] != 0 ) @@ -905,14 +1384,6 @@ cSampleManager::LoadPedComment(uint32 nComment) break; } - - case MUSICMODE_FRONTEND: - { - if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE) - return false; - - break; - } } } @@ -998,24 +1469,24 @@ bool cSampleManager::UpdateReverb(void) if ( AudioManager.GetFrameCounter() & 15 ) return false; - - float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM); - float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT); - float z = AudioManager.GetReflectionsDistance(REFLECTION_UP); - - float normy = norm(y, 5.0f, 40.0f); - float normx = norm(x, 5.0f, 40.0f); - float normz = norm(z, 5.0f, 40.0f); - - #define ZR(v, a, b) (((v)==0)?(a):(b)) - #define CALCRATIO(x,y,z,min,max,val) (ZR(y, ZR(x, ZR(z, min, max), min), ZR(x, ZR(z, min, max), ZR(z, min, val)))) - - float fRatio = CALCRATIO(normx, normy, normz, 0.3f, 0.5f, (normy+normx+normz)/3.0f); - - #undef CALCRATIO - #undef ZE + + float fRatio = 0.0f; + +#define MIN_DIST 0.5f +#define CALCULATE_RATIO(value, maxDist, maxRatio) (value > MIN_DIST && value < maxDist ? value / maxDist * maxRatio : 0) + + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_NORTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_SOUTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_WEST), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_EAST), 10.0f, 1/2.f); + + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_NORTH) + AudioManager.GetReflectionsDistance(REFLECTION_SOUTH)) / 2.f, 4.0f, 1/3.f); + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_WEST) + AudioManager.GetReflectionsDistance(REFLECTION_EAST)) / 2.f, 4.0f, 1/3.f); + +#undef CALCULATE_RATIO +#undef MIN_DIST - fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f); + fRatio = clamp(fRatio, 0.0f, 0.6f); if ( fRatio == _fPrevEaxRatioDestination ) return false; @@ -1026,6 +1497,7 @@ bool cSampleManager::UpdateReverb(void) if ( usingEAX3 ) #endif { + fRatio = Min(fRatio * 1.67f, 1.0f); if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) { EAX_SetAll(&EAX3Params); @@ -1040,16 +1512,17 @@ bool cSampleManager::UpdateReverb(void) } */ - _fEffectsLevel = 1.0f - fRatio * 0.5f; + _fEffectsLevel = fRatio * 0.75f; } } else { if ( _usingEFX ) - _fEffectsLevel = (1.0f - fRatio) * 0.4f; + _fEffectsLevel = fRatio * 0.8f; else - _fEffectsLevel = (1.0f - fRatio) * 0.7f; + _fEffectsLevel = fRatio * 0.22f; } + _fEffectsLevel = Min(_fEffectsLevel, 1.0f); _fPrevEaxRatioDestination = fRatio; @@ -1187,12 +1660,14 @@ cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) nChannelVolume[nChannel] = vol; - if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_FINALE ) - { - nChannelVolume[nChannel] = vol / 4; + // increase the volume for JB.MP3 and S4_BDBD.MP3 + if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) { + if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE) + nChannelVolume[nChannel] = 0; + else + nChannelVolume[nChannel] >>= 2; } - + aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); } } @@ -1260,7 +1735,7 @@ cSampleManager::StopChannel(uint32 nChannel) void cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream) { - char filename[256]; + char filename[MAX_PATH]; ASSERT( nStream < MAX_STREAMS ); @@ -1318,6 +1793,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream) bool cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) { + uint32 position = nPos; char filename[256]; ASSERT( nStream < MAX_STREAMS ); @@ -1330,6 +1806,135 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) aStream[nStream] = NULL; } + if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER ) + { + uint32 i = 0; + do { + if(i != 0 || _bIsMp3Active) { + if(++_CurMP3Index >= nNumMP3s) _CurMP3Index = 0; + + _CurMP3Pos = 0; + + tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); + + if(mp3) { + mp3 = _pMP3List; + if(mp3 == NULL) { + _bIsMp3Active = false; + nFile = 0; + strcat(filename, StreamedNameTable[nFile]); + + CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + ASSERT(stream != NULL); + + aStream[nStream] = stream; + + if (stream->IsOpened()) { + if (stream->Setup()) { + if (position != 0) + stream->SetPosMS(position); + + stream->Start(); + } + + return true; + } else { + delete stream; + aStream[nStream] = NULL; + } + + return false; + } + } + + if (mp3->pLinkPath != NULL) + aStream[nStream] = new CStream(mp3->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]); + else { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, mp3->aFilename); + + aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + } + + if (aStream[nStream]->IsOpened()) { + if (aStream[nStream]->Setup()) { + aStream[nStream]->Start(); + } + + return true; + } else { + delete aStream[nStream]; + aStream[nStream] = NULL; + } + + _bIsMp3Active = false; + continue; + } + if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] ) + position = 0; + + tMP3Entry *e; + if ( !_GetMP3PosFromStreamPos(&position, &e) ) + { + if ( e == NULL ) + { + nFile = 0; + strcat(filename, StreamedNameTable[nFile]); + CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + ASSERT(stream != NULL); + + aStream[nStream] = stream; + + if (stream->IsOpened()) { + if (stream->Setup()) { + if (position != 0) + stream->SetPosMS(position); + + stream->Start(); + } + + return true; + } else { + delete stream; + aStream[nStream] = NULL; + } + + return false; + } + } + + if (e->pLinkPath != NULL) + aStream[nStream] = new CStream(e->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]); + else { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, e->aFilename); + + aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + } + + if (aStream[nStream]->IsOpened()) { + if (aStream[nStream]->Setup()) { + if (position != 0) + aStream[nStream]->SetPosMS(position); + + aStream[nStream]->Start(); + } + + _bIsMp3Active = true; + return true; + } else { + delete aStream[nStream]; + aStream[nStream] = NULL; + } + + _bIsMp3Active = false; + + } while(++i < nNumMP3s); + + position = 0; + nFile = 0; + } + strcpy(filename, StreamedNameTable[nFile]); CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); @@ -1337,21 +1942,16 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) aStream[nStream] = stream; - if ( stream->IsOpened() ) - { - nStreamLength[nFile] = stream->GetLengthMS(); - if ( stream->Setup() ) - { - if ( nPos != 0 ) - stream->SetPosMS(nPos); - + if ( stream->IsOpened() ) { + if ( stream->Setup() ) { + if (position != 0) + stream->SetPosMS(position); + stream->Start(); } return true; - } - else - { + } else { delete stream; aStream[nStream] = NULL; } @@ -1394,11 +1994,16 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect { ASSERT( nStream < MAX_STREAMS ); + float boostMult = 0.0f; + if ( nVolume > MAX_VOLUME ) nVolume = MAX_VOLUME; if ( nPan > MAX_VOLUME ) nPan = MAX_VOLUME; + + if ( MusicManager.GetRadioInCar() == USERTRACK && !MusicManager.CheckForMusicInterruptions() ) + boostMult = m_nMP3BoostVolume / 64.f; nStreamVolume[nStream] = nVolume; nStreamPan [nStream] = nPan; @@ -1408,13 +2013,13 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect if ( stream ) { if ( nEffectFlag ) { - if ( nStream == 1 ) // TODO(MIAMI): || nStream == 2 when we have second mission channel? + if ( nStream == 1 || nStream == 2 ) stream->SetVolume(128*nVolume*m_nEffectsVolume >> 14); else stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14); } else - stream->SetVolume(m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14); + stream->SetVolume((m_nMusicFadeVolume*nVolume*(uint32)(m_nMusicVolume * boostMult + m_nMusicVolume)) >> 14); stream->SetPan(nPan); } @@ -1511,8 +2116,7 @@ cSampleManager::InitialiseSampleBanks(void) void cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel) { - if (m_bInitialised) - nStreamLoopedFlag[nChannel] = nLoopFlag; + nStreamLoopedFlag[nChannel] = nLoopFlag; } #endif diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h index bc5d3ba9..973a1585 100644 --- a/src/audio/soundlist.h +++ b/src/audio/soundlist.h @@ -142,7 +142,7 @@ enum eSound : uint16 SOUND_PED_TAXI_WAIT, SOUND_PED_ATTACK, SOUND_PED_DEFEND, - SOUND_140, + SOUND_PED_HEALING, SOUND_PED_LEAVE_VEHICLE, SOUND_PED_EVADE, SOUND_PED_FLEE_RUN, @@ -212,123 +212,63 @@ enum eSound : uint16 enum eScriptSounds : uint16 { - SCRIPT_SOUND_0 = 0, - SCRIPT_SOUND_1, - SCRIPT_SOUND_2, - SCRIPT_SOUND_3, - SCRIPT_SOUND_PARTY_1_LOOP_S, - SCRIPT_SOUND_PARTY_1_LOOP_L, - SCRIPT_SOUND_PARTY_2_LOOP_S, - SCRIPT_SOUND_PARTY_2_LOOP_L, - SCRIPT_SOUND_PARTY_3_LOOP_S, - SCRIPT_SOUND_PARTY_3_LOOP_L, - SCRIPT_SOUND_PARTY_4_LOOP_S, - SCRIPT_SOUND_PARTY_4_LOOP_L, - SCRIPT_SOUND_PARTY_5_LOOP_S, - SCRIPT_SOUND_PARTY_5_LOOP_L, - SCRIPT_SOUND_PARTY_6_LOOP_S, - SCRIPT_SOUND_PARTY_6_LOOP_L, - SCRIPT_SOUND_PARTY_7_LOOP_S, - SCRIPT_SOUND_PARTY_7_LOOP_L, - SCRIPT_SOUND_PARTY_8_LOOP_S, - SCRIPT_SOUND_PARTY_8_LOOP_L, - SCRIPT_SOUND_PARTY_9_LOOP_S, - SCRIPT_SOUND_PARTY_9_LOOP_L, - SCRIPT_SOUND_PARTY_10_LOOP_S, - SCRIPT_SOUND_PARTY_10_LOOP_L, - SCRIPT_SOUND_PARTY_11_LOOP_S, - SCRIPT_SOUND_PARTY_11_LOOP_L, - SCRIPT_SOUND_PARTY_12_LOOP_S, - SCRIPT_SOUND_PARTY_12_LOOP_L, - SCRIPT_SOUND_PARTY_13_LOOP_S, - SCRIPT_SOUND_PARTY_13_LOOP_L, - SCRIPT_SOUND_STRIP_CLUB_LOOP_1_S, - SCRIPT_SOUND_STRIP_CLUB_LOOP_1_L, - SCRIPT_SOUND_STRIP_CLUB_LOOP_2_S, - SCRIPT_SOUND_STRIP_CLUB_LOOP_2_L, - SCRIPT_SOUND_WORK_SHOP_LOOP_S, - SCRIPT_SOUND_WORK_SHOP_LOOP_L, - SCRIPT_SOUND_SAWMILL_LOOP_S, - SCRIPT_SOUND_SAWMILL_LOOP_L, - SCRIPT_SOUND_38, - SCRIPT_SOUND_39, - - // 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, - SCRIPT_SOUND_MARCO_BISTRO_L, - SCRIPT_SOUND_AIRPORT_LOOP_S, - SCRIPT_SOUND_AIRPORT_LOOP_L, - SCRIPT_SOUND_SHOP_LOOP_S, - SCRIPT_SOUND_SHOP_LOOP_L, - SCRIPT_SOUND_CINEMA_LOOP_S, - SCRIPT_SOUND_CINEMA_LOOP_L, - SCRIPT_SOUND_DOCKS_LOOP_S, - SCRIPT_SOUND_DOCKS_LOOP_L, - SCRIPT_SOUND_HOME_LOOP_S, - SCRIPT_SOUND_HOME_LOOP_L, - SCRIPT_SOUND_FRANKIE_PIANO, - SCRIPT_SOUND_PARTY_1_LOOP, - SCRIPT_SOUND_PORN_CINEMA_1_S, - SCRIPT_SOUND_PORN_CINEMA_1_L, - SCRIPT_SOUND_PORN_CINEMA_2_S, - SCRIPT_SOUND_PORN_CINEMA_2_L, - SCRIPT_SOUND_PORN_CINEMA_3_S, - SCRIPT_SOUND_PORN_CINEMA_3_L, - SCRIPT_SOUND_BANK_ALARM_LOOP_S, - SCRIPT_SOUND_BANK_ALARM_LOOP_L, - SCRIPT_SOUND_POLICE_BALL_LOOP_S, - SCRIPT_SOUND_POLICE_BALL_LOOP_L, - SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_S, - SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_L, - SCRIPT_SOUND_74, - SCRIPT_SOUND_75, - SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S, - SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L, - SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S, - SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L, - SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_S, - SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_L, - SCRIPT_SOUND_EVIDENCE_PICKUP, - SCRIPT_SOUND_UNLOAD_GOLD, - SCRIPT_SOUND_RAVE_1_LOOP_S, - SCRIPT_SOUND_RAVE_1_LOOP_L, - SCRIPT_SOUND_RAVE_2_LOOP_S, - SCRIPT_SOUND_RAVE_2_LOOP_L, - SCRIPT_SOUND_RAVE_3_LOOP_S, - SCRIPT_SOUND_RAVE_3_LOOP_L, - SCRIPT_SOUND_MISTY_SEX_S, - SCRIPT_SOUND_MISTY_SEX_L, - SCRIPT_SOUND_GATE_START_CLUNK, - SCRIPT_SOUND_GATE_STOP_CLUNK, + SCRIPT_SOUND_BANK_ALARM_LOOP = 0, SCRIPT_SOUND_PART_MISSION_COMPLETE, - SCRIPT_SOUND_CHUNKY_RUN_SHOUT, - SCRIPT_SOUND_SECURITY_GUARD_AWAY_SHOUT, + SCRIPT_SOUND_POLICE_CELL_DOOR_SLIDING_LOOP, + SCRIPT_SOUND_POLICE_CELL_DOOR_CLUNK, + SCRIPT_SOUND_GARAGE_DOOR_SLIDING_LOOP, + SCRIPT_SOUND_GARAGE_DOOR_CLUNK, + SCRIPT_SOUND_SNORING_LOOP, SCRIPT_SOUND_RACE_START_3, SCRIPT_SOUND_RACE_START_2, SCRIPT_SOUND_RACE_START_1, SCRIPT_SOUND_RACE_START_GO, - SCRIPT_SOUND_SWAT_PED_SHOUT, - SCRIPT_SOUND_PRETEND_FIRE_LOOP, - SCRIPT_SOUND_AMMUNATION_CHAT_1, - SCRIPT_SOUND_AMMUNATION_CHAT_2, - SCRIPT_SOUND_AMMUNATION_CHAT_3, + SCRIPT_SOUND_SHOOTING_RANGE_TARGET_MOVING_LOOP, + SCRIPT_SOUND_SHOOTING_RANGE_TARGET_HIT, + SCRIPT_SOUND_AMMUNATION_BUY_WEAPON, + SCRIPT_SOUND_AMMUNATION_BUY_WEAPON_DENIED, + SCRIPT_SOUND_WMYCW_TICKET_SPEECH, + SCRIPT_SOUND_IMRAN_ARM_BOMB, + SCRIPT_SOUND_ANDY_SNIPER_SHOT, + SCRIPT_SOUND_WILLIE_CARD_SWIPE, + SCRIPT_SOUND_MALE_AMBULANCE_OUCH, + SCRIPT_SOUND_FEMALE_AMBULANCE_OUCH, + SCRIPT_SOUND_BUILDING_BAR_1, + SCRIPT_SOUND_BUILDING_BAR_2, + SCRIPT_SOUND_BUILDING_BAR_3, + SCRIPT_SOUND_BUILDING_BAR_4, + SCRIPT_SOUND_BUILDING_BIKER_BAR, + SCRIPT_SOUND_BUILDING_CHURCH, + SCRIPT_SOUND_BUILDING_CLUB, + SCRIPT_SOUND_BUILDING_CUBA_1, + SCRIPT_SOUND_BUILDING_CUBA_2, + SCRIPT_SOUND_BUILDING_VOODOO, + SCRIPT_SOUND_BUILDING_MUSIC_SHOP, + SCRIPT_SOUND_BUILDING_STRIPCLUB_1, + SCRIPT_SOUND_BUILDING_STRIPCLUB_2, + SCRIPT_SOUND_BUILDING_SUPERSWEEP, + SCRIPT_SOUND_SEAPLANE_LOW_FUEL, + SCRIPT_SOUND_NEW_BUILDING_BAR_1, + SCRIPT_SOUND_NEW_BUILDING_BAR_2, + SCRIPT_SOUND_NEW_BUILDING_BAR_3, + SCRIPT_SOUND_NEW_BUILDING_BAR_4, + SCRIPT_SOUND_NEW_BUILDING_MALIBU_1, + SCRIPT_SOUND_NEW_BUILDING_MALIBU_2, + SCRIPT_SOUND_NEW_BUILDING_MALIBU_3, + SCRIPT_SOUND_NEW_BUILDING_STRIP_1, + SCRIPT_SOUND_NEW_BUILDING_STRIP_2, + SCRIPT_SOUND_NEW_BUILDING_STRIP_3, + SCRIPT_SOUND_NEW_BUILDING_CHURCH, + SCRIPT_SOUND_NEW_BUILDING_FAN_1, + SCRIPT_SOUND_NEW_BUILDING_FAN_2, + SCRIPT_SOUND_NEW_BUILDING_INSECT_1, + SCRIPT_SOUND_NEW_BUILDING_INSECT_2, + SCRIPT_SOUND_NEW_WATERFALL, SCRIPT_SOUND_BULLET_HIT_GROUND_1, SCRIPT_SOUND_BULLET_HIT_GROUND_2, SCRIPT_SOUND_BULLET_HIT_GROUND_3, SCRIPT_SOUND_BULLET_HIT_WATER, // no sound - SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_1, - SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_2, SCRIPT_SOUND_PAYPHONE_RINGING, - SCRIPT_SOUND_113, SCRIPT_SOUND_GLASS_BREAK_L, SCRIPT_SOUND_GLASS_BREAK_S, SCRIPT_SOUND_GLASS_CRACK, @@ -337,6 +277,7 @@ enum eScriptSounds : uint16 { SCRIPT_SOUND_BOX_DESTROYED_2, SCRIPT_SOUND_METAL_COLLISION, SCRIPT_SOUND_TIRE_COLLISION, + SCRIPT_SOUND_HIT_BALL, SCRIPT_SOUND_GUNSHELL_DROP, SCRIPT_SOUND_GUNSHELL_DROP_SOFT, SCRIPT_SOUND_TOTAL, diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp index da661b8c..1b14e3d7 100644 --- a/src/control/AutoPilot.cpp +++ b/src/control/AutoPilot.cpp @@ -6,7 +6,8 @@ #include "Curves.h" #include "PathFind.h" -//--MIAMI: done +//--MIAMI: file done + void CAutoPilot::ModifySpeed(float speed) { m_fMaxTrafficSpeed = Max(0.01f, speed); @@ -40,7 +41,6 @@ void CAutoPilot::ModifySpeed(float speed) #endif } -//--MIAMI: done void CAutoPilot::RemoveOnePathNode() { --m_nPathFindNodesCount; @@ -49,7 +49,6 @@ void CAutoPilot::RemoveOnePathNode() } #ifdef COMPATIBLE_SAVES -//--MIAMI: TODO void CAutoPilot::Save(uint8*& buf) { WriteSaveBuf<int32>(buf, m_nCurrentRouteNode); @@ -73,6 +72,9 @@ void CAutoPilot::Save(uint8*& buf) WriteSaveBuf<uint32>(buf, m_nTimeTempAction); WriteSaveBuf<float>(buf, m_fMaxTrafficSpeed); WriteSaveBuf<uint8>(buf, m_nCruiseSpeed); + WriteSaveBuf<uint8>(buf, m_nCruiseSpeedMultiplierType); + SkipSaveBuf(buf, 2); + WriteSaveBuf<float>(buf, m_fCruiseSpeedMultiplier); uint8 flags = 0; if (m_bSlowedDownBecauseOfCars) flags |= BIT(0); if (m_bSlowedDownBecauseOfPeds) flags |= BIT(1); @@ -80,6 +82,7 @@ void CAutoPilot::Save(uint8*& buf) if (m_bStayInFastLane) flags |= BIT(3); if (m_bIgnorePathfinding) flags |= BIT(4); WriteSaveBuf<uint8>(buf, flags); + WriteSaveBuf<uint8>(buf, m_nSwitchDistance); SkipSaveBuf(buf, 2); WriteSaveBuf<float>(buf, m_vecDestinationCoors.x); WriteSaveBuf<float>(buf, m_vecDestinationCoors.y); @@ -89,7 +92,6 @@ void CAutoPilot::Save(uint8*& buf) SkipSaveBuf(buf, 6); } -//--MIAMI: TODO void CAutoPilot::Load(uint8*& buf) { m_nCurrentRouteNode = ReadSaveBuf<int32>(buf); @@ -113,12 +115,16 @@ void CAutoPilot::Load(uint8*& buf) m_nTimeTempAction = ReadSaveBuf<uint32>(buf); m_fMaxTrafficSpeed = ReadSaveBuf<float>(buf); m_nCruiseSpeed = ReadSaveBuf<uint8>(buf); + m_nCruiseSpeedMultiplierType = ReadSaveBuf<uint8>(buf); + SkipSaveBuf(buf, 2); + m_fCruiseSpeedMultiplier = ReadSaveBuf<float>(buf); uint8 flags = ReadSaveBuf<uint8>(buf); m_bSlowedDownBecauseOfCars = !!(flags & BIT(0)); m_bSlowedDownBecauseOfPeds = !!(flags & BIT(1)); m_bStayInCurrentLevel = !!(flags & BIT(2)); m_bStayInFastLane = !!(flags & BIT(3)); m_bIgnorePathfinding = !!(flags & BIT(4)); + m_nSwitchDistance = ReadSaveBuf<uint8>(buf); SkipSaveBuf(buf, 2); m_vecDestinationCoors.x = ReadSaveBuf<float>(buf); m_vecDestinationCoors.y = ReadSaveBuf<float>(buf); diff --git a/src/control/Bridge.cpp b/src/control/Bridge.cpp index 1e63cf30..1a1c03bd 100644 --- a/src/control/Bridge.cpp +++ b/src/control/Bridge.cpp @@ -6,6 +6,8 @@ #include "PathFind.h" #include "Stats.h" +//--MIAMI: file done + CEntity *CBridge::pLiftRoad; CEntity *CBridge::pLiftPart; CEntity *CBridge::pWeight; diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 93098d6d..db7d7b66 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -292,7 +292,7 @@ CCarCtrl::GenerateOneRandomCar() break; } } - if (!ThePaths.NewGenerateCarCreationCoors(vecTargetPos.x, vecTargetPos.y, frontX, frontY, + if (!ThePaths.GenerateCarCreationCoors(vecTargetPos.x, vecTargetPos.y, frontX, frontY, preferredDistance, angleLimit, invertAngleLimitTest, &spawnPosition, &curNodeId, &nextNodeId, &positionBetweenNodes, carClass == COPS && pWanted->m_nWantedLevel >= 1)) return; @@ -3228,7 +3228,7 @@ bool CCarCtrl::GenerateOneEmergencyServicesCar(uint32 mi, CVector vecPos) int curNode, nextNode; float posBetweenNodes; while (!created && attempts < 5){ - if (ThePaths.NewGenerateCarCreationCoors(pPlayerPos.x, pPlayerPos.y, 0.707f, 0.707f, + if (ThePaths.GenerateCarCreationCoors(pPlayerPos.x, pPlayerPos.y, 0.707f, 0.707f, 120.0f, -1.0f, true, &spawnPos, &curNode, &nextNode, &posBetweenNodes, false)){ int16 colliding[2]; if (!ThePaths.GetNode(curNode)->bWaterPath) { diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index 1191e8ad..e44cdda9 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -7,6 +7,7 @@ #include "Timer.h" #include "DMAudio.h" #include "Population.h" +#include "Replay.h" #include "Weapon.h" #include "World.h" #include "Stats.h" @@ -14,9 +15,8 @@ #include "Text.h" #include "Vehicle.h" #include "GameLogic.h" -#ifdef FIX_BUGS -#include "Replay.h" -#endif + +//--MIAMI: file done except TODO #define FRENZY_ANY_PED -1 #define FRENZY_ANY_CAR -2 @@ -27,7 +27,8 @@ int32 CDarkel::TimeOfFrenzyStart; int32 CDarkel::WeaponType; int32 CDarkel::AmmoInterruptedWeapon; int32 CDarkel::KillsNeeded; -int8 CDarkel::InterruptedWeapon; +int32 CDarkel::InterruptedWeaponType; +int32 CDarkel::InterruptedWeaponSelected; /* * TODO: Collect timer/kill counter RGBA colors on top like in Hud/Frontend. @@ -61,14 +62,12 @@ CDarkel::CalcFade(uint32 time, uint32 start, uint32 end) return 0; } -// Screen positions taken from VC void CDarkel::DrawMessages() { -#ifdef FIX_BUGS if (CReplay::IsPlayingBack()) return; -#endif + switch (Status) { case KILLFRENZY_ONGOING: { @@ -77,8 +76,8 @@ CDarkel::DrawMessages() CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(30.0f)); CFont::SetCentreOn(); CFont::SetPropOn(); - uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart; - if (CDarkel::bStandardSoundAndMessages) { + uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart; + if (bStandardSoundAndMessages) { if (timePassedSinceStart >= 3000 && timePassedSinceStart < 11000) { CFont::SetScale(SCREEN_SCALE_X(1.3f), SCREEN_SCALE_Y(1.3f)); CFont::SetJustifyOff(); @@ -103,8 +102,8 @@ CDarkel::DrawMessages() CFont::SetCentreOff(); CFont::SetRightJustifyOn(); CFont::SetFontStyle(FONT_HEADING); - if (CDarkel::TimeLimit >= 0) { - uint32 timeLeft = CDarkel::TimeLimit - (CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart); + if (TimeLimit >= 0) { + uint32 timeLeft = TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart); sprintf(gString, "%d:%02d", timeLeft / 60000, timeLeft % 60000 / 1000); AsciiToUnicode(gString, gUString); if (timeLeft > 4000 || CTimer::GetFrameCounter() & 1) { @@ -114,7 +113,7 @@ CDarkel::DrawMessages() CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f), SCREEN_SCALE_Y(108.0f), gUString); } } - sprintf(gString, "%d", (CDarkel::KillsNeeded >= 0 ? CDarkel::KillsNeeded : 0)); + sprintf(gString, "%d", (KillsNeeded >= 0 ? KillsNeeded : 0)); AsciiToUnicode(gString, gUString); CFont::SetColor(CRGBA(0, 0, 0, 255)); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(144.0f), gUString); @@ -124,9 +123,9 @@ CDarkel::DrawMessages() } case KILLFRENZY_PASSED: { - if (CDarkel::bStandardSoundAndMessages) { - uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart; - if (CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart < 5000) { + if (bStandardSoundAndMessages) { + uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart; + if (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart < 5000) { CFont::SetBackgroundOff(); CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(20.0f)); CFont::SetCentreOn(); @@ -186,7 +185,20 @@ CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle) } } RegisteredKills[vehicle->GetModelIndex()]++; - CStats::CarsExploded++; + switch (vehicle->GetVehicleAppearance()) { + case VEHICLE_APPEARANCE_CAR: + case VEHICLE_APPEARANCE_BIKE: + CStats::CarsExploded++;; + break; + case VEHICLE_APPEARANCE_HELI: + case VEHICLE_APPEARANCE_PLANE: + CStats::HelisDestroyed++; + break; + case VEHICLE_APPEARANCE_BOAT: + CStats::BoatsExploded++; + break; + } + } void @@ -245,23 +257,7 @@ CDarkel::ResetOnPlayerDeath() Status = KILLFRENZY_FAILED; TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); - eWeaponType fixedWeapon; - if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - fixedWeapon = WEAPONTYPE_UZI; - else - fixedWeapon = (eWeaponType)WeaponType; - - CPlayerPed *player = FindPlayerPed(); - if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { - player->m_nSelectedWepSlot = InterruptedWeapon; - player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon; - } - - if (FindPlayerVehicle()) { - player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId); - player->m_currentWeapon = player->m_nSelectedWepSlot; - player->MakeChangesForNewWeapon(player->m_currentWeapon); - } + DealWithWeaponChangeAtEndOfFrenzy(); } void @@ -298,16 +294,19 @@ CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 mode CPlayerPed *player = FindPlayerPed(); if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { - InterruptedWeapon = player->m_currentWeapon; - player->GiveWeapon(fixedWeapon, 0); + InterruptedWeaponSelected = player->GetWeapon()->m_eWeaponType; + player->RemoveWeaponAnims(InterruptedWeaponSelected, -1000.0f); + InterruptedWeaponType = player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_eWeaponType; AmmoInterruptedWeapon = player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal; + if (InterruptedWeaponType) + CModelInfo::GetModelInfo(CWeaponInfo::GetWeaponInfo((eWeaponType)InterruptedWeaponType)->m_nModelId)->AddRef(); player->GiveWeapon(fixedWeapon, 30000); - player->m_nSelectedWepSlot = player->GetWeaponSlot(fixedWeapon); + player->SetCurrentWeapon(fixedWeapon); player->MakeChangesForNewWeapon(player->m_nSelectedWepSlot); if (FindPlayerVehicle()) { - player->m_currentWeapon = player->m_nSelectedWepSlot; - player->GetWeapon()->m_nAmmoInClip = Min(player->GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition); + player->SetCurrentWeapon(FindPlayerPed()->m_nSelectedWepSlot); + player->SetAmmo(fixedWeapon, Min(player->GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition)); player->ClearWeaponTarget(); } } @@ -343,24 +342,7 @@ CDarkel::Update() CPopulation::m_AllRandomPedsThisType = -1; Status = KILLFRENZY_FAILED; TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); - - eWeaponType fixedWeapon; - if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - fixedWeapon = WEAPONTYPE_UZI; - else - fixedWeapon = (eWeaponType)WeaponType; - - CPlayerPed *player = FindPlayerPed(); - if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { - player->m_nSelectedWepSlot = InterruptedWeapon; - player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon; - } - - if (FindPlayerVehicle()) { - player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId); - player->m_currentWeapon = player->m_nSelectedWepSlot; - player->MakeChangesForNewWeapon(player->m_currentWeapon); - } + DealWithWeaponChangeAtEndOfFrenzy(); if (bStandardSoundAndMessages) DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_FAILED, 0); @@ -377,25 +359,50 @@ CDarkel::Update() FindPlayerPed()->m_pWanted->SetWantedLevel(0); - eWeaponType fixedWeapon; - if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - fixedWeapon = WEAPONTYPE_UZI; - else - fixedWeapon = (eWeaponType)WeaponType; - - CPlayerPed* player = FindPlayerPed(); - if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { - player->m_nSelectedWepSlot = InterruptedWeapon; - player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon; - } - - if (FindPlayerVehicle()) { - player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId); - player->m_currentWeapon = player->m_nSelectedWepSlot; - player->MakeChangesForNewWeapon(player->m_currentWeapon); - } + DealWithWeaponChangeAtEndOfFrenzy(); if (bStandardSoundAndMessages) DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0); } } + +void +CDarkel::DealWithWeaponChangeAtEndOfFrenzy() +{ + eWeaponType fixedWeapon; + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + fixedWeapon = WEAPONTYPE_UZI; + else + fixedWeapon = (eWeaponType)WeaponType; + + if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS && InterruptedWeaponType) + CModelInfo::GetModelInfo(CWeaponInfo::GetWeaponInfo((eWeaponType)InterruptedWeaponType)->m_nModelId)->RemoveRef(); + + if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { + int slot = CWeaponInfo::GetWeaponInfo(fixedWeapon)->m_nWeaponSlot; + FindPlayerPed()->RemoveWeaponModel(FindPlayerPed()->GetWeapon(slot).GetInfo()->m_nModelId); + FindPlayerPed()->GetWeapon(slot).m_eWeaponType = WEAPONTYPE_UNARMED; + FindPlayerPed()->GetWeapon(slot).m_nAmmoTotal = 0; + FindPlayerPed()->GetWeapon(slot).m_nAmmoInClip = 0; + FindPlayerPed()->GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY; + FindPlayerPed()->RemoveWeaponAnims(fixedWeapon, -1000.0f); + CModelInfo::GetModelInfo(CWeaponInfo::GetWeaponInfo(fixedWeapon)->m_nModelId)->RemoveRef(); + } + + CPlayerPed* player = FindPlayerPed(); + if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { + player->m_nSelectedWepSlot = CWeaponInfo::GetWeaponInfo((eWeaponType)InterruptedWeaponSelected)->m_nWeaponSlot; + player->GiveWeapon((eWeaponType)InterruptedWeaponType, AmmoInterruptedWeapon, true); + } + + if (FindPlayerVehicle()) { + player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId); + if (FindPlayerPed()->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType) + FindPlayerPed()->m_nSelectedWepSlot = WEAPONSLOT_SUBMACHINEGUN; + else + FindPlayerPed()->m_nSelectedWepSlot = WEAPONSLOT_UNARMED; + player->SetCurrentWeapon(FindPlayerPed()->m_nSelectedWepSlot); + player->MakeChangesForNewWeapon(player->m_currentWeapon); + //player->RemoveDriveByAnims(); // TODO(MIAMI) + } +} diff --git a/src/control/Darkel.h b/src/control/Darkel.h index 0f5c2329..91955479 100644 --- a/src/control/Darkel.h +++ b/src/control/Darkel.h @@ -23,7 +23,8 @@ private: static int32 WeaponType; static int32 AmmoInterruptedWeapon; static int32 KillsNeeded; - static int8 InterruptedWeapon; + static int32 InterruptedWeaponType; + static int32 InterruptedWeaponSelected; static bool bStandardSoundAndMessages; static bool bNeedHeadShot; static bool bProperKillFrenzy; @@ -49,5 +50,6 @@ public: static void ResetOnPlayerDeath(); static void StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot); static void Update(); + static void DealWithWeaponChangeAtEndOfFrenzy(); }; diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp index 573720be..98209c85 100644 --- a/src/control/GameLogic.cpp +++ b/src/control/GameLogic.cpp @@ -45,9 +45,10 @@ CVector CGameLogic::ShortCutDropOffForMission; float CGameLogic::ShortCutDropOffOrientationForMission; bool CGameLogic::MissionDropOffReadyToBeUsed; -//--MIAMI: file done except TODO +//--MIAMI: file done #define SHORTCUT_TAXI_COST (9) +#define TOTAL_BUSTED_AUDIO (28) void CGameLogic::InitAtStartOfGame() @@ -196,7 +197,7 @@ CGameLogic::Update() sprintf(name, pPlayerInfo.m_nCurrentBustedAudio >= 10 ? "bust_%d" : "bust_0%d", pPlayerInfo.m_nCurrentBustedAudio); DMAudio.ClearMissionAudio(0); DMAudio.PreloadMissionAudio(0, name); - pPlayerInfo.m_nCurrentBustedAudio = pPlayerInfo.m_nCurrentBustedAudio % 28 + 1; // enum? const? TODO + pPlayerInfo.m_nCurrentBustedAudio = pPlayerInfo.m_nCurrentBustedAudio % TOTAL_BUSTED_AUDIO + 1; } } if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 4000 && diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index dc07d142..44a961c9 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -26,6 +26,8 @@ #include "Wanted.h" #include "World.h" +//--MIAMI: file done + #define CRUSHER_GARAGE_X1 (1135.5f) #define CRUSHER_GARAGE_Y1 (57.0f) #define CRUSHER_GARAGE_Z1 (-1.0f) @@ -236,7 +238,6 @@ int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X pGarage->m_nTimeToStartAction = 0; pGarage->field_2 = false; pGarage->m_nTargetModelIndex = targetId; - pGarage->field_96 = nil; pGarage->m_bCollectedCarsState = 0; pGarage->m_bDeactivated = false; pGarage->m_bResprayHappened = false; @@ -2141,11 +2142,11 @@ void CGarages::SetAllDoorsBackToOriginalHeight() } } -// TODO(MIAMI) void CGarages::Save(uint8 * buf, uint32 * size) { -INITSAVEBUF - *size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)); +//INITSAVEBUF + *size = 7876; // for some reason it's not actual size again + //*size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)); CloseHideOutGaragesBeforeSave(); WriteSaveBuf(buf, NumGarages); WriteSaveBuf(buf, (uint32)BombsAreFree); @@ -2163,7 +2164,7 @@ INITSAVEBUF } for (int i = 0; i < NUM_GARAGES; i++) WriteSaveBuf(buf, aGarages[i]); -VALIDATESAVEBUF(*size); +//VALIDATESAVEBUF(*size); } const CStoredCar &CStoredCar::operator=(const CStoredCar & other) @@ -2185,11 +2186,11 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other) return *this; } -//TODO(MIAMI) void CGarages::Load(uint8* buf, uint32 size) { -INITSAVEBUF - assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage))); +//INITSAVEBUF + assert(size = 7876); + //assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage))); CloseHideOutGaragesBeforeSave(); NumGarages = ReadSaveBuf<uint32>(buf); BombsAreFree = ReadSaveBuf<uint32>(buf); @@ -2210,7 +2211,6 @@ INITSAVEBUF aGarages[i].m_pDoor1 = nil; aGarages[i].m_pDoor2 = nil; aGarages[i].m_pTarget = nil; - aGarages[i].field_96 = nil; aGarages[i].m_bRecreateDoorOnNextRefresh = true; aGarages[i].RefreshDoorPointers(true); if (aGarages[i].m_eGarageType == GARAGE_CRUSHER) @@ -2218,7 +2218,7 @@ INITSAVEBUF else aGarages[i].UpdateDoorsHeight(); } -VALIDATESAVEBUF(size); +//VALIDATESAVEBUF(size); MessageEndTime = 0; bCamShouldBeOutisde = false; diff --git a/src/control/Garages.h b/src/control/Garages.h index 43f40261..04c01719 100644 --- a/src/control/Garages.h +++ b/src/control/Garages.h @@ -132,7 +132,6 @@ class CGarage uint32 m_nTimeToStartAction; uint8 m_bCollectedCarsState; CVehicle *m_pTarget; - void* field_96; // unused CStoredCar m_sStoredCar; // not needed void OpenThisGarage(); diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp index e85893e6..41dc735f 100644 --- a/src/control/PathFind.cpp +++ b/src/control/PathFind.cpp @@ -8,6 +8,8 @@ #include "Lines.h" // for debug #include "PathFind.h" +//--MIAMI: file done except mobile unused function + bool gbShowPedPaths; bool gbShowCarPaths; bool gbShowCarPathsLinks; @@ -226,7 +228,6 @@ CPedPath::AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *p } } -//--MIAMI: done // Make sure all externals link TO an internal void CPathInfoForObject::SwapConnectionsToBeRightWayRound(void) @@ -246,7 +247,6 @@ CPathInfoForObject::SwapConnectionsToBeRightWayRound(void) } } -//--MIAMI: done void CPathFind::Init(void) { @@ -263,7 +263,6 @@ CPathFind::Init(void) m_pathNodes[i].distance = MAX_DIST; } -//--MIAMI: done void CPathFind::AllocatePathFindInfoMem(int16 numPathGroups) { @@ -294,14 +293,12 @@ CPathFind::AllocatePathFindInfoMem(int16 numPathGroups) NumDetachedCarNodeGroups = 0; } -//--MIAMI: done void CPathFind::RegisterMapObject(CTreadable *mapObject) { m_mapObjects[m_numMapObjects++] = mapObject; } -//--MIAMI: done void CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, bool crossing, uint8 spawnRate) { @@ -329,7 +326,6 @@ CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, InfoForTilePeds[id*12].SwapConnectionsToBeRightWayRound(); } -//--MIAMI: done void CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, int8 numLeft, int8 numRight, bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate) @@ -358,7 +354,6 @@ CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, InfoForTileCars[id*12].SwapConnectionsToBeRightWayRound(); } -//--MIAMI: done void CPathFind::StoreDetachedNodeInfoPed(int32 node, int8 type, int32 next, float x, float y, float z, float width, bool crossing, bool disabled, bool betweenLevels, uint8 spawnRate) @@ -392,7 +387,6 @@ CPathFind::StoreDetachedNodeInfoPed(int32 node, int8 type, int32 next, float x, } } -//--MIAMI: done void CPathFind::StoreDetachedNodeInfoCar(int32 node, int8 type, int32 next, float x, float y, float z, float width, int8 numLeft, int8 numRight, bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate, bool onlySmallBoats) @@ -426,7 +420,6 @@ CPathFind::StoreDetachedNodeInfoCar(int32 node, int8 type, int32 next, float x, } } -//--MIAMI: done void CPathFind::CalcNodeCoors(float x, float y, float z, int id, CVector *out) { @@ -437,7 +430,6 @@ CPathFind::CalcNodeCoors(float x, float y, float z, int id, CVector *out) *out = m_mapObjects[id]->GetMatrix() * pos; } -//--MIAMI: done bool CPathFind::LoadPathFindData(void) { @@ -445,7 +437,6 @@ CPathFind::LoadPathFindData(void) return false; } -//--MIAMI: done void CPathFind::PreparePathData(void) { @@ -536,7 +527,6 @@ CPathFind::PreparePathData(void) printf("Done with PreparePathData\n"); } -//--MIAMI: done /* String together connected nodes in a list by a flood fill algorithm */ void CPathFind::CountFloodFillGroups(uint8 type) @@ -608,7 +598,6 @@ CPathFind::CountFloodFillGroups(uint8 type) int32 TempListLength; -//--MIAMI: done void CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo, float maxdist, CPathInfoForObject *detachednodes, int numDetached) @@ -813,7 +802,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor m_carPathLinks[m_numCarPathLinks].dirY = tempnodes[j].dirY; m_carPathLinks[m_numCarPathLinks].x = tempnodes[j].pos.x*8.0f; m_carPathLinks[m_numCarPathLinks].y = tempnodes[j].pos.y*8.0f; - m_carPathLinks[m_numCarPathLinks].flag1 = false; + m_carPathLinks[m_numCarPathLinks].trafficLightDirection = false; m_carPathLinks[m_numCarPathLinks].width = tempnodes[j].width; m_carPathLinks[m_numCarPathLinks].pathNodeIndex = i; m_carPathLinks[m_numCarPathLinks].numLeftLanes = tempnodes[j].numLeftLanes; @@ -892,7 +881,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor m_carPathLinks[m_numCarPathLinks].dirY = dy*100.0f; m_carPathLinks[m_numCarPathLinks].x = posx*8.0f; m_carPathLinks[m_numCarPathLinks].y = posy*8.0f; - m_carPathLinks[m_numCarPathLinks].flag1 = false; + m_carPathLinks[m_numCarPathLinks].trafficLightDirection = false; m_carPathLinks[m_numCarPathLinks].width = width; m_carPathLinks[m_numCarPathLinks].pathNodeIndex = i; m_carPathLinks[m_numCarPathLinks].numLeftLanes = -1; @@ -1028,7 +1017,6 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor delete[] mapObjIndices; } -//--MIAMI: done float CPathFind::CalcRoadDensity(float x, float y) { @@ -1051,7 +1039,6 @@ CPathFind::CalcRoadDensity(float x, float y) return density/2500.0f; } -//--MIAMI: done bool CPathFind::TestForPedTrafficLight(CPathNode *n1, CPathNode *n2) { @@ -1062,7 +1049,6 @@ CPathFind::TestForPedTrafficLight(CPathNode *n1, CPathNode *n2) return false; } -//--MIAMI: done bool CPathFind::TestCrossesRoad(CPathNode *n1, CPathNode *n2) { @@ -1073,7 +1059,6 @@ CPathFind::TestCrossesRoad(CPathNode *n1, CPathNode *n2) return false; } -//--MIAMI: done void CPathFind::AddNodeToList(CPathNode *node, int32 listId) { @@ -1086,7 +1071,6 @@ CPathFind::AddNodeToList(CPathNode *node, int32 listId) node->distance = listId; } -//--MIAMI: done void CPathFind::RemoveNodeFromList(CPathNode *node) { @@ -1095,7 +1079,6 @@ CPathFind::RemoveNodeFromList(CPathNode *node) node->GetNext()->SetPrev(node->GetPrev()); } -//--MIAMI: done void CPathFind::RemoveBadStartNode(CVector pos, CPathNode **nodes, int16 *n) { @@ -1123,7 +1106,6 @@ CPathFind::SetLinksBridgeLights(float x1, float x2, float y1, float y2, bool ena } #endif -//--MIAMI: done void CPathFind::SwitchOffNodeAndNeighbours(int32 nodeId, bool disable) { @@ -1139,7 +1121,6 @@ CPathFind::SwitchOffNodeAndNeighbours(int32 nodeId, bool disable) } } -//--MIAMI: done void CPathFind::SwitchRoadsOffInArea(float x1, float x2, float y1, float y2, float z1, float z2, bool disable) { @@ -1155,7 +1136,6 @@ CPathFind::SwitchRoadsOffInArea(float x1, float x2, float y1, float y2, float z1 } } -//--MIAMI: done void CPathFind::SwitchPedRoadsOffInArea(float x1, float x2, float y1, float y2, float z1, float z2, bool disable) { @@ -1171,7 +1151,6 @@ CPathFind::SwitchPedRoadsOffInArea(float x1, float x2, float y1, float y2, float } } -//--MIAMI: unused (still needed for script here) void CPathFind::SwitchRoadsInAngledArea(float x1, float y1, float z1, float x2, float y2, float z2, float length, uint8 type, uint8 mode) { @@ -1223,7 +1202,6 @@ CPathFind::SwitchRoadsInAngledArea(float x1, float y1, float z1, float x2, float } } -//--MIAMI: unused (still needed for script here) void CPathFind::MarkRoadsBetweenLevelsNodeAndNeighbours(int32 nodeId) { @@ -1239,7 +1217,6 @@ CPathFind::MarkRoadsBetweenLevelsNodeAndNeighbours(int32 nodeId) } } -//--MIAMI: unused (still needed for script here) void CPathFind::MarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2) { @@ -1254,7 +1231,6 @@ CPathFind::MarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, } } -//--MIAMI: unused (still needed for script here) void CPathFind::PedMarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2) { @@ -1269,9 +1245,8 @@ CPathFind::PedMarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y } } -//--MIAMI: done int32 -CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, bool ignoreFlagB4, bool bWaterPath) +CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, bool ignoreSelected, bool bWaterPath) { int i; int firstNode, lastNode; @@ -1293,7 +1268,7 @@ CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bo for(i = firstNode; i < lastNode; i++){ if(ignoreDisabled && m_pathNodes[i].bDisabled) continue; if(ignoreBetweenLevels && m_pathNodes[i].bBetweenLevels) continue; - if(ignoreFlagB4 && m_pathNodes[i].flagB4) continue; + if(ignoreSelected && m_pathNodes[i].bSelected) continue; if(bWaterPath != m_pathNodes[i].bWaterPath) continue; dist = Abs(m_pathNodes[i].GetX() - coors.x) + Abs(m_pathNodes[i].GetY() - coors.y) + @@ -1306,7 +1281,6 @@ CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bo return closestDist < distLimit ? closestNode : -1; } -//--MIAMI: done int32 CPathFind::FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, float dirX, float dirY) { @@ -1345,7 +1319,102 @@ CPathFind::FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, floa return closestNode; } -//--MIAMI: done +void +CPathFind::FindNodePairClosestToCoors(CVector coors, uint8 type, int* node1, int* node2, float* angle, float minDist, float maxDist, bool ignoreDisabled, bool ignoreBetweenLevels, bool bWaterPath) +{ + int i, j; + int firstNode, lastNode, connectedNode; + float dist; + float closestDist = 10000.0f; + int closestNode = 0, closestConnectedNode = 0; + + switch (type) { + case PATH_CAR: + firstNode = 0; + lastNode = m_numCarPathNodes; + break; + case PATH_PED: + firstNode = m_numCarPathNodes; + lastNode = m_numPathNodes; + break; + } + + for (i = firstNode; i < lastNode; i++) { + if (ignoreDisabled && m_pathNodes[i].bDisabled) continue; + if (ignoreBetweenLevels && m_pathNodes[i].bBetweenLevels) continue; + if (bWaterPath != m_pathNodes[i].bWaterPath) continue; + dist = Abs(m_pathNodes[i].GetX() - coors.x) + + Abs(m_pathNodes[i].GetY() - coors.y) + + 3.0f * Abs(m_pathNodes[i].GetZ() - coors.z); + if (dist < closestDist) { + for (j = 0; j < m_pathNodes[i].numLinks; j++) { + connectedNode = ConnectedNode(m_pathNodes[i].firstLink + j); + if (ignoreDisabled && m_pathNodes[connectedNode].bDisabled) continue; + if (ignoreBetweenLevels && m_pathNodes[connectedNode].bBetweenLevels) continue; + if (bWaterPath != m_pathNodes[connectedNode].bWaterPath) continue; + if ((m_pathNodes[connectedNode].GetPosition() - m_pathNodes[i].GetPosition()).Magnitude() > minDist) { + closestDist = dist; + closestNode = i; + closestConnectedNode = connectedNode; + } + } + } + } + if (closestDist < maxDist) { + *node1 = closestNode; + *node2 = closestConnectedNode; + CVector dir(m_pathNodes[*node2].GetX() - m_pathNodes[*node1].GetX(), m_pathNodes[*node2].GetY() - m_pathNodes[*node1].GetY(), 0.0f); + dir.Normalise(); + *angle = RADTODEG(Atan2(-dir.x, dir.y)); + } + else { + *node1 = -1; + *node2 = -1; + *angle = 0.0f; + } +} + +int32 +CPathFind::FindNthNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, int N, bool bWaterPath) +{ + int i; + int firstNode, lastNode; + switch (type) { + case PATH_CAR: + firstNode = 0; + lastNode = m_numCarPathNodes; + break; + case PATH_PED: + firstNode = m_numCarPathNodes; + lastNode = m_numPathNodes; + break; + } + for (i = firstNode; i < lastNode; i++) + m_pathNodes[i].bSelected = false; + + for (; N > 0; N--) { + i = FindNodeClosestToCoors(coors, type, distLimit, ignoreDisabled, ignoreBetweenLevels, true, bWaterPath); + if (i < 0) + return -1; + m_pathNodes[i].bSelected = true; + } + return FindNodeClosestToCoors(coors, type, distLimit, ignoreDisabled, ignoreBetweenLevels, true, bWaterPath); +} + +CVector +CPathFind::FindNodeCoorsForScript(int32 id) +{ + // the point is to return valid position in case there is a divider in the middle of the road + if (!m_pathNodes[id].HasDivider() || m_pathNodes[id].numLinks == 0) + return m_pathNodes[id].GetPosition(); + CVector2D dir(m_pathNodes[ConnectedNode(m_pathNodes[id].firstLink)].GetX() - m_pathNodes[id].GetX(), + m_pathNodes[ConnectedNode(m_pathNodes[id].firstLink)].GetY() - m_pathNodes[id].GetY()); + dir.Normalise(); + if (dir.x < 0) + dir = -dir; + return m_pathNodes[id].GetPosition() + CVector(-dir.y, dir.x, 0.0f) * (LANE_WIDTH / 2 + m_pathNodes[id].GetDividerWidth()); +} + float CPathFind::FindNodeOrientationForCarPlacement(int32 nodeId) { @@ -1357,7 +1426,6 @@ CPathFind::FindNodeOrientationForCarPlacement(int32 nodeId) return RADTODEG(dir.Heading()); } -//--MIAMI: unused (still needed for script here) float CPathFind::FindNodeOrientationForCarPlacementFacingDestination(int32 nodeId, float x, float y, bool towards) { @@ -1401,10 +1469,8 @@ CPathFind::FindNodeOrientationForCarPlacementFacingDestination(int32 nodeId, flo return RADTODEG(dir.Heading()); } -// no "New" in MIAMI -//--MIAMI: TODO bool -CPathFind::NewGenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled) +CPathFind::GenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled) { int i, j; int node1, node2; @@ -1457,67 +1523,83 @@ CPathFind::NewGenerateCarCreationCoors(float x, float y, float dirX, float dirY, return false; } -//--MIAMI: TODO bool CPathFind::GeneratePedCreationCoors(float x, float y, float minDist, float maxDist, float minDistOffScreen, float maxDistOffScreen, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, CMatrix *camMatrix) { int i; int node1, node2; + float node1_dist, node2_dist; + static int32 node_cnt; if(m_numPedPathNodes == 0) return false; - for(i = 0; i < 400; i++){ - node1 = m_numCarPathNodes + CGeneral::GetRandomNumber() % m_numPedPathNodes; - if(DistanceSqr2D(m_pathNodes[node1].GetPosition(), x, y) < sq(maxDist+30.0f)){ - if(m_pathNodes[node1].numLinks == 0) - continue; - int link = m_pathNodes[node1].firstLink + CGeneral::GetRandomNumber() % m_pathNodes[node1].numLinks; - if(ConnectionCrossesRoad(link)) - continue; - node2 = ConnectedNode(link); - if(m_pathNodes[node1].bDisabled || m_pathNodes[node2].bDisabled) - continue; + for(i = 0; i < 230; i++){ + if (node_cnt++ >= m_numPedPathNodes) + node_cnt = 0; + node1 = node_cnt + m_numCarPathNodes; + node1_dist = Distance2D(m_pathNodes[node1].GetPosition(), x, y); + if(node1_dist < maxDist+30.0f){ + if(m_pathNodes[node1].numLinks != 0) + break; + } + } + if (i >= 230) + return false; - float f2 = (CGeneral::GetRandomNumber()&0xFF)/256.0f; - float f1 = 1.0f - f2; - *pPositionBetweenNodes = f2; - CVector pos = m_pathNodes[node1].GetPosition()*f1 + m_pathNodes[node2].GetPosition()*f2; - if(Distance2D(pos, x, y) < maxDist+20.0f){ - pos.x += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f; - pos.y += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f; - float dist = Distance2D(pos, x, y); - - bool visible; - if(camMatrix) - visible = TheCamera.IsSphereVisible(pos, 2.0f, camMatrix); - else - visible = TheCamera.IsSphereVisible(pos, 2.0f); - if(!visible){ - minDist = minDistOffScreen; - maxDist = maxDistOffScreen; - } - if(minDist < dist && dist < maxDist){ - *pNode1 = node1; - *pNode2 = node2; - *pPosition = pos; - - bool found; - float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z+2.0f, &found); - if(!found) - return false; - if(Abs(groundZ - pos.z) > 3.0f) - return false; - pPosition->z = groundZ; - return true; - } + for(i = 0; i < m_pathNodes[node1].numLinks; i++){ + int link = m_pathNodes[node1].firstLink + i; + if(ConnectionCrossesRoad(link)) + continue; + node2 = ConnectedNode(link); + if(m_pathNodes[node1].bDisabled || m_pathNodes[node2].bDisabled) + continue; + node2_dist = Distance2D(m_pathNodes[node2].GetPosition(), x, y); + if ((node1_dist < maxDist || node2_dist < maxDist) && (node1_dist > minDistOffScreen || node2_dist > minDistOffScreen)) + break; + } + if(i >= m_pathNodes[node1].numLinks) + return false; + + for(i = 0; i < 5; i++){ + float f2 = (CGeneral::GetRandomNumber()&0xFF)/256.0f; + float f1 = 1.0f - f2; + *pPositionBetweenNodes = f2; + CVector pos = m_pathNodes[node1].GetPosition()*f1 + m_pathNodes[node2].GetPosition()*f2; + if(Distance2D(pos, x, y) < maxDist+20.0f){ + pos.x += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f; + pos.y += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f; + float dist = Distance2D(pos, x, y); + + bool visible; + if(camMatrix) + visible = TheCamera.IsSphereVisible(pos, 2.0f, camMatrix); + else + visible = TheCamera.IsSphereVisible(pos, 2.0f); + if(!visible){ + minDist = minDistOffScreen; + maxDist = maxDistOffScreen; + } + if(visible && (minDist < dist && dist < maxDist) || + !visible && (minDistOffScreen < dist && dist < maxDistOffScreen)){ + *pNode1 = node1; + *pNode2 = node2; + *pPosition = pos; + + bool found; + float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z+2.0f, &found); + if(!found) + return false; + if(Abs(groundZ - pos.z) > 3.0f) + return false; + pPosition->z = groundZ; + return true; } } } return false; } -//--MIAMI: done void CPathFind::FindNextNodeWandering(uint8 type, CVector coors, CPathNode **lastNode, CPathNode **nextNode, uint8 curDir, uint8 *nextDir) { @@ -1584,7 +1666,6 @@ CPathFind::FindNextNodeWandering(uint8 type, CVector coors, CPathNode **lastNode static CPathNode *apNodesToBeCleared[6525]; -//--MIAMI: done void CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector target, CPathNode **nodes, int16 *pNumNodes, int16 maxNumNodes, CVehicle *vehicle, float *pDist, float distLimit, int32 targetNodeId) { @@ -1676,7 +1757,6 @@ static CPathNode *pNodeList[32]; static int16 DummyResult; static int16 DummyResult2; -//--MIAMI: done bool CPathFind::TestCoorsCloseness(CVector target, uint8 type, CVector start) { @@ -1692,7 +1772,6 @@ CPathFind::TestCoorsCloseness(CVector target, uint8 type, CVector start) return dist < 100.0f; } -//--MIAMI: done void CPathFind::Save(uint8 *buf, uint32 *size) { @@ -1714,7 +1793,6 @@ CPathFind::Save(uint8 *buf, uint32 *size) buf[i/8 + n] &= ~(1 << i%8); } -//--MIAMI: done void CPathFind::Load(uint8 *buf, uint32 size) { diff --git a/src/control/PathFind.h b/src/control/PathFind.h index 820d0b86..acf9929a 100644 --- a/src/control/PathFind.h +++ b/src/control/PathFind.h @@ -52,6 +52,8 @@ public: static void AddNodeToList(CPedPathNode *pNode, int16 index, CPedPathNode *pList); static void AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *pPosition); static void AddBlockadeSectorList(CPtrList& list, CPedPathNode(*pathNodes)[40], CVector *pPosition); + static void AddBuildingBlockade(CEntity*, CPedPathNode(*)[40], CVector*); + static void AddBuildingBlockadeSectorList(CPtrList&, CPedPathNode(*)[40], CVector*); }; struct CPathNode @@ -74,7 +76,7 @@ struct CPathNode uint8 bWaterPath : 1; uint8 bOnlySmallBoats : 1; - uint8 flagB4 : 1; // where is this set? + uint8 bSelected : 1; uint8 speedLimit : 2; //uint8 flagB20 : 1; //uint8 flagB40 : 1; @@ -115,7 +117,7 @@ struct CCarPathLink int8 dirY; int8 numLeftLanes : 3; int8 numRightLanes : 3; - uint8 flag1 : 1; + uint8 trafficLightDirection : 1; uint8 trafficLightType : 2; uint8 bBridgeLights : 1; // at least in LCS... int8 width; @@ -160,6 +162,7 @@ struct CPathInfoForObject uint8 spawnRate : 4; + void CheckIntegrity(void); void SwapConnectionsToBeRightWayRound(void); }; extern CPathInfoForObject *InfoForTileCars; @@ -189,6 +192,14 @@ struct CTempNodeExternal // made up name bool isCross; }; +// from mobile +template<typename T> +class CRoute +{ + T m_node[8]; +}; + + class CPathFind { public: @@ -242,12 +253,14 @@ public: void MarkRoadsBetweenLevelsNodeAndNeighbours(int32 nodeId); void MarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2); void PedMarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2); -// TODO(MIAMI): check callers for new arguments - int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled = false, bool ignoreBetweenLevels = false, bool ignoreFlagB4 = false, bool bWaterPath = false); + int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled = false, bool ignoreBetweenLevels = false, bool ignoreSelected = false, bool bWaterPath = false); int32 FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, float dirX, float dirY); + void FindNodePairClosestToCoors(CVector coors, uint8 type, int* node1, int* node2, float* angle, float minDist, float maxDist, bool ignoreDisabled = false, bool ignoreBetweenLevels = false, bool bWaterPath = false); + int32 FindNthNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, int N, bool bWaterPath = false); + CVector FindNodeCoorsForScript(int32 id); float FindNodeOrientationForCarPlacement(int32 nodeId); float FindNodeOrientationForCarPlacementFacingDestination(int32 nodeId, float x, float y, bool towards); - bool NewGenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled = false); + bool GenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled = false); bool GeneratePedCreationCoors(float x, float y, float minDist, float maxDist, float minDistOffScreen, float maxDistOffScreen, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, CMatrix *camMatrix); void FindNextNodeWandering(uint8, CVector, CPathNode**, CPathNode**, uint8, uint8*); void DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector target, CPathNode **nodes, int16 *numNodes, int16 maxNumNodes, CVehicle *vehicle, float *dist, float distLimit, int32 forcedTargetNode); @@ -267,6 +280,16 @@ public: void ConnectionSetTrafficLight(int id) { m_connections[id] |= 0x4000; } void DisplayPathData(void); + + // Following methods are present on mobile but are unused. TODO: implement them + void SavePathFindData(void); + void ComputeRoute(uint8, const CVector&, const CVector&, CRoute<CPathNode*>&); + void RecordNodesClosestToCoors(CVector, uint8, int, CPathNode**, float, bool, bool, bool); + void RecordNodesInCircle(const CVector&, float, uint8, int, CPathNode**, bool, bool, bool, bool); + void ArrangeOneNodeList(CPathInfoForObject*, int16); + void ArrangeNodes(int16); + void RegisterMarker(CVector*); + void Shutdown(void); }; extern CPathFind ThePaths; diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 7a9808f6..ddf7cefb 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -49,30 +49,70 @@ uint32 CPickups::StaticCamStartTime; tPickupMessage CPickups::aMessages[NUMPICKUPMESSAGES]; -// TODO(Miami) -uint16 AmmoForWeapon[20] = { 0, 1, 45, 125, 25, 150, 300, 25, 5, 250, 5, 5, 0, 500, 0, 100, 0, 0, 0, 0 }; +// --MIAMI: Done +uint16 AmmoForWeapon[WEAPONTYPE_TOTALWEAPONS + 1] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 68, 24, + 32, 28, 20, 200, 120, 120, 120, 120, 120, 40, 28, 8, 300, 200, 1000, 1, 400, 36, 0 }; + +// --MIAMI: Done +uint16 AmmoForWeapon_OnStreet[WEAPONTYPE_TOTALWEAPONS + 1] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 34, 12, + 16, 14, 10, 100, 60, 60, 60, 60, 60, 20, 14, 4, 150, 100, 500, 1, 400, 36, 0 }; // --MIAMI: Done -uint16 AmmoForWeapon_OnStreet[WEAPONTYPE_TOTALWEAPONS] = { - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 34, - 12, 16, 14, 10, 100, 60, 60, 60, 60, 60, 20, 14, - 4, 150, 100, 500, 1, 400, 36, 0, +uint16 CostOfWeapon[WEAPONTYPE_TOTALWEAPONS + 3] = { 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1000, 1000, + 1000, 500, 8000, 250, 400, 1200, 1250, 1250, 800, 800, 650, 1200, 5000, 400, + 10000, 10000, 8000, 8000, 8000, 10000, 1000, 11000, 500, 20, 10, 0 }; + +struct +{ + uint8 r,g,b; + float unk; +} aPickupColors[] = { + { 128, 128, 128, 1.0f }, + { 128, 128, 128, 1.0f }, + { 97, 194, 247, 1.0f }, + { 97, 194, 247, 1.0f }, + { 97, 194, 247, 1.0f }, + { 97, 194, 247, 1.0f }, + { 97, 194, 247, 1.0f }, + { 97, 194, 247, 1.0f }, + { 97, 194, 247, 1.0f }, + { 97, 194, 247, 1.0f }, + { 97, 194, 247, 1.0f }, + { 97, 194, 247, 1.0f }, + { 27, 89, 130, 1.0f }, + { 27, 89, 130, 1.0f }, + { 27, 89, 130, 1.0f }, + { 27, 89, 130, 1.0f }, + { 27, 89, 130, 1.0f }, + { 149, 194, 24, 1.0f }, + { 149, 194, 24, 1.0f }, + { 45, 155, 90, 1.0f }, + { 45, 155, 90, 1.0f }, + { 45, 155, 90, 1.0f }, + { 255, 227, 79, 1.0f }, + { 255, 227, 79, 1.0f }, + { 255, 227, 79, 1.0f }, + { 255, 227, 79, 1.0f }, + { 254, 137, 0, 1.0f }, + { 254, 137, 0, 1.0f }, + { 249, 131, 215, 1.0f }, + { 249, 131, 215, 1.0f }, + { 164, 40, 178, 1.0f }, + { 164, 40, 178, 1.0f }, + { 164, 40, 178, 1.0f }, + { 164, 40, 178, 1.0f }, + { 69, 69, 69, 1.0f }, + { 69, 69, 69, 1.0f }, + { 69, 69, 69, 1.0f }, + { 255, 100, 100, 1.0f }, + { 128, 255, 128, 1.0f }, + { 100, 100, 255, 1.0f }, + { 255, 255, 100, 1.0f }, + { 255, 100, 100, 1.0f }, + { 100, 255, 100, 1.0f }, + { 255, 255, 255, 1.0f } }; -uint16 CostOfWeapon[20] = { 0, 10, 250, 800, 1500, 3000, 5000, 10000, 25000, 25000, 2000, 2000, 0, 50000, 0, 3000, 0, 0, 0, 0 }; - -// TODO(Miami): Those are all placeholders!! -uint8 aWeaponReds[] = { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 0, 128, 255, 255, 0, 255, 0, 128, 128, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 128, 0, 255, 0 }; -uint8 aWeaponGreens[] = { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -0, 255, 128, 255, 0, 255, 128, 255, 0, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -0, 255, 0, 255, 0 }; -uint8 aWeaponBlues[] = { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -0, 0, 255, 0, 255, 255, 0, 128, 255, 0, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -0, 128, 255, 0, 0 }; + void ModifyStringLabelForControlSetting(char *str) @@ -117,15 +157,36 @@ CPickup::Remove() m_eType = PICKUP_NONE; } +// --MIAMI: Done CObject * -CPickup::GiveUsAPickUpObject(int32 handle) +CPickup::GiveUsAPickUpObject(CObject **ppObject, CObject **ppExtraObject, int32 handle, int32 extraHandle) { - CObject *object; + CObject *&object = *ppObject; + CObject *&extraObject = *ppExtraObject; + + object = extraObject = nil; + + int32 modelId = -1; + if (CModelInfo::GetModelInfo(m_eModelIndex)->GetModelType() == MITYPE_WEAPON) { + CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(((CWeaponModelInfo*)CModelInfo::GetModelInfo(m_eModelIndex))->GetWeaponInfo()); + modelId = weaponInfo->m_nModelId; + if (modelId == m_eModelIndex) + modelId = weaponInfo->m_nModel2Id; + } - if (handle <= 0) object = new CObject(m_eModelIndex, false); - else { + if (handle >= 0) { CPools::MakeSureSlotInObjectPoolIsEmpty(handle); - object = new(handle) CObject(m_eModelIndex, false); + if (extraHandle >= 0) + CPools::MakeSureSlotInObjectPoolIsEmpty(extraHandle); + if (object == nil) + object = new(handle) CObject(m_eModelIndex, false); + + if (extraHandle >= 0 && modelId != -1 && extraObject == nil) + extraObject = new(extraHandle) CObject(modelId, false); + } else { + object = new CObject(m_eModelIndex, false); + if (modelId != -1) + extraObject = new CObject(modelId, false); } if (object == nil) return nil; @@ -139,15 +200,38 @@ CPickup::GiveUsAPickUpObject(int32 handle) object->bExplosionProof = true; object->bUsesCollision = false; object->bIsPickup = true; + object->obj_flag_02 = m_effects; object->bHasPreRenderEffects = true; - object->m_nBonusValue = m_eModelIndex == MI_PICKUP_BONUS ? m_nQuantity : 0; + if (extraObject) { + extraObject->ObjectCreatedBy = MISSION_OBJECT; + extraObject->SetPosition(m_vecPos); + extraObject->SetOrientation(0.0f, 0.0f, -HALFPI); + extraObject->GetMatrix().UpdateRW(); + extraObject->UpdateRwFrame(); + + extraObject->bAffectedByGravity = false; + extraObject->bExplosionProof = true; + extraObject->bUsesCollision = false; + extraObject->bIsPickup = true; + extraObject->obj_flag_02 = true; + extraObject->bHasPreRenderEffects = true; + extraObject->m_nBonusValue = 0; + extraObject->bPickupObjWithMessage = false; + extraObject->bOutOfStock = false; + } + + object->m_nBonusValue = (m_eModelIndex == MI_PICKUP_BONUS || m_eModelIndex == MI_PICKUP_CLOTHES) ? m_nQuantity : 0; switch (m_eType) { case PICKUP_IN_SHOP: object->bPickupObjWithMessage = true; object->bOutOfStock = false; + if (m_eModelIndex == MI_PICKUP_HEALTH || m_eModelIndex == MI_PICKUP_ADRENALINE) + object->m_nCostValue = 0; + else + object->m_nCostValue = CostOfWeapon[CPickups::WeaponForModel(m_eModelIndex)]; break; case PICKUP_ON_STREET: case PICKUP_ONCE: @@ -193,28 +277,20 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) float waterLevel; if (m_pObject) { - m_pObject->SetPosition(m_vecPos); - // TODO(Miami): Extra object + m_pObject->GetMatrix().GetPosition() = m_vecPos; + if (m_pExtraObject) + m_pExtraObject->GetMatrix().GetPosition() = m_vecPos; } if (m_eType == PICKUP_ASSET_REVENUE) { - uint32 oldTimer = m_nTimer; + uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nTimer; m_nTimer = CTimer::GetTimeInMilliseconds(); - float calculatedRevenue; - if ((FindPlayerCoors() - m_vecPos).Magnitude() > 10.0) { - uint32 timePassed = CTimer::GetTimeInMilliseconds() - oldTimer; - calculatedRevenue = m_nRevenue + (timePassed * m_nMoneySpeed) * sq(1.f / 1200.f); - } else { - calculatedRevenue = m_nRevenue; - } - m_nRevenue = Min(calculatedRevenue, m_nQuantity); - // TODO(Miami): For pickup glow effect? - /* - if (calculatedRevenue < 10.0) { - m_pObject->m_nCostValue = 0; - } else { - m_pObject->m_nCostValue = calculatedRevenue; - } - */ + + if (Distance(FindPlayerCoors(), m_vecPos) > 10.0f) + m_fRevenue += float(timePassed * m_nMoneySpeed) / SQR(1200.0f); + + m_fRevenue = Min(m_fRevenue, m_nQuantity); + + m_pObject->m_nCostValue = m_fRevenue < 10 ? 0 : m_fRevenue; } if (m_bRemoved) { @@ -222,7 +298,7 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) // respawn pickup if we're far enough float dist = (FindPlayerCoors().x - m_vecPos.x) * (FindPlayerCoors().x - m_vecPos.x) + (FindPlayerCoors().y - m_vecPos.y) * (FindPlayerCoors().y - m_vecPos.y); if (dist > 100.0f || m_eType == PICKUP_IN_SHOP && dist > 2.4f) { - m_pObject = GiveUsAPickUpObject(-1); + m_pObject = GiveUsAPickUpObject(&m_pObject, &m_pExtraObject, -1, -1); if (m_pObject) { CWorld::Add(m_pObject); m_bRemoved = false; @@ -232,6 +308,14 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) return false; } + if (!m_pObject) { + GiveUsAPickUpObject(&m_pObject, &m_pExtraObject, -1, -1); + if (m_pObject) + CWorld::Add(m_pObject); + if (m_pExtraObject) + CWorld::Add(m_pExtraObject); + } + if (!m_pObject) return false; if (!IsMine()) { @@ -261,6 +345,10 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) } } + // MIAMI code here + + // ... + // if we didn't then we've got nothing to do if (isPickupTouched && CanBePickedUp(player, playerId)) { CPad::GetPad(0)->StartShake(120, 100); @@ -345,8 +433,8 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) DMAudio.PlayFrontEndSound(SOUND_PICKUP_MONEY, 0); return true; case PICKUP_ASSET_REVENUE: - CWorld::Players[CWorld::PlayerInFocus].m_nMoney += m_nRevenue; - m_nRevenue = 0; + CWorld::Players[CWorld::PlayerInFocus].m_nMoney += m_fRevenue; + m_fRevenue = 0.0f; DMAudio.PlayFrontEndSound(SOUND_PICKUP_MONEY, 0); return false; // TODO(Miami): Control flow @@ -462,6 +550,23 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) return false; } +// --MIAMI: Done +void +CPickup::GetRidOfObjects() +{ + if (m_pObject) { + CWorld::Remove(m_pObject); + delete m_pObject; + m_pObject = nil; + } + if (m_pExtraObject) { + CWorld::Remove(m_pExtraObject); + delete m_pExtraObject; + m_pExtraObject = nil; + } +} + +// --MIAMI: Done void CPickups::Init(void) { @@ -470,6 +575,7 @@ CPickups::Init(void) aPickUps[i].m_eType = PICKUP_NONE; aPickUps[i].m_nIndex = 1; aPickUps[i].m_pObject = nil; + aPickUps[i].m_pExtraObject = nil; } for (int i = 0; i < NUMCOLLECTEDPICKUPS; i++) @@ -502,6 +608,7 @@ CPickups::TryToMerge_WeaponType(CVector pos, eWeaponType weapon, uint8 type, uin return false; } +// --MIAMI: Done bool CPickups::IsPickUpPickedUp(int32 pickupId) { @@ -514,11 +621,12 @@ CPickups::IsPickUpPickedUp(int32 pickupId) return false; } +// --MIAMI: Done void CPickups::PassTime(uint32 time) { for (int i = 0; i < NUMPICKUPS; i++) { - if (aPickUps[i].m_eType != PICKUP_NONE) { + if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_eType != PICKUP_ASSET_REVENUE) { if (aPickUps[i].m_nTimer <= time) aPickUps[i].m_nTimer = 0; else @@ -527,6 +635,7 @@ CPickups::PassTime(uint32 time) } } +// --MIAMI: Done int32 CPickups::GetActualPickupIndex(int32 index) { @@ -537,6 +646,7 @@ CPickups::GetActualPickupIndex(int32 index) return (uint16)index; } +// --MIAMI: Done bool CPickups::GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex) { @@ -566,8 +676,7 @@ CPickups::GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex) DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); return true; } else if (modelIndex == MI_PICKUP_BRIBE) { - int32 level = FindPlayerPed()->m_pWanted->m_nWantedLevel - 1; - if (level < 0) level = 0; + int32 level = Max(FindPlayerPed()->m_pWanted->m_nWantedLevel - 1, 0); player->SetWantedLevel(level); DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); return true; @@ -578,6 +687,7 @@ CPickups::GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex) return false; } +// --MIAMI: Todo void CPickups::RemoveAllFloatingPickups() { @@ -592,10 +702,11 @@ CPickups::RemoveAllFloatingPickups() } } +// --MIAMI: Done void CPickups::RemovePickUp(int32 pickupIndex) { - int32 index = CPickups::GetActualPickupIndex(pickupIndex); + int32 index = GetActualPickupIndex(pickupIndex); if (index == -1) return; if (aPickUps[index].m_pObject) { @@ -603,10 +714,16 @@ CPickups::RemovePickUp(int32 pickupIndex) delete aPickUps[index].m_pObject; aPickUps[index].m_pObject = nil; } + if (aPickUps[index].m_pExtraObject) { + CWorld::Remove(aPickUps[index].m_pExtraObject); + delete aPickUps[index].m_pExtraObject; + aPickUps[index].m_pExtraObject = nil; + } aPickUps[index].m_eType = PICKUP_NONE; aPickUps[index].m_bRemoved = true; } +// --MIAMI: Done int32 CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity, uint32 rate, bool highPriority, char* pText) { @@ -620,7 +737,8 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan break; } } - } else { + } + if (!bFreeFound) { for (slot = 0; slot < NUMGENERALPICKUPS; slot++) { if (aPickUps[slot].m_eType == PICKUP_NONE) { bFreeFound = true; @@ -640,6 +758,7 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan } if (slot >= NUMGENERALPICKUPS) return -1; + aPickUps[slot].GetRidOfObjects(); } } @@ -649,8 +768,10 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan aPickUps[slot].m_bRemoved = false; aPickUps[slot].m_nQuantity = quantity; aPickUps[slot].m_nMoneySpeed = rate; - aPickUps[slot].m_nRevenue = 0; + aPickUps[slot].m_fRevenue = 0.0f; aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds(); + aPickUps[slot].m_effects = highPriority; + aPickUps[slot].m_effects2 = false; if (type == PICKUP_ONCE_TIMEOUT) aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 20000; else if (type == PICKUP_ONCE_TIMEOUT_SLOW) @@ -671,18 +792,22 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan aPickUps[slot].m_sTextKey[0] = '\0'; aPickUps[slot].m_vecPos = pos; - aPickUps[slot].m_pObject = aPickUps[slot].GiveUsAPickUpObject(-1); + aPickUps[slot].m_pObject = aPickUps[slot].GiveUsAPickUpObject(&aPickUps[slot].m_pObject, &aPickUps[slot].m_pExtraObject, -1, -1); if (aPickUps[slot].m_pObject) CWorld::Add(aPickUps[slot].m_pObject); + if (aPickUps[slot].m_pExtraObject) + CWorld::Add(aPickUps[slot].m_pExtraObject); return GetNewUniquePickupIndex(slot); } +// --MIAMI: Done int32 CPickups::GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity) { return GenerateNewOne(pos, ModelForWeapon(weaponType), type, quantity); } +// --MIAMI: Done int32 CPickups::GetNewUniquePickupIndex(int32 slot) { @@ -711,6 +836,7 @@ CPickups::WeaponForModel(int32 model) return (eWeaponType)((CWeaponModelInfo*)CModelInfo::GetModelInfo(model))->GetWeaponInfo(); } +// --MIAMI: Done void CPickups::AddToCollectedPickupsArray(int32 index) { @@ -729,7 +855,7 @@ CPickups::Update() #ifdef CAMERA_PICKUP if ( bPickUpcamActivated ) // taken from PS2 { - float dist = (FindPlayerCoors() - StaticCamCoors).Magnitude2D(); + float dist = Distance2D(StaticCamCoors, FindPlayerCoors()); float mult; if ( dist < 10.0f ) mult = 1.0f - (dist / 10.0f ); @@ -745,8 +871,7 @@ CPickups::Update() TheCamera.TakeControl(FindPlayerVehicle(), CCam::MODE_FIXED, JUMP_CUT, CAMCONTROL_SCRIPT); } - if ( FindPlayerVehicle() != pPlayerVehicle - || (FindPlayerCoors() - StaticCamCoors).Magnitude() > 40.0f + if ( FindPlayerVehicle() != pPlayerVehicle || Distance(StaticCamCoors, FindPlayerCoors()) > 40.0f || ((CTimer::GetTimeInMilliseconds() - StaticCamStartTime) > 60000) ) { TheCamera.RestoreWithJumpCut(); @@ -754,15 +879,13 @@ CPickups::Update() } } #endif - if (CPad::GetPad(0)->CollectPickupJustDown()) { + if (CPad::GetPad(0)->CollectPickupJustDown()) CollectPickupBuffer = 6; - } else { + else CollectPickupBuffer = Max(0, CollectPickupBuffer - 1); - } - if (PlayerOnWeaponPickup) { + if (PlayerOnWeaponPickup) PlayerOnWeaponPickup = Max(0, PlayerOnWeaponPickup - 1); - } #define PICKUPS_FRAME_SPAN (6) #ifdef FIX_BUGS @@ -782,9 +905,24 @@ CPickups::Update() } } +// --MIAMI: Done +CPickup* +CPickups::FindPickUpForThisObject(CEntity *object) +{ + for (uint32 i = 0; i < NUMPICKUPS; i++) { + if (aPickUps[i].m_eType != PICKUP_NONE && (aPickUps[i].m_pObject == object || aPickUps[i].m_pExtraObject == object)) { + return &aPickUps[i]; + } + } + return &aPickUps[0]; +} + +// --MIAMI: Done void CPickups::DoPickUpEffects(CEntity *entity) { + CPickup *pickup = FindPickUpForThisObject(entity); + if (entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) entity->bDoNotRender = CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame; @@ -802,7 +940,7 @@ CPickups::DoPickUpEffects(CEntity *entity) doInnerGlow = true; doOuterGlow = false; } else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR) { - colorId = WEAPONTYPE_TOTALWEAPONS + 1; + colorId = WEAPONTYPE_ARMOUR; } else if (entity->GetModelIndex() == MI_PICKUP_BRIBE) { doInnerGlow = true; doOuterGlow = false; @@ -811,33 +949,92 @@ CPickups::DoPickUpEffects(CEntity *entity) doInnerGlow = true; doOuterGlow = false; } else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS) { - colorId = WEAPONTYPE_TOTALWEAPONS; + colorId = WEAPONTYPE_HEALTH; + doInnerGlow = true; + doOuterGlow = false; + } else if (entity->GetModelIndex() == MI_PICKUP_PROPERTY) { doInnerGlow = true; doOuterGlow = false; + } else if (entity->GetModelIndex() == MI_PICKUP_PROPERTY_FORSALE) { + doInnerGlow = true; + doOuterGlow = false; + } else if (entity->GetModelIndex() == MI_PICKUP_REVENUE) { + doInnerGlow = true; + doOuterGlow = false; + } else if (entity->GetModelIndex() == MI_PICKUP_SAVEGAME) { + doInnerGlow = true; + doOuterGlow = false; + } else if (entity->GetModelIndex() == MI_PICKUP_CLOTHES) { + colorId = WEAPONTYPE_TOTALWEAPONS; + doOuterGlow = false; + doInnerGlow = true; } else colorId = WeaponForModel(entity->GetModelIndex()); - const CVector& pos = entity->GetPosition(); + const CVector& pos = pickup->m_vecPos; if (doOuterGlow) { - float colorModifier = ((CGeneral::GetRandomNumber() & 0x1F) * 0.015f + 1.0f) * modifiedSin * 0.15f; - CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, 2.0f, 0.0f, 0.0f, -2.0f, 0, - aWeaponReds[colorId] * colorModifier, aWeaponGreens[colorId] * colorModifier, aWeaponBlues[colorId] * colorModifier, 4.0f, - 1.0f, 40.0f, false, 0.0f); + bool corona1 = false; + bool corona2 = false; + int timerVal = (CTimer::GetTimeInMilliseconds() >> 9) & 7; + + if (timerVal < 3) + corona1 = false; + else if (timerVal == 3) + corona1 = (CGeneral::GetRandomNumber() & 3) != 0; + else + corona1 = true; - float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f; - CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aWeaponReds[colorId] * modifiedSin / 256.0f, aWeaponGreens[colorId] * modifiedSin / 256.0f, aWeaponBlues[colorId] * modifiedSin / 256.0f, CPointLights::FOG_NONE, true); - float size = (CGeneral::GetRandomNumber() & 0xF) * 0.0005f + 0.6f; - CCoronas::RegisterCorona((uintptr)entity, - aWeaponReds[colorId] * modifiedSin / 2.0f, aWeaponGreens[colorId] * modifiedSin / 2.0f, aWeaponBlues[colorId] * modifiedSin / 2.0f, - 255, - pos, - size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + timerVal = (timerVal - 1) & 7; + if (timerVal < 3) + corona2 = false; + else if (timerVal == 3) + corona2 = (CGeneral::GetRandomNumber() & 3) != 0; + else + corona2 = true; + + if (((CObject*)entity)->obj_flag_02) { + corona2 = false; + corona1 = false; + } + + if (corona1) { + CCoronas::RegisterCorona((uintptr)entity, + aPickupColors[colorId].r * 0.45f, aPickupColors[colorId].g * 0.45f, aPickupColors[colorId].b * 0.45f, + 255, pos, 0.76f, 65.0f, + CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, + 0.0f, false, -0.4f); + CShadows::StoreStaticShadow((uintptr)entity, + SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, 2.0f, 0.0f, 0.0f, -2.0f, 0, + aPickupColors[colorId].r * 0.3f, aPickupColors[colorId].g * 0.3f, aPickupColors[colorId].b * 0.3f, + 4.0f, 1.0f, 40.0f, false, 0.0f); + float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f; + CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aPickupColors[colorId].r / 256.0f, aPickupColors[colorId].g / 256.0f, aPickupColors[colorId].b / 256.0f, CPointLights::FOG_NONE, true); + } else + CCoronas::RegisterCorona((uintptr)entity, 0, 0, 0, 255, pos, 0.57f, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + + if (corona2) { + CCoronas::RegisterCorona( + (uintptr)entity + 1, + aPickupColors[colorId].r * 0.55f, aPickupColors[colorId].g * 0.55f, aPickupColors[colorId].b * 0.55f, + 255, + pos, + 0.6f, + 65.0f, + CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, + 0.0f, false, -0.4f); + if (!corona1) + CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, 2.0f, 0.0f, 0.0f, -2.0f, 0, + aPickupColors[colorId].r * 0.25f, aPickupColors[colorId].g * 0.25f, aPickupColors[colorId].b * 0.25f, + 4.0f, 1.0f, 40.0f, false, 0.0f); + } else + CCoronas::RegisterCorona((uintptr)entity + 1, 0, 0, 0, 255, pos, 0.45f, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); } CObject *object = (CObject*)entity; - if (object->bPickupObjWithMessage || object->bOutOfStock || object->m_nBonusValue) { - float dist = (TheCamera.GetPosition() - pos).Magnitude(); - const float MAXDIST = 12.0f; + if (object->bPickupObjWithMessage || object->bOutOfStock || object->m_nBonusValue || object->m_nCostValue) { + + float dist = Distance2D(pos, TheCamera.GetPosition()); + const float MAXDIST = 14.0f; if (dist < MAXDIST && NumMessages < NUMPICKUPMESSAGES) { RwV3d vecOut; @@ -848,38 +1045,85 @@ CPickups::DoPickUpEffects(CEntity *entity) aMessages[NumMessages].m_dist.x = fDistX; aMessages[NumMessages].m_dist.y = fDistY; aMessages[NumMessages].m_weaponType = WeaponForModel(entity->GetModelIndex()); - aMessages[NumMessages].m_color.red = aWeaponReds[colorId]; - aMessages[NumMessages].m_color.green = aWeaponGreens[colorId]; - aMessages[NumMessages].m_color.blue = aWeaponBlues[colorId]; + aMessages[NumMessages].m_color.red = aPickupColors[colorId].r; + aMessages[NumMessages].m_color.green = aPickupColors[colorId].g; + aMessages[NumMessages].m_color.blue = aPickupColors[colorId].b; aMessages[NumMessages].m_color.alpha = (1.0f - dist / MAXDIST) * 128.0f; aMessages[NumMessages].m_bOutOfStock = object->bOutOfStock; aMessages[NumMessages].m_quantity = object->m_nBonusValue; + aMessages[NumMessages].money = object->m_nCostValue; NumMessages++; } } } uint32 model = entity->GetModelIndex(); - CColModel* colModel = entity->GetColModel(); + CColModel *colModel = entity->GetColModel(); CVector colLength = colModel->boundingBox.max - colModel->boundingBox.min; + float maxDimension = Max(colLength.x, Max(colLength.y, colLength.z)); - float scale = (Max(1.f, 1.2f / Max(colLength.x, Max(colLength.y, colLength.z))) - 1.0f) * 0.6f + 1.0f; + float scale = (Max(1.f, 1.2f / maxDimension) - 1.0f) * 0.6f + 1.0f; if (model == MI_MINIGUN || model == MI_MINIGUN2) scale = 1.2f; entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), scale); + if (entity->GetModelIndex() == MI_MINIGUN2) { + CMatrix matrix1; + CMatrix matrix2; // unused + entity->SetPosition(pickup->m_vecPos); + matrix1.SetRotateX(0.0f); + matrix1.Rotate(DEGTORAD(4.477f), DEGTORAD(-29.731), DEGTORAD(-1.064)); + matrix1.Translate(CVector(0.829, -0.001, 0.226)); + entity->GetMatrix() *= matrix1; + } + + if (doOuterGlow) { + CVector scale(0.0f, 0.0f, 0.0f); + if (colLength.x == maxDimension) + scale.x = colLength.x; + else if (colLength.y == maxDimension) + scale.y = colLength.y; + else + scale.z = colLength.z; + + for (int i = 0; i < 4; i++) { + CVector pos = entity->GetMatrix() * (scale * ((float)i / 3.0f)); + CCoronas::RegisterCorona( + (uintptr)entity + 8 + i, + aPickupColors[colorId].r * 0.15f, + aPickupColors[colorId].g * 0.15f, + aPickupColors[colorId].b * 0.15f, + 255, + pos, + 1.0f, + 65.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, + CCoronas::REFLECTION_OFF, + CCoronas::LOSCHECK_OFF, + CCoronas::STREAK_OFF, + 0.0f); + } + } + if (doInnerGlow) - CCoronas::RegisterCorona((uintptr)entity + 1, 126, 69, 121, 255, entity->GetPosition(), 1.2f, 50.0f, - CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.f, false); + CCoronas::RegisterCorona( +#ifdef FIX_BUGS + (uintptr)entity + 8 + 4, +#else + (uintptr)entity + 9, +#endif + 126, 69, 121, 255, entity->GetPosition(), 1.2f, 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f); } } +// --MIAMI: Done void CPickups::DoMineEffects(CEntity *entity) { const CVector &pos = entity->GetPosition(); - float dist = (TheCamera.GetPosition() - pos).Magnitude(); + float dist = Distance(pos, TheCamera.GetPosition()); const float MAXDIST = 20.0f; if (dist < MAXDIST) { @@ -894,11 +1138,12 @@ CPickups::DoMineEffects(CEntity *entity) entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0x3FF) * DEGTORAD(360.0f / 0x400)); } +// --MIAMI: Done void CPickups::DoMoneyEffects(CEntity *entity) { const CVector &pos = entity->GetPosition(); - float dist = (TheCamera.GetPosition() - pos).Magnitude(); + float dist = Distance(pos, TheCamera.GetPosition()); const float MAXDIST = 20.0f; if (dist < MAXDIST) { @@ -913,11 +1158,12 @@ CPickups::DoMoneyEffects(CEntity *entity) entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800)); } +// --MIAMI: Done void CPickups::DoCollectableEffects(CEntity *entity) { const CVector &pos = entity->GetPosition(); - float dist = (TheCamera.GetPosition() - pos).Magnitude(); + float dist = Distance(pos, TheCamera.GetPosition()); const float MAXDIST = 14.0f; if (dist < MAXDIST) { @@ -932,18 +1178,22 @@ CPickups::DoCollectableEffects(CEntity *entity) entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0xFFF) * DEGTORAD(360.0f / 0x1000)); } +// --MIAMI: Done void CPickups::RenderPickUpText() { wchar *strToPrint; for (int32 i = 0; i < NumMessages; i++) { - if (aMessages[i].m_quantity <= 39) { + + if (aMessages[i].money != 0) { + sprintf(gString, "$%d", aMessages[i].money); + AsciiToUnicode(gString, gUString); + strToPrint = gUString; + } else { switch (aMessages[i].m_quantity) // could use some enum maybe { case 0: - if (aMessages[i].m_weaponType == WEAPONTYPE_TOTALWEAPONS) { // unreachable code? - // what is this?? - sprintf(gString, "%d/%d", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 2903); + if (aMessages[i].m_weaponType == WEAPONTYPE_HEALTH || aMessages[i].m_weaponType == WEAPONTYPE_ARMOUR) { strToPrint = nil; } else { if (aMessages[i].m_bOutOfStock) @@ -956,121 +1206,43 @@ CPickups::RenderPickUpText() } break; case 1: - strToPrint = TheText.Get("SECURI"); + strToPrint = TheText.Get("OUTFT1"); break; case 2: - strToPrint = TheText.Get("MOONBM"); + strToPrint = TheText.Get("OUTFT2"); break; case 3: - strToPrint = TheText.Get("COACH"); + strToPrint = TheText.Get("OUTFT3"); break; case 4: - strToPrint = TheText.Get("FLATBED"); + strToPrint = TheText.Get("OUTFT4"); break; case 5: - strToPrint = TheText.Get("LINERUN"); + strToPrint = TheText.Get("OUTFT5"); break; case 6: - strToPrint = TheText.Get("TRASHM"); + strToPrint = TheText.Get("OUTFT6"); break; case 7: - strToPrint = TheText.Get("PATRIOT"); + strToPrint = TheText.Get("OUTFT7"); break; case 8: - strToPrint = TheText.Get("WHOOPEE"); + strToPrint = TheText.Get("OUTFT8"); break; case 9: - strToPrint = TheText.Get("BLISTA"); + strToPrint = TheText.Get("OUTFT9"); break; case 10: - strToPrint = TheText.Get("MULE"); + strToPrint = TheText.Get("OUTFT10"); break; case 11: - strToPrint = TheText.Get("YANKEE"); + strToPrint = TheText.Get("OUTFT11"); break; case 12: - strToPrint = TheText.Get("BOBCAT"); + strToPrint = TheText.Get("OUTFT12"); break; case 13: - strToPrint = TheText.Get("DODO"); - break; - case 14: - strToPrint = TheText.Get("BUS"); - break; - case 15: - strToPrint = TheText.Get("RUMPO"); - break; - case 16: - strToPrint = TheText.Get("PONY"); - break; - case 17: - strToPrint = TheText.Get("SENTINL"); - break; - case 18: - strToPrint = TheText.Get("CHEETAH"); - break; - case 19: - strToPrint = TheText.Get("BANSHEE"); - break; - case 20: - strToPrint = TheText.Get("IDAHO"); - break; - case 21: - strToPrint = TheText.Get("INFERNS"); - break; - case 22: - strToPrint = TheText.Get("TAXI"); - break; - case 23: - strToPrint = TheText.Get("KURUMA"); - break; - case 24: - strToPrint = TheText.Get("STRETCH"); - break; - case 25: - strToPrint = TheText.Get("PEREN"); - break; - case 26: - strToPrint = TheText.Get("STINGER"); - break; - case 27: - strToPrint = TheText.Get("MANANA"); - break; - case 28: - strToPrint = TheText.Get("LANDSTK"); - break; - case 29: - strToPrint = TheText.Get("STALION"); - break; - case 30: - strToPrint = TheText.Get("BFINJC"); - break; - case 31: - strToPrint = TheText.Get("CABBIE"); - break; - case 32: - strToPrint = TheText.Get("ESPERAN"); - break; - case 33: - strToPrint = TheText.Get("FIRETRK"); - break; - case 34: - strToPrint = TheText.Get("AMBULAN"); - break; - case 35: - strToPrint = TheText.Get("ENFORCR"); - break; - case 36: - strToPrint = TheText.Get("FBICAR"); - break; - case 37: - strToPrint = TheText.Get("RHINO"); - break; - case 38: - strToPrint = TheText.Get("BARRCKS"); - break; - case 39: - strToPrint = TheText.Get("POLICAR"); + strToPrint = TheText.Get("OUTFT13"); break; default: break; @@ -1081,12 +1253,16 @@ CPickups::RenderPickUpText() CFont::SetPropOn(); CFont::SetBackgroundOff(); - const float MAX_SCALE = 1.0f; +#ifdef FIX_BUGS + const float MAX_SCALE = SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH; +#else + const float MAX_SCALE = RsGlobal.width / DEFAULT_SCREEN_WIDTH; +#endif - float fScaleY = aMessages[i].m_dist.y / 100.0f; + float fScaleY = aMessages[i].m_dist.y / 30.0f; if (fScaleY > MAX_SCALE) fScaleY = MAX_SCALE; - float fScaleX = aMessages[i].m_dist.x / 100.0f; + float fScaleX = aMessages[i].m_dist.x / 30.0f; if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE; CFont::SetScale(fScaleX, fScaleY); @@ -1102,6 +1278,7 @@ CPickups::RenderPickUpText() NumMessages = 0; } +// --MIAMI: Done void CPickups::CreateSomeMoney(CVector pos, int money) { @@ -1121,6 +1298,30 @@ CPickups::CreateSomeMoney(CVector pos, int money) } } +// --MIAMI: Done +void +CPickups::RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo(eWeaponType weaponType) +{ + uint32 weaponSlot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot; + if (weaponSlot >= WEAPONSLOT_SHOTGUN && weaponSlot <= WEAPONSLOT_RIFLE) { + for (int slot = 0; slot < NUMPICKUPS; slot++) { + if (aPickUps[slot].m_eType == PICKUP_ONCE || aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT || aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT_SLOW) { + if (aPickUps[slot].m_pObject) { + if (CWeaponInfo::GetWeaponInfo(WeaponForModel(aPickUps[slot].m_pObject->GetModelIndex()))->m_nWeaponSlot == weaponSlot && + aPickUps[slot].m_nQuantity == 0) { + CWorld::Remove(aPickUps[slot].m_pObject); + delete aPickUps[slot].m_pObject; + aPickUps[slot].m_bRemoved = true; + aPickUps[slot].m_pObject = nil; + aPickUps[slot].m_eType = PICKUP_NONE; + } + } + } + } + } +} + +// --MIAMI: Done void CPickups::Load(uint8 *buf, uint32 size) { @@ -1129,8 +1330,13 @@ INITSAVEBUF for (int32 i = 0; i < NUMPICKUPS; i++) { aPickUps[i] = ReadSaveBuf<CPickup>(buf); - if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil) - aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pObject - 1); + if (aPickUps[i].m_eType != PICKUP_NONE) { + if (aPickUps[i].m_pObject != nil) + aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pObject - 1); + if (aPickUps[i].m_pExtraObject != nil) + aPickUps[i].m_pExtraObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pExtraObject - 1); + } + } CollectedPickUpIndex = ReadSaveBuf<uint16>(buf); @@ -1143,17 +1349,23 @@ INITSAVEBUF VALIDATESAVEBUF(size) } +// --MIAMI: Done void CPickups::Save(uint8 *buf, uint32 *size) { - *size = sizeof(aPickUps) + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected); + *size = sizeof(aPickUps); + *size += sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected); INITSAVEBUF for (int32 i = 0; i < NUMPICKUPS; i++) { CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]); - if (buf_pickup->m_eType != PICKUP_NONE && buf_pickup->m_pObject != nil) - buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex(buf_pickup->m_pObject) + 1); + if (buf_pickup->m_eType != PICKUP_NONE) { + if (buf_pickup->m_pObject != nil) + buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex(buf_pickup->m_pObject) + 1); + if (buf_pickup->m_pExtraObject != nil) + buf_pickup->m_pExtraObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex(buf_pickup->m_pExtraObject) + 1); + } } WriteSaveBuf(buf, CollectedPickUpIndex); @@ -1168,40 +1380,6 @@ VALIDATESAVEBUF(*size) void CPacManPickup::Update() { - if (FindPlayerVehicle() == nil) return; - - CVehicle *veh = FindPlayerVehicle(); - - if (DistanceSqr2D(FindPlayerVehicle()->GetPosition(), m_vecPosn.x, m_vecPosn.y) < 100.0f && veh->IsSphereTouchingVehicle(m_vecPosn.x, m_vecPosn.y, m_vecPosn.z, 1.5f)) { - switch (m_eType) - { - case PACMAN_SCRAMBLE: - { - veh->m_nPacManPickupsCarried++; - veh->m_vecMoveSpeed *= 0.65f; - float massMult = (veh->m_fMass + 250.0f) / veh->m_fMass; - veh->m_fMass *= massMult; - veh->m_fTurnMass *= massMult; - veh->m_fForceMultiplier *= massMult; - FindPlayerPed()->m_pWanted->m_nChaos += 10; - FindPlayerPed()->m_pWanted->UpdateWantedLevel(); - DMAudio.PlayFrontEndSound(SOUND_PICKUP_PACMAN_PACKAGE, 0); - break; - } - case PACMAN_RACE: - CPacManPickups::PillsEatenInRace++; - DMAudio.PlayFrontEndSound(SOUND_PICKUP_PACMAN_PILL, 0); - break; - default: - break; - } - m_eType = PACMAN_NONE; - if (m_pObject != nil) { - CWorld::Remove(m_pObject); - delete m_pObject; - m_pObject = nil; - } - } } int32 CollectGameState; @@ -1215,52 +1393,11 @@ bool CPacManPickups::bPMActive; void CPacManPickups::Init() { - for (int i = 0; i < NUMPACMANPICKUPS; i++) - aPMPickUps[i].m_eType = PACMAN_NONE; - bPMActive = false; } void CPacManPickups::Update() { - if (FindPlayerVehicle()) { - float dist = Distance(FindPlayerCoors(), CVector(1072.0f, -948.0f, 14.5f)); - switch (CollectGameState) { - case 1: - if (dist < 10.0f) { - ThingsToCollect -= FindPlayerVehicle()->m_nPacManPickupsCarried; - FindPlayerVehicle()->m_nPacManPickupsCarried = 0; - FindPlayerVehicle()->m_fMass /= FindPlayerVehicle()->m_fForceMultiplier; - FindPlayerVehicle()->m_fTurnMass /= FindPlayerVehicle()->m_fForceMultiplier; - FindPlayerVehicle()->m_fForceMultiplier = 1.0f; - } - if (ThingsToCollect <= 0) { - CollectGameState = 2; - ClearPMPickUps(); - } - break; - case 2: - if (dist > 11.0f) - CollectGameState = 0; - break; - case 20: - if (Distance(FindPlayerCoors(), LastPickUpCoors) > 30.0f) { - LastPickUpCoors = FindPlayerCoors(); - printf("%f, %f, %f,\n", LastPickUpCoors.x, LastPickUpCoors.y, LastPickUpCoors.z); - } - break; - default: - break; - } - } - if (bPMActive) { -#define PACMANPICKUPS_FRAME_SPAN (4) - for (uint32 i = (CTimer::GetFrameCounter() % PACMANPICKUPS_FRAME_SPAN) * (NUMPACMANPICKUPS / PACMANPICKUPS_FRAME_SPAN); i < ((CTimer::GetFrameCounter() % PACMANPICKUPS_FRAME_SPAN) + 1) * (NUMPACMANPICKUPS / PACMANPICKUPS_FRAME_SPAN); i++) { - if (aPMPickUps[i].m_eType != PACMAN_NONE) - aPMPickUps[i].Update(); - } -#undef PACMANPICKUPS_FRAME_SPAN - } } void @@ -1275,107 +1412,6 @@ static const CVector aRacePoints1[] = { CVector(913.27899f, -93.524231f, 7.4325991f), CVector(912.60852f, -63.15905f, 7.4533591f), CVector(934.22144f, -42.049122f, 7.4511471f), - CVector(958.88092f, -23.863735f, 7.4652338f), - CVector(978.50812f, -0.78458798f, 5.13515f), - CVector(1009.4175f, -2.1041219f, 2.4461579f), - CVector(1040.6313f, -2.0793829f, 2.293175f), - CVector(1070.7863f, -2.084095f, 2.2789791f), - CVector(1100.5773f, -8.468729f, 5.3248072f), - CVector(1119.9341f, -31.738031f, 7.1913071f), - CVector(1122.1664f, -62.762737f, 7.4703908f), - CVector(1122.814f, -93.650566f, 8.5577497f), - CVector(1125.8253f, -124.26616f, 9.9803305f), - CVector(1153.8727f, -135.47169f, 14.150617f), - CVector(1184.0831f, -135.82845f, 14.973998f), - CVector(1192.0432f, -164.57816f, 19.18627f), - CVector(1192.7761f, -194.28871f, 24.799675f), - CVector(1215.1527f, -215.0714f, 25.74975f), - CVector(1245.79f, -215.39304f, 28.70726f), - CVector(1276.2477f, -216.39485f, 33.71236f), - CVector(1306.5535f, -216.71007f, 39.711472f), - CVector(1335.0244f, -224.59329f, 46.474979f), - CVector(1355.4879f, -246.27664f, 49.934841f), - CVector(1362.6003f, -276.47064f, 49.96265f), - CVector(1363.027f, -307.30847f, 49.969173f), - CVector(1365.343f, -338.08609f, 49.967789f), - CVector(1367.5957f, -368.01105f, 50.092304f), - CVector(1368.2749f, -398.38049f, 50.061268f), - CVector(1366.9034f, -429.98483f, 50.057545f), - CVector(1356.8534f, -459.09259f, 50.035545f), - CVector(1335.5819f, -481.13544f, 47.217903f), - CVector(1306.7552f, -491.07443f, 40.202629f), - CVector(1275.5978f, -491.33194f, 33.969223f), - CVector(1244.702f, -491.46451f, 29.111021f), - CVector(1213.2222f, -491.8754f, 25.771168f), - CVector(1182.7729f, -492.19995f, 24.749964f), - CVector(1152.6874f, -491.42221f, 21.70038f), - CVector(1121.5352f, -491.94604f, 20.075182f), - CVector(1090.7056f, -492.63751f, 17.585758f), - CVector(1059.6008f, -491.65762f, 14.848632f), - CVector(1029.113f, -489.66031f, 14.918498f), - CVector(998.20679f, -486.78107f, 14.945688f), - CVector(968.00555f, -484.91266f, 15.001229f), - CVector(937.74939f, -492.09015f, 14.958629f), - CVector(927.17352f, -520.97736f, 14.972308f), - CVector(929.29749f, -552.08643f, 14.978855f), - CVector(950.69525f, -574.47778f, 14.972788f), - CVector(974.02826f, -593.56024f, 14.966445f), - CVector(989.04779f, -620.12854f, 14.951016f), - CVector(1014.1639f, -637.3905f, 14.966736f), - CVector(1017.5961f, -667.3736f, 14.956415f), - CVector(1041.9735f, -685.94391f, 15.003841f), - CVector(1043.3064f, -716.11298f, 14.974236f), - CVector(1043.5337f, -746.63855f, 14.96919f), - CVector(1044.142f, -776.93823f, 14.965424f), - CVector(1044.2657f, -807.29395f, 14.97171f), - CVector(1017.0797f, -820.1076f, 14.975431f), - CVector(986.23865f, -820.37103f, 14.972883f), - CVector(956.10065f, -820.23291f, 14.981133f), - CVector(925.86914f, -820.19049f, 14.976553f), - CVector(897.69702f, -831.08734f, 14.962709f), - CVector(868.06586f, -835.99237f, 14.970685f), - CVector(836.93054f, -836.84387f, 14.965049f), - CVector(811.63586f, -853.7915f, 15.067576f), - CVector(811.46344f, -884.27368f, 12.247812f), - CVector(811.60651f, -914.70959f, 9.2393751f), - CVector(811.10425f, -945.16272f, 5.817255f), - CVector(816.54584f, -975.64587f, 4.998558f), - CVector(828.2951f, -1003.3685f, 5.0471172f), - CVector(852.28839f, -1021.5963f, 4.9371028f), - CVector(882.50067f, -1025.4459f, 5.14077f), - CVector(912.84821f, -1026.7874f, 8.3415451f), - CVector(943.68274f, -1026.6914f, 11.341879f), - CVector(974.4129f, -1027.3682f, 14.410345f), - CVector(1004.1079f, -1036.0778f, 14.92961f), - CVector(1030.1144f, -1051.1224f, 14.850387f), - CVector(1058.7585f, -1060.342f, 14.821624f), - CVector(1087.7797f, -1068.3263f, 14.800561f), - CVector(1099.8807f, -1095.656f, 11.877907f), - CVector(1130.0005f, -1101.994f, 11.853914f), - CVector(1160.3809f, -1101.6355f, 11.854824f), - CVector(1191.8524f, -1102.1577f, 11.853843f), - CVector(1223.3307f, -1102.7448f, 11.852233f), - CVector(1253.564f, -1098.1045f, 11.853944f), - CVector(1262.0203f, -1069.1785f, 14.8147f), - CVector(1290.9998f, -1059.1882f, 14.816016f), - CVector(1316.246f, -1041.0635f, 14.81109f), - CVector(1331.7539f, -1013.835f, 14.81207f), - CVector(1334.0579f, -983.55402f, 14.827253f), - CVector(1323.2429f, -954.23083f, 14.954678f), - CVector(1302.7495f, -932.21216f, 14.962917f), - CVector(1317.418f, -905.89325f, 14.967506f), - CVector(1337.9503f, -883.5025f, 14.969675f), - CVector(1352.6929f, -855.96954f, 14.967854f), - CVector(1357.2388f, -826.26971f, 14.97295f), - CVector(1384.8668f, -812.47693f, 12.907736f), - CVector(1410.8983f, -795.39056f, 12.052228f), - CVector(1433.901f, -775.55811f, 11.96265f), - CVector(1443.8615f, -746.92511f, 11.976114f), - CVector(1457.7015f, -720.00903f, 11.971177f), - CVector(1481.5685f, -701.30237f, 11.977908f), - CVector(1511.4004f, -696.83295f, 11.972709f), - CVector(1542.1796f, -695.61676f, 11.970441f), - CVector(1570.3301f, -684.6239f, 11.969202f), CVector(0.0f, 0.0f, 0.0f), }; @@ -1387,119 +1423,56 @@ CPacManPickups::GeneratePMPickUpsForRace(int32 race) void CPacManPickups::GenerateOnePMPickUp(CVector pos) { - bPMActive = true; - aPMPickUps[0].m_eType = PACMAN_RACE; - aPMPickUps[0].m_vecPosn = pos; } void CPacManPickups::Render() { - if (!bPMActive) return; - - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[6])); - - RwV3d pos; - float w, h; - - for (int i = 0; i < NUMPACMANPICKUPS; i++) { - switch (aPMPickUps[i].m_eType) - { - case PACMAN_SCRAMBLE: - case PACMAN_RACE: - if (CSprite::CalcScreenCoors(aPMPickUps[i].m_vecPosn, &pos, &w, &h, true) && pos.z < 100.0f) { - if (aPMPickUps[i].m_pObject != nil) { - aPMPickUps[i].m_pObject->GetMatrix().SetRotateZOnly((CTimer::GetTimeInMilliseconds() % 1024) * TWOPI / 1024.0f); - aPMPickUps[i].m_pObject->GetMatrix().UpdateRW(); - aPMPickUps[i].m_pObject->UpdateRwFrame(); - } - float fsin = Sin((CTimer::GetTimeInMilliseconds() % 1024) * 6.28f / 1024.0f); // yes, it is 6.28f when it was TWOPI just now... - CSprite::RenderOneXLUSprite(pos.x, pos.y, pos.z, 0.8f * w * fsin, 0.8f * h, 100, 50, 5, 255, 1.0f / pos.z, 255); - } - break; - default: - break; - } - } - - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, FALSE); } void CPacManPickups::ClearPMPickUps() { - bPMActive = false; - - for (int i = 0; i < NUMPACMANPICKUPS; i++) { - if (aPMPickUps[i].m_pObject != nil) { - CWorld::Remove(aPMPickUps[i].m_pObject); - delete aPMPickUps[i].m_pObject; - aPMPickUps[i].m_pObject = nil; - } - aPMPickUps[i].m_eType = PACMAN_NONE; - } } void CPacManPickups::StartPacManRace(int32 race) { - GeneratePMPickUpsForRace(race); - PillsEatenInRace = 0; } void CPacManPickups::StartPacManRecord() { - CollectGameState = 20; - LastPickUpCoors = FindPlayerCoors(); } uint32 CPacManPickups::QueryPowerPillsEatenInRace() { - return PillsEatenInRace; + return 0; } void CPacManPickups::ResetPowerPillsEatenInRace() { - PillsEatenInRace = 0; } void CPacManPickups::CleanUpPacManStuff() { - ClearPMPickUps(); } void CPacManPickups::StartPacManScramble(CVector pos, float scrambleMult, int16 count) { - GeneratePMPickUps(pos, scrambleMult, count, PACMAN_SCRAMBLE); } uint32 CPacManPickups::QueryPowerPillsCarriedByPlayer() { - if (FindPlayerVehicle()) - return FindPlayerVehicle()->m_nPacManPickupsCarried; return 0; } void CPacManPickups::ResetPowerPillsCarriedByPlayer() { - if (FindPlayerVehicle() != nil) { - FindPlayerVehicle()->m_nPacManPickupsCarried = 0; - FindPlayerVehicle()->m_fMass /= FindPlayerVehicle()->m_fForceMultiplier; - FindPlayerVehicle()->m_fTurnMass /= FindPlayerVehicle()->m_fForceMultiplier; - FindPlayerVehicle()->m_fForceMultiplier = 1.0f; - } } diff --git a/src/control/Pickups.h b/src/control/Pickups.h index d7d22174..6c3045f7 100644 --- a/src/control/Pickups.h +++ b/src/control/Pickups.h @@ -34,21 +34,23 @@ class CPickup { public: CVector m_vecPos; - uint32 m_nRevenue; + float m_fRevenue; CObject *m_pObject; CObject *m_pExtraObject; - uint16 m_nQuantity; + uint32 m_nQuantity; uint32 m_nTimer; - int16 m_nMoneySpeed; + uint16 m_nMoneySpeed; int16 m_eModelIndex; uint16 m_nIndex; char m_sTextKey[8]; ePickupType m_eType; bool m_bRemoved; - uint8 m_effects; + uint8 m_effects:1; + uint8 m_effects2:1; - CObject *GiveUsAPickUpObject(int32 handle); + CObject *GiveUsAPickUpObject(CObject **object, CObject **extraObject, int32 handle, int32 extraHandle); bool Update(CPlayerPed *player, CVehicle *vehicle, int playerId); + void GetRidOfObjects(); private: bool IsMine() { return m_eType >= PICKUP_MINE_INACTIVE && m_eType <= PICKUP_FLOATINGPACKAGE_FLOATING; } inline bool CanBePickedUp(CPlayerPed *player, int playerId); @@ -64,8 +66,9 @@ struct tPickupMessage eWeaponType m_weaponType; CVector2D m_dist; CRGBA m_color; - uint8 m_bOutOfStock : 1; + uint8 m_bOutOfStock; uint8 m_quantity; + uint16 money; }; class CPickups @@ -111,13 +114,13 @@ public: static CVector StaticCamCoors; static uint32 StaticCamStartTime; -//TODO(MIAMI) - static void RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo(eWeaponType) {} + static void RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo(eWeaponType); + static CPickup *FindPickUpForThisObject(CEntity*); }; -extern uint16 AmmoForWeapon[20]; -extern uint16 AmmoForWeapon_OnStreet[WEAPONTYPE_TOTALWEAPONS]; -extern uint16 CostOfWeapon[20]; +extern uint16 AmmoForWeapon[WEAPONTYPE_TOTALWEAPONS + 1]; +extern uint16 AmmoForWeapon_OnStreet[WEAPONTYPE_TOTALWEAPONS + 1]; +extern uint16 CostOfWeapon[WEAPONTYPE_TOTALWEAPONS + 3]; enum ePacmanPickupType { diff --git a/src/control/Record.cpp b/src/control/Record.cpp index 5e6c7cdb..9b4a21fc 100644 --- a/src/control/Record.cpp +++ b/src/control/Record.cpp @@ -10,6 +10,8 @@ #include "VehicleModelInfo.h" #include "World.h" +//--MIAMI: file done + uint16 CRecordDataForGame::RecordingState; void CRecordDataForGame::Init(void) diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 0aec58bb..4fdd3439 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -53,6 +53,8 @@ #include "Fluff.h" #include "WaterCreatures.h" +//--MIAMI: file done except TODO + uint8 CReplay::Mode; CAddressInReplayBuffer CReplay::Record; CAddressInReplayBuffer CReplay::Playback; @@ -160,7 +162,6 @@ static void(*CBArray[])(CAnimBlendAssociation*, void*) = &CPed::PedAnimShuffleCB, &CPed::DeleteSunbatheIdleAnimCB, &StartTalkingOnMobileCB, &FinishTalkingOnMobileCB }; -// --MIAMI: Done static uint8 FindCBFunctionID(void(*f)(CAnimBlendAssociation*, void*)) { for (int i = 0; i < sizeof(CBArray) / sizeof(*CBArray); i++){ @@ -171,13 +172,11 @@ static uint8 FindCBFunctionID(void(*f)(CAnimBlendAssociation*, void*)) return 0; } -// --MIAMI: Done static void(*FindCBFunction(uint8 id))(CAnimBlendAssociation*, void*) { return CBArray[id]; } -// --MIAMI: Done static void ApplyPanelDamageToCar(uint32 panels, CAutomobile* vehicle, bool flying) { if(vehicle->Damage.GetPanelStatus(VEHPANEL_FRONT_LEFT) != CDamageManager::GetPanelStatus(panels, VEHPANEL_FRONT_LEFT)){ @@ -210,7 +209,6 @@ static void ApplyPanelDamageToCar(uint32 panels, CAutomobile* vehicle, bool flyi } } -// --MIAMI: Done void PrintElementsInPtrList(void) { for (CPtrNode* node = CWorld::GetBigBuildingList(LEVEL_GENERIC).first; node; node = node->next) { @@ -218,7 +216,6 @@ void PrintElementsInPtrList(void) } } -// --MIAMI: Done void CReplay::Init(void) { pBuf0 = nil; @@ -261,20 +258,17 @@ void CReplay::Init(void) MarkEverythingAsNew(); } -// --MIAMI: Done void CReplay::DisableReplays(void) { bReplayEnabled = false; } -// --MIAMI: Done void CReplay::EnableReplays(void) { bReplayEnabled = true; } void PlayReplayFromHD(void); -// --MIAMI: Done void CReplay::Update(void) { if (CCutsceneMgr::IsCutsceneProcessing() || CPad::GetPad(0)->ArePlayerControlsDisabled() || CScriptPaths::IsOneActive() || FrontEndMenuManager.GetIsMenuActive()) { @@ -309,7 +303,6 @@ void CReplay::Update(void) } } -// --MIAMI: Done except TODO void CReplay::RecordThisFrame(void) { uint32 memory_required = sizeof(tGeneralPacket) + sizeof(tClockPacket) + sizeof(tWeatherPacket) + sizeof(tTimerPacket) + sizeof(tMiscPacket); @@ -394,10 +387,8 @@ void CReplay::RecordThisFrame(void) tBulletTracePacket* bt = (tBulletTracePacket*)&Record.m_pBase[Record.m_nOffset]; bt->type = REPLAYPACKET_BULLET_TRACES; bt->index = i; - bt->frames = CBulletTraces::aTraces[i].m_framesInUse; - bt->lifetime = CBulletTraces::aTraces[i].m_lifeTime; - bt->inf = CBulletTraces::aTraces[i].m_vecCurrentPos; - bt->sup = CBulletTraces::aTraces[i].m_vecTargetPos; + bt->inf = CBulletTraces::aTraces[i].m_vecStartPos; + bt->sup = CBulletTraces::aTraces[i].m_vecEndPos; Record.m_nOffset += sizeof(*bt); } tMiscPacket* misc = (tMiscPacket*)&Record.m_pBase[Record.m_nOffset]; @@ -413,7 +404,6 @@ void CReplay::RecordThisFrame(void) Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END; } -// --MIAMI: Done void CReplay::GoToNextBlock(void) { Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END; @@ -426,7 +416,6 @@ void CReplay::GoToNextBlock(void) MarkEverythingAsNew(); } -// --MIAMI: Done void CReplay::RecordParticle(tParticleType type, const CVector& vecPos, const CVector& vecDir, float fSize, const RwRGBA& color) { if (Record.m_nOffset > REPLAYBUFFERSIZE - 16 - sizeof(tParticlePacket)) @@ -449,7 +438,6 @@ void CReplay::RecordParticle(tParticleType type, const CVector& vecPos, const CV Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END; } -// --MIAMI: Done void CReplay::StorePedUpdate(CPed *ped, int id) { tPedUpdatePacket* pp = (tPedUpdatePacket*)&Record.m_pBase[Record.m_nOffset]; @@ -469,7 +457,6 @@ void CReplay::StorePedUpdate(CPed *ped, int id) Record.m_nOffset += sizeof(tPedUpdatePacket); } -// --MIAMI: Done void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state) { CAnimBlendAssociation* second; @@ -515,7 +502,6 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state) } } -// --MIAMI: Done void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState *state) { for (int i = 0; i < NUM_MAIN_ANIMS_IN_REPLAY; i++){ @@ -573,7 +559,6 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState } } -// --MIAMI: Done void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayBuffer *buffer) { tPedUpdatePacket *pp = (tPedUpdatePacket*)&buffer->m_pBase[buffer->m_nOffset]; @@ -618,14 +603,12 @@ void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayB buffer->m_nOffset += sizeof(tPedUpdatePacket); } -// --MIAMI: Done bool HasAnimGroupLoaded(uint8 group) { CAnimBlendAssocGroup* pGroup = &CAnimManager::GetAnimAssocGroups()[group]; return pGroup->animBlock && pGroup->animBlock->isLoaded; } -// --MIAMI: Done void CReplay::RetrievePedAnimation(CPed *ped, CStoredAnimationState *state) { CAnimBlendAssociation* anim1; @@ -669,7 +652,6 @@ void CReplay::RetrievePedAnimation(CPed *ped, CStoredAnimationState *state) } } -// --MIAMI: Done void CReplay::RetrieveDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState *state) { CAnimBlendAssociation* assoc; @@ -715,7 +697,6 @@ void CReplay::RetrieveDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationSt } } -// --MIAMI: Done void CReplay::PlaybackThisFrame(void) { static int FrameSloMo = 0; @@ -743,7 +724,6 @@ void CReplay::PlaybackThisFrame(void) // next two functions are only found in mobile version // most likely they were optimized out for being unused -// --MIAMI: Done void CReplay::TriggerPlaybackLastCoupleOfSeconds(uint32 start, uint8 cam_mode, float cam_x, float cam_y, float cam_z, uint32 slomo) { if (Mode != MODE_RECORD) @@ -755,7 +735,6 @@ void CReplay::TriggerPlaybackLastCoupleOfSeconds(uint32 start, uint8 cam_mode, f Mode = MODE_RECORD; } -// --MIAMI: Done bool CReplay::FastForwardToTime(uint32 start) { uint32 timer = 0; @@ -765,7 +744,6 @@ bool CReplay::FastForwardToTime(uint32 start) return true; } -// --MIAMI: Done void CReplay::StoreCarUpdate(CVehicle *vehicle, int id) { tVehicleUpdatePacket* vp = (tVehicleUpdatePacket*)&Record.m_pBase[Record.m_nOffset]; @@ -806,7 +784,6 @@ void CReplay::StoreCarUpdate(CVehicle *vehicle, int id) Record.m_nOffset += sizeof(tVehicleUpdatePacket); } -// --MIAMI: Done void CReplay::StoreBikeUpdate(CVehicle* vehicle, int id) { CBike* bike = (CBike*)vehicle; @@ -832,7 +809,6 @@ void CReplay::StoreBikeUpdate(CVehicle* vehicle, int id) Record.m_nOffset += sizeof(tBikeUpdatePacket); } -// --MIAMI: Done void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressInReplayBuffer *buffer) { tVehicleUpdatePacket* vp = (tVehicleUpdatePacket*)&buffer->m_pBase[buffer->m_nOffset]; @@ -906,7 +882,6 @@ void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressI ((CBoat*)vehicle)->m_fMovingSpeed = vp->skimmer_speed / 50.0f; } -// --MIAMI: Done void CReplay::ProcessBikeUpdate(CVehicle* vehicle, float interpolation, CAddressInReplayBuffer* buffer) { CBike* bike = (CBike*)vehicle; @@ -940,7 +915,6 @@ void CReplay::ProcessBikeUpdate(CVehicle* vehicle, float interpolation, CAddress CWorld::Add(vehicle); } -// --MIAMI: Done bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, float interpolation, uint32 *pTimer) { CBulletTraces::Init(); @@ -1141,10 +1115,8 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo { tBulletTracePacket* pb = (tBulletTracePacket*)&ptr[offset]; CBulletTraces::aTraces[pb->index].m_bInUse = true; - CBulletTraces::aTraces[pb->index].m_framesInUse = pb->frames; - CBulletTraces::aTraces[pb->index].m_lifeTime = pb->lifetime; - CBulletTraces::aTraces[pb->index].m_vecCurrentPos = pb->inf; - CBulletTraces::aTraces[pb->index].m_vecTargetPos = pb->sup; + CBulletTraces::aTraces[pb->index].m_vecStartPos = pb->inf; + CBulletTraces::aTraces[pb->index].m_vecEndPos = pb->sup; buffer->m_nOffset += sizeof(tBulletTracePacket); break; } @@ -1197,7 +1169,6 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo return false; } -// --MIAMI: Done void CReplay::FinishPlayback(void) { if (Mode != MODE_PLAYBACK) @@ -1220,7 +1191,6 @@ void CReplay::FinishPlayback(void) DMAudio.SetMusicFadeVol(127); } -// --MIAMI: Done void CReplay::EmptyReplayBuffer(void) { if (Mode == MODE_PLAYBACK) @@ -1236,7 +1206,6 @@ void CReplay::EmptyReplayBuffer(void) MarkEverythingAsNew(); } -// --MIAMI: Done void CReplay::ProcessReplayCamera(void) { switch (CameraMode) { @@ -1283,7 +1252,6 @@ void CReplay::ProcessReplayCamera(void) extern CWeaponEffects gCrossHair; -// --MIAMI: Done except TODO void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene) { if (Mode != MODE_RECORD) @@ -1343,7 +1311,6 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca CDraw::SetFOV(70.0f); } -// --MIAMI: Done void CReplay::StoreStuffInMem(void) { #ifdef FIX_BUGS @@ -1430,7 +1397,6 @@ void CReplay::StoreStuffInMem(void) CScriptPaths::Save_ForReplay(); } -// --MIAMI: Done void CReplay::RestoreStuffFromMem(void) { CPools::GetVehiclePool()->CopyBack(pBuf0, pBuf1); @@ -1655,7 +1621,6 @@ void CReplay::RestoreStuffFromMem(void) DMAudio.ChangeMusicMode(MUSICMODE_GAME); } -// --MIAMI: Done void CReplay::EmptyPedsAndVehiclePools(void) { int i = CPools::GetVehiclePool()->GetSize(); @@ -1676,7 +1641,6 @@ void CReplay::EmptyPedsAndVehiclePools(void) } } -// --MIAMI: Done void CReplay::EmptyAllPools(void) { EmptyPedsAndVehiclePools(); @@ -1698,7 +1662,6 @@ void CReplay::EmptyAllPools(void) } } -// --MIAMI: Done void CReplay::MarkEverythingAsNew(void) { int i = CPools::GetVehiclePool()->GetSize(); @@ -1748,7 +1711,6 @@ void CReplay::SaveReplayToHD(void) CFileMgr::SetDir(""); } -// --MIAMI: Done void PlayReplayFromHD(void) { CFileMgr::SetDirMyDocuments(); @@ -1781,7 +1743,6 @@ void PlayReplayFromHD(void) CReplay::StreamAllNecessaryCarsAndPeds(); } -// --MIAMI: Done void CReplay::StreamAllNecessaryCarsAndPeds(void) { for (int slot = 0; slot < NUM_REPLAYBUFFERS; slot++) { @@ -1806,7 +1767,6 @@ void CReplay::StreamAllNecessaryCarsAndPeds(void) CStreaming::LoadAllRequestedModels(false); } -// --MIAMI: Done void CReplay::FindFirstFocusCoordinate(CVector *coord) { *coord = CVector(0.0f, 0.0f, 0.0f); @@ -1822,7 +1782,6 @@ void CReplay::FindFirstFocusCoordinate(CVector *coord) } } -// --MIAMI: Done bool CReplay::ShouldStandardCameraBeProcessed(void) { if (Mode != MODE_PLAYBACK) @@ -1832,7 +1791,6 @@ bool CReplay::ShouldStandardCameraBeProcessed(void) return FindPlayerVehicle() != nil; } -// --MIAMI: Done void CReplay::ProcessLookAroundCam(void) { if (!bAllowLookAroundCam) @@ -1889,7 +1847,6 @@ void CReplay::ProcessLookAroundCam(void) RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera)); } -// --MIAMI: Done size_t CReplay::FindSizeOfPacket(uint8 type) { switch (type) { @@ -1911,7 +1868,6 @@ size_t CReplay::FindSizeOfPacket(uint8 type) return 0; } -// --MIAMI: Done (function didn't change since III and we already had it modified) void CReplay::Display() { static int TimeCount = 0; diff --git a/src/control/Restart.cpp b/src/control/Restart.cpp index 8fa018d6..052e6b61 100644 --- a/src/control/Restart.cpp +++ b/src/control/Restart.cpp @@ -4,6 +4,8 @@ #include "Zones.h" #include "PathFind.h" +//--MIAMI: file done + uint8 CRestart::OverrideHospitalLevel; uint8 CRestart::OverridePoliceStationLevel; bool CRestart::bFadeInAfterNextArrest; diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp index e7831b82..dee2cbe3 100644 --- a/src/control/RoadBlocks.cpp +++ b/src/control/RoadBlocks.cpp @@ -236,7 +236,7 @@ CRoadBlocks::CreateRoadBlockBetween2Points(CVector point1, CVector point2) tmp.GetPosition().z += fModelRadius - 0.6f; pVehicle->m_matrix = tmp; pVehicle->PlaceOnRoadProperly(); - pVehicle->bIsStatic = false; + pVehicle->SetIsStatic(false); pVehicle->m_matrix.UpdateRW(); pVehicle->m_nDoorLock = CARLOCK_UNLOCKED; CCarCtrl::JoinCarWithRoadSystem(pVehicle); diff --git a/src/control/SceneEdit.cpp b/src/control/SceneEdit.cpp index a7727fde..21512290 100644 --- a/src/control/SceneEdit.cpp +++ b/src/control/SceneEdit.cpp @@ -20,6 +20,8 @@ #include "WeaponInfo.h" #include "World.h" +//--MIAMI: file done + bool CSceneEdit::m_bEditOn; int32 CSceneEdit::m_bCameraFollowActor; bool CSceneEdit::m_bRecording; @@ -1070,7 +1072,7 @@ bool CSceneEdit::SelectWeapon(void) } if (CPad::GetPad(1)->GetLeftShoulder1JustDown()) { if (++m_nWeaponType >= WEAPONTYPE_DETONATOR) - m_nWeaponType = WEAPONTYPE_BASEBALLBAT; + m_nWeaponType = WEAPONTYPE_BRASSKNUCKLE; pActors[m_nActor]->ClearWeapons(); pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000); pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId); @@ -1078,7 +1080,7 @@ bool CSceneEdit::SelectWeapon(void) } else if (CPad::GetPad(1)->GetRightShoulder1JustDown()){ if (--m_nWeaponType <= WEAPONTYPE_UNARMED) - m_nWeaponType = WEAPONTYPE_GRENADE; + m_nWeaponType = WEAPONTYPE_MINIGUN; pActors[m_nActor]->ClearWeapons(); pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000); pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId); diff --git a/src/control/Script.cpp b/src/control/Script.cpp index aa4e109f..86c9e86e 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -31,6 +31,7 @@ #include "GameLogic.h" #include "Garages.h" #include "General.h" +#include "Glass.h" #ifdef MISSION_REPLAY #include "GenericGameStorage.h" #endif @@ -1704,7 +1705,7 @@ static void PossiblyWakeThisEntity(CPhysical* pEntity, bool ifColLoaded = false) return; if (!ifColLoaded || CColStore::HasCollisionLoaded(pEntity->GetPosition())) { pEntity->bIsStaticWaitingForCollision = false; - if (!pEntity->IsStatic()) + if (!pEntity->GetIsStatic()) pEntity->AddToMovingList(); } } @@ -1804,9 +1805,8 @@ void CMissionCleanup::Process() if (!CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) TheCamera.Restore(); TheCamera.SetWideScreenOff(); - // TODO(MIAMI) - //CSpecialFX::bLiftCam = false; - //CSpecialFX::bVideoCam = false; + CSpecialFX::bLiftCam = false; + CSpecialFX::bVideoCam = false; CTimeCycle::StopExtraColour(0); for (int i = 0; i < MISSION_AUDIO_SLOTS; i++) DMAudio.ClearMissionAudio(i); @@ -1817,7 +1817,7 @@ void CMissionCleanup::Process() CStreaming::SetMissionDoesntRequireModel(MI_CUTOBJ01 + i); CStreaming::ms_disableStreaming = false; CHud::m_ItemToFlash = -1; - CHud::SetHelpMessage(nil, false); // TODO(MIAMI): third parameter is false + CHud::SetHelpMessage(nil, false); CUserDisplay::OnscnTimer.m_bDisabled = false; CTheScripts::RemoveScriptTextureDictionary(); CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByCops = false; @@ -1827,7 +1827,7 @@ void CMissionCleanup::Process() CWorld::Players[0].m_pPed->m_nDrunkCountdown = 0; CPad::GetPad(0)->SetDrunkInputDelay(0); CWorld::Players[0].m_bDriveByAllowed = true; - // DMAudio::ShutUpPlayerTalking(0); // TODO(Miami) + DMAudio.ShutUpPlayerTalking(0); CVehicle::bDisableRemoteDetonation = false; CVehicle::bDisableRemoteDetonationOnContact = false; CGameLogic::ClearShortCut(); @@ -2381,9 +2381,11 @@ void CTheScripts::Process() case 4: AllowMissionReplay = 5; RetryMission(0, 0); + break; case 6: AllowMissionReplay = 7; TimeToWaitTill = CTimer::GetTimeInMilliseconds() + 500; + break; case 7: if (TimeToWaitTill < CTimer::GetTimeInMilliseconds()) { AllowMissionReplay = 0; @@ -3971,7 +3973,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel(); - car->bIsStatic = false; + car->SetIsStatic(false); /* Again weird usage of virtual functions. */ if (car->IsBoat()) { car->Teleport(pos); @@ -4124,6 +4126,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CMessages::AddMessageJumpQ(key, ScriptParams[0], ScriptParams[1]); return 0; } + /* case COMMAND_PRINT_SOON: { wchar* key = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -4131,6 +4134,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CMessages::AddMessageSoon(key, ScriptParams[0], ScriptParams[1]); return 0; } + */ case COMMAND_CLEAR_PRINTS: CMessages::ClearMessages(); return 0; @@ -5383,22 +5387,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) case COMMAND_ADD_ONE_OFF_SOUND: { CollectParameters(&m_nIp, 4); - // TODO(MIAMI) - // SOUND_PART_MISSION_COMPLETE == 1 - // SOUND_RACE_START_3 == 7 - // SOUND_RACE_START_2 == 8 - // SOUND_RACE_START_1 == 9 - // SOUND_RACE_START_GO == 10 - // SOUND_AMMUNATION_BUY_WEAPON == 13 - // SOUND_AMMUNATION_BUY_WEAPON_DENIED == 14 - // SOUND_AMMUNATION_IMRAN_ARM_BOMB == 16 switch (ScriptParams[3]) { - case SCRIPT_SOUND_EVIDENCE_PICKUP: - DMAudio.PlayFrontEndSound(SOUND_EVIDENCE_PICKUP, 0); - return 0; - case SCRIPT_SOUND_UNLOAD_GOLD: - DMAudio.PlayFrontEndSound(SOUND_UNLOAD_GOLD, 0); - return 0; case SCRIPT_SOUND_PART_MISSION_COMPLETE: DMAudio.PlayFrontEndSound(SOUND_PART_MISSION_COMPLETE, 0); return 0; @@ -5414,6 +5403,15 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) case SCRIPT_SOUND_RACE_START_GO: DMAudio.PlayFrontEndSound(SOUND_RACE_START_GO, 0); return 0; + case SCRIPT_SOUND_AMMUNATION_BUY_WEAPON: + DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON_BOUGHT, 0); + return 0; + case SCRIPT_SOUND_AMMUNATION_BUY_WEAPON_DENIED: + DMAudio.PlayFrontEndSound(SOUND_GARAGE_NO_MONEY, 0); + return 0; + case SCRIPT_SOUND_IMRAN_ARM_BOMB: + DMAudio.PlayFrontEndSound(SOUND_AMMUNATION_IMRAN_ARM_BOMB, 0); + return 0; default: break; } @@ -6372,7 +6370,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) } case COMMAND_ADD_EXPLOSION: CollectParameters(&m_nIp, 4); - CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0); + CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, true); return 0; case COMMAND_IS_CAR_UPRIGHT: @@ -7042,7 +7040,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); CCoronas::RegisterCorona((uintptr)this + m_nIp, ScriptParams[6], ScriptParams[7], ScriptParams[8], - 255, pos, *(float*)&ScriptParams[3], 150.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f); // TODO(MIAMI): more params + 255, pos, *(float*)&ScriptParams[3], 150.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f); return 0; } case COMMAND_DRAW_LIGHT: @@ -7497,7 +7495,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); - CPathNode* pNode = &ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, 1, 999999.9f)]; + CPathNode* pNode = &ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, 1, 999999.9f, true)]; *(CVector*)&ScriptParams[0] = pNode->GetPosition(); StoreParameters(&m_nIp, 3); return 0; @@ -7508,8 +7506,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); - CPathNode* pNode = &ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f)]; - *(CVector*)&ScriptParams[0] = pNode->GetPosition(); + *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true)); StoreParameters(&m_nIp, 3); return 0; } @@ -8760,11 +8757,11 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) } case COMMAND_INDUSTRIAL_PASSED: CStats::IndustrialPassed = true; - DMAudio.PlayRadioAnnouncement(13); //TODO: enum? + DMAudio.PlayRadioAnnouncement(STREAMED_SOUND_ANNOUNCE_COMMERCIAL_OPEN); return 0; case COMMAND_COMMERCIAL_PASSED: CStats::CommercialPassed = true; - DMAudio.PlayRadioAnnouncement(14); //TODO: enum? + DMAudio.PlayRadioAnnouncement(STREAMED_SOUND_ANNOUNCE_SUBURBAN_OPEN); return 0; case COMMAND_SUBURBAN_PASSED: CStats::SuburbanPassed = true; @@ -8978,7 +8975,6 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CollectParameters(&m_nIp, 1); char zone[KEY_LENGTH_IN_SCRIPT]; CTheScripts::ReadTextLabelFromScript(&m_nIp, zone); -// TODO(MIAMI): just getting this to compile with new argument int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_DEFAULT); if (zone_id != -1) m_nIp += KEY_LENGTH_IN_SCRIPT; @@ -9649,13 +9645,13 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) script_assert(pObject); if (ScriptParams[1]) { if (pObject->bIsStatic) { - pObject->bIsStatic = false; + pObject->SetIsStatic(false); pObject->AddToMovingList(); } } else { if (!pObject->bIsStatic) { - pObject->bIsStatic = true; + pObject->SetIsStatic(true); pObject->RemoveFromMovingList(); } } @@ -10344,8 +10340,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); int node = ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true); - // TODO(MIAMI): replace GetPosition with FindNodeCoorsForScript - *(CVector*)&ScriptParams[0] = ThePaths.m_pathNodes[node].GetPosition(); + *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(node); *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacement(node); StoreParameters(&m_nIp, 4); return 0; @@ -11204,7 +11199,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) return 0; */ case COMMAND_ARE_ANY_CAR_CHEATS_ACTIVATED: - UpdateCompareFlag(CVehicle::bAllDodosCheat || CVehicle::bCheat3 || CVehicle::bHoverCheat || CVehicle::bCheat8); // TODO(MIAMI): more cheats! + UpdateCompareFlag(CVehicle::bAllDodosCheat || CVehicle::bCheat3 || CVehicle::bHoverCheat || CVehicle::bCheat8 || CVehicle::bCheat9); return 0; case COMMAND_SET_CHAR_SUFFERS_CRITICAL_HITS: { @@ -12284,10 +12279,20 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_GET_CLOSEST_STRAIGHT_ROAD: { CollectParameters(&m_nIp, 5); - debug("GET_CLOSEST_STRAIGHT_ROAD not implemented!\n"); - for (int i = 0; i < 7; i++) - ScriptParams[i] = 0; - StoreParameters(&m_nIp, 7); // TODO(MIAMI) + int node1, node2; + float angle; + ThePaths.FindNodePairClosestToCoors(*(CVector*)&ScriptParams[0], PATH_CAR, &node1, &node2, &angle, + *(float*)&ScriptParams[3], *(float*)&ScriptParams[4], true, true); + if (node1 == -1) { + for (int i = 0; i < 7; i++) + ScriptParams[i] = 0; + } + else { + *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(node1); + *(CVector*)&ScriptParams[3] = ThePaths.FindNodeCoorsForScript(node2); + *(float*)&ScriptParams[6] = angle; + } + StoreParameters(&m_nIp, 7); return 0; } case COMMAND_SET_CAR_FORWARD_SPEED: @@ -12395,7 +12400,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_SWITCH_SECURITY_CAMERA: { CollectParameters(&m_nIp, 1); - debug("SWITCH_SECURITY_CAMERA is not implemented\n"); // TODO(MIAMI) + CSpecialFX::bVideoCam = ScriptParams[0] != 0; return 0; } //case COMMAND_IS_CHAR_IN_FLYING_VEHICLE: @@ -12461,9 +12466,11 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_GET_NTH_CLOSEST_CAR_NODE: { CollectParameters(&m_nIp, 4); - debug("GET_NTH_CLOSEST_CAR_NODE is not implemented\n"); // TODO(MIAMI) - ScriptParams[0] = 0; - StoreParameters(&m_nIp, 1); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= MAP_Z_LOW_LIMIT) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(ThePaths.FindNthNodeClosestToCoors(pos, 0, 999999.9f, true, true, ScriptParams[3] - 1)); + StoreParameters(&m_nIp, 3); return 0; } //case COMMAND_GET_NTH_CLOSEST_CHAR_NODE: @@ -12833,7 +12840,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_SWITCH_LIFT_CAMERA: { CollectParameters(&m_nIp, 1); - debug("SWITCH_LIFT_CAMERA is not implemented\n"); // TODO(MIAMI) + CSpecialFX::bLiftCam = ScriptParams[0] != 0; return 0; } case COMMAND_CLOSE_ALL_CAR_DOORS: @@ -12896,7 +12903,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_PRINT_HELP_FOREVER: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); - CHud::SetHelpMessage(text, false); // TODO(MIAMI): third param is true + CHud::SetHelpMessage(text, false, true); return 0; } //case COMMAND_PRINT_HELP_FOREVER_WITH_NUMBER: @@ -13002,12 +13009,12 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_HAS_GLASS_BEEN_SHATTERED_NEARBY: { CollectParameters(&m_nIp, 3); - static bool bShowed = false; - if (!bShowed) { - debug("HAS_GLASS_BEEN_SHATTERED_NEARBY not implemented, default to TRUE\n"); // TODO(MIAMI) - bShowed = true; - } - UpdateCompareFlag(true); + + bool shattered = false; + if ( CGlass::HasGlassBeenShatteredAtCoors(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2]) ) + shattered = true; + + UpdateCompareFlag(shattered); return 0; } case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_BONE: @@ -13252,7 +13259,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_SET_TONIGHTS_EVENT: { CollectParameters(&m_nIp, 1); - debug("skipping SET_TONIGHTS_EVENT\n"); // TODO(MIAMI) + CScrollBar::TonightsEvent = ScriptParams[0]; return 0; } case COMMAND_CLEAR_CHAR_LAST_DAMAGE_ENTITY: @@ -13416,9 +13423,9 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; script_assert(pPed); if (pPed->bInVehicle) { - if (pPed->GetWeapon(5).m_eWeaponType) { // TODO(MIAMI): enum - if (pPed->GetWeapon(5).m_nAmmoTotal < ScriptParams[1]) - pPed->SetAmmo(pPed->GetWeapon(5).m_eWeaponType, ScriptParams[1]); + if (pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType) { + if (pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_nAmmoTotal < ScriptParams[1]) + pPed->SetAmmo(pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType, ScriptParams[1]); } else { pPed->GiveWeapon(WEAPONTYPE_UZI, ScriptParams[1], true); @@ -13440,7 +13447,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_ADD_EXPLOSION_NO_SOUND: { CollectParameters(&m_nIp, 4); - CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0); // TODO(MIAMI): last arg is 0 + CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, false); return 0; } case COMMAND_SET_OBJECT_AREA_VISIBLE: @@ -13716,7 +13723,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) pVehicle->bDontLoadCollision = true; if (pVehicle->bIsStaticWaitingForCollision) { pVehicle->bIsStaticWaitingForCollision = false; - if (!pVehicle->IsStatic()) + if (!pVehicle->GetIsStatic()) pVehicle->AddToMovingList(); } } @@ -13739,7 +13746,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) pPed->bDontLoadCollision = true; if (pPed->bIsStaticWaitingForCollision) { pPed->bIsStaticWaitingForCollision = false; - if (!pPed->IsStatic()) + if (!pPed->GetIsStatic()) pPed->AddToMovingList(); } } diff --git a/src/control/Script.h b/src/control/Script.h index ac11f967..8949fe05 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -288,8 +288,8 @@ class CTheScripts static uint16 ScriptsUpdated; static uint32 LastMissionPassedTime; static uint16 NumberOfExclusiveMissionScripts; - static bool bPlayerIsInTheStatium; public: + static bool bPlayerIsInTheStatium; static uint8 RiotIntensity; static bool bPlayerHasMetDebbieHarry; public: @@ -563,4 +563,4 @@ void RetryMission(int, int); #ifdef USE_DEBUG_SCRIPT_LOADER extern int scriptToLoad; -#endif
\ No newline at end of file +#endif diff --git a/src/control/TrafficLights.cpp b/src/control/TrafficLights.cpp index 5559b1c4..ecfc7207 100644 --- a/src/control/TrafficLights.cpp +++ b/src/control/TrafficLights.cpp @@ -15,8 +15,7 @@ #include "Weather.h" #include "World.h" -// TODO: figure out the meaning of this -enum { SOME_FLAG = 0x80 }; +//--MIAMI: file done bool CTrafficLights::bGreenLightsCheat; @@ -28,113 +27,286 @@ CTrafficLights::DisplayActualLight(CEntity *ent) int phase; if(FindTrafficLightType(ent) == 1) - phase = LightForCars1(); + phase = LightForCars1_Visual(); else - phase = LightForCars2(); - - int i; - CBaseModelInfo *mi = CModelInfo::GetModelInfo(ent->GetModelIndex()); - float x = mi->Get2dEffect(0)->pos.x; - float yMin = mi->Get2dEffect(0)->pos.y; - float yMax = mi->Get2dEffect(0)->pos.y; - float zMin = mi->Get2dEffect(0)->pos.z; - float zMax = mi->Get2dEffect(0)->pos.z; - for(i = 1; i < 6; i++){ - assert(mi->Get2dEffect(i)); - yMin = Min(yMin, mi->Get2dEffect(i)->pos.y); - yMax = Max(yMax, mi->Get2dEffect(i)->pos.y); - zMin = Min(zMin, mi->Get2dEffect(i)->pos.z); - zMax = Max(zMax, mi->Get2dEffect(i)->pos.z); + phase = LightForCars2_Visual(); + + int i, m = ent->GetModelIndex(); + if (MI_TRAFFICLIGHTS == m) { + CBaseModelInfo* mi = CModelInfo::GetModelInfo(ent->GetModelIndex()); + float x = mi->Get2dEffect(0)->pos.x; + float yMin = mi->Get2dEffect(0)->pos.y; + float yMax = mi->Get2dEffect(0)->pos.y; + float zMin = mi->Get2dEffect(0)->pos.z; + float zMax = mi->Get2dEffect(0)->pos.z; + for (i = 1; i < 6; i++) { + assert(mi->Get2dEffect(i)); + yMin = Min(yMin, mi->Get2dEffect(i)->pos.y); + yMax = Max(yMax, mi->Get2dEffect(i)->pos.y); + zMin = Min(zMin, mi->Get2dEffect(i)->pos.z); + zMax = Max(zMax, mi->Get2dEffect(i)->pos.z); + } + + CVector pos1, pos2; + uint8 r, g; + int id; + switch (phase) { + case CAR_LIGHTS_GREEN: + r = 0; + g = 255; + pos1 = ent->GetMatrix() * CVector(x, yMax, zMin); + pos2 = ent->GetMatrix() * CVector(x, yMin, zMin); + id = 0; + break; + case CAR_LIGHTS_YELLOW: + r = 255; + g = 128; + pos1 = ent->GetMatrix() * CVector(x, yMax, (zMin + zMax) / 2.0f); + pos2 = ent->GetMatrix() * CVector(x, yMin, (zMin + zMax) / 2.0f); + id = 1; + break; + case CAR_LIGHTS_RED: + r = 255; + g = 0; + pos1 = ent->GetMatrix() * CVector(x, yMax, zMax); + pos2 = ent->GetMatrix() * CVector(x, yMin, zMax); + id = 2; + break; + default: + r = 0; + g = 0; + pos1 = ent->GetMatrix() * CVector(x, yMax, (zMin + zMax) / 2.0f); + pos2 = ent->GetMatrix() * CVector(x, yMin, (zMin + zMax) / 2.0f); + id = -1; + break; + } + + if (CWeather::TrafficLightBrightness > 0.5f) + CPointLights::AddLight(CPointLights::LIGHT_POINT, + pos1, CVector(0.0f, 0.0f, 0.0f), 8.0f, + r / 255.0f, g / 255.0f, 0 / 255.0f, CPointLights::FOG_NORMAL, true); + + if (CWeather::TrafficLightBrightness > 0.05f) + CShadows::StoreStaticShadow((uintptr)ent, + SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos1, + 8.0f, 0.0f, 0.0f, -8.0f, 128, + r * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + g * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 0 * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 12.0f, 1.0f, 40.0f, false, 0.0f); + + if (DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f) + CCoronas::RegisterCorona((uintptr)ent + id, + r * CTimeCycle::GetSpriteBrightness() * 0.7f, + g * CTimeCycle::GetSpriteBrightness() * 0.7f, + 0 * CTimeCycle::GetSpriteBrightness() * 0.7f, + 255, + pos1, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, + CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + else + CCoronas::RegisterCorona((uintptr)ent + id + 3, + r * CTimeCycle::GetSpriteBrightness() * 0.7f, + g * CTimeCycle::GetSpriteBrightness() * 0.7f, + 0 * CTimeCycle::GetSpriteBrightness() * 0.7f, + 255, + pos2, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, + CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + + CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); + CBrightLights::RegisterOne(pos2, ent->GetUp(), -ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); } + else if (MI_TRAFFICLIGHTS_VERTICAL == m) { + CBaseModelInfo* mi = CModelInfo::GetModelInfo(ent->GetModelIndex()); + float x = mi->Get2dEffect(0)->pos.x; + float yMin = mi->Get2dEffect(0)->pos.y; + float yMax = mi->Get2dEffect(0)->pos.y; + float zMin = mi->Get2dEffect(0)->pos.z; + float zMax = mi->Get2dEffect(0)->pos.z; + for (i = 1; i < 6; i++) { + assert(mi->Get2dEffect(i)); + yMin = Min(yMin, mi->Get2dEffect(i)->pos.y); + yMax = Max(yMax, mi->Get2dEffect(i)->pos.y); + zMin = Min(zMin, mi->Get2dEffect(i)->pos.z); + zMax = Max(zMax, mi->Get2dEffect(i)->pos.z); + } + + CVector pos1; + uint8 r, g; + int id; + switch (phase) { + case CAR_LIGHTS_GREEN: + r = 0; + g = 255; + pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos; + id = 0; + break; + case CAR_LIGHTS_YELLOW: + r = 255; + g = 128; + pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos; + id = 1; + break; + case CAR_LIGHTS_RED: + r = 255; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(0)->pos; + id = 2; + break; + default: + r = 0; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos; + id = -1; + break; + } - CVector pos1, pos2; - uint8 r, g; - int id; - switch(phase){ - case CAR_LIGHTS_GREEN: - r = 0; - g = 255; - pos1 = ent->GetMatrix() * CVector(x, yMax, zMin); - pos2 = ent->GetMatrix() * CVector(x, yMin, zMin); - id = 0; - break; - case CAR_LIGHTS_YELLOW: - r = 255; - g = 128; - pos1 = ent->GetMatrix() * CVector(x, yMax, (zMin+zMax)/2.0f); - pos2 = ent->GetMatrix() * CVector(x, yMin, (zMin+zMax)/2.0f); - id = 1; - break; - case CAR_LIGHTS_RED: - default: - r = 255; - g = 0; - pos1 = ent->GetMatrix() * CVector(x, yMax, zMax); - pos2 = ent->GetMatrix() * CVector(x, yMin, zMax); - id = 2; - break; + CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); + + if (CWeather::TrafficLightBrightness > 0.5f) + CPointLights::AddLight(CPointLights::LIGHT_POINT, + pos1, CVector(0.0f, 0.0f, 0.0f), 8.0f, + r / 255.0f, g / 255.0f, 0 / 255.0f, CPointLights::FOG_NORMAL, true); + + if (CWeather::TrafficLightBrightness > 0.05f) + CShadows::StoreStaticShadow((uintptr)ent, + SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos1, + 8.0f, 0.0f, 0.0f, -8.0f, 128, + r * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + g * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 0 * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 12.0f, 1.0f, 40.0f, false, 0.0f); + + if (DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f) + CCoronas::RegisterCorona((uintptr)ent + id, + r * CTimeCycle::GetSpriteBrightness() * 0.7f, + g * CTimeCycle::GetSpriteBrightness() * 0.7f, + 0 * CTimeCycle::GetSpriteBrightness() * 0.7f, + 255, + pos1, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, + CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); } + else if (MI_TRAFFICLIGHTS_MIAMI == m || MI_TRAFFICLIGHTS_TWOVERTICAL == m) { + CBaseModelInfo* mi = CModelInfo::GetModelInfo(ent->GetModelIndex()); + CVector pos1, pos2; + uint8 r, g; + int id; + if (MI_TRAFFICLIGHTS_MIAMI == m) { + switch (phase) { + case CAR_LIGHTS_GREEN: + r = 0; + g = 255; + pos1 = ent->GetMatrix() * mi->Get2dEffect(4)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(5)->pos; + id = 0; + break; + case CAR_LIGHTS_YELLOW: + r = 255; + g = 128; + pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(3)->pos; + id = 1; + break; + case CAR_LIGHTS_RED: + r = 255; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(0)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(1)->pos; + id = 2; + break; + default: + r = 0; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(3)->pos; + id = -1; + break; + } + } + else { + switch (phase) { + case CAR_LIGHTS_GREEN: + r = 0; + g = 255; + pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(5)->pos; + id = 0; + break; + case CAR_LIGHTS_YELLOW: + r = 255; + g = 128; + pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(4)->pos; + id = 1; + break; + case CAR_LIGHTS_RED: + r = 255; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(0)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(3)->pos; + id = 2; + break; + default: + r = 0; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(4)->pos; + id = -1; + break; + } + } - if(CClock::GetHours() > 19 || CClock::GetHours() < 6 || CWeather::Foggyness > 0.05f) - CPointLights::AddLight(CPointLights::LIGHT_POINT, - pos1, CVector(0.0f, 0.0f, 0.0f), 8.0f, - r/255.0f, g/255.0f, 0/255.0f, CPointLights::FOG_NORMAL, true); - - CShadows::StoreStaticShadow((uintptr)ent, - SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos1, - 8.0f, 0.0f, 0.0f, -8.0f, 128, - r*CTimeCycle::GetLightOnGroundBrightness()/8.0f, - g*CTimeCycle::GetLightOnGroundBrightness()/8.0f, - 0*CTimeCycle::GetLightOnGroundBrightness()/8.0f, - 12.0f, 1.0f, 40.0f, false, 0.0f); - - if(DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f) - CCoronas::RegisterCorona((uintptr)ent + id, - r*CTimeCycle::GetSpriteBrightness()*0.7f, - g*CTimeCycle::GetSpriteBrightness()*0.7f, - 0*CTimeCycle::GetSpriteBrightness()*0.7f, - 255, - pos1, 1.75f*CTimeCycle::GetSpriteSize(), 50.0f, - CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, - CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); - else - CCoronas::RegisterCorona((uintptr)ent + id + 3, - r*CTimeCycle::GetSpriteBrightness()*0.7f, - g*CTimeCycle::GetSpriteBrightness()*0.7f, - 0*CTimeCycle::GetSpriteBrightness()*0.7f, - 255, - pos2, 1.75f*CTimeCycle::GetSpriteSize(), 50.0f, - CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, - CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); - - CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); - CBrightLights::RegisterOne(pos2, ent->GetUp(), -ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); - -/* - static const float top = -0.127f; - static const float bot = -0.539f; - static const float mid = bot + (top-bot)/3.0f; - static const float left = 1.256f; - static const float right = 0.706f; - phase = CTrafficLights::LightForPeds(); - if(phase == PED_LIGHTS_DONT_WALK){ - CVector p0(2.7f, right, top); - CVector p1(2.7f, left, top); - CVector p2(2.7f, right, mid); - CVector p3(2.7f, left, mid); - CShinyTexts::RegisterOne(ent->GetMatrix()*p0, ent->GetMatrix()*p1, ent->GetMatrix()*p2, ent->GetMatrix()*p3, - 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, - SHINYTEXT_WALK, 255, 0, 0, 60.0f); - }else if(phase == PED_LIGHTS_WALK || CTimer::GetTimeInMilliseconds() & 0x100){ - CVector p0(2.7f, right, mid); - CVector p1(2.7f, left, mid); - CVector p2(2.7f, right, bot); - CVector p3(2.7f, left, bot); - CShinyTexts::RegisterOne(ent->GetMatrix()*p0, ent->GetMatrix()*p1, ent->GetMatrix()*p2, ent->GetMatrix()*p3, - 1.0f, 0.5f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f, - SHINYTEXT_WALK, 255, 255, 255, 60.0f); + CVector pos = (pos1 + pos2) / 2; + if (id >= 0) { + CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); + CBrightLights::RegisterOne(pos2, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); + } + + if (CWeather::TrafficLightBrightness > 0.5f) + CPointLights::AddLight(CPointLights::LIGHT_POINT, + pos, CVector(0.0f, 0.0f, 0.0f), 8.0f, + r / 255.0f, g / 255.0f, 0 / 255.0f, CPointLights::FOG_NORMAL, true); + + if (CWeather::TrafficLightBrightness > 0.05f) + CShadows::StoreStaticShadow((uintptr)ent, + SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, + 8.0f, 0.0f, 0.0f, -8.0f, 128, + r * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + g * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 0 * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 12.0f, 1.0f, 40.0f, false, 0.0f); + + if (id >= 0) { + if (DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f) + CCoronas::RegisterCorona((uintptr)ent + id, + r * CTimeCycle::GetSpriteBrightness() * 0.7f, + g * CTimeCycle::GetSpriteBrightness() * 0.7f, + 0 * CTimeCycle::GetSpriteBrightness() * 0.7f, + 255, + pos1, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, + CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + else + CCoronas::RegisterCorona((uintptr)ent + id, + r * CTimeCycle::GetSpriteBrightness() * 0.7f, + g * CTimeCycle::GetSpriteBrightness() * 0.7f, + 0 * CTimeCycle::GetSpriteBrightness() * 0.7f, + 255, + pos2, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, + CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + } } -*/ +} + +bool DoesLineSegmentIntersect(float l1x1, float l1y1, float l1x2, float l1y2, float l2x1, float l2y1, float l2x2, float l2y2) +{ + return ((l2y2 - l1y1) * (l1x2 - l1x1) + (l1x1 - l2x2) * (l1y2 - l1y1)) * + ((l2y1 - l1y1) * (l1x2 - l1x1) + (l1x1 - l2x1) * (l1y2 - l1y1)) <= 0.0f && + ((l1y2 - l2y1) * (l2x2 - l2x1) + (l2y2 - l2y1) * (l2x1 - l1x2)) * + ((l1y1 - l2y1) * (l2x2 - l2x1) + (l2y2 - l2y1) * (l2x1 - l1x1)) <= 0.0f; } void @@ -152,33 +324,28 @@ CTrafficLights::ScanForLightsOnMap(void) if (!IsTrafficLight(light->GetModelIndex())) continue; + CVector pos1 = light->GetMatrix() * CVector(17.0f, 0.0f, 0.0f); + CVector pos2 = light->GetMatrix() * CVector(-15.0f, 0.0f, 0.0f); + // Check cars - for(i = 0; i < ThePaths.m_numCarPathLinks; i++){ - CVector2D dist = ThePaths.m_carPathLinks[i].GetPosition() - light->GetPosition(); - float dotY = Abs(DotProduct2D(dist, light->GetForward())); // forward is direction of car light - float dotX = DotProduct2D(dist, light->GetRight()); // towards base of light - // it has to be on the correct side of the node and also not very far away - if(dotX < 0.0f && dotX > -15.0f && dotY < 3.0f){ - float dz = ThePaths.m_pathNodes[ThePaths.m_carPathLinks[i].pathNodeIndex].GetZ() - - light->GetPosition().z; - if(dz < 15.0f){ - ThePaths.m_carPathLinks[i].trafficLightType = FindTrafficLightType(light); - // Find two neighbour nodes of this one - int n1 = -1; - int n2 = -1; - for(j = 0; j < ThePaths.m_numPathNodes; j++) - for(l = 0; l < ThePaths.m_pathNodes[j].numLinks; l++) - if(ThePaths.m_carPathConnections[ThePaths.m_pathNodes[j].firstLink + l] == i){ - if(n1 == -1) - n1 = j; - else - n2 = j; - } - // What's going on here? - if(ThePaths.m_pathNodes[n1].numLinks <= ThePaths.m_pathNodes[n2].numLinks) - n1 = n2; - if(ThePaths.m_carPathLinks[i].pathNodeIndex != n1) - ThePaths.m_carPathLinks[i].trafficLightType |= SOME_FLAG; + for(i = 0; i < ThePaths.m_numCarPathNodes; i++){ + if ((ThePaths.m_pathNodes[i].GetPosition() - pos1).MagnitudeSqr() >= SQR(100.0f)) + continue; + for (j = 0; j < ThePaths.m_pathNodes[i].numLinks; j++){ + int con = ThePaths.ConnectedNode(ThePaths.m_pathNodes[i].firstLink + j); + if (i < con) { + CVector i_pos = ThePaths.m_pathNodes[i].GetPosition(); + CVector con_pos = ThePaths.m_pathNodes[con].GetPosition(); + if (Abs(pos1.z - (i_pos.z + con_pos.z) / 2) < 10.0f && + DoesLineSegmentIntersect(pos1.x, pos1.y, pos2.x, pos2.y, i_pos.x, i_pos.y, con_pos.x, con_pos.y)) { + //debug("Setting up light: nodes %f %f %f - %f %f %f, light %f %f %f - %f %f %f\n", i_pos.x, i_pos.y, i_pos.z, con_pos.x, con_pos.y, con_pos.z, pos1.x, pos1.y, pos1.z, pos2.x, pos2.y, pos2.z); + int link = ThePaths.m_carPathConnections[ThePaths.m_pathNodes[i].firstLink + j]; + ThePaths.m_carPathLinks[link].trafficLightType = FindTrafficLightType(light); + if (ThePaths.m_pathNodes[i].numLinks > ThePaths.m_pathNodes[con].numLinks) + con = i; + if (ThePaths.m_carPathLinks[link].pathNodeIndex != con) + ThePaths.m_carPathLinks[link].trafficLightDirection = true; + } } } } @@ -209,15 +376,18 @@ bool CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop) { int node, type; + bool direction; node = vehicle->AutoPilot.m_nNextPathNodeInfo; type = ThePaths.m_carPathLinks[node].trafficLightType; + direction = ThePaths.m_carPathLinks[node].trafficLightDirection; + if(type){ - if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nNextRouteNode) && - (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nNextRouteNode)) + if((direction || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nNextRouteNode) && + (!direction || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nNextRouteNode)) if(alwaysStop || - (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN || - (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ + type == 1 && LightForCars1() != CAR_LIGHTS_GREEN || + type == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].GetPosition(), ThePaths.m_carPathLinks[node].GetDirection()); if(vehicle->AutoPilot.m_nNextDirection == -1){ @@ -232,12 +402,13 @@ CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop) node = vehicle->AutoPilot.m_nCurrentPathNodeInfo; type = ThePaths.m_carPathLinks[node].trafficLightType; + direction = ThePaths.m_carPathLinks[node].trafficLightDirection; if(type){ - if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nCurrentRouteNode) && - (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nCurrentRouteNode)) + if((direction || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nCurrentRouteNode) && + (!direction || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nCurrentRouteNode)) if(alwaysStop || - (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN || - (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ + type == 1 && LightForCars1() != CAR_LIGHTS_GREEN || + type == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].GetPosition(), ThePaths.m_carPathLinks[node].GetDirection()); if(vehicle->AutoPilot.m_nCurrentDirection == -1){ @@ -253,12 +424,13 @@ CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop) if(vehicle->GetStatus() == STATUS_PHYSICS){ node = vehicle->AutoPilot.m_nPreviousPathNodeInfo; type = ThePaths.m_carPathLinks[node].trafficLightType; + direction = ThePaths.m_carPathLinks[node].trafficLightDirection; if(type){ - if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nPrevRouteNode) && - (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nPrevRouteNode)) + if((direction || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nPrevRouteNode) && + (!direction || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nPrevRouteNode)) if(alwaysStop || - (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN || - (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ + type == 1 && LightForCars1() != CAR_LIGHTS_GREEN || + type == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].GetPosition(), ThePaths.m_carPathLinks[node].GetDirection()); if(vehicle->AutoPilot.m_nPreviousDirection == -1){ @@ -348,3 +520,19 @@ CTrafficLights::LightForCars2(void) else return CAR_LIGHTS_RED; } + +uint8 +CTrafficLights::LightForCars1_Visual(void) +{ + if (CWeather::Wind <= 1.1f) + return LightForCars1(); + return (CTimer::GetTimeInMilliseconds() & 0x400 ? CAR_LIGHTS_NONE : CAR_LIGHTS_YELLOW); +} + +uint8 +CTrafficLights::LightForCars2_Visual(void) +{ + if (CWeather::Wind <= 1.1f) + return LightForCars2(); + return (CTimer::GetTimeInMilliseconds() & 0x400 ? CAR_LIGHTS_NONE : CAR_LIGHTS_YELLOW); +} diff --git a/src/control/TrafficLights.h b/src/control/TrafficLights.h index 6cd5e04a..8dba45e1 100644 --- a/src/control/TrafficLights.h +++ b/src/control/TrafficLights.h @@ -10,7 +10,8 @@ enum { CAR_LIGHTS_GREEN = 0, CAR_LIGHTS_YELLOW, - CAR_LIGHTS_RED + CAR_LIGHTS_RED, + CAR_LIGHTS_NONE }; class CTrafficLights @@ -24,6 +25,8 @@ public: static uint8 LightForPeds(void); static uint8 LightForCars1(void); static uint8 LightForCars2(void); + static uint8 LightForCars1_Visual(void); + static uint8 LightForCars2_Visual(void); static bool ShouldCarStopForLight(CVehicle*, bool); static bool ShouldCarStopForBridge(CVehicle*); }; diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index b996e77f..7af652ad 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -4247,7 +4247,7 @@ CCam::GetLookFromLampPostPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, C CWorld::FindObjectsInRange(TargetCoors, 30.0f, true, &NumObjects, 15, Objects, false, false, false, true, true); float NearestDist = 10000.0f; for(i = 0; i < NumObjects; i++){ - if(Objects[i]->IsStatic() && Objects[i]->GetUp().z > 0.9f && IsLampPost(Objects[i]->GetModelIndex())){ + if(Objects[i]->GetIsStatic() && Objects[i]->GetUp().z > 0.9f && IsLampPost(Objects[i]->GetModelIndex())){ float Dist = (Objects[i]->GetPosition() - TargetCoors).Magnitude2D(); if(Abs(ARRESTCAM_LAMP_BEST_DIST - Dist) < NearestDist){ CVector TestStart = Objects[i]->GetColModel()->boundingBox.max; diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index a6ab62bc..fdc63a05 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -240,9 +240,8 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size) CdReadInfo *pChannel = &gpReadInfo[channel]; ASSERT( pChannel != nil ); - if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) { - if (pChannel->nSectorOffset == _GET_OFFSET(offset) && pChannel->nSectorsToRead >= size) + if (pChannel->hFile == hImage - 1 && pChannel->nSectorOffset == _GET_OFFSET(offset) && pChannel->nSectorsToRead >= size) return STREAM_SUCCESS; flushStream[channel] = 1; @@ -293,7 +292,6 @@ CdStreamGetStatus(int32 channel) if ( pChannel->nStatus != STREAM_NONE ) { int32 status = pChannel->nStatus; - pChannel->nStatus = STREAM_NONE; return status; @@ -322,15 +320,16 @@ CdStreamSync(int32 channel) pthread_kill(pChannel->pChannelThread, SIGUSR1); if (pChannel->bReading) { pChannel->bLocked = true; - sem_wait(pChannel->pDoneSemaphore); + while (pChannel->bLocked) + sem_wait(pChannel->pDoneSemaphore); } #else pChannel->nSectorsToRead = 0; if (pChannel->bReading) { pChannel->bLocked = true; pthread_kill(_gCdStreamThread, SIGUSR1); - sem_wait(pChannel->pDoneSemaphore); - + while (pChannel->bLocked) + sem_wait(pChannel->pDoneSemaphore); } #endif pChannel->bReading = false; @@ -341,8 +340,8 @@ CdStreamSync(int32 channel) if ( pChannel->nSectorsToRead != 0 ) { pChannel->bLocked = true; - - sem_wait(pChannel->pDoneSemaphore); + while (pChannel->bLocked) + sem_wait(pChannel->pDoneSemaphore); } pChannel->bReading = false; @@ -443,9 +442,9 @@ void *CdStreamThread(void *param) #endif pChannel->nSectorsToRead = 0; - if ( pChannel->bLocked ) { + pChannel->bLocked = 0; sem_post(pChannel->pDoneSemaphore); } pChannel->bReading = false; diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index 5b57cb73..a47ca3cf 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -406,8 +406,8 @@ CFireManager::ExtinguishPointWithWater(CVector point, float range) CFire *fireToExtinguish = &m_aFires[fireI]; fireToExtinguish->m_fWaterExtinguishCountdown -= 0.012f * CTimer::GetTimeStep(); CVector steamPos = fireToExtinguish->m_vecPos + - CVector((CGeneral::GetRandomNumber() - 128) * 31.f / 200.f, - (CGeneral::GetRandomNumber() - 128) * 31.f / 200.f, + CVector((CGeneral::GetRandomNumber() - 128) * 3.1f / 200.f, + (CGeneral::GetRandomNumber() - 128) * 3.1f / 200.f, CGeneral::GetRandomNumber() / 200.f); CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, steamPos, CVector(0.f, 0.f, 0.2f), nil, 0.5f); diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 59649e93..4eda2301 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -37,6 +37,7 @@ #include "Messages.h" #include "FileLoader.h" #include "User.h" +#include "sampman.h" // TODO(Miami): Remove that!! That was my map implementation for III, instead use MAP_ENHACEMENTS on some places #define CUSTOM_MAP @@ -376,8 +377,7 @@ CMenuManager::CMenuManager() m_bShowMouse = true; m_nHoverOption = HOVEROPTION_NOT_HOVERING; - // TODO(Miami) - // DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); + DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); m_bMenuActive = false; m_bActivateSaveMenu = false; m_bWantToLoad = false; @@ -426,9 +426,7 @@ CMenuManager::Initialise(void) DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); m_PrefsRadioStation = DMAudio.GetRadioInCar(); - - // TODO(Miami) - // DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); + DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); if (DMAudio.IsMP3RadioChannelAvailable()) { if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > USERTRACK) m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10; @@ -570,6 +568,7 @@ CMenuManager::CheckHover(int x1, int x2, int y1, int y2) m_nMousePosY > y1 && m_nMousePosY < y2; } +// --MIAMI: Done void CMenuManager::CheckSliderMovement(int value) { @@ -587,14 +586,27 @@ CMenuManager::CheckSliderMovement(int value) CRenderer::ms_lodDistScale = m_PrefsLOD; break; case MENUACTION_MUSICVOLUME: - m_PrefsMusicVolume += value * (128/32); - m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 65); - DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { + m_PrefsMusicVolume += value * (128 / 32); + m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 65); + DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); + } break; case MENUACTION_SFXVOLUME: - m_PrefsSfxVolume += value * (128/32); - m_PrefsSfxVolume = clamp(m_PrefsSfxVolume, 0, 65); - DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { + m_PrefsSfxVolume += value * (128 / 32); + m_PrefsSfxVolume = clamp(m_PrefsSfxVolume, 0, 65); + DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); + } + break; + case MENUACTION_MP3VOLUMEBOOST: + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { + if (DMAudio.IsMP3RadioChannelAvailable()) { + m_PrefsMP3BoostVolume += value * (128 / 32); + m_PrefsMP3BoostVolume = clamp(m_PrefsMP3BoostVolume, 0, 65); + DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); + } + } break; case MENUACTION_MOUSESENS: TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // ??? @@ -1065,20 +1077,17 @@ CMenuManager::DrawStandardMenus(bool activeScreen) else if (m_nPrefsAudio3DProviderIndex == -1) rightText = TheText.Get("FEA_ADP"); else { - char* provider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex); - if (provider != NULL) { - if (!strcmp(strupr(provider), "DIRECTSOUND3D HARDWARE SUPPORT")) { - strcpy(provider, "DSOUND3D HARDWARE SUPPORT"); - } - else if (!strcmp(strupr(provider), "DIRECTSOUND3D SOFTWARE EMULATION")) { - strcpy(provider, "DSOUND3D SOFTWARE EMULATION"); - } - AsciiToUnicode(provider, unicodeTemp); - rightText = unicodeTemp; - } - else { - rightText = TheText.Get("not defined"); + char *rawProvider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex); + AsciiToUnicode(rawProvider, unicodeTemp); + char *provider = UnicodeToAscii(unicodeTemp); // genius + strupr(provider); + if (!strcmp(provider, "DIRECTSOUND3D HARDWARE SUPPORT")) { + strcpy(provider, "DSOUND3D HARDWARE SUPPORT"); + } else if (!strcmp(provider, "DIRECTSOUND3D SOFTWARE EMULATION")) { + strcpy(provider, "DSOUND3D SOFTWARE EMULATION"); } + AsciiToUnicode(provider, unicodeTemp); + rightText = unicodeTemp; } break; case MENUACTION_SPEAKERCONF: { @@ -4007,6 +4016,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u if (selectedProvider != NO_AUDIO_PROVIDER) { if (selectedProvider == -1) selectedProvider = m_nPrefsAudio3DProviderIndex = DMAudio.AutoDetect3DProviders(); + m_nPrefsAudio3DProviderIndex = DMAudio.SetCurrent3DProvider(m_nPrefsAudio3DProviderIndex); if (selectedProvider != m_nPrefsAudio3DProviderIndex) { SetHelperText(5); @@ -4039,7 +4049,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u m_PrefsMP3BoostVolume = 0; m_PrefsStereoMono = 1; m_PrefsSpeakers = 0; - // DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); // TODO(Miami) + DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); DMAudio.SetRadioInCar(m_PrefsRadioStation); @@ -4180,11 +4190,36 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u break; #endif case MENUACTION_AUDIOHW: - // TODO(Miami): What are the extra things in here?? - if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex += changeAmount; - m_nPrefsAudio3DProviderIndex = clamp(m_nPrefsAudio3DProviderIndex, 0, DMAudio.GetNum3DProvidersAvailable() - 1); + + bool checkIfForbidden = true; + while (checkIfForbidden) { + checkIfForbidden = false; + + if (m_nPrefsAudio3DProviderIndex < -1) + m_nPrefsAudio3DProviderIndex = DMAudio.GetNum3DProvidersAvailable() - 1; + else if (m_nPrefsAudio3DProviderIndex > DMAudio.GetNum3DProvidersAvailable() - 1) + m_nPrefsAudio3DProviderIndex = -1; + + // what a retarded move... + if (m_nPrefsAudio3DProviderIndex != -1) { + char* provider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex); + strupr(provider); + if (!strcmp(provider, "MILES FAST 2D POSITIONAL AUDIO")) { + m_nPrefsAudio3DProviderIndex += changeAmount; + checkIfForbidden = true; + + } else if (!strcmp(provider, "AUREAL A3D 2.0 (TM)")) { + m_nPrefsAudio3DProviderIndex += changeAmount; + checkIfForbidden = true; + + } else if (!strcmp(provider, "AUREAL A3D INTERACTIVE (TM)")) { + m_nPrefsAudio3DProviderIndex += changeAmount; + checkIfForbidden = true; + } + } + } } break; case MENUACTION_SPEAKERCONF: @@ -4543,19 +4578,13 @@ CMenuManager::UnloadTextures() CUserDisplay::PlaceName.ProcessAfterFrontEndShutDown(); } +// --MIAMI: Done void CMenuManager::WaitForUserCD() { CSprite2d *splash; char *splashscreen = nil; -#if (!(defined RANDOMSPLASH) && !(defined GTA3_1_1_PATCH)) - if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame) - splashscreen = "mainsc2"; - else - splashscreen = "mainsc1"; -#endif - splash = LoadSplash(splashscreen); if (RsGlobal.quit) @@ -4707,6 +4736,53 @@ CMenuManager::PrintMap(void) } CRadar::DrawBlips(); + if (m_PrefsShowLegends) { + CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(40.0f)); + CFont::SetRightJustifyWrap(SCREEN_SCALE_X(84.0f)); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetColor(CRGBA(255, 150, 225, FadeIn(255))); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); + CFont::SetCentreOn(); + CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + CFont::SetScale(SCREEN_SCALE_X(0.65f), SCREEN_SCALE_Y(0.95f)); + + int secondColumnStart = (CRadar::MapLegendCounter - 1) / 2; + int boxBottom = MENU_Y(100.0f); + + // + 3, because we want 19*3 px padding + for (int i = 0; i < secondColumnStart + 3; i++) { + boxBottom += MENU_Y(19.f); + } + + CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(95.0f), MENU_Y(100.0f), MENU_X_LEFT_ALIGNED(555.f), boxBottom), + CRGBA(0, 0, 0, FadeIn(190))); + + CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(102.0f), TheText.Get("FE_MLG")); + CFont::SetRightJustifyOff(); + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + if (m_PrefsLanguage == LANGUAGE_AMERICAN) + CFont::SetScale(SCREEN_SCALE_X(0.55f), SCREEN_SCALE_Y(0.55f)); + else + CFont::SetScale(SCREEN_SCALE_X(0.45f), SCREEN_SCALE_Y(0.55f)); + + CFont::SetColor(CRGBA(225, 225, 225, FadeIn(255))); + CFont::SetDropShadowPosition(0); + + int y = MENU_Y(127.0f); + int x = MENU_X_LEFT_ALIGNED(160.0f); + + for (int16 i = 0; i < CRadar::MapLegendCounter; i++) { + CRadar::DrawLegend(x, y, CRadar::MapLegendList[i]); + + if (i == secondColumnStart) { + x = MENU_X_LEFT_ALIGNED(350.0f); + y = MENU_Y(127.0f); + } else { + y += MENU_Y(19.0f); + } + } + } #ifdef CUSTOM_MAP CVector2D mapPoint; @@ -4785,7 +4861,7 @@ CMenuManager::PrintMap(void) #endif m_bMenuMapActive = false; - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(5.0f)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(10.0f)); CFont::SetRightJustifyWrap(SCREEN_SCALE_X(10.0f)); DisplayHelperText("FEH_MPH"); } diff --git a/src/core/Pad.h b/src/core/Pad.h index 01f5bb9b..9f9f81b6 100644 --- a/src/core/Pad.h +++ b/src/core/Pad.h @@ -436,6 +436,7 @@ public: bool GetLeftShockJustDown() { return !!(NewState.LeftShock && !OldState.LeftShock); } bool GetRightShockJustDown() { return !!(NewState.RightShock && !OldState.RightShock); } bool GetStartJustDown() { return !!(NewState.Start && !OldState.Start); } + bool GetSelectJustDown() { return !!(NewState.Select && !OldState.Select); } bool GetLeftStickXJustDown() { return !!(NewState.LeftStickX && !OldState.LeftStickX); } bool GetLeftStickYJustDown() { return !!(NewState.LeftStickY && !OldState.LeftStickY); } @@ -461,6 +462,7 @@ public: bool GetRightShoulder1(void) { return !!NewState.RightShoulder1; } bool GetRightShoulder2(void) { return !!NewState.RightShoulder2; } bool GetStart() { return !!NewState.Start; } + bool GetSelect() { return !!NewState.Select; } int16 GetLeftStickX(void) { return NewState.LeftStickX; } int16 GetLeftStickY(void) { return NewState.LeftStickY; } int16 GetRightStickX(void) { return NewState.RightStickX; } @@ -478,4 +480,4 @@ public: }; VALIDATE_SIZE(CPad, 0xFC); -extern CPad Pads[MAX_PADS];
\ No newline at end of file +extern CPad Pads[MAX_PADS]; diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index fe2cf7ad..b25fa4e1 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -2,6 +2,7 @@ #include "Pools.h" +#include "Bike.h" #include "Boat.h" #include "CarCtrl.h" #ifdef MISSION_REPLAY @@ -13,6 +14,8 @@ #include "Wanted.h" #include "World.h" +//--MIAMI: file done + CCPtrNodePool *CPools::ms_pPtrNodePool; CEntryInfoNodePool *CPools::ms_pEntryInfoNodePool; CPedPool *CPools::ms_pPedPool; @@ -24,7 +27,6 @@ CDummyPool *CPools::ms_pDummyPool; CAudioScriptObjectPool *CPools::ms_pAudioScriptObjectPool; CColModelPool *CPools::ms_pColModelPool; -//--MIAMI: done void CPools::Initialise(void) { @@ -40,7 +42,6 @@ CPools::Initialise(void) ms_pColModelPool = new CColModelPool(NUMCOLMODELS, "ColModel"); } -//--MIAMI: done void CPools::ShutDown(void) { @@ -119,7 +120,8 @@ void CPools::LoadVehiclePool(uint8* buf, uint32 size) INITSAVEBUF int nNumCars = ReadSaveBuf<int>(buf); int nNumBoats = ReadSaveBuf<int>(buf); - for (int i = 0; i < nNumCars + nNumBoats; i++) { + int nNumBikes = ReadSaveBuf<int>(buf); + for (int i = 0; i < nNumCars + nNumBoats + nNumBikes; i++) { uint32 type = ReadSaveBuf<uint32>(buf); int16 model = ReadSaveBuf<int16>(buf); CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY); @@ -131,13 +133,15 @@ INITSAVEBUF pVehicle = new(slot) CBoat(model, RANDOM_VEHICLE); else if (type == VEHICLE_TYPE_CAR) pVehicle = new(slot) CAutomobile(model, RANDOM_VEHICLE); + else if (type == VEHICLE_TYPE_BIKE) + pVehicle = new(slot) CBike(model, RANDOM_VEHICLE); else assert(0); --CCarCtrl::NumRandomCars; pVehicle->Load(buf); CWorld::Add(pVehicle); #else - char* vbuf = new char[Max(CAutomobile::nSaveStructSize, CBoat::nSaveStructSize)]; + char* vbuf = new char[Max(CBike::nSaveStructSize, Max(CAutomobile::nSaveStructSize, CBoat::nSaveStructSize))]; if (type == VEHICLE_TYPE_BOAT) { memcpy(vbuf, buf, sizeof(CBoat)); SkipSaveBuf(buf, sizeof(CBoat)); @@ -156,6 +160,17 @@ INITSAVEBUF pAutomobile->Damage = ((CAutomobile*)vbuf)->Damage; pAutomobile->SetupDamageAfterLoad(); } + else if (type == VEHICLE_TYPE_BIKE) { +#ifdef FIX_BUGS + memcpy(vbuf, buf, sizeof(CBike)); +#else + memcpy(vbuf, buf, sizeof(CAutomobile)); +#endif + SkipSaveBuf(buf, sizeof(CBike)); + CBike* pBike = new(slot) CBike(model, RANDOM_VEHICLE); + pVehicle = pBike; + --CCarCtrl::NumRandomCars; + } else assert(0); CVehicle* pBufferVehicle = (CVehicle*)vbuf; @@ -193,6 +208,7 @@ INITSAVEBUF (pVehicle->GetAddressOfEntityProperties())[0] = (pBufferVehicle->GetAddressOfEntityProperties())[0]; (pVehicle->GetAddressOfEntityProperties())[1] = (pBufferVehicle->GetAddressOfEntityProperties())[1]; pVehicle->AutoPilot = pBufferVehicle->AutoPilot; + CCarCtrl::UpdateCarCount(pVehicle, false); CWorld::Add(pVehicle); delete[] vbuf; #endif @@ -205,6 +221,7 @@ void CPools::SaveVehiclePool(uint8* buf, uint32* size) INITSAVEBUF int nNumCars = 0; int nNumBoats = 0; + int nNumBikes = 0; int nPoolSize = GetVehiclePool()->GetSize(); for (int i = 0; i < nPoolSize; i++) { CVehicle* pVehicle = GetVehiclePool()->GetSlot(i); @@ -226,19 +243,25 @@ INITSAVEBUF ++nNumCars; if (pVehicle->IsBoat() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) ++nNumBoats; + if (pVehicle->IsBike() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) + ++nNumBoats; #else if (!pVehicle->pDriver && !bHasPassenger) { if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) ++nNumCars; if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) ++nNumBoats; + if (pVehicle->IsBike() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) + ++nNumBoats; #endif } } *size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CAutomobile::nSaveStructSize) + sizeof(int) + - nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CBoat::nSaveStructSize) + sizeof(int); + nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CBoat::nSaveStructSize) + sizeof(int) + + nNumBikes * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CBike::nSaveStructSize) + sizeof(int); WriteSaveBuf(buf, nNumCars); WriteSaveBuf(buf, nNumBoats); + WriteSaveBuf(buf, nNumBikes); for (int i = 0; i < nPoolSize; i++) { CVehicle* pVehicle = GetVehiclePool()->GetSlot(i); if (!pVehicle) @@ -258,9 +281,9 @@ INITSAVEBUF #endif #ifdef COMPATIBLE_SAVES #ifdef MISSION_REPLAY - if ((pVehicle->IsCar() || pVehicle->IsBoat()) && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) { + if ((pVehicle->IsCar() || pVehicle->IsBoat() || pVehicle->IsBike()) && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) { #else - if ((pVehicle->IsCar() || pVehicle->IsBoat()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { + if ((pVehicle->IsCar() || pVehicle->IsBoat() || pVehicle->IsBike()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { #endif WriteSaveBuf<uint32>(buf, pVehicle->m_vehType); WriteSaveBuf<int16>(buf, pVehicle->GetModelIndex()); @@ -290,6 +313,17 @@ INITSAVEBUF memcpy(buf, pVehicle, sizeof(CBoat)); SkipSaveBuf(buf, sizeof(CBoat)); } +#ifdef MISSION_REPLAY + if (pVehicle->IsBike() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) { +#else + if (pVehicle->IsBike() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { +#endif + WriteSaveBuf(buf, (uint32)pVehicle->m_vehType); + WriteSaveBuf(buf, pVehicle->GetModelIndex()); + WriteSaveBuf(buf, GetVehicleRef(pVehicle)); + memcpy(buf, pVehicle, sizeof(CBike)); + SkipSaveBuf(buf, sizeof(CBike)); + } #endif } } @@ -311,8 +345,9 @@ INITSAVEBUF ++nObjects; } *size = nObjects * (sizeof(int16) + sizeof(int) + sizeof(CCompressedMatrix) + - sizeof(float) + sizeof(CCompressedMatrix) + sizeof(int8) + 7 * sizeof(bool) + sizeof(float) + - sizeof(int8) + sizeof(int8) + sizeof(uint32) + 2 * sizeof(uint32)) + sizeof(int); + sizeof(float) + sizeof(CCompressedMatrix) + sizeof(int8) + 7 * sizeof(bool) + sizeof(int16) + + + sizeof(int8) * 2 + sizeof(float) + sizeof(int8) + sizeof(int8) + + sizeof(uint32) + 2 * sizeof(uint32)) + sizeof(int); CopyToBuf(buf, nObjects); for (int i = 0; i < nPoolSize; i++) { CObject* pObject = GetObjectPool()->GetSlot(i); @@ -343,6 +378,9 @@ INITSAVEBUF CopyToBuf(buf, bGlassBroken); CopyToBuf(buf, bHasBeenDamaged); CopyToBuf(buf, bUseVehicleColours); + CopyToBuf(buf, pObject->m_nCostValue); + CopyToBuf(buf, pObject->m_nBonusValue); + SkipSaveBuf(buf, 1); CopyToBuf(buf, pObject->m_fCollisionDamageMultiplier); CopyToBuf(buf, pObject->m_nCollisionDamageEffect); CopyToBuf(buf, pObject->m_nSpecialCollisionResponseCases); @@ -392,6 +430,9 @@ INITSAVEBUF pBufferObject->bHasBeenDamaged = bitFlag; CopyFromBuf(buf, bitFlag); pBufferObject->bUseVehicleColours = bitFlag; + CopyFromBuf(buf, pBufferObject->m_nCostValue); + CopyFromBuf(buf, pBufferObject->m_nBonusValue); + SkipSaveBuf(buf, 1); CopyFromBuf(buf, pBufferObject->m_fCollisionDamageMultiplier); CopyFromBuf(buf, pBufferObject->m_nCollisionDamageEffect); CopyFromBuf(buf, pBufferObject->m_nSpecialCollisionResponseCases); @@ -426,6 +467,8 @@ INITSAVEBUF (pObject->GetAddressOfEntityProperties())[1] = (pBufferObject->GetAddressOfEntityProperties())[1]; #endif pObject->bHasCollided = false; + pObject->m_nCostValue = pBufferObject->m_nCostValue; + pObject->m_nBonusValue = pBufferObject->m_nBonusValue; CWorld::Add(pObject); delete[] obuf; } diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index 5317040f..8fe900ae 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -15,6 +15,9 @@ #include "World.h" #include "Streaming.h" #include "SpecialFX.h" +#include "Font.h" + +// --MIAMI: file done float CRadar::m_radarRange; sRadarTrace CRadar::ms_RadarTrace[NUMRADARBLIPS]; @@ -123,7 +126,7 @@ static_assert(RADAR_TILE_SIZE == (RADAR_SIZE_Y / RADAR_NUM_TILES), "CRadar: not CRGBA CRadar::ArrowBlipColour1; CRGBA CRadar::ArrowBlipColour2; -uint16 CRadar::MapLegendCounter; +int16 CRadar::MapLegendCounter; int16 CRadar::MapLegendList[NUM_MAP_LEGENDS]; #ifdef MAP_ENHANCEMENTS int CRadar::TargetMarkerId = -1; @@ -153,7 +156,7 @@ void RequestMapSection(int32 x, int32 y) void RemoveMapSection(int32 x, int32 y) { - if (x >= 0 && x <= 7 && y >= 0 && y <= 7) + if (x >= 0 && x <= RADAR_NUM_TILES - 1 && y >= 0 && y <= RADAR_NUM_TILES - 1) CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]); } @@ -260,7 +263,6 @@ int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D & return edge; } - uint8 CRadar::CalculateBlipAlpha(float dist) { if (FrontEndMenuManager.m_bMenuMapActive) @@ -269,8 +271,8 @@ uint8 CRadar::CalculateBlipAlpha(float dist) if (dist <= 1.0f) return 255; - if (dist <= 5.0f) - return (128.0f * ((dist - 1.0f) / 4.0f)) + ((1.0f - (dist - 1.0f) / 4.0f) * 255.0f); + if (dist <= 10.0f) + return (128.0f * ((dist - 1.0f) / 9.0f)) + ((1.0f - (dist - 1.0f) / 9.0f) * 255.0f); return 128; } @@ -507,7 +509,6 @@ void CRadar::DrawBlips() DrawRadarSprite(RADAR_SPRITE_NORTH, out.x, out.y, 255); } - CEntity *blipEntity = nil; for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) { if (!ms_RadarTrace[blipId].m_bInUse) continue; @@ -516,173 +517,65 @@ void CRadar::DrawBlips() case BLIP_CAR: case BLIP_CHAR: case BLIP_OBJECT: - if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE - || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_GUN) { + if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_PROPERTY + && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive)) + DrawEntityBlip(blipId); - switch (ms_RadarTrace[blipId].m_eBlipType) { - case BLIP_CAR: - blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - break; - case BLIP_CHAR: - blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - if (blipEntity != nil) { - if (((CPed*)blipEntity)->InVehicle()) - blipEntity = ((CPed*)blipEntity)->m_pMyVehicle; - } - break; - case BLIP_OBJECT: - blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - break; - default: - break; - } - if (blipEntity) { - uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { - if (CTheScripts::IsDebugOn()) { - ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius); - ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; - if (ms_RadarTrace[blipId].m_Radius < 1.0f) - ms_RadarTrace[blipId].m_Radius = 5.0f; - } - } - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { - TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); - float dist = LimitRadarPoint(in); - TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - } - else { -#ifdef TRIANGULAR_BLIPS - const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector& blipPos = blipEntity->GetPosition(); - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; - } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); -#else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); -#endif - } - } - } - } - } break; case BLIP_COORD: case BLIP_CONTACT_POINT: - if ((ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE - || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_GUN) - && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) { - - uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { - if (CTheScripts::IsDebugOn()) { - ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius); - ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; - if (ms_RadarTrace[blipId].m_Radius < 1.0f) - ms_RadarTrace[blipId].m_Radius = 5.0f; - } - } - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { - TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); - float dist = LimitRadarPoint(in); - TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - } - else { -#ifdef TRIANGULAR_BLIPS - const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector& blipPos = ms_RadarTrace[blipId].m_vecPos; - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; - } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); -#else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); -#endif - } - } - } - } + if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_PHONE + && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive)) + DrawCoordBlip(blipId); + break; default: break; } } + + // New in VC: Always draw Hardware/gun/pay'n spray/save blips for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) { if (!ms_RadarTrace[blipId].m_bInUse) continue; + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_HARDWARE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN) + continue; + switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_CAR: case BLIP_CHAR: case BLIP_OBJECT: - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE - && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN) { + if (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive) + DrawEntityBlip(blipId); - switch (ms_RadarTrace[blipId].m_eBlipType) { - case BLIP_CAR: - blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - break; - case BLIP_CHAR: - blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - if (blipEntity != nil) { - if (((CPed*)blipEntity)->InVehicle()) - blipEntity = ((CPed*)blipEntity)->m_pMyVehicle; - } - break; - case BLIP_OBJECT: - blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - break; - default: - break; - } + break; + case BLIP_COORD: + case BLIP_CONTACT_POINT: + if (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive) + DrawCoordBlip(blipId); + + break; + default: + break; + } + } - if (blipEntity) { - uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { - if (CTheScripts::IsDebugOn()) { - ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius); - ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; - if (ms_RadarTrace[blipId].m_Radius < 1.0f) - ms_RadarTrace[blipId].m_Radius = 5.0f; - } - } - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { - TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); - float dist = LimitRadarPoint(in); - TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - else -#ifdef TRIANGULAR_BLIPS - { - const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector& blipPos = blipEntity->GetPosition(); - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; - } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); - } -#else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); -#endif - } - } - } - } + for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) { + if (!ms_RadarTrace[blipId].m_bInUse) + continue; + + switch (ms_RadarTrace[blipId].m_eBlipType) { + case BLIP_CAR: + case BLIP_CHAR: + case BLIP_OBJECT: + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_HARDWARE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_PROPERTY + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN + && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive)) + + DrawEntityBlip(blipId); break; default: break; @@ -695,44 +588,12 @@ void CRadar::DrawBlips() switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_COORD: case BLIP_CONTACT_POINT: - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE - && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN - && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) { - - uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { - if (CTheScripts::IsDebugOn()) { - ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius); - ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; - if (ms_RadarTrace[blipId].m_Radius < 1.0f) - ms_RadarTrace[blipId].m_Radius = 5.0f; - } - } - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { - TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); - float dist = LimitRadarPoint(in); - TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - else -#ifdef TRIANGULAR_BLIPS - { - const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector& blipPos = ms_RadarTrace[blipId].m_vecPos; - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; - } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); - } -#else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); -#endif - } - } - } + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_HARDWARE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_PROPERTY + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_PHONE + && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive)) + + DrawCoordBlip(blipId); break; default: break; @@ -740,7 +601,12 @@ void CRadar::DrawBlips() } if (FrontEndMenuManager.m_bMenuMapActive) { CVector2D in, out; - TransformRealWorldPointToRadarSpace(in, FindPlayerCentreOfWorld_NoSniperShift()); + if (!CTheScripts::bPlayerIsInTheStatium) + TransformRealWorldPointToRadarSpace(in, FindPlayerCentreOfWorld_NoSniperShift()); + else + TransformRealWorldPointToRadarSpace(in, CVector2D(-1302.5f, 1332.8f)); + + LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); DrawYouAreHereSprite(out.x, out.y); } @@ -771,8 +637,6 @@ void CRadar::DrawMap() void CRadar::DrawRadarMap() { - // Game calculates an unused CRect here - DrawRadarMask(); // top left ist (0, 0) @@ -812,14 +676,20 @@ void CRadar::DrawRadarMask() }; RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDZERO); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT); RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); +#if !defined(GTA_PS2_STUFF) && defined(RWLIBS) + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS); +#else + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDZERO); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); +#endif CVector2D out[8]; CVector2D in; @@ -840,7 +710,11 @@ void CRadar::DrawRadarMask() CSprite2d::SetMaskVertices(8, (float *)out); RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), 8); - }; + } +#if !defined(GTA_PS2_STUFF) && defined(RWLIBS) + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); +#endif + } void CRadar::DrawRadarSection(int32 x, int32 y) @@ -858,11 +732,8 @@ void CRadar::DrawRadarSection(int32 x, int32 y) GetTextureCorners(x, y, worldPoly); ClipRadarTileCoords(x, y); - assert(CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])); - txd = CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])->texDict; - if (txd) - texture = GetFirstTexture(txd); - if (texture == nil) + if (!CTheScripts::bPlayerIsInTheStatium && + (!(txd = CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])->texDict) || !(texture = GetFirstTexture(txd)))) return; for (i = 0; i < 4; i++) @@ -880,8 +751,15 @@ void CRadar::DrawRadarSection(int32 x, int32 y) TransformRealWorldToTexCoordSpace(texCoords[i], worldPoly[i], x, y); TransformRadarPointToScreenSpace(screenPoly[i], radarPoly[i]); } - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(texture)); - CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(255, 255, 255, 255)); + + if (CTheScripts::bPlayerIsInTheStatium) { + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil); + CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(204, 204, 204, 255)); + } else { + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(texture)); + CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(255, 255, 255, 255)); + } + // check done above now // if(numVertices > 2) RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), numVertices); @@ -907,28 +785,17 @@ void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha) void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha) { CVector curPosn[4]; - CVector oldPosn[4]; - - curPosn[0].x = x - SCREEN_SCALE_X(5.6f); - curPosn[0].y = y + SCREEN_SCALE_Y(5.6f); - - curPosn[1].x = x + SCREEN_SCALE_X(5.6f); - curPosn[1].y = y + SCREEN_SCALE_Y(5.6f); - - curPosn[2].x = x - SCREEN_SCALE_X(5.6f); - curPosn[2].y = y - SCREEN_SCALE_Y(5.6f); - - curPosn[3].x = x + SCREEN_SCALE_X(5.6f); - curPosn[3].y = y - SCREEN_SCALE_Y(5.6f); + const float sizeX = SCREEN_SCALE_X(8.0f); + const float correctedAngle = angle - PI / 4.f; + const float sizeY = SCREEN_SCALE_Y(8.0f); for (uint32 i = 0; i < 4; i++) { - oldPosn[i] = curPosn[i]; - - curPosn[i].x = x + (oldPosn[i].x - x) * Cos(angle) + (oldPosn[i].y - y) * Sin(angle); - curPosn[i].y = y - (oldPosn[i].x - x) * Sin(angle) + (oldPosn[i].y - y) * Cos(angle); + const float cornerAngle = i * HALFPI + correctedAngle; + curPosn[i].x = x + (0.0f * Cos(cornerAngle) + 1.0f * Sin(cornerAngle)) * sizeX; + curPosn[i].y = y - (0.0f * Sin(cornerAngle) - 1.0f * Cos(cornerAngle)) * sizeY; } - sprite->Draw(curPosn[2].x, curPosn[2].y, curPosn[3].x, curPosn[3].y, curPosn[0].x, curPosn[0].y, curPosn[1].x, curPosn[1].y, CRGBA(255, 255, 255, alpha)); + sprite->Draw(curPosn[3].x, curPosn[3].y, curPosn[2].x, curPosn[2].y, curPosn[0].x, curPosn[0].y, curPosn[1].x, curPosn[1].y, CRGBA(255, 255, 255, alpha)); } int32 CRadar::GetActualBlipArrayIndex(int32 i) @@ -954,43 +821,43 @@ uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright) { int32 c; switch (color) { - case 0: + case RADAR_TRACE_RED: if (bright) c = 0x712B49FF; else c = 0x7F0000FF; break; - case 1: + case RADAR_TRACE_GREEN: if (bright) c = 0x5FA06AFF; else c = 0x007F00FF; break; - case 2: + case RADAR_TRACE_LIGHT_BLUE: if (bright) c = 0x80A7F3FF; else c = 0x00007FFF; break; - case 3: + case RADAR_TRACE_GRAY: if (bright) c = 0xE1E1E1FF; else c = 0x7F7F7FFF; break; - case 4: + case RADAR_TRACE_YELLOW: if (bright) c = 0xFFFF00FF; else c = 0x7F7F00FF; break; - case 5: + case RADAR_TRACE_MAGENTA: if (bright) c = 0xFF00FFFF; else c = 0x7F007FFF; break; - case 6: + case RADAR_TRACE_CYAN: if (bright) c = 0x00FFFFFF; else @@ -1055,12 +922,65 @@ void CRadar::LoadAllRadarBlips(uint8 *buf, uint32 size) INITSAVEBUF CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE); - for (int i = 0; i < NUMRADARBLIPS; i++) - ms_RadarTrace[i] = ReadSaveBuf<sRadarTrace>(buf); + for (int i = 0; i < NUMRADARBLIPS; i++) { + ms_RadarTrace[i].m_nColor = ReadSaveBuf<uint32>(buf); + ms_RadarTrace[i].m_Radius = ReadSaveBuf<float>(buf); + ms_RadarTrace[i].m_eBlipType = ReadSaveBuf<uint32>(buf); + ms_RadarTrace[i].m_nEntityHandle = ReadSaveBuf<int32>(buf); + ms_RadarTrace[i].m_vec2DPos.x = ReadSaveBuf<float>(buf); // CVector2D + ms_RadarTrace[i].m_vec2DPos.y = ReadSaveBuf<float>(buf); + ms_RadarTrace[i].m_vecPos = ReadSaveBuf<CVector>(buf); + ms_RadarTrace[i].m_BlipIndex = ReadSaveBuf<uint16>(buf); + ms_RadarTrace[i].m_bDim = ReadSaveBuf<bool>(buf); + ms_RadarTrace[i].m_bInUse = ReadSaveBuf<bool>(buf); + ms_RadarTrace[i].m_bShortRange = ReadSaveBuf<bool>(buf); + ms_RadarTrace[i].m_unused = ReadSaveBuf<bool>(buf); + ms_RadarTrace[i].m_wScale = ReadSaveBuf<int16>(buf); + ms_RadarTrace[i].m_eBlipDisplay = ReadSaveBuf<uint16>(buf); + ms_RadarTrace[i].m_eRadarSprite = ReadSaveBuf<uint16>(buf); + } VALIDATESAVEBUF(size); } +void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size) +{ + *size = SAVE_HEADER_SIZE + NUMRADARBLIPS * sizeof(sRadarTraceSave); + +INITSAVEBUF + WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE); + +#ifdef MAP_ENHANCEMENTS + if (TargetMarkerId != -1) { + ClearBlip(TargetMarkerId); + TargetMarkerId = -1; + } +#endif + + for (int i = 0; i < NUMRADARBLIPS; i++) { + sRadarTraceSave *saveStruct = (sRadarTraceSave*) buf; + + saveStruct->m_nColor = ms_RadarTrace[i].m_nColor; + saveStruct->m_Radius = ms_RadarTrace[i].m_Radius; + saveStruct->m_eBlipType = ms_RadarTrace[i].m_eBlipType; + saveStruct->m_nEntityHandle = ms_RadarTrace[i].m_nEntityHandle; + saveStruct->m_vec2DPos = ms_RadarTrace[i].m_vec2DPos; + saveStruct->m_vecPos = ms_RadarTrace[i].m_vecPos; + saveStruct->m_BlipIndex = ms_RadarTrace[i].m_BlipIndex; + saveStruct->m_bDim = ms_RadarTrace[i].m_bDim; + saveStruct->m_bInUse = ms_RadarTrace[i].m_bInUse; + saveStruct->m_bShortRange = ms_RadarTrace[i].m_bShortRange; + saveStruct->m_unused = ms_RadarTrace[i].m_unused; + saveStruct->m_wScale = ms_RadarTrace[i].m_wScale; + saveStruct->m_eBlipDisplay = ms_RadarTrace[i].m_eBlipDisplay; + saveStruct->m_eRadarSprite = ms_RadarTrace[i].m_eRadarSprite; + + SkipSaveBuf(buf, sizeof(sRadarTraceSave)); + } + +VALIDATESAVEBUF(*size); +} + void CRadar::LoadTextures() { @@ -1115,25 +1035,6 @@ void CRadar::RemoveRadarSections() RemoveMapSection(i, j); } -void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size) -{ - *size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace); -INITSAVEBUF - WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE); - -#ifdef MAP_ENHANCEMENTS - if (TargetMarkerId != -1) { - ClearBlip(TargetMarkerId); - TargetMarkerId = -1; - } -#endif - - for (int i = 0; i < NUMRADARBLIPS; i++) - WriteSaveBuf(buf, ms_RadarTrace[i]); - -VALIDATESAVEBUF(*size); -} - void CRadar::SetBlipSprite(int32 i, int32 icon) { int index = CRadar::GetActualBlipArrayIndex(i); @@ -1142,7 +1043,7 @@ void CRadar::SetBlipSprite(int32 i, int32 icon) } } -int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display) +int CRadar::SetCoordBlip(eBlipType type, CVector pos, uint32 color, eBlipDisplay display) { int nextBlip; for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) { @@ -1154,7 +1055,7 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay return -1; #endif ms_RadarTrace[nextBlip].m_eBlipType = type; - ms_RadarTrace[nextBlip].m_nColor = color; + ms_RadarTrace[nextBlip].m_nColor = RADAR_TRACE_MAGENTA; ms_RadarTrace[nextBlip].m_bDim = true; ms_RadarTrace[nextBlip].m_bInUse = true; ms_RadarTrace[nextBlip].m_bShortRange = false; @@ -1168,7 +1069,7 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay return CRadar::GetNewUniqueBlipIndex(nextBlip); } -int CRadar::SetShortRangeCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display) +int CRadar::SetShortRangeCoordBlip(eBlipType type, CVector pos, uint32 color, eBlipDisplay display) { int index = SetCoordBlip(type, pos, color, display); if (index == -1) @@ -1177,7 +1078,7 @@ int CRadar::SetShortRangeCoordBlip(eBlipType type, CVector pos, int32 color, eBl return index; } -int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDisplay display) +int CRadar::SetEntityBlip(eBlipType type, int32 handle, uint32 color, eBlipDisplay display) { int nextBlip; for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) { @@ -1189,7 +1090,7 @@ int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDispla return -1; #endif ms_RadarTrace[nextBlip].m_eBlipType = type; - ms_RadarTrace[nextBlip].m_nColor = color; + ms_RadarTrace[nextBlip].m_nColor = RADAR_TRACE_YELLOW; ms_RadarTrace[nextBlip].m_bDim = true; ms_RadarTrace[nextBlip].m_bInUse = true; ms_RadarTrace[nextBlip].m_bShortRange = false; @@ -1261,12 +1162,12 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, switch (mode) { case BLIP_MODE_TRIANGULAR_UP: - // size++; // VC does size + 1 for triangles + size++; CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 3.0f), y + SCREEN_SCALE_Y(size + 2.0f), x - (SCREEN_SCALE_X(size + 3.0f)), y + SCREEN_SCALE_Y(size + 2.0f), x, y - (SCREEN_SCALE_Y(size + 3.0f)), x, y - (SCREEN_SCALE_Y(size + 3.0f)), CRGBA(0, 0, 0, alpha)); CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 1.0f), y + SCREEN_SCALE_Y(size + 1.0f), x - (SCREEN_SCALE_X(size + 1.0f)), y + SCREEN_SCALE_Y(size + 1.0f), x, y - (SCREEN_SCALE_Y(size + 1.0f)), x, y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha)); break; case BLIP_MODE_TRIANGULAR_DOWN: - // size++; // VC does size + 1 for triangles + size++; CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 2.0f), x, y + SCREEN_SCALE_Y(size + 3.0f), x + SCREEN_SCALE_X(size + 3.0f), y - (SCREEN_SCALE_Y(size + 2.0f)), x - (SCREEN_SCALE_X(size + 3.0f)), y - (SCREEN_SCALE_Y(size + 2.0f)), CRGBA(0, 0, 0, alpha)); CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 1.0f), x, y + SCREEN_SCALE_Y(size + 1.0f), x + SCREEN_SCALE_X(size + 1.0f), y - (SCREEN_SCALE_Y(size + 1.0f)), x - (SCREEN_SCALE_X(size + 1.0f)), y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha)); break; @@ -1275,21 +1176,6 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha)); break; } - - // TODO(Miami): Map - // VC uses -1 for coords and -2 for entities but meh, I don't want to edit DrawBlips - if (FrontEndMenuManager.m_bMenuMapActive) { - bool alreadyThere = false; - for (int i = 0; i < NUM_MAP_LEGENDS; i++) { - if (MapLegendList[i] == -1) - alreadyThere = true; - } - if (!alreadyThere) { - MapLegendList[MapLegendCounter] = -1; - MapLegendCounter++; - ArrowBlipColour1 = CRGBA(red, green, blue, alpha); - } - } } void CRadar::Shutdown() @@ -1338,7 +1224,8 @@ void CRadar::Shutdown() void CRadar::StreamRadarSections(const CVector &posn) { - StreamRadarSections(Floor((2000.0f + posn.x) / 500.0f), Ceil(7.0f - (2000.0f + posn.y) / 500.0f)); + if (!CStreaming::ms_disableStreaming) + StreamRadarSections(Floor((RADAR_MAX_X + posn.x) / RADAR_TILE_SIZE), Ceil((RADAR_NUM_TILES - 1) - (RADAR_MAX_Y + posn.y) / RADAR_TILE_SIZE)); } void CRadar::StreamRadarSections(int32 x, int32 y) @@ -1405,8 +1292,8 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D void CRadar::CalculateCachedSinCos() { - if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED - || FrontEndMenuManager.m_bMenuMapActive ) { + if (/*TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED || */ + FrontEndMenuManager.m_bMenuMapActive ) { cachedSin = 0.0f; cachedCos = 1.0f; } else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) { @@ -1445,7 +1332,7 @@ CRadar::InitFrontEndMap() void CRadar::DrawYouAreHereSprite(float x, float y) { - static uint32 lastChange = 0; + static PauseModeTime lastChange = 0; static bool show = true; if (show) { @@ -1461,13 +1348,30 @@ CRadar::DrawYouAreHereSprite(float x, float y) } if (show) { - float left = x - SCREEN_SCALE_X(12.0f); - float top = y; - float right = SCREEN_SCALE_X(12.0) + x; - float bottom = y - SCREEN_SCALE_Y(24.0f); - CentreSprite.Draw(CRect(left, top, right, bottom), CRGBA(255, 255, 255, 255)); + const float left = x - SCREEN_SCALE_X(8.0f); + const float top = y - SCREEN_SCALE_Y(40.0f); + const float right = x + SCREEN_SCALE_X(40.0); + const float bottom = y + SCREEN_SCALE_Y(8.0f); + MapHereSprite.Draw(CRect(left + SCREEN_SCALE_X(2.f), top + SCREEN_SCALE_Y(2.f), right + SCREEN_SCALE_X(2.f), bottom + SCREEN_SCALE_Y(2.f)), + CRGBA(0, 0, 0, 255)); + + MapHereSprite.Draw(CRect(left, top, right, bottom), CRGBA(255, 255, 255, 255)); + + CFont::SetWrapx(right + SCREEN_SCALE_X(28.0f)); + CFont::SetRightJustifyWrap(right); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetColor(CRGBA(255, 150, 225, 255)); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); + CFont::SetCentreOff(); + CFont::SetRightJustifyOff(); + CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + CFont::SetScale(SCREEN_SCALE_X(0.65f), SCREEN_SCALE_Y(0.95f)); + CFont::PrintString(right, top, TheText.Get("MAP_YAH")); + CFont::SetDropShadowPosition(0); + CFont::DrawFonts(); } - MapLegendList[MapLegendCounter++] = RADAR_SPRITE_CENTRE; + MapLegendList[MapLegendCounter++] = RADAR_SPRITE_MAP_HERE; } #ifdef MAP_ENHANCEMENTS @@ -1485,8 +1389,8 @@ CRadar::ToggleTargetMarker(float x, float y) return; ms_RadarTrace[nextBlip].m_eBlipType = BLIP_COORD; - ms_RadarTrace[nextBlip].m_nColor = 0x333333FF; - ms_RadarTrace[nextBlip].m_bDim = 1; + ms_RadarTrace[nextBlip].m_nColor = RADAR_TRACE_GRAY; + ms_RadarTrace[nextBlip].m_bDim = 0; ms_RadarTrace[nextBlip].m_bInUse = 1; ms_RadarTrace[nextBlip].m_Radius = 1.0f; CVector pos(x, y, CWorld::FindGroundZForCoord(x,y)); @@ -1505,3 +1409,287 @@ CRadar::ToggleTargetMarker(float x, float y) } #endif +void +CRadar::DrawEntityBlip(int32 blipId) +{ + CVector2D out; + CVector2D in; + CEntity *blipEntity; + switch (ms_RadarTrace[blipId].m_eBlipType) { + case BLIP_CAR: + blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); + break; + case BLIP_CHAR: + blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); + if (blipEntity != nil) { + if (((CPed*)blipEntity)->InVehicle()) + blipEntity = ((CPed*)blipEntity)->m_pMyVehicle; + } + break; + case BLIP_OBJECT: + blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); + break; + default: + break; + } + if (blipEntity) { + uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); + if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { + if (CTheScripts::IsDebugOn()) { + ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius); + ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; + if (ms_RadarTrace[blipId].m_Radius < 1.0f) + ms_RadarTrace[blipId].m_Radius = 5.0f; + } + } + if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { + TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); + float dist = LimitRadarPoint(in); + TransformRadarPointToScreenSpace(out, in); + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); + } else { + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = blipEntity->GetPosition(); + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); + + if (FrontEndMenuManager.m_bMenuMapActive) { + bool alreadyThere = false; + for (int i = 0; i < NUM_MAP_LEGENDS; i++) { + if (MapLegendList[i] == -2) + alreadyThere = true; + } + if (!alreadyThere) { + MapLegendList[MapLegendCounter] = -2; + MapLegendCounter++; + ArrowBlipColour2 = CRGBA((uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + } + } + } + } + } + } +} + +void +CRadar::DrawCoordBlip(int32 blipId) +{ + CVector2D out; + CVector2D in; + if (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission()) { + + uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); + if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { + if (CTheScripts::IsDebugOn()) { + ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius); + ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; + if (ms_RadarTrace[blipId].m_Radius < 1.0f) + ms_RadarTrace[blipId].m_Radius = 5.0f; + } + } + if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { + TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); + float dist = LimitRadarPoint(in); + TransformRadarPointToScreenSpace(out, in); + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); + } else { + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = ms_RadarTrace[blipId].m_vecPos; + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); + + if (FrontEndMenuManager.m_bMenuMapActive) { + bool alreadyThere = false; + for (int i = 0; i < NUM_MAP_LEGENDS; i++) { + if (MapLegendList[i] == -1) + alreadyThere = true; + } + if (!alreadyThere) { + MapLegendList[MapLegendCounter] = -1; + MapLegendCounter++; + ArrowBlipColour1 = CRGBA((uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + } + } + } + } + } + } +} + +void +CRadar::DrawLegend(int32 x, int32 y, int32 sprite) +{ + if (sprite < 0) { + static PauseModeTime lastChange = 0; + static int8 blipMode = 0; + + CRGBA color; + if (sprite == -1) { + color = ArrowBlipColour1; + } else { + color = ArrowBlipColour2; + } + + if (CTimer::GetTimeInMillisecondsPauseMode() - lastChange > 600) { + lastChange = CTimer::GetTimeInMillisecondsPauseMode(); + if ( blipMode == 2 ) + blipMode = 0; + else + ++blipMode; + } + + switch (blipMode) { + case BLIP_MODE_TRIANGULAR_UP: + CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(14.0f), y + SCREEN_SCALE_Y(13.0f), x + SCREEN_SCALE_X(2.0f), y + SCREEN_SCALE_Y(13.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(2.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(2.0f), CRGBA(0, 0, 0, 255)); + CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(12.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(4.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(4.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(4.0f), color); + break; + case BLIP_MODE_TRIANGULAR_DOWN: + CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(14.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(14.0f), x + SCREEN_SCALE_X(2.f), y + SCREEN_SCALE_Y(3.0f), x + SCREEN_SCALE_X(2.f), y + SCREEN_SCALE_Y(3.0f), CRGBA(0, 0, 0, 255)); + CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(12.f), y + SCREEN_SCALE_Y(4.0f), x + SCREEN_SCALE_X(4.f), y + SCREEN_SCALE_Y(4.0f), color); + break; + case BLIP_MODE_SQUARE: + CSprite2d::DrawRect(CRect(x + SCREEN_SCALE_X(4.0f), y + SCREEN_SCALE_Y(3.0f), SCREEN_SCALE_X(12.0f) + x, SCREEN_SCALE_Y(12.0f) + y), CRGBA(0, 0, 0, 255)); + CSprite2d::DrawRect(CRect(x + SCREEN_SCALE_X(5.0f), y + SCREEN_SCALE_Y(4.0f), SCREEN_SCALE_X(11.0f) + x, SCREEN_SCALE_Y(11.0f) + y), color); + break; + } + + } else { + RadarSprites[sprite]->Draw(CRect(x, y, x + SCREEN_SCALE_X(16.f), y + SCREEN_SCALE_X(16.f)), CRGBA(255, 255, 255, 255)); + } + + wchar *text; + switch ( sprite ) { + case RADAR_SPRITE_ENTITY_BLIP: + text = TheText.Get("LG_38"); + break; + case RADAR_SPRITE_COORD_BLIP: + text = TheText.Get("LG_35"); + break; + case RADAR_SPRITE_MAP_HERE: + text = TheText.Get("LG_01"); + break; + case RADAR_SPRITE_AVERY: + text = TheText.Get("LG_02"); + break; + case RADAR_SPRITE_BIKER: + text = TheText.Get("LG_03"); + break; + case RADAR_SPRITE_CORTEZ: + text = TheText.Get("LG_04"); + break; + case RADAR_SPRITE_DIAZ: + text = TheText.Get("LG_05"); + break; + case RADAR_SPRITE_KENT: + text = TheText.Get("LG_06"); + break; + case RADAR_SPRITE_LAWYER: + text = TheText.Get("LG_07"); + break; + case RADAR_SPRITE_PHIL: + text = TheText.Get("LG_08"); + break; + case RADAR_SPRITE_BIKERS: + text = TheText.Get("LG_03"); + break; + case RADAR_SPRITE_BOATYARD: + text = TheText.Get("LG_09"); + break; + case RADAR_SPRITE_MALIBU_CLUB: + text = TheText.Get("LG_10"); + break; + case RADAR_SPRITE_CUBANS: + text = TheText.Get("LG_11"); + break; + case RADAR_SPRITE_FILM: + text = TheText.Get("LG_12"); + break; + case RADAR_SPRITE_GUN: + text = TheText.Get("LG_13"); + break; + case RADAR_SPRITE_HAITIANS: + text = TheText.Get("LG_14"); + break; + case RADAR_SPRITE_HARDWARE: + text = TheText.Get("LG_15"); + break; + case RADAR_SPRITE_SAVE: + text = TheText.Get("LG_16"); + break; + case RADAR_SPRITE_STRIP: + text = TheText.Get("LG_37"); + break; + case RADAR_SPRITE_ICE: + text = TheText.Get("LG_17"); + break; + case RADAR_SPRITE_KCABS: + text = TheText.Get("LG_18"); + break; + case RADAR_SPRITE_LOVEFIST: + text = TheText.Get("LG_19"); + break; + case RADAR_SPRITE_PRINTWORKS: + text = TheText.Get("LG_20"); + break; + case RADAR_SPRITE_PROPERTY: + text = TheText.Get("LG_21"); + break; + case RADAR_SPRITE_SUNYARD: + text = TheText.Get("LG_36"); + break; + case RADAR_SPRITE_SPRAY: + text = TheText.Get("LG_22"); + break; + case RADAR_SPRITE_TSHIRT: + text = TheText.Get("LG_23"); + break; + case RADAR_SPRITE_TOMMY: + text = TheText.Get("LG_24"); + break; + case RADAR_SPRITE_PHONE: + text = TheText.Get("LG_25"); + break; + case RADAR_SPRITE_RADIO_WILDSTYLE: + text = TheText.Get("LG_26"); + break; + case RADAR_SPRITE_RADIO_FLASH: + text = TheText.Get("LG_27"); + break; + case RADAR_SPRITE_RADIO_KCHAT: + text = TheText.Get("LG_28"); + break; + case RADAR_SPRITE_RADIO_FEVER: + text = TheText.Get("LG_29"); + break; + case RADAR_SPRITE_RADIO_VROCK: + text = TheText.Get("LG_30"); + break; + case RADAR_SPRITE_RADIO_VCPR: + text = TheText.Get("LG_31"); + break; + case RADAR_SPRITE_RADIO_ESPANTOSO: + text = TheText.Get("LG_32"); + break; + case RADAR_SPRITE_RADIO_EMOTION: + text = TheText.Get("LG_33"); + break; + case RADAR_SPRITE_RADIO_WAVE: + text = TheText.Get("LG_34"); + break; + default: + break; + } + CFont::PrintString(SCREEN_SCALE_X(20.f) + x, SCREEN_SCALE_Y(3.0f) + y, text); +} diff --git a/src/core/Radar.h b/src/core/Radar.h index 100da8f3..8f2e7069 100644 --- a/src/core/Radar.h +++ b/src/core/Radar.h @@ -98,6 +98,17 @@ enum eRadarSprite enum { + RADAR_TRACE_RED, + RADAR_TRACE_GREEN, + RADAR_TRACE_LIGHT_BLUE, + RADAR_TRACE_GRAY, + RADAR_TRACE_YELLOW, + RADAR_TRACE_MAGENTA, + RADAR_TRACE_CYAN +}; + +enum +{ BLIP_MODE_TRIANGULAR_UP = 0, BLIP_MODE_TRIANGULAR_DOWN, BLIP_MODE_SQUARE, @@ -108,17 +119,39 @@ struct sRadarTrace uint32 m_nColor; uint32 m_eBlipType; // eBlipType int32 m_nEntityHandle; - CVector2D m_vec2DPos; + CVector m_vec2DPos; CVector m_vecPos; uint16 m_BlipIndex; bool m_bDim; bool m_bInUse; bool m_bShortRange; + bool m_unused; + float m_Radius; + int16 m_wScale; + uint16 m_eBlipDisplay; // eBlipDisplay + uint16 m_eRadarSprite; // eRadarSprite +}; + +// Either that was a thing while saving/loading blips, or they added sizes of each field one by one. I want to do the former. +#pragma pack(push,1) +struct sRadarTraceSave +{ + uint32 m_nColor; float m_Radius; + uint32 m_eBlipType; // eBlipType + int32 m_nEntityHandle; + CVector2D m_vec2DPos; + CVector m_vecPos; + uint16 m_BlipIndex; + bool m_bDim; + bool m_bInUse; + bool m_bShortRange; + bool m_unused; int16 m_wScale; uint16 m_eBlipDisplay; // eBlipDisplay uint16 m_eRadarSprite; // eRadarSprite }; +#pragma pack(pop) // Values for screen space #define RADAR_LEFT (40.0f) @@ -176,7 +209,7 @@ public: static CRGBA ArrowBlipColour1; static CRGBA ArrowBlipColour2; static int16 MapLegendList[NUM_MAP_LEGENDS]; - static uint16 MapLegendCounter; + static int16 MapLegendCounter; #ifdef MAP_ENHANCEMENTS static int TargetMarkerId; @@ -215,9 +248,9 @@ public: static void RemoveRadarSections(); static void SaveAllRadarBlips(uint8*, uint32*); static void SetBlipSprite(int32 i, int32 icon); - static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay); - static int32 SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay); - static int32 SetShortRangeCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay); + static int32 SetCoordBlip(eBlipType type, CVector pos, uint32, eBlipDisplay); + static int32 SetEntityBlip(eBlipType type, int32, uint32, eBlipDisplay); + static int32 SetShortRangeCoordBlip(eBlipType type, CVector pos, uint32, eBlipDisplay); static void SetRadarMarkerState(int32 i, bool flag); static void ShowRadarMarker(CVector pos, uint32 color, float radius); static void ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha); @@ -229,7 +262,8 @@ public: static void TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in); static void TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in); static void TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in); - - // no in CRadar in the game: static void CalculateCachedSinCos(); + static void DrawEntityBlip(int32 blipId); + static void DrawCoordBlip(int32 blipId); + static void DrawLegend(int32, int32, int32); }; diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index ddde4664..40d4acee 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -903,7 +903,7 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag int i, n; mi = CModelInfo::GetModelInfo(modelId); - if(!CGeneral::faststrcmp("CSPlay", modelName)){ + if(strncasecmp("CSPlay", modelName, 6) == 0){ char *curname = CModelInfo::GetModelInfo(MI_PLAYER)->GetName(); for(int i = 0; CSnames[i][0]; i++){ if(strcasecmp(curname, IGnames[i]) == 0){ diff --git a/src/core/TempColModels.cpp b/src/core/TempColModels.cpp index e12b48dd..203d24d0 100644 --- a/src/core/TempColModels.cpp +++ b/src/core/TempColModels.cpp @@ -22,7 +22,11 @@ CColModel CTempColModels::ms_colModelWeapon; CColSphere s_aPedSpheres[3]; CColSphere s_aPed2Spheres[3]; CColSphere s_aPedGSpheres[4]; +#ifdef FIX_BUGS +CColSphere s_aDoorSpheres[3]; +#else CColSphere s_aDoorSpheres[4]; +#endif CColSphere s_aBumperSpheres[4]; CColSphere s_aPanelSpheres[4]; CColSphere s_aBonnetSpheres[4]; @@ -130,7 +134,11 @@ CTempColModels::Initialise(void) s_aDoorSpheres[1].center = CVector(0.0f, -0.95f, -0.35f); s_aDoorSpheres[2].center = CVector(0.0f, -0.6f, 0.25f); +#ifdef FIX_BUGS for (i = 0; i < ARRAY_SIZE(s_aDoorSpheres); i++) { +#else + for (i = 0; i < ARRAY_SIZE(s_aPed2Spheres); i++) { +#endif s_aDoorSpheres[i].surface = SURFACE_CAR_PANEL; s_aDoorSpheres[i].piece = 0; } @@ -286,9 +294,13 @@ CTempColModels::Initialise(void) SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2); - - ms_colModelWeapon.boundingSphere.Set(0.25f, CVector(0.0f, 0.0f, 0.0f)); - ms_colModelWeapon.boundingBox.Set(CVector(-0.25f, -0.25, -0.25f), CVector(0.25f, 0.25, 0.25f)); + ms_colModelWeapon.boundingSphere.radius = 0.25f; + ms_colModelWeapon.boundingBox.min.x = -0.25f; + ms_colModelWeapon.boundingBox.min.y = -0.25f; + ms_colModelWeapon.boundingBox.min.z = -0.25f; + ms_colModelWeapon.boundingBox.max.x = 0.25f; + ms_colModelWeapon.boundingBox.max.y = 0.25f; + ms_colModelWeapon.boundingBox.max.z = 0.25f; #undef SET_COLMODEL_SPHERES } diff --git a/src/core/Timer.cpp b/src/core/Timer.cpp index f60adf07..bdef6187 100644 --- a/src/core/Timer.cpp +++ b/src/core/Timer.cpp @@ -5,6 +5,9 @@ #include "DMAudio.h" #include "Record.h" #include "Timer.h" +#include "SpecialFX.h" + +// --MIAMI: file done uint32 CTimer::m_snTimeInMilliseconds; PauseModeTime CTimer::m_snTimeInMillisecondsPauseMode = 1; @@ -95,7 +98,7 @@ void CTimer::Update(void) _oldPerfCounter = pc; - float updInCyclesScaled = updInCycles * ms_fTimeScale; + float updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale; // We need that real frame time to fix transparent menu bug. #ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND @@ -141,7 +144,7 @@ void CTimer::Update(void) } } - if ( ms_fTimeStep < 0.01f && !GetIsPaused() ) + if ( ms_fTimeStep < 0.01f && !GetIsPaused() && !CSpecialFX::bSnapShotActive) ms_fTimeStep = 0.01f; ms_fTimeStepNonClipped = ms_fTimeStep; diff --git a/src/core/World.cpp b/src/core/World.cpp index 6d5e8a81..14c06a81 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -79,7 +79,7 @@ CWorld::Add(CEntity *ent) if(ent->IsBuilding() || ent->IsDummy()) return; - if(!ent->IsStatic()) ((CPhysical *)ent)->AddToMovingList(); + if(!ent->GetIsStatic()) ((CPhysical *)ent)->AddToMovingList(); } void @@ -94,7 +94,7 @@ CWorld::Remove(CEntity *ent) if(ent->IsBuilding() || ent->IsDummy()) return; - if(!ent->IsStatic()) ((CPhysical *)ent)->RemoveFromMovingList(); + if(!ent->GetIsStatic()) ((CPhysical *)ent)->RemoveFromMovingList(); } void @@ -1962,7 +1962,7 @@ CWorld::Process(void) RemoveEntityInsteadOfProcessingIt(movingEnt); } else { movingEnt->ProcessControl(); - if(movingEnt->IsStatic()) { movingEnt->RemoveFromMovingList(); } + if(movingEnt->GetIsStatic()) { movingEnt->RemoveFromMovingList(); } } } bForceProcessControl = true; @@ -1973,7 +1973,7 @@ CWorld::Process(void) RemoveEntityInsteadOfProcessingIt(movingEnt); } else { movingEnt->ProcessControl(); - if(movingEnt->IsStatic()) { movingEnt->RemoveFromMovingList(); } + if(movingEnt->GetIsStatic()) { movingEnt->RemoveFromMovingList(); } } } } @@ -2133,13 +2133,13 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa CObject *pObject = (CObject *)pEntity; CVehicle *pVehicle = (CVehicle *)pEntity; if(!pEntity->bExplosionProof && (!pEntity->IsPed() || !pPed->bInVehicle)) { - if(pEntity->IsStatic()) { + if(pEntity->GetIsStatic()) { if(pEntity->IsObject()) { if (fPower > pObject->m_fUprootLimit || IsFence(pObject->GetModelIndex())) { if (IsGlass(pObject->GetModelIndex())) { CGlass::WindowRespondsToExplosion(pObject, position); } else { - pObject->bIsStatic = false; + pObject->SetIsStatic(false); pObject->AddToMovingList(); int16 modelId = pEntity->GetModelIndex(); if(modelId != MI_FIRE_HYDRANT || @@ -2157,18 +2157,18 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa } } } - if(pEntity->IsStatic()) { + if(pEntity->GetIsStatic()) { float fDamageMultiplier = (fRadius - fMagnitude) * 2.0f / fRadius; float fDamage = 300.0f * Min(fDamageMultiplier, 1.0f); pObject->ObjectDamage(fDamage); } } else { - pEntity->bIsStatic = false; + pEntity->SetIsStatic(false); pEntity->AddToMovingList(); } } - if(!pEntity->IsStatic()) { + if(!pEntity->GetIsStatic()) { float fDamageMultiplier = Min((fRadius - fMagnitude) * 2.0f / fRadius, 1.0f); CVector vecForceDir = vecDistance * (fPower * pEntity->m_fMass * 0.00071429f * fDamageMultiplier / diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp index 288b975e..45fe6fff 100644 --- a/src/core/Zones.cpp +++ b/src/core/Zones.cpp @@ -633,14 +633,17 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size) INITSAVEBUF int i; +#define CZONE_SAVE_SIZE (sizeof(char)*8+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(eZoneType)+sizeof(eLevelName)+sizeof(int16)+sizeof(int16)+sizeof(int32)+sizeof(int32)+sizeof(int32)) + *size = SAVE_HEADER_SIZE + sizeof(m_CurrLevel) + sizeof(FindIndex) + sizeof(int16) // padding - + sizeof(NavigationZoneArray) + sizeof(InfoZoneArray) + sizeof(ZoneInfoArray) + + CZONE_SAVE_SIZE * ARRAY_SIZE(NavigationZoneArray) + CZONE_SAVE_SIZE * ARRAY_SIZE(InfoZoneArray) + sizeof(ZoneInfoArray) + sizeof(TotalNumberOfNavigationZones) + sizeof(TotalNumberOfInfoZones) + sizeof(TotalNumberOfZoneInfos) + sizeof(int16) // padding - + sizeof(MapZoneArray) + sizeof(AudioZoneArray) + + CZONE_SAVE_SIZE * ARRAY_SIZE(MapZoneArray) + sizeof(AudioZoneArray) + sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones); +#undef CZONE_SAVE_SIZE uint32 length = 0; WriteSaveHeaderWithLength(buffer, length, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE); diff --git a/src/core/Zones.h b/src/core/Zones.h index 3a74427d..5306d9f1 100644 --- a/src/core/Zones.h +++ b/src/core/Zones.h @@ -77,7 +77,7 @@ public: static CZone *GetInfoZone(uint16 i) { return &InfoZoneArray[i]; } static CZone *GetNavigationZone(uint16 i) { return &NavigationZoneArray[i]; } static CZone *GetMapZone(uint16 i) { return &MapZoneArray[i]; } - static CZone *GetAudioZone(uint16 i) { return &InfoZoneArray[AudioZoneArray[i]]; } + static CZone *GetAudioZone(uint16 i) { return &NavigationZoneArray[AudioZoneArray[i]]; } static void PostZoneCreation(void); static void CheckZonesForOverlap(void); static void InsertZoneIntoZoneHierarchy(CZone *zone); diff --git a/src/core/config.h b/src/core/config.h index 3f077f4c..770a7c2e 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -172,7 +172,6 @@ enum Config { # define RANDOMSPLASH # define VU_COLLISION #elif defined GTA_PC -# define GTA3_1_1_PATCH //# define GTA3_STEAM_PATCH //# define GTAVC_JP_PATCH # ifdef GTA_PS2_STUFF @@ -263,7 +262,6 @@ enum Config { // Hud, frontend and radar //#define BETA_SLIDING_TEXT -#define TRIANGULAR_BLIPS // height indicating triangular radar blips, as in VC #define PC_MENU #ifndef PC_MENU @@ -315,9 +313,7 @@ enum Config { #define FREE_CAM // Rotating cam // Audio -#ifndef AUDIO_OAL // is not working yet for openal #define AUDIO_CACHE // cache sound lengths to speed up the cold boot -#endif //#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS diff --git a/src/core/main.cpp b/src/core/main.cpp index b39a9c8b..012dda2e 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -644,7 +644,7 @@ ProcessSlowMode(void) do { - if ( CPad::GetPad(1)->GetLeftShoulder1JustDown() || CPad::GetPad(1)->GetRightShoulder1() ) + if ( CPad::GetPad(1)->GetSelectJustDown() || CPad::GetPad(1)->GetStart() ) break; if ( stop ) @@ -658,10 +658,7 @@ ProcessSlowMode(void) RwCameraBeginUpdate(Scene.camera); RwCameraEndUpdate(Scene.camera); - if ( CPad::GetPad(1)->GetLeftShoulder1JustDown() || CPad::GetPad(1)->GetRightShoulder1() ) - break; - - } while (!CPad::GetPad(1)->GetRightShoulder1()); + } while (!CPad::GetPad(1)->GetSelectJustDown() && !CPad::GetPad(1)->GetStart()); CPad::GetPad(0)->OldState.LeftStickX = lX; @@ -714,22 +711,32 @@ int32 FrameSamples; struct tZonePrint { - char name[12]; - CRect rect; + char name[11]; + char area[5]; + CRect rect; }; tZonePrint ZonePrint[] = { - { "suburban", CRect(-1639.4f, 1014.3f, -226.23f, -1347.9f) }, - { "comntop", CRect(-223.52f, 203.62f, 616.79f, -413.6f) }, - { "comnbtm", CRect(-227.24f, -413.6f, 620.51f, -911.84f) }, - { "comse", CRect( 200.35f, -911.84f, 620.51f, -1737.3f) }, - { "comsw", CRect(-223.52f, -911.84f, 200.35f, -1737.3f) }, - { "industsw", CRect( 744.05f, -473.0f, 1067.5f, -1331.5f) }, - { "industne", CRect( 1067.5f, 282.19f, 1915.3f, -473.0f) }, - { "industnw", CRect( 744.05f, 324.95f, 1067.5f, -473.0f) }, - { "industse", CRect( 1070.3f, -473.0f, 1918.1f, -1331.5f) }, - { "no zone", CRect( 0.0f, 0.0f, 0.0f, 0.0f) } + { "DOWNTOWN", "GM", CRect(-1500.0f, 1500.0f, -300.0f, 980.0f)}, + { "DOWNTOWS", "KB", CRect(-1200.0f, 980.0f, -300.0f, 435.0f)}, + { "GOLF", "NT", CRect(-300.0f, 660.0f, 320.0f, -255.0f)}, + { "LITTLEHA", "AG", CRect(-1250.0f, -310.0f, -746.0f, -926.0f)}, + { "HAITI", "CJ", CRect(-1355.0f, 30.0f, -637.0f, -304.0f)}, + { "HAITIN", "SM", CRect(-1355.0f, 435.0f, -637.0f, 30.0f)}, + { "DOCKS", "AW", CRect(-1122.0f, -926.0f, -609.0f, -1575.0f)}, + { "AIRPORT", "NT", CRect(-2000.0f, 200.0f, -871.0f, -2000.0f)}, + { "STARISL", "CJ", CRect(-724.0f, -320.0f, -40.0f, -380.0f)}, + { "CENT.ISLA", "NT", CRect(-163.0f, 1260.0f, 120.0f, 830.0f)}, + { "MALL", "AW", CRect( 300.0f, 1266.0f, 483.0f, 995.0f)}, + { "MANSION", "KB", CRect(-724.0f, -500.0f, -40.0f, -670.0f)}, + { "NBEACH", "AS", CRect( 120.0f, 1340.0f, 900.0f, 600.0f)}, + { "NBEACHBT", "AS", CRect( 200.0f, 680.0f, 660.0f, -50.0f)}, + { "NBEACHW", "AS", CRect(-93.0f, 80.0f, 410.0f, -680.0f)}, + { "OCEANDRV", "AC", CRect( 200.0f, -964.0f, 955.0f, -1797.0f)}, + { "OCEANDN", "WS", CRect( 400.0f, 50.0f, 955.0f, -964.0f)}, + { "WASHINGTN", "AC", CRect(-320.0f, -487.0f, 500.0f, -1200.0f)}, + { "WASHINBTM", "AC", CRect(-255.0f, -1200.0f, 500.0f, -1690.0f)} }; #ifndef MASTER @@ -737,14 +744,12 @@ void DisplayGameDebugText() { static bool bDisplayPosn = false; - static bool bDisplayRate = false; - static bool bDisplayCheatStr = false; + static bool bDisplayCheatStr = false; // custom #ifndef FINAL { SETTWEAKPATH("GameDebugText"); TWEAKBOOL(bDisplayPosn); - TWEAKBOOL(bDisplayRate); TWEAKBOOL(bDisplayCheatStr); } #endif @@ -777,23 +782,8 @@ DisplayGameDebugText() FramesPerSecondCounter = 0.0f; FrameSamples = 0; } - - if ( !TheCamera.WorldViewerBeingUsed - && CPad::GetPad(1)->GetSquare() - && CPad::GetPad(1)->GetTriangle() - && CPad::GetPad(1)->GetLeftShoulder2JustDown() ) - { - bDisplayPosn = !bDisplayPosn; - } - if ( CPad::GetPad(1)->GetSquare() - && CPad::GetPad(1)->GetTriangle() - && CPad::GetPad(1)->GetRightShoulder2JustDown() ) - { - bDisplayRate = !bDisplayRate; - } - - if ( bDisplayPosn || bDisplayRate ) + if ( bDisplayPosn ) { CVector pos = FindPlayerCoors(); int32 ZoneId = ARRAY_SIZE(ZonePrint)-1; // no zone @@ -810,43 +800,42 @@ DisplayGameDebugText() } //NOTE: fps should be 30, but its 29 due to different fp2int conversion - if ( bDisplayRate ) - sprintf(str, "X:%5.1f, Y:%5.1f, Z:%5.1f, F-%d, %s", pos.x, pos.y, pos.z, (int32)FramesPerSecond, ZonePrint[ZoneId].name); - else - sprintf(str, "X:%5.1f, Y:%5.1f, Z:%5.1f, %s", pos.x, pos.y, pos.z, ZonePrint[ZoneId].name); - + sprintf(str, "X:%4.0f Y:%4.0f Z:%4.0f F-%d %s-%s", pos.x, pos.y, pos.z, (int32)FramesPerSecond, + ZonePrint[ZoneId].name, ZonePrint[ZoneId].area); + AsciiToUnicode(str, ustr); - // Let's not scale those numbers, they look better that way :eyes: - CFont::SetPropOff(); + CFont::SetPropOn(); CFont::SetBackgroundOff(); - CFont::SetScale(0.7f, 1.5f); + CFont::SetScale(SCREEN_SCALE_X(0.6f), SCREEN_SCALE_Y(0.8f)); CFont::SetCentreOff(); CFont::SetRightJustifyOff(); CFont::SetJustifyOff(); CFont::SetBackGroundOnlyTextOff(); - CFont::SetWrapx(640.0f); - CFont::SetFontStyle(FONT_HEADING); - + CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH)); + CFont::SetFontStyle(FONT_STANDARD); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); + CFont::SetDropShadowPosition(2); CFont::SetColor(CRGBA(0, 0, 0, 255)); - CFont::PrintString(42.0f, 42.0f, ustr); + CFont::PrintString(41.0f, 41.0f, ustr); - CFont::SetColor(CRGBA(255, 108, 0, 255)); + CFont::SetColor(CRGBA(205, 205, 0, 255)); CFont::PrintString(40.0f, 40.0f, ustr); } + // custom if (bDisplayCheatStr) { sprintf(str, "%s", CPad::KeyBoardCheatString); AsciiToUnicode(str, ustr); - CFont::SetPropOff(); + CFont::SetPropOn(); CFont::SetBackgroundOff(); - CFont::SetScale(0.7f, 1.5f); + CFont::SetScale(SCREEN_SCALE_X(0.6f), SCREEN_SCALE_Y(0.8f)); CFont::SetCentreOn(); CFont::SetBackGroundOnlyTextOff(); - CFont::SetWrapx(640.0f); - CFont::SetFontStyle(FONT_HEADING); + CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH)); + CFont::SetFontStyle(FONT_STANDARD); CFont::SetColor(CRGBA(0, 0, 0, 255)); CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.5f)+2.f, SCREEN_SCALE_FROM_BOTTOM(20.0f)+2.f, ustr); @@ -968,8 +957,8 @@ Render2dStuff(void) CSceneEdit::Draw(); else CHud::Draw(); - // TODO(Miami) - // CSpecialFX::Render2DFXs(); + + CSpecialFX::Render2DFXs(); CUserDisplay::OnscnTimer.ProcessForDisplay(); CMessages::Display(); CDarkel::DrawMessages(); @@ -1007,6 +996,9 @@ Render2dStuffAfterFade(void) DisplayGameDebugText(); #endif +#ifdef MOBILE_IMPROVEMENTS + if (CDraw::FadeValue != 0) +#endif CHud::DrawAfterFade(); CFont::DrawFonts(); CCredits::Render(); @@ -1065,9 +1057,7 @@ Idle(void *arg) if(arg == nil) return; - // m_bRenderGameInMenu is there in III PS2 but I don't know about VC PS2. - if((!FrontEndMenuManager.m_bMenuActive/* || FrontEndMenuManager.m_bRenderGameInMenu*/) && - TheCamera.GetScreenFadeStatus() != FADE_2) + if(!FrontEndMenuManager.m_bMenuActive && TheCamera.GetScreenFadeStatus() != FADE_2) { #ifdef GTA_PC // This is from SA, but it's nice for windowed mode diff --git a/src/entities/Entity.h b/src/entities/Entity.h index fbf5cb3b..08d1900a 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -104,7 +104,8 @@ public: eEntityStatus GetStatus() const { return (eEntityStatus)m_status; } void SetStatus(eEntityStatus status) { m_status = status; } CColModel *GetColModel(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); } - bool IsStatic(void) { return bIsStatic || bIsStaticWaitingForCollision; } + bool GetIsStatic(void) const { return bIsStatic || bIsStaticWaitingForCollision; } + void SetIsStatic(bool state) { bIsStatic = state; } #ifdef COMPATIBLE_SAVES void SaveEntityFlags(uint8*& buf); void LoadEntityFlags(uint8*& buf); diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index b190d03a..5483641f 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -344,7 +344,7 @@ CPhysical::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) AddCollisionRecord(ent); if(!ent->IsBuilding()) // Can't this catch dummies too? ((CPhysical*)ent)->AddCollisionRecord(this); - if(ent->IsBuilding() || ent->IsStatic()) + if(ent->IsBuilding() || ent->GetIsStatic()) this->bHasHitWall = true; } return numSpheres; @@ -380,7 +380,7 @@ CPhysical::ProcessControl(void) m_nStaticFrames++; if(m_nStaticFrames > 10){ m_nStaticFrames = 10; - bIsStatic = true; + SetIsStatic(true); m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f); m_vecMoveFriction = m_vecMoveSpeed; @@ -614,7 +614,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl } float speedA, speedB; - if(B->IsStatic() && !foo){ + if(B->GetIsStatic() && !foo){ if(A->bPedPhysics){ speedA = DotProduct(A->m_vecMoveSpeed, colpoint.normal); if(speedA < 0.0f){ @@ -625,7 +625,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(IsGlass(B->GetModelIndex())) CGlass::WindowRespondsToCollision(B, impulseA, A->m_vecMoveSpeed, colpoint.point, false); else if(!B->bInfiniteMass){ - B->bIsStatic = false; + B->SetIsStatic(false); CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 2; CStats::PropertyDestroyed += CGeneral::GetRandomNumberInRange(30, 60); } @@ -637,7 +637,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl return true; } }else if(!B->bInfiniteMass) - B->bIsStatic = false; + B->SetIsStatic(false); if(B->bInfiniteMass){ impulseA = -speedA * A->m_fMass; @@ -675,7 +675,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(IsGlass(B->GetModelIndex())) CGlass::WindowRespondsToCollision(B, impulseA, A->m_vecMoveSpeed, colpoint.point, false); else - B->bIsStatic = false; + B->SetIsStatic(false); int16 model = B->GetModelIndex(); if(model == MI_FIRE_HYDRANT && !Bobj->bHasBeenDamaged){ CParticleObject::AddObject(POBJECT_FIRE_HYDRANT, B->GetPosition() - CVector(0.0f, 0.0f, 0.5f), true); @@ -699,11 +699,11 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl return true; } }else if(!B->bInfiniteMass) - B->bIsStatic = false; + B->SetIsStatic(false); } } - if(B->IsStatic()) + if(B->GetIsStatic()) return false; if(!B->bInfiniteMass && !B->m_phy_flagA08) B->AddToMovingList(); @@ -1231,7 +1231,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) canshift = true; else canshift = A->IsPed() && - B->IsObject() && B->IsStatic() && !Bobj->bHasBeenDamaged; + B->IsObject() && B->GetIsStatic() && !Bobj->bHasBeenDamaged; if(B == A || B->m_scanCode == CWorld::GetCurrentScanCode() || !B->bUsesCollision || @@ -1255,7 +1255,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) CObject *Aobj = (CObject*)A; if(Aobj->ObjectCreatedBy != TEMP_OBJECT && !Aobj->bHasBeenDamaged && - Aobj->IsStatic()){ + Aobj->GetIsStatic()){ if(Aobj->m_pCollidingEntity == B) Aobj->m_pCollidingEntity = nil; }else if(Aobj->m_pCollidingEntity != B){ @@ -1272,7 +1272,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) CObject *Bobj = (CObject*)B; if(Bobj->ObjectCreatedBy != TEMP_OBJECT && !Bobj->bHasBeenDamaged && - Bobj->IsStatic()){ + Bobj->GetIsStatic()){ if(Bobj->m_pCollidingEntity == A) Bobj->m_pCollidingEntity = nil; }else if(Bobj->m_pCollidingEntity != A){ @@ -1595,7 +1595,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) skipCollision = true; else if(Aobj->ObjectCreatedBy == TEMP_OBJECT || Aobj->bHasBeenDamaged || - !Aobj->IsStatic()){ + !Aobj->GetIsStatic()){ if(Aobj->m_pCollidingEntity == B) skipCollision = true; else if(Aobj->m_nCollisionDamageEffect < DAMAGE_EFFECT_SMASH_COMPLETELY){ @@ -1614,7 +1614,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) skipCollision = true; else if(Bobj->ObjectCreatedBy == TEMP_OBJECT || Bobj->bHasBeenDamaged || - !Bobj->IsStatic()){ + !Bobj->GetIsStatic()){ if(Bobj->m_pCollidingEntity == A) skipCollision = true; else if(Bobj->m_nCollisionDamageEffect < DAMAGE_EFFECT_SMASH_COMPLETELY){ diff --git a/src/math/Vector.h b/src/math/Vector.h index 7ee01149..082b296f 100644 --- a/src/math/Vector.h +++ b/src/math/Vector.h @@ -115,6 +115,14 @@ Distance(const CVector &v1, const CVector &v2) return (v2 - v1).Magnitude(); } +inline float +Distance2D(const CVector &v1, const CVector &v2) +{ + float x = v2.x - v1.x; + float y = v2.y - v1.y; + return Sqrt(x*x + y*y); +} + class CMatrix; CVector Multiply3x3(const CMatrix &mat, const CVector &vec); diff --git a/src/math/Vector2D.h b/src/math/Vector2D.h index 2c4e57b5..deabd0b1 100644 --- a/src/math/Vector2D.h +++ b/src/math/Vector2D.h @@ -53,6 +53,9 @@ public: CVector2D operator/(float t) const { return CVector2D(x/t, y/t); } + CVector2D operator-() const { + return CVector2D(-x, -y); + } }; inline float diff --git a/src/modelinfo/PedModelInfo.cpp b/src/modelinfo/PedModelInfo.cpp index e4758a96..bd515391 100644 --- a/src/modelinfo/PedModelInfo.cpp +++ b/src/modelinfo/PedModelInfo.cpp @@ -78,7 +78,6 @@ ColNodeInfo m_pColNodeInfos[NUMPEDINFONODES] = { void CPedModelInfo::CreateHitColModelSkinned(RpClump *clump) { - CVector center; RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(clump); CColModel *colmodel = new CColModel; CColSphere *spheres = (CColSphere*)RwMalloc(NUMPEDINFONODES*sizeof(CColSphere)); @@ -97,23 +96,17 @@ CPedModelInfo::CreateHitColModelSkinned(RpClump *clump) RwV3d pos = { 0.0f, 0.0f, 0.0f }; RwV3dTransformPoints(&pos, &pos, 1, mat); - center.x = pos.x + m_pColNodeInfos[i].x; - center.y = pos.y + 0.0f; - center.z = pos.z + m_pColNodeInfos[i].z; - spheres[i].Set(m_pColNodeInfos[i].radius, center, SURFACE_PED, m_pColNodeInfos[i].pieceType); + spheres[i].center = pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z); + spheres[i].radius = m_pColNodeInfos[i].radius; + spheres[i].surface = SURFACE_PED; + spheres[i].piece = m_pColNodeInfos[i].pieceType; } RwMatrixDestroy(invmat); RwMatrixDestroy(mat); colmodel->spheres = spheres; colmodel->numSpheres = NUMPEDINFONODES; - center.x = center.y = center.z = 0.0f; - colmodel->boundingSphere.Set(2.0f, center); - CVector min, max; - min.x = min.y = -0.5f; - min.z = -1.2f; - max.x = max.y = 0.5f; - max.z = 1.2f; - colmodel->boundingBox.Set(min, max); + colmodel->boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + colmodel->boundingBox.Set(CVector(-0.5f, -0.5f, -1.2f), CVector(0.5f, 0.5f, 1.2f)); colmodel->level = LEVEL_GENERIC; m_hitColModel = colmodel; } @@ -141,9 +134,7 @@ CPedModelInfo::AnimatePedColModelSkinned(RpClump *clump) RwV3d pos = { 0.0f, 0.0f, 0.0f }; RwV3dTransformPoints(&pos, &pos, 1, mat); - spheres[i].center.x = pos.x + m_pColNodeInfos[i].x; - spheres[i].center.y = pos.y + 0.0f; - spheres[i].center.z = pos.z + m_pColNodeInfos[i].z; + spheres[i].center = pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z); } RwMatrixDestroy(invmat); RwMatrixDestroy(mat); @@ -167,9 +158,7 @@ CPedModelInfo::AnimatePedColModelSkinnedWorld(RpClump *clump) RwV3d pos = { 0.0f, 0.0f, 0.0f }; RwV3dTransformPoints(&pos, &pos, 1, mat); - spheres[i].center.x = pos.x + m_pColNodeInfos[i].x; - spheres[i].center.y = pos.y + 0.0f; - spheres[i].center.z = pos.z + m_pColNodeInfos[i].z; + spheres[i].center = pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z); } return m_hitColModel; } diff --git a/src/modelinfo/WeaponModelInfo.cpp b/src/modelinfo/WeaponModelInfo.cpp index 2a79fada..bd8f5cb8 100644 --- a/src/modelinfo/WeaponModelInfo.cpp +++ b/src/modelinfo/WeaponModelInfo.cpp @@ -40,10 +40,10 @@ CWeaponModelInfo::SetWeaponInfo(int32 weaponId) m_atomics[2] = (RpAtomic*)weaponId; } -int32 +eWeaponType CWeaponModelInfo::GetWeaponInfo(void) { - return (int32)(uintptr)m_atomics[2]; + return (eWeaponType)(uintptr)m_atomics[2]; } void diff --git a/src/modelinfo/WeaponModelInfo.h b/src/modelinfo/WeaponModelInfo.h index 5c690c29..548bf8a6 100644 --- a/src/modelinfo/WeaponModelInfo.h +++ b/src/modelinfo/WeaponModelInfo.h @@ -1,6 +1,7 @@ #pragma once #include "SimpleModelInfo.h" +#include "WeaponType.h" class CWeaponModelInfo : public CSimpleModelInfo { @@ -18,5 +19,5 @@ public: void Init(void); void SetWeaponInfo(int32 weaponId); - int32 GetWeaponInfo(void); + eWeaponType GetWeaponInfo(void); }; diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index 9a9eaa73..8b78bdbd 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -98,7 +98,7 @@ CObject::ProcessControl(void) CPhysical::ProcessControl(); if (mod_Buoyancy.ProcessBuoyancy(this, m_fBuoyancy, &point, &impulse)) { bIsInWater = true; - bIsStatic = false; + SetIsStatic(false); ApplyMoveForce(impulse); ApplyTurnForce(impulse, point); float fTimeStep = Pow(0.97f, CTimer::GetTimeStep()); @@ -197,7 +197,7 @@ CObject::ObjectDamage(float amount) case DAMAGE_EFFECT_SMASH_COMPLETELY: bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -209,7 +209,7 @@ CObject::ObjectDamage(float amount) else { bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -218,7 +218,7 @@ CObject::ObjectDamage(float amount) case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY: { bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -241,7 +241,7 @@ CObject::ObjectDamage(float amount) case DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY: { bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -264,7 +264,7 @@ CObject::ObjectDamage(float amount) case DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY: { bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -289,7 +289,7 @@ CObject::ObjectDamage(float amount) case DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY: { bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -329,7 +329,7 @@ CObject::Init(void) CObjectData::SetObjectData(GetModelIndex(), *this); m_nEndOfLifeTime = 0; ObjectCreatedBy = GAME_OBJECT; - bIsStatic = true; + SetIsStatic(true); bIsPickup = false; bPickupObjWithMessage = false; bOutOfStock = false; diff --git a/src/objects/Object.h b/src/objects/Object.h index b81e84b6..ce45509f 100644 --- a/src/objects/Object.h +++ b/src/objects/Object.h @@ -70,7 +70,8 @@ public: uint8 bUseVehicleColours : 1; uint8 bIsWeapon : 1; uint8 bIsStreetLight : 1; - int8 m_nBonusValue; + int8 m_nBonusValue; + uint16 m_nCostValue; float m_fCollisionDamageMultiplier; uint8 m_nCollisionDamageEffect; uint8 m_nSpecialCollisionResponseCases; diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp index 1950c4b3..74a7c9ba 100644 --- a/src/peds/CivilianPed.cpp +++ b/src/peds/CivilianPed.cpp @@ -425,7 +425,7 @@ void CCivilianPed::FindNearbyAttractorsSectorList(CPtrList& list, float& minDist { for (CPtrNode* pNode = list.first; pNode != nil; pNode = pNode->next) { CEntity* pEntity = (CEntity*)pNode->item; - if (pEntity->IsObject() && (!pEntity->IsStatic() || ((CObject*)pEntity)->bHasBeenDamaged)) + if (pEntity->IsObject() && (!pEntity->GetIsStatic() || ((CObject*)pEntity)->bHasBeenDamaged)) continue; CBaseModelInfo* pModelInfo = CModelInfo::GetModelInfo(pEntity->GetModelIndex()); for (int i = 0; i < pModelInfo->GetNum2dEffects(); i++) { diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp index 5b91daad..24d9a6a1 100644 --- a/src/peds/EmergencyPed.cpp +++ b/src/peds/EmergencyPed.cpp @@ -9,6 +9,8 @@ #include "CarCtrl.h" #include "Accident.h" +// --MIAMI: file done + CEmergencyPed::CEmergencyPed(uint32 type) : CPed(type) { switch (type){ @@ -97,7 +99,7 @@ CEmergencyPed::FiremanAI(void) case EMERGENCY_PED_READY: nearestFire = gFireManager.FindNearestFire(GetPosition(), &fireDist); if (nearestFire) { - m_nPedState = PED_NONE; + SetPedState(PED_NONE); SetSeek(nearestFire->m_vecPos, 1.0f); SetMoveState(PEDMOVE_RUN); m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE; @@ -110,7 +112,7 @@ CEmergencyPed::FiremanAI(void) case EMERGENCY_PED_DETERMINE_NEXT_STATE: nearestFire = gFireManager.FindNearestFire(GetPosition(), &fireDist); if (nearestFire && nearestFire != m_pAttendedFire) { - m_nPedState = PED_NONE; + SetPedState(PED_NONE); SetSeek(nearestFire->m_vecPos, 1.0f); SetMoveState(PEDMOVE_RUN); #ifdef FIX_BUGS @@ -149,7 +151,7 @@ CEmergencyPed::FiremanAI(void) #ifdef FIX_BUGS bIsRunning = false; #endif - m_nPedState = PED_NONE; + SetPedState(PED_NONE); SetWanderPath(CGeneral::GetRandomNumber() & 7); m_pAttendedFire = nil; m_nEmergencyPedState = EMERGENCY_PED_READY; @@ -164,15 +166,20 @@ CEmergencyPed::MedicAI(void) { float distToEmergency; if (!bInVehicle && IsPedInControl()) { - ScanForThreats(); - if (m_threatEntity && m_threatEntity->IsPed() && ((CPed*)m_threatEntity)->IsPlayer()) { - if (((CPed*)m_threatEntity)->GetWeapon()->IsTypeMelee()) { - SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity); - } else { - SetFlee(m_threatEntity, 6000); - Say(SOUND_PED_FLEE_SPRINT); + ScanForDelayedResponseThreats(); + if (m_threatFlags && CTimer::GetTimeInMilliseconds() > m_threatCheckTimer) { + CheckThreatValidity(); + m_threatFlags = 0; + m_threatCheckTimer = 0; + if (m_threatEntity && m_threatEntity->IsPed() && ((CPed*)m_threatEntity)->IsPlayer()) { + if (((CPed*)m_threatEntity)->GetWeapon()->IsTypeMelee()) { + SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity); + } else { + SetFlee(m_threatEntity, 6000); + Say(SOUND_PED_FLEE_SPRINT); + } + return; } - return; } } @@ -225,8 +232,7 @@ CEmergencyPed::MedicAI(void) m_pRevivedPed->RegisterReference((CEntity**)&m_pRevivedPed); m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID); m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD); - SetSeek((headPos + midPos) * 0.5f, 1.0f); - SetObjective(OBJECTIVE_NONE); + SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector((headPos + midPos) * 0.5f)); bIsRunning = true; m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE; m_pAttendedAccident = nearestAccident; @@ -239,6 +245,7 @@ CEmergencyPed::MedicAI(void) CPed* driver = m_pMyVehicle->pDriver; if (driver && driver->m_nPedType != PEDTYPE_EMERGENCY && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) { SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, driver); + } else if (m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER && m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) { @@ -265,8 +272,7 @@ CEmergencyPed::MedicAI(void) } m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID); m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD); - SetSeek((headPos + midPos) * 0.5f, nearestAccident->m_nMedicsPerformingCPR * 0.5f + 1.0f); - SetObjective(OBJECTIVE_NONE); + SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector((headPos + midPos) * 0.5f)); bIsRunning = true; --m_pAttendedAccident->m_nMedicsAttending; ++nearestAccident->m_nMedicsAttending; @@ -296,11 +302,11 @@ CEmergencyPed::MedicAI(void) } else { m_pRevivedPed->m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds(); SetMoveState(PEDMOVE_STILL); - m_nPedState = PED_CPR; + SetPedState(PED_CPR); m_nLastPedState = PED_CPR; SetLookFlag(m_pRevivedPed, 0); SetLookTimer(500); - //Say(SOUND_PED_HEALING); + Say(SOUND_PED_HEALING); if (m_pAttendedAccident->m_nMedicsPerformingCPR) { SetIdle(); m_nEmergencyPedState = EMERGENCY_PED_STAND_STILL; @@ -355,12 +361,12 @@ CEmergencyPed::MedicAI(void) break; } m_nEmergencyPedState = EMERGENCY_PED_STOP_CPR; - m_nPedState = PED_NONE; + SetPedState(PED_NONE); SetMoveState(PEDMOVE_WALK); m_pVehicleAnim = nil; if (!m_pRevivedPed->bBodyPartJustCameOff) { m_pRevivedPed->m_fHealth = 100.0f; - m_pRevivedPed->m_nPedState = PED_NONE; + m_pRevivedPed->SetPedState(PED_NONE); m_pRevivedPed->m_nLastPedState = PED_WANDER_PATH; m_pRevivedPed->SetGetUp(); m_pRevivedPed->bUsesCollision = true; @@ -369,6 +375,8 @@ CEmergencyPed::MedicAI(void) m_pRevivedPed->bIsPedDieAnimPlaying = false; m_pRevivedPed->bKnockedUpIntoAir = false; m_pRevivedPed->m_pCollidingEntity = nil; + m_pRevivedPed->bKnockedOffBike = false; + m_pRevivedPed->Say(SOUND_PED_ACCIDENTREACTION1); } break; case EMERGENCY_PED_STOP_CPR: @@ -389,7 +397,7 @@ CEmergencyPed::MedicAI(void) break; case EMERGENCY_PED_STOP: m_bStartedToCPR = false; - m_nPedState = PED_NONE; + SetPedState(PED_NONE); if (m_pAttendedAccident) { m_pAttendedAccident->m_pVictim = nil; --m_pAttendedAccident->m_nMedicsAttending; diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index c5b19241..82298e74 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -14,6 +14,7 @@ #include "AnimBlendClumpData.h" #include "AnimBlendAssociation.h" #include "Fire.h" +#include "Glass.h" #include "DMAudio.h" #include "General.h" #include "SurfaceTable.h" @@ -5865,7 +5866,7 @@ CPed::FightStrike(CVector &touchedNodePos, bool fightWithWeapon) if (m_fightState == FIGHTSTATE_JUST_ATTACKED) return false; - // TODO(Miami): BreakGlassPhysically + CGlass::BreakGlassPhysically(touchedNodePos, radius); for (int i = 0; i < m_numNearPeds; i++) { int8 pedFound = 0; @@ -15403,17 +15404,17 @@ CPed::ProcessObjective(void) CVector distance = m_nextRoutePointPos - GetPosition(); distance.z = 0.0f; if (m_objective == OBJECTIVE_GOTO_SHELTER_ON_FOOT) { - if (m_nMoveState == PEDMOVE_SPRINT && distance.Magnitude() < SQR(2.0f)) { + if (m_nMoveState == PEDMOVE_RUN && distance.MagnitudeSqr() < SQR(2.0f)) { SetMoveState(PEDMOVE_WALK); bIsRunning = false; } - else if (CWeather::Rain < 0.2f && m_attractor) { + if (CWeather::Rain < 0.2f && m_attractor) { GetPedAttractorManager()->DeRegisterPed(this, m_attractor); return; } } else if (m_objective == OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT) { - if (m_nMoveState == PEDMOVE_SPRINT && distance.Magnitude() < SQR(4.0f)) { + if (m_nMoveState == PEDMOVE_RUN && distance.MagnitudeSqr() < SQR(4.0f)) { SetMoveState(PEDMOVE_WALK); bIsRunning = false; } @@ -15439,8 +15440,10 @@ CPed::ProcessObjective(void) } } if (sq(m_distanceToCountSeekDone) < distance.MagnitudeSqr()) { - if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer || GetPedState() != PED_SEEK_POS) + if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer || GetPedState() != PED_SEEK_POS) { + m_vecSeekPos = m_nextRoutePointPos; SetSeek(m_vecSeekPos, m_distanceToCountSeekDone); + } } else { if (!bReachedAttractorHeadingTarget) { @@ -15510,6 +15513,10 @@ CPed::ProcessObjective(void) SetObjective(OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN); break; } + } else { + m_prevObjective = OBJECTIVE_NONE; + SetObjective(OBJECTIVE_WAIT_ON_FOOT); + m_objectiveTimer = 0; } } } @@ -15693,11 +15700,11 @@ CPed::ProcessObjective(void) } if (!pVan->m_bSirenOrAlarm) { GetPedAttractorManager()->DeRegisterPed(this, m_attractor); - return; // ??? + return; // Why? } if (pVan->GetStatus() == STATUS_WRECKED) { GetPedAttractorManager()->DeRegisterPed(this, m_attractor); - return; // ??? + return; // Why? } break; } @@ -16422,11 +16429,11 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) if (!collidingEnt->IsBuilding()) ((CPhysical*)collidingEnt)->AddCollisionRecord(this); - if (ourCollidedSpheres > 0 && (collidingEnt->IsBuilding() || collidingEnt->IsStatic())) { + if (ourCollidedSpheres > 0 && (collidingEnt->IsBuilding() || collidingEnt->GetIsStatic())) { bHasHitWall = true; } } - if (collidingEnt->IsBuilding() || collidingEnt->IsStatic()) { + if (collidingEnt->IsBuilding() || collidingEnt->GetIsStatic()) { if (bWasStanding) { CVector sphereNormal; float normalLength; @@ -17003,72 +17010,69 @@ CPed::ProcessBuoyancy(void) } } } - float speedMult = 0.0f; - if (buoyancyImpulse.z / m_fMass > GRAVITY * CTimer::GetTimeStep() - || mod_Buoyancy.m_waterlevel > GetPosition().z) { + } + float speedMult = 0.0f; + if (buoyancyImpulse.z / m_fMass > GRAVITY * CTimer::GetTimeStep() + || mod_Buoyancy.m_waterlevel > GetPosition().z + 0.6f) { + speedMult = pow(0.9f, CTimer::GetTimeStep()); + m_vecMoveSpeed.x *= speedMult; + m_vecMoveSpeed.y *= speedMult; + m_vecMoveSpeed.z *= speedMult; + bIsStanding = false; + bIsDrowning = true; + InflictDamage(nil, WEAPONTYPE_DROWNING, 3.0f * CTimer::GetTimeStep(), PEDPIECE_TORSO, 0); + } + if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.25f * CTimer::GetTimeStep()) { + if (speedMult == 0.0f) { speedMult = pow(0.9f, CTimer::GetTimeStep()); - m_vecMoveSpeed.x *= speedMult; - m_vecMoveSpeed.y *= speedMult; - m_vecMoveSpeed.z *= speedMult; - bIsStanding = false; - bIsDrowning = true; - InflictDamage(nil, WEAPONTYPE_DROWNING, 3.0f * CTimer::GetTimeStep(), PEDPIECE_TORSO, 0); - } - if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.25f * CTimer::GetTimeStep()) { - if (speedMult == 0.0f) { - speedMult = pow(0.9f, CTimer::GetTimeStep()); - } - m_vecMoveSpeed.x *= speedMult; - m_vecMoveSpeed.y *= speedMult; - if (m_vecMoveSpeed.z >= -0.1f) { - if (m_vecMoveSpeed.z < -0.04f) - m_vecMoveSpeed.z = -0.02f; - } else { - m_vecMoveSpeed.z = -0.01f; - DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f); - CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition(); - float level = 0.0f; - if (CWaterLevel::GetWaterLevel(aBitForward, &level, false)) - aBitForward.z = level; - - 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 - return; - } else - bTouchingWater = false; - - if (nGenerateWaterCircles && CTimer::GetTimeInMilliseconds() >= nGenerateWaterCircles) { - CVector pos = GetPosition(); - float level = 0.0f; - if (CWaterLevel::GetWaterLevel(pos, &level, false)) - pos.z = level; + m_vecMoveSpeed.x *= speedMult; + m_vecMoveSpeed.y *= speedMult; + if (m_vecMoveSpeed.z >= -0.1f) { + if (m_vecMoveSpeed.z < -0.04f) + m_vecMoveSpeed.z = -0.02f; + } else { + m_vecMoveSpeed.z = -0.01f; + DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f); + CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition(); + float level = 0.0f; + if (CWaterLevel::GetWaterLevel(aBitForward, &level, false)) + aBitForward.z = level; - if (pos.z != 0.0f) { - nGenerateWaterCircles = 0; - for(int i = 0; i < 4; i++) { - 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); + 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; } } - } + if (nGenerateWaterCircles && CTimer::GetTimeInMilliseconds() >= nGenerateWaterCircles) { + CVector pos = GetPosition(); + float level = 0.0f; + if (CWaterLevel::GetWaterLevel(pos, &level, false)) + pos.z = level; - if (nGenerateRaindrops && CTimer::GetTimeInMilliseconds() >= nGenerateRaindrops) { - CVector pos = GetPosition(); - float level = 0.0f; - if (CWaterLevel::GetWaterLevel(pos, &level, false)) - pos.z = level; + if (pos.z != 0.0f) { + nGenerateWaterCircles = 0; + for(int i = 0; i < 4; i++) { + 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); + } + } + } + if (nGenerateRaindrops && CTimer::GetTimeInMilliseconds() >= nGenerateRaindrops) { + CVector pos = GetPosition(); + float level = 0.0f; + if (CWaterLevel::GetWaterLevel(pos, &level, false)) + pos.z = level; - if (pos.z >= 0.0f) { - pos.z += 0.25f; - nGenerateRaindrops = 0; - CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true); + if (pos.z >= 0.0f) { + pos.z += 0.25f; + nGenerateRaindrops = 0; + CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true); + } } - } + } else + bTouchingWater = false; } // --MIAMI: Done @@ -18411,7 +18415,7 @@ CPed::SeekCar(void) { m_fRotationCur = m_fRotationDest; if (!bVehEnterDoorIsBlocked) { - vehToSeek->bIsStatic = false; + vehToSeek->SetIsStatic(false); if (m_objective == OBJECTIVE_SOLICIT_VEHICLE) { SetSolicit(1000); } else if (m_objective == OBJECTIVE_BUY_ICE_CREAM) { @@ -20037,15 +20041,13 @@ CPed::Save(uint8*& buf) CopyToBuf(buf, GetPosition().z); SkipSaveBuf(buf, 288); CopyToBuf(buf, CharCreatedBy); - SkipSaveBuf(buf, 351); + SkipSaveBuf(buf, 499); CopyToBuf(buf, m_fHealth); CopyToBuf(buf, m_fArmour); - SkipSaveBuf(buf, 148); - for (int i = 0; i < 13; i++) // has to be hardcoded + SkipSaveBuf(buf, 172); + for (int i = 0; i < 10; i++) // has to be hardcoded m_weapons[i].Save(buf); - SkipSaveBuf(buf, 5); - CopyToBuf(buf, m_maxWeaponTypeAllowed); - SkipSaveBuf(buf, 162); + SkipSaveBuf(buf, 252); } void @@ -20057,16 +20059,15 @@ CPed::Load(uint8*& buf) CopyFromBuf(buf, GetMatrix().GetPosition().z); SkipSaveBuf(buf, 288); CopyFromBuf(buf, CharCreatedBy); - SkipSaveBuf(buf, 351); + SkipSaveBuf(buf, 499); CopyFromBuf(buf, m_fHealth); CopyFromBuf(buf, m_fArmour); - SkipSaveBuf(buf, 148); + SkipSaveBuf(buf, 172); + m_currentWeapon = WEAPONTYPE_UNARMED; CWeapon bufWeapon; - for (int i = 0; i < 13; i++) { // has to be hardcoded + for (int i = 0; i < 10; i++) { // has to be hardcoded bufWeapon.Load(buf); - if (i >= 10) - continue; // tmp hack before we fix save/load if (bufWeapon.m_eWeaponType != WEAPONTYPE_UNARMED) { int modelId = CWeaponInfo::GetWeaponInfo(bufWeapon.m_eWeaponType)->m_nModelId; @@ -20081,9 +20082,7 @@ CPed::Load(uint8*& buf) GiveWeapon(bufWeapon.m_eWeaponType, bufWeapon.m_nAmmoTotal); } } - SkipSaveBuf(buf, 5); - CopyFromBuf(buf, m_maxWeaponTypeAllowed); - SkipSaveBuf(buf, 162); + SkipSaveBuf(buf, 252); } #undef CopyFromBuf #undef CopyToBuf diff --git a/src/peds/PedAttractor.cpp b/src/peds/PedAttractor.cpp index 9f77f2a4..45bed947 100644 --- a/src/peds/PedAttractor.cpp +++ b/src/peds/PedAttractor.cpp @@ -135,8 +135,10 @@ void CPedAttractorManager::RemoveIceCreamVanEffects(C2dEffect* pEffect) if (vVehicleToEffect.empty()) return; for (std::vector<CVehicleToEffect>::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend();) { - if (assoc->GetVehicle() != pVehicle) - return; + if (assoc->GetVehicle() != pVehicle) { + assoc++; + continue; + } uint32 total = 0; for (uint32 j = 0; j < NUM_ATTRACTORS_FOR_ICECREAM_VAN; j++) { if (FindAssociatedAttractor(assoc->GetEffect(j), vIceCreamAttractors)) @@ -377,12 +379,16 @@ bool CPedAttractor::BroadcastDeparture(CPed* pPed) if (pPed->GetPedState() == PED_IDLE || pPed->GetPedState() == PED_NONE) pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y)); } - else if (qid == 0) - pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(vecQueueDir.x, vecQueueDir.y)); - else if (qid == vWaitingQueue.size() - 1) - pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y)); - else - pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.y, -vecQueueDir.z)); + else { + pPed->SetObjective(OBJECTIVE_NONE); + if (qid == 0) + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(vecQueueDir.x, vecQueueDir.y)); + else if (qid == vWaitingQueue.size() - 1) + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y)); + else + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.y, -vecQueueDir.x)); + UpdatePedStateOnDeparture(pPed); + } vWaitingQueue.erase(vWaitingQueue.cbegin() + qid); for (std::vector<CPed*>::iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++pPedIt) { CPed* pPed = *pPedIt; @@ -414,12 +420,16 @@ bool CPedShelterAttractor::BroadcastDeparture(CPed* pPed) if (pPed->GetPedState() == PED_IDLE || pPed->GetPedState() == PED_NONE) pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y)); } - else if (qid == 0) - pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(vecQueueDir.x, vecQueueDir.y)); - else if (qid == vWaitingQueue.size() - 1) - pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y)); - else - pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.y, -vecQueueDir.z)); + else { + pPed->SetObjective(OBJECTIVE_NONE); + if (qid == 0) + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(vecQueueDir.x, vecQueueDir.y)); + else if (qid == vWaitingQueue.size() - 1) + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y)); + else + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.y, -vecQueueDir.x)); + UpdatePedStateOnDeparture(pPed); + } vWaitingQueue.erase(vWaitingQueue.cbegin() + qid); for (std::vector<CPed*>::iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++pPedIt) { CPed* pPed = *pPedIt; diff --git a/src/peds/PedDebug.cpp b/src/peds/PedDebug.cpp index 0809581b..aed11357 100644 --- a/src/peds/PedDebug.cpp +++ b/src/peds/PedDebug.cpp @@ -7,11 +7,10 @@ #include "Sprite.h" #include "Text.h" -// TODO(Miami) static char ObjectiveText[][28] = { "No Obj", "Wait on Foot", - "Wait on Foot For Cop", + "Wait on Foot for cop", "Flee on Foot Till Safe", "Guard Spot", "Guard Area", @@ -22,8 +21,8 @@ static char ObjectiveText[][28] = { "Flee Char on Foot Till Safe", "Flee Char on Foot Always", "GoTo Char on Foot", - "GoTo Char on Foot Walking", - "Hassle Char", + "GoTo Char on Foot walking", + "Hassle char", "Follow Char in Formation", "Leave Car", "Enter Car as Passenger", @@ -40,14 +39,30 @@ static char ObjectiveText[][28] = { "Guard Attack", "Set Leader", "Follow Route", - "Solicit", + "Solicit vehicle", "Take Taxi", "Catch Train", "Buy IceCream", "Steal Any Car", - "Steal Any Mission Car", + "Steal any mission car", "Mug Char", - "Leave Car and Die", + "Lv car die", + "Goto seat", + "Goto atm", + "Flee car", + "Sunbathe", + "Goto bus stop", + "Goto pizza", + "Goto shelter", + "Aim gun at", + "Wander", + "Wait on foot at shltr", + "Sprint to area", + "Kill char on boat", + "Solicit ped", + "Wait at bus stop", + "Goto ice cream van foot", + "Wait foot icecream van" }; static char StateText[][18] = { @@ -84,11 +99,11 @@ static char StateText[][18] = { "Investigate", "Step away", "On Fire", - "Sun Bathe", + "Bathe", "Flash", "Jog", - "Answer Mobile", - "Unknown", + "Answer mobile", + "Hang out", "STATES_NO_AI", "Abseil", "Sit", @@ -114,7 +129,7 @@ static char StateText[][18] = { "Exit Car", "Hands Up", "Arrested", - "Deploying Stinger" + "Deply stgr" }; static char PersonalityTypeText[][18] = { @@ -141,8 +156,7 @@ static char PersonalityTypeText[][18] = { "Geek Girl", "Old Girl", "Tough Girl", - "Tramp Male", - "Tramp Female", + "Tramp", "Tourist", "Prostitute", "Criminal", @@ -151,8 +165,6 @@ static char PersonalityTypeText[][18] = { "Psycho", "Steward", "Sports Fan", - "Shopper", - "Old Shopper" }; static char WaitStateText[][16] = { @@ -177,6 +189,21 @@ static char WaitStateText[][16] = { "Play HandsCower", "Play Chat", "Finish Flee", + "Sit down", + "Sit down rvrs", + "Sit up", + "Sit idle", + "Use atm", + "Sunbth pre", + "Sunbth down", + "Sunbth idle", + "Riot", + "Fast fall", + "Bomber", + "Stripper", + "Ground attack", + "Lance sitting", + "Handsup simple" }; void diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 041fb5e8..1f53853f 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -23,7 +23,7 @@ const uint32 CPlayerPed::nSaveStructSize = #ifdef COMPATIBLE_SAVES - 1520; + 1752; #else sizeof(CPlayerPed); #endif @@ -1935,7 +1935,7 @@ CPlayerPed::Save(uint8*& buf) CopyToBuf(buf, m_nTargettableObjects[1]); CopyToBuf(buf, m_nTargettableObjects[2]); CopyToBuf(buf, m_nTargettableObjects[3]); - SkipSaveBuf(buf, 116); + SkipSaveBuf(buf, 164); } void @@ -1949,7 +1949,7 @@ CPlayerPed::Load(uint8*& buf) CopyFromBuf(buf, m_nTargettableObjects[1]); CopyFromBuf(buf, m_nTargettableObjects[2]); CopyFromBuf(buf, m_nTargettableObjects[3]); - SkipSaveBuf(buf, 116); + SkipSaveBuf(buf, 164); } #undef CopyFromBuf #undef CopyToBuf diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp index 94533f4a..d52c8c7c 100644 --- a/src/peds/Population.cpp +++ b/src/peds/Population.cpp @@ -945,7 +945,7 @@ CPopulation::ConvertToRealObject(CDummyObject *dummy) if (IsGlass(obj->GetModelIndex()) && !mi->m_isArtistGlass) { obj->bIsVisible = false; } else if (obj->GetModelIndex() == MI_BUOY) { - obj->bIsStatic = false; + obj->SetIsStatic(false); obj->m_vecMoveSpeed = CVector(0.0f, 0.0f, -0.001f); obj->bTouchingWater = true; obj->AddToMovingList(); diff --git a/src/render/2dEffect.h b/src/render/2dEffect.h index baf07342..8ad2b946 100644 --- a/src/render/2dEffect.h +++ b/src/render/2dEffect.h @@ -88,14 +88,10 @@ public: if(type == EFFECT_LIGHT){ if(light.corona) RwTextureDestroy(light.corona); -#ifdef GTA3_1_1_PATCH light.corona = nil; -#endif if(light.shadow) RwTextureDestroy(light.shadow); -#ifdef GTA3_1_1_PATCH light.shadow = nil; -#endif } } }; diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp index 773561f3..19a172fb 100644 --- a/src/render/Fluff.cpp +++ b/src/render/Fluff.cpp @@ -386,6 +386,8 @@ CMovingThing CMovingThings::StartCloseList; CMovingThing CMovingThings::EndCloseList; int16 CMovingThings::Num; CMovingThing CMovingThings::aMovingThings[NUMMOVINGTHINGS]; + +int32 CScrollBar::TonightsEvent; void CMovingThings::Init() { @@ -1603,7 +1605,7 @@ void CScriptPath::Update(void) { void CScriptPath::Clear(void) { if (m_pNode) - delete m_pNode; + delete[] m_pNode; m_pNode = nil; m_numNodes = 0; for (int i = 0; i < 6; i++) diff --git a/src/render/Fluff.h b/src/render/Fluff.h index a6a28cb7..f61da350 100644 --- a/src/render/Fluff.h +++ b/src/render/Fluff.h @@ -170,6 +170,9 @@ private: float m_fScale; public: + static int TonightsEvent; + +public: void SetVisibility(bool visible) { m_bVisible = visible; } bool IsVisible() { return m_bVisible; } diff --git a/src/render/Font.cpp b/src/render/Font.cpp index f14e45cd..787a0c40 100644 --- a/src/render/Font.cpp +++ b/src/render/Font.cpp @@ -475,10 +475,14 @@ CFont::PrintString(float xstart, float ystart, wchar *s) bool first; wchar *start, *t; + Details.bFlash = false; + if(*s == '*') return; + Details.anonymous_25++; if(Details.background){ + RenderState.color = Details.color; GetNumberLines(xstart, ystart, s); // BUG: result not used GetTextRect(&rect, xstart, ystart, s); CSprite2d::DrawRect(rect, Details.backgroundColor); @@ -1292,6 +1296,7 @@ CFont::RenderFontBuffer() RenderState = *(CFontRenderState*)&FontRenderStateBuf[0]; textPosX = RenderState.fTextPosX; textPosY = RenderState.fTextPosY; + color = RenderState.color; tFontRenderStatePointer pRenderStateBufPointer; pRenderStateBufPointer.pRenderState = (CFontRenderState*)&FontRenderStateBuf[0]; for (++pRenderStateBufPointer.pRenderState; pRenderStateBufPointer.pStr < FontRenderStatePointer.pStr; pRenderStateBufPointer.pStr++) { diff --git a/src/render/Glass.cpp b/src/render/Glass.cpp index c52d49bd..0e26ee0b 100644 --- a/src/render/Glass.cpp +++ b/src/render/Glass.cpp @@ -3,6 +3,8 @@ #include "Glass.h" #include "Timer.h" #include "Object.h" +#include "Vehicle.h" +#include "Pools.h" #include "General.h" #include "AudioScriptObject.h" #include "World.h" @@ -14,6 +16,7 @@ #include "ModelIndices.h" #include "main.h" #include "soundlist.h" +#include "SurfaceTable.h" uint32 CGlass::NumGlassEntities; @@ -57,17 +60,17 @@ const CVector2D CoorsWithTriangle[NUM_GLASSTRIANGLES][3] = #define TEMPBUFFERVERTHILIGHTOFFSET 0 #define TEMPBUFFERINDEXHILIGHTOFFSET 0 -#define TEMPBUFFERVERTHILIGHTSIZE 128 +#define TEMPBUFFERVERTHILIGHTSIZE 256 #define TEMPBUFFERINDEXHILIGHTSIZE 512 #define TEMPBUFFERVERTSHATTEREDOFFSET TEMPBUFFERVERTHILIGHTSIZE #define TEMPBUFFERINDEXSHATTEREDOFFSET TEMPBUFFERINDEXHILIGHTSIZE -#define TEMPBUFFERVERTSHATTEREDSIZE 192 +#define TEMPBUFFERVERTSHATTEREDSIZE 384 #define TEMPBUFFERINDEXSHATTEREDSIZE 768 #define TEMPBUFFERVERTREFLECTIONOFFSET TEMPBUFFERVERTSHATTEREDSIZE #define TEMPBUFFERINDEXREFLECTIONOFFSET TEMPBUFFERINDEXSHATTEREDSIZE -#define TEMPBUFFERVERTREFLECTIONSIZE 256 +#define TEMPBUFFERVERTREFLECTIONSIZE 512 #define TEMPBUFFERINDEXREFLECTIONSIZE 1024 int32 TempBufferIndicesStoredHiLight = 0; @@ -83,10 +86,16 @@ CFallingGlassPane::Update(void) if ( CTimer::GetTimeInMilliseconds() >= m_nTimer ) { // Apply MoveSpeed - GetPosition() += m_vecMoveSpeed * CTimer::GetTimeStep(); + if ( m_bCarGlass ) + GetPosition() += m_vecMoveSpeed * CTimer::GetTimeStep() * 0.35f; + else + GetPosition() += m_vecMoveSpeed * CTimer::GetTimeStep(); // Apply Gravity - m_vecMoveSpeed.z -= 0.02f * CTimer::GetTimeStep(); + if ( m_bCarGlass ) + m_vecMoveSpeed.z -= 0.01f * CTimer::GetTimeStep(); + else + m_vecMoveSpeed.z -= 0.02f * CTimer::GetTimeStep(); // Apply TurnSpeed GetRight() += CrossProduct(m_vecTurn, GetRight()); @@ -106,24 +115,27 @@ CFallingGlassPane::Update(void) RwRGBA color = { 255, 255, 255, 255 }; - static int32 nFrameGen = 0; - - for ( int32 i = 0; i < 4; i++ ) + if ( !m_bCarGlass ) { - dir.x = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f); - dir.y = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f); - dir.z = CGeneral::GetRandomNumberInRange(0.05f, 0.20f); - - CParticle::AddParticle(PARTICLE_CAR_DEBRIS, - pos, - dir, - nil, - CGeneral::GetRandomNumberInRange(0.02f, 0.2f), - color, - CGeneral::GetRandomNumberInRange(-40, 40), - 0, - ++nFrameGen & 3, - 500); + static int32 nFrameGen = 0; + + for ( int32 i = 0; i < 4; i++ ) + { + dir.x = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f); + dir.y = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f); + dir.z = CGeneral::GetRandomNumberInRange(0.05f, 0.20f); + + CParticle::AddParticle(PARTICLE_CAR_DEBRIS, + pos, + dir, + nil, + CGeneral::GetRandomNumberInRange(0.02f, 0.2f), + color, + CGeneral::GetRandomNumberInRange(-40, 40), + 0, + ++nFrameGen & 3, + 500); + } } } } @@ -146,7 +158,10 @@ CFallingGlassPane::Render(void) CGlass::RenderHiLightPolys(); // HiLight Polys - + + if ( m_bCarGlass && color < 64 ) + color = 64; + RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], color, color, color, color); RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], color, color, color, color); RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], color, color, color, color); @@ -186,9 +201,9 @@ CFallingGlassPane::Render(void) if ( TempBufferIndicesStoredShattered >= TEMPBUFFERINDEXSHATTEREDSIZE-7 || TempBufferVerticesStoredShattered >= TEMPBUFFERVERTSHATTEREDSIZE-4 ) CGlass::RenderShatteredPolys(); - uint8 shatteredColor = 255; + uint8 shatteredColor = 140; if ( distToCamera > 30.0f ) - shatteredColor = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 255); + shatteredColor = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 140); RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], shatteredColor, shatteredColor, shatteredColor, shatteredColor); RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], shatteredColor, shatteredColor, shatteredColor, shatteredColor); @@ -292,8 +307,8 @@ CGlass::FindFreePane(void) } void -CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector point, - float moveSpeed, bool cracked, bool explosion) +CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector center, + float moveSpeed, bool cracked, bool explosion, int32 stepmul, bool carGlass) { float upLen = up.Magnitude(); float rightLen = right.Magnitude(); @@ -304,10 +319,10 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig float rightSteps = rightLen + 0.75f; if ( rightSteps < 1.0f ) rightSteps = 1.0f; - uint32 ysteps = (uint32)upSteps; + uint32 ysteps = stepmul * (uint32)upSteps; if ( ysteps > 3 ) ysteps = 3; - uint32 xsteps = (uint32)rightSteps; + uint32 xsteps = stepmul * (uint32)rightSteps; if ( xsteps > 3 ) xsteps = 3; if ( explosion ) @@ -338,11 +353,8 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig pane->m_nTriIndex = i; pane->GetRight() = (right * rightScl) / rightLen; -#ifdef FIX_BUGS pane->GetUp() = (up * upScl) / upLen; -#else - pane->GetUp() = (up * upScl) / rightLen; // copypaste bug -#endif + CVector fwd = CrossProduct(pane->GetRight(), pane->GetUp()); fwd.Normalise(); @@ -358,7 +370,7 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig if ( moveSpeed != 0.0f ) { - CVector dist = pane->GetPosition() - point; + CVector dist = pane->GetPosition() - center; dist.Normalise(); pane->m_vecMoveSpeed += moveSpeed * dist; @@ -371,10 +383,11 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig switch ( type ) { case 0: + case 2: pane->m_nTimer = CTimer::GetTimeInMilliseconds(); break; case 1: - float dist = (pane->GetPosition() - point).Magnitude(); + float dist = (pane->GetPosition() - center).Magnitude(); pane->m_nTimer = uint32(dist*100 + CTimer::GetTimeInMilliseconds()); break; } @@ -382,6 +395,7 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig pane->m_fGroundZ = groundZ; pane->m_bShattered = cracked; pane->m_fStep = upLen / float(ysteps); + pane->m_bCarGlass = carGlass; pane->m_bActive = true; } } @@ -393,9 +407,9 @@ void CGlass::AskForObjectToBeRenderedInGlass(CEntity *entity) { #ifdef FIX_BUGS - if ( NumGlassEntities < NUM_GLASSPANES ) + if ( NumGlassEntities < NUM_GLASSENTITIES ) #else - if ( NumGlassEntities < NUM_GLASSPANES-1 ) + if ( NumGlassEntities < NUM_GLASSENTITIES-1 ) #endif { apEntitiesToBeRendered[NumGlassEntities++] = entity; @@ -613,42 +627,48 @@ CGlass::WindowRespondsToCollision(CEntity *entity, float amount, CVector speed, CColModel *col = object->GetColModel(); ASSERT(col!=nil); - CVector a = object->GetMatrix() * col->vertices[0].Get(); - CVector b = object->GetMatrix() * col->vertices[1].Get(); - CVector c = object->GetMatrix() * col->vertices[2].Get(); - CVector d = object->GetMatrix() * col->vertices[3].Get(); - - float minx = Min(Min(a.x, b.x), Min(c.x, d.x)); - float maxx = Max(Max(a.x, b.x), Max(c.x, d.x)); - float miny = Min(Min(a.y, b.y), Min(c.y, d.y)); - float maxy = Max(Max(a.y, b.y), Max(c.y, d.y)); - float minz = Min(Min(a.z, b.z), Min(c.z, d.z)); - float maxz = Max(Max(a.z, b.z), Max(c.z, d.z)); - - - if ( amount > 300.0f ) - { - PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_L, object->GetPosition()); - - GeneratePanesForWindow(0, - CVector(minx, miny, minz), - CVector(0.0f, 0.0f, maxz-minz), - CVector(maxx-minx, maxy-miny, 0.0f), - speed, point, 0.1f, !!object->bGlassCracked, explosion); - } - else + if ( col->numTriangles == 2 ) { - PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_S, object->GetPosition()); - - GeneratePanesForWindow(1, - CVector(minx, miny, minz), - CVector(0.0f, 0.0f, maxz-minz), - CVector(maxx-minx, maxy-miny, 0.0f), - speed, point, 0.1f, !!object->bGlassCracked, explosion); + CVector a = col->vertices[0].Get(); + CVector b = col->vertices[1].Get(); + CVector c = col->vertices[2].Get(); + CVector d = col->vertices[3].Get(); + + float minx = Min(Min(a.x, b.x), Min(c.x, d.x)); + float maxx = Max(Max(a.x, b.x), Max(c.x, d.x)); + float miny = Min(Min(a.y, b.y), Min(c.y, d.y)); + float maxy = Max(Max(a.y, b.y), Max(c.y, d.y)); + float minz = Min(Min(a.z, b.z), Min(c.z, d.z)); + float maxz = Max(Max(a.z, b.z), Max(c.z, d.z)); + + CVector pa = object->GetMatrix() * CVector(minx, miny, minz); + CVector pb = object->GetMatrix() * CVector(maxx, maxy, minz); + + if ( amount > 300.0f ) + { + PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_L, object->GetPosition()); + + GeneratePanesForWindow(0, + pa, + CVector(0.0f, 0.0f, maxz-minz), + pb - pa, + speed, point, 0.1f, !!object->bGlassCracked, explosion, 1, false); + } + else + { + PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_S, object->GetPosition()); + + GeneratePanesForWindow(1, + pa, + CVector(0.0f, 0.0f, maxz-minz), + pb - pa, + speed, point, 0.1f, !!object->bGlassCracked, explosion, 1, false); + } } - + object->bGlassBroken = true; - object->GetMatrix().GetPosition().z = -100.0f; + object->bIsVisible = false; + object->bUsesCollision = true; } void @@ -658,7 +678,7 @@ CGlass::WindowRespondsToSoftCollision(CEntity *entity, float amount) CObject *object = (CObject *)entity; - if ( amount > 50.0f && !object->bGlassCracked ) + if ( entity->bUsesCollision && amount > 50.0f && !object->bGlassCracked ) { PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition()); object->bGlassCracked = true; @@ -674,15 +694,18 @@ CGlass::WasGlassHitByBullet(CEntity *entity, CVector point) if ( IsGlass(object->GetModelIndex()) ) { - if ( !object->bGlassCracked ) - { - PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition()); - object->bGlassCracked = true; - } - else + if ( object->bUsesCollision ) { - if ( (CGeneral::GetRandomNumber() & 3) == 2 ) - WindowRespondsToCollision(object, 0.0f, CVector(0.0f, 0.0f, 0.0f), point, false); + if ( !object->bGlassCracked ) + { + PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition()); + object->bGlassCracked = true; + } + else + { + if ( (CGeneral::GetRandomNumber() & 3) == 2 ) + WindowRespondsToCollision(object, 0.0f, CVector(0.0f, 0.0f, 0.0f), point, false); + } } } } @@ -693,19 +716,304 @@ CGlass::WindowRespondsToExplosion(CEntity *entity, CVector point) ASSERT(entity!=nil); CObject *object = (CObject *)entity; + + if ( object->bUsesCollision ) + { + CVector distToGlass = object->GetPosition() - point; + + float fDistToGlass = distToGlass.Magnitude(); + + if ( fDistToGlass < 10.0f ) + { + distToGlass *= (0.3f / fDistToGlass); // normalise + WindowRespondsToCollision(object, 10000.0f, distToGlass, object->GetPosition(), true); + } + else + { + if ( fDistToGlass < 30.0f ) + object->bGlassCracked = true; + } + } +} - CVector distToGlass = object->GetPosition() - point; - float fDistToGlass = distToGlass.Magnitude(); +void +CGlass::CarWindscreenShatters(CVehicle *vehicle, bool unk) +{ + ASSERT(vehicle!=nil); + + CColModel *col = vehicle->GetColModel(); + ASSERT(col!=nil); + + if ( col->numTriangles < 2 ) + return; + + CColTriangle *tria = nil; + int32 triIndex = -1; + CColTriangle *trib = nil; + + for ( int32 i = 0; i < col->numTriangles; i++ ) + { + CColTriangle *tri = &col->triangles[i]; + if ( tri->surface == SURFACE_GLASS ) + { + if ( tria ) + { + trib = tri; + break; + } + + triIndex = i; + tria = tri; + } + } + + if ( trib == nil ) + return; + + CCollision::CalculateTrianglePlanes(col); + + CColTrianglePlane *triPlanes = col->trianglePlanes; + + if ( triPlanes == nil ) + return; + + CVector planeNormal; + triPlanes[triIndex].GetNormal(planeNormal); + planeNormal = Multiply3x3(vehicle->GetMatrix(), planeNormal); + + CVector vec1 = CrossProduct(vehicle->GetRight(), planeNormal); + vec1.Normalise(); + + CVector vec2 = CrossProduct(planeNormal, vehicle->GetUp()); + vec2.Normalise(); + + CVector v[6]; + float proj1[6]; + float proj2[6]; + + v[0] = col->vertices[tria->a].Get(); + v[1] = col->vertices[tria->b].Get(); + v[2] = col->vertices[tria->c].Get(); + + v[3] = col->vertices[trib->a].Get(); + v[4] = col->vertices[trib->b].Get(); + v[5] = col->vertices[trib->c].Get(); + + v[0] = vehicle->GetMatrix() * v[0]; + v[1] = vehicle->GetMatrix() * v[1]; + v[2] = vehicle->GetMatrix() * v[2]; + v[3] = vehicle->GetMatrix() * v[3]; + v[4] = vehicle->GetMatrix() * v[4]; + v[5] = vehicle->GetMatrix() * v[5]; + + proj1[0] = DotProduct(v[0], vec1); + proj2[0] = DotProduct(v[0], vec2); + proj1[1] = DotProduct(v[1], vec1); + proj2[1] = DotProduct(v[1], vec2); + proj1[2] = DotProduct(v[2], vec1); + proj2[2] = DotProduct(v[2], vec2); + + proj1[3] = DotProduct(v[3], vec1); + proj2[3] = DotProduct(v[3], vec2); + proj1[4] = DotProduct(v[4], vec1); + proj2[4] = DotProduct(v[4], vec2); + proj1[5] = DotProduct(v[5], vec1); + proj2[5] = DotProduct(v[5], vec2); + + int32 originIndex = 0; + float max1 = proj1[0]; + float max2 = proj2[0]; + float origin = proj1[0] + proj2[0]; + + for ( int32 i = 1; i < 6; i++ ) + { + float o = proj1[i] + proj2[i]; + if ( o < origin ) + { + origin = o; + originIndex = i; + } + + if ( proj1[i] > max1 ) + max1 = proj1[i]; + if ( proj2[i] > max2 ) + max2 = proj2[i]; + } + + float bound1 = max1 - proj1[originIndex]; + float bound2 = max2 - proj2[originIndex]; + + PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_L, vehicle->GetPosition()); + + CVector center = v[originIndex] + ((0.5f*bound1) * vec1) + ((0.5f*bound2) * vec2); + CVector speed = vehicle->m_vecMoveSpeed; + CVector right = bound2 * vec2; + CVector up = bound1 * vec1; + CVector pos = v[originIndex]; + + GeneratePanesForWindow(2, pos, up, right, speed, center, 0.1f, false, false, 2, true); +} - if ( fDistToGlass < 10.0f ) +bool +CGlass::HasGlassBeenShatteredAtCoors(float x, float y, float z) +{ + CEntity *entity = nil; + float dist = 20.0f; + + int32 nStartX = Max(CWorld::GetSectorIndexX(x - 30.0f), 0); + int32 nStartY = Max(CWorld::GetSectorIndexY(y - 30.0f), 0); + int32 nEndX = Min(CWorld::GetSectorIndexX(x + 30.0f), NUMSECTORS_X-1); + int32 nEndY = Min(CWorld::GetSectorIndexY(y + 30.0f), NUMSECTORS_Y-1); + + CWorld::AdvanceCurrentScanCode(); + + for ( int32 y = nStartY; y <= nEndY; y++ ) { - distToGlass *= (0.3f / fDistToGlass); // normalise - WindowRespondsToCollision(object, 10000.0f, distToGlass, object->GetPosition(), true); + for ( int32 x = nStartX; x <= nEndX; x++ ) + { + CSector *sector = CWorld::GetSector(x, y); + + ASSERT(sector != nil); + + FindWindowSectorList(sector->m_lists[ENTITYLIST_OBJECTS], &dist, &entity, x, y, z); + FindWindowSectorList(sector->m_lists[ENTITYLIST_DUMMIES], &dist, &entity, x, y, z); + } } - else + + if ( entity ) { - if ( fDistToGlass < 30.0f ) - object->bGlassCracked = true; + if ( entity->GetType() == ENTITY_TYPE_DUMMY ) + return false; + + return !!((CObject*)entity)->bGlassBroken; } + + return false; } + +void +CGlass::FindWindowSectorList(CPtrList &list, float *dist, CEntity **entity, float x, float y, float z) +{ + ASSERT(dist!=nil); + ASSERT(entity!=nil); + + CPtrNode *node = list.first; + + while ( node != nil ) + { + CEntity *ent = (CEntity *)node->item; + uint16 scanCode = ent->m_scanCode; + node = node->next; + + ASSERT(ent!=nil); + + if ( IsGlass(ent->GetModelIndex()) ) + { + if ( scanCode != CWorld::GetCurrentScanCode() ) + { + ent->m_scanCode = CWorld::GetCurrentScanCode(); + + float dst = (CVector(x,y,z) - ent->GetPosition()).Magnitude(); + + if ( dst < *dist ) + { + *dist = dst; + *entity = ent; + } + } + } + } +} + +void +CGlass::BreakGlassPhysically(CVector pos, float radius) +{ + static uint32 breakTime = 0; + + if ( CTimer::GetTimeInMilliseconds() < breakTime + 1000 && CTimer::GetTimeInMilliseconds() >= breakTime ) + return; + + CColSphere sphere; + sphere.piece = 0; + sphere.radius = radius; + sphere.surface = 0; + + for ( int32 i = CPools::GetObjectPool()->GetSize() - 1; i >= 0; i-- ) + { + CObject *object = CPools::GetObjectPool()->GetSlot(i); + if (object) + { + if ( IsGlass(object->GetModelIndex()) ) + { + if ( object->bUsesCollision ) + { + CColModel *col = object->GetColModel(); + ASSERT(col!=nil); + + if ( col->numTriangles < 2 ) + continue; + + bool hit = false; + + CVector dist = pos - object->GetPosition(); + + sphere.center.x = DotProduct(dist, object->GetRight()); + sphere.center.y = DotProduct(dist, object->GetForward()); + sphere.center.z = DotProduct(dist, object->GetUp()); + + CCollision::CalculateTrianglePlanes(col); + + for ( int32 j = 0; j < col->numTriangles; j++ ) + { + if ( CCollision::TestSphereTriangle(sphere, + col->vertices, col->triangles[i], col->trianglePlanes[i]) ) + { + hit = true; + } + } + + if ( hit ) + { + breakTime = CTimer::GetTimeInMilliseconds(); + + if ( object->bGlassCracked ) + { + CVector a = col->vertices[0].Get(); + CVector b = col->vertices[1].Get(); + CVector c = col->vertices[2].Get(); + CVector d = col->vertices[3].Get(); + + float minx = Min(Min(a.x, b.x), Min(c.x, d.x)); + float maxx = Max(Max(a.x, b.x), Max(c.x, d.x)); + float miny = Min(Min(a.y, b.y), Min(c.y, d.y)); + float maxy = Max(Max(a.y, b.y), Max(c.y, d.y)); + float minz = Min(Min(a.z, b.z), Min(c.z, d.z)); + float maxz = Max(Max(a.z, b.z), Max(c.z, d.z)); + + CVector pa = object->GetMatrix() * CVector(minx, miny, minz); + CVector pb = object->GetMatrix() * CVector(maxx, maxy, minz); + + PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_S, object->GetPosition()); + + GeneratePanesForWindow(1, + pa, + CVector(0.0f, 0.0f, maxz-minz), + pb - pa, + CVector(0.0f, 0.0f, 0.0f), pos, 0.1f, !!object->bGlassCracked, false, 1, false); + + object->bGlassBroken = true; + object->bIsVisible = false; + object->bUsesCollision = false; + } + else + { + PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition()); + object->bGlassCracked = true; + } + } + } + } + } + } +}
\ No newline at end of file diff --git a/src/render/Glass.h b/src/render/Glass.h index 937ab6a9..f1c85779 100644 --- a/src/render/Glass.h +++ b/src/render/Glass.h @@ -2,6 +2,7 @@ class CEntity; class CVehicle; +class CPtrList; class CFallingGlassPane : public CMatrix { @@ -14,6 +15,7 @@ public: uint8 m_nTriIndex; bool m_bActive; bool m_bShattered; + bool m_bCarGlass; CFallingGlassPane() { } ~CFallingGlassPane() { } @@ -39,7 +41,7 @@ public: static void Update(void); static void Render(void); static CFallingGlassPane *FindFreePane(void); - static void GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector point, float moveSpeed, bool cracked, bool explosion); + static void GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector center, float moveSpeed, bool cracked, bool explosion, int32 stepmul, bool carGlass); static void AskForObjectToBeRenderedInGlass(CEntity *entity); static void RenderEntityInGlass(CEntity *entity); static int32 CalcAlphaWithNormal(CVector *normal); @@ -50,8 +52,8 @@ public: static void WindowRespondsToSoftCollision(CEntity *entity, float amount); static void WasGlassHitByBullet(CEntity *entity, CVector point); static void WindowRespondsToExplosion(CEntity *entity, CVector point); - -//TODO(MIAMI) - static void CarWindscreenShatters(CVehicle *vehicle, bool unk) {} - static void BreakGlassPhysically(CVector, float) {} + static void CarWindscreenShatters(CVehicle *vehicle, bool unk); + static bool HasGlassBeenShatteredAtCoors(float x, float y, float z); + static void FindWindowSectorList(CPtrList &list, float *dist, CEntity **entity, float x, float y, float z); + static void BreakGlassPhysically(CVector pos, float radius); };
\ No newline at end of file diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index 3ea756fa..753bb42b 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -583,7 +583,7 @@ void CHud::Draw() CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f), SCREEN_SCALE_Y(65.0f), sPrint); - if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || CTimer::GetFrameCounter() & 1) { + if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || CTimer::GetFrameCounter() & 4) { // CFont::SetColor(ARMOUR_COLOR); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f + 52.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon); } diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp index fa8379f0..7864b0f0 100644 --- a/src/render/SpecialFX.cpp +++ b/src/render/SpecialFX.cpp @@ -24,21 +24,44 @@ #include "ColStore.h" #include "Coronas.h" #include "Script.h" +#include "DMAudio.h" RwIm3DVertex StreakVertices[4]; RwImVertexIndex StreakIndexList[12]; -RwIm3DVertex TraceVertices[6]; -RwImVertexIndex TraceIndexList[12]; +RwIm3DVertex TraceVertices[10]; +static RwImVertexIndex TraceIndexList[48] = {0, 5, 7, 0, 7, 2, 0, 7, 5, 0, 2, 7, 0, 4, 9, 0, + 9, 5, 0, 9, 4, 0, 5, 9, 0, 1, 6, 0, 6, 5, 0, 6, + 1, 0, 5, 6, 0, 3, 8, 0, 8, 5, 0, 8, 3, 0, 5, 8 }; +bool CSpecialFX::bVideoCam; +bool CSpecialFX::bLiftCam; bool CSpecialFX::bSnapShotActive; int32 CSpecialFX::SnapShotFrames; +static RwTexture* gpSmokeTrailTexture; + void CSpecialFX::Init(void) { CBulletTraces::Init(); + RwIm3DVertexSetU(&TraceVertices[0], 0.0); + RwIm3DVertexSetV(&TraceVertices[0], 0.0); + RwIm3DVertexSetU(&TraceVertices[1], 1.0); + RwIm3DVertexSetV(&TraceVertices[1], 0.0); + RwIm3DVertexSetU(&TraceVertices[2], 1.0); + RwIm3DVertexSetV(&TraceVertices[2], 0.0); + RwIm3DVertexSetU(&TraceVertices[3], 1.0); + RwIm3DVertexSetV(&TraceVertices[3], 0.0); + RwIm3DVertexSetU(&TraceVertices[4], 1.0); + RwIm3DVertexSetV(&TraceVertices[4], 0.0); + RwIm3DVertexSetU(&TraceVertices[5], 0.0); + RwIm3DVertexSetU(&TraceVertices[6], 1.0); + RwIm3DVertexSetU(&TraceVertices[7], 1.0); + RwIm3DVertexSetU(&TraceVertices[8], 1.0); + RwIm3DVertexSetU(&TraceVertices[9], 1.0); + RwIm3DVertexSetU(&StreakVertices[0], 0.0f); RwIm3DVertexSetV(&StreakVertices[0], 0.0f); RwIm3DVertexSetU(&StreakVertices[1], 1.0f); @@ -47,7 +70,6 @@ CSpecialFX::Init(void) RwIm3DVertexSetV(&StreakVertices[2], 0.0f); RwIm3DVertexSetU(&StreakVertices[3], 1.0f); RwIm3DVertexSetV(&StreakVertices[3], 0.0f); - StreakIndexList[0] = 0; StreakIndexList[1] = 1; StreakIndexList[2] = 2; @@ -61,43 +83,51 @@ CSpecialFX::Init(void) StreakIndexList[10] = 2; StreakIndexList[11] = 3; - RwIm3DVertexSetRGBA(&TraceVertices[0], 20, 20, 20, 255); - RwIm3DVertexSetRGBA(&TraceVertices[1], 20, 20, 20, 255); - RwIm3DVertexSetRGBA(&TraceVertices[2], 70, 70, 70, 255); - RwIm3DVertexSetRGBA(&TraceVertices[3], 70, 70, 70, 255); - RwIm3DVertexSetRGBA(&TraceVertices[4], 10, 10, 10, 255); - RwIm3DVertexSetRGBA(&TraceVertices[5], 10, 10, 10, 255); - RwIm3DVertexSetU(&TraceVertices[0], 0.0); - RwIm3DVertexSetV(&TraceVertices[0], 0.0); - RwIm3DVertexSetU(&TraceVertices[1], 1.0); - RwIm3DVertexSetV(&TraceVertices[1], 0.0); - RwIm3DVertexSetU(&TraceVertices[2], 0.0); - RwIm3DVertexSetV(&TraceVertices[2], 0.5); - RwIm3DVertexSetU(&TraceVertices[3], 1.0); - RwIm3DVertexSetV(&TraceVertices[3], 0.5); - RwIm3DVertexSetU(&TraceVertices[4], 0.0); - RwIm3DVertexSetV(&TraceVertices[4], 1.0); - RwIm3DVertexSetU(&TraceVertices[5], 1.0); - RwIm3DVertexSetV(&TraceVertices[5], 1.0); - - TraceIndexList[0] = 0; - TraceIndexList[1] = 2; - TraceIndexList[2] = 1; - TraceIndexList[3] = 1; - TraceIndexList[4] = 2; - TraceIndexList[5] = 3; - TraceIndexList[6] = 2; - TraceIndexList[7] = 4; - TraceIndexList[8] = 3; - TraceIndexList[9] = 3; - TraceIndexList[10] = 4; - TraceIndexList[11] = 5; - CMotionBlurStreaks::Init(); CBrightLights::Init(); CShinyTexts::Init(); CMoneyMessages::Init(); C3dMarkers::Init(); + CSpecialFX::bSnapShotActive = false; + CSpecialFX::bVideoCam = false; + CSpecialFX::SnapShotFrames = 0; + CSpecialFX::bLiftCam = false; + CTxdStore::PushCurrentTxd(); + CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle")); + if(gpSmokeTrailTexture == nil) + gpSmokeTrailTexture = RwTextureRead("smoketrail", 0); + CTxdStore::PopCurrentTxd(); +} + +void +CSpecialFX::AddWeaponStreak(int type) +{ + static CMatrix matrix; + CVector start; + CVector end; + + if (FindPlayerPed() != nil && FindPlayerPed()->m_pWeaponModel != nil) { + switch (type) { + case WEAPONTYPE_BASEBALLBAT: + matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel)); + start = matrix * CVector(0.02f, 0.05f, 0.07f); + end = matrix * CVector(0.246f, 0.0325f, 0.796f); + break; + case WEAPONTYPE_GOLFCLUB: + matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel)); + start = matrix * CVector(0.02f, 0.05f, 0.07f); + end = matrix * CVector(-0.054f, 0.0325f, 0.796f); + break; + case WEAPONTYPE_KATANA: + matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel)); + start = matrix * CVector(0.02f, 0.05f, 0.07f); + end = matrix * CVector(0.096f, -0.0175f, 1.096f); + break; + default: + return; + } + CMotionBlurStreaks::RegisterStreak((uintptr)FindPlayerPed()->m_pWeaponModel, 100, 100, 100, start, end); + } } RwObject* @@ -119,23 +149,16 @@ CSpecialFX::Update(void) { CMotionBlurStreaks::Update(); CBulletTraces::Update(); - - if(FindPlayerPed() && - FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && - FindPlayerPed()->GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING){ -#ifdef PED_SKIN - if(IsClumpSkinned(FindPlayerPed()->GetClump())){ - LookForBatCB((RwObject*)FindPlayerPed()->m_pWeaponModel, CModelInfo::GetModelInfo(MI_BASEBALL_BAT)); - }else -#endif - RwFrameForAllObjects(FindPlayerPed()->m_pFrames[PED_HANDR]->frame, LookForBatCB, CModelInfo::GetModelInfo(MI_BASEBALL_BAT)); - } } void CSpecialFX::Shutdown(void) { C3dMarkers::Shutdown(); + if (gpSmokeTrailTexture) { + RwTextureDestroy(gpSmokeTrailTexture); + gpSmokeTrailTexture = nil; + } } void @@ -149,6 +172,80 @@ CSpecialFX::Render(void) C3dMarkers::Render(); } +void +CSpecialFX::Render2DFXs(void) +{ + if (CSpecialFX::bVideoCam) { + CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(20.0f)); + CFont::SetCentreOff(); + CFont::SetPropOn(); + CFont::SetColor(CRGBA(0, 255, 0, 200)); + FONT_LOCALE(FONT_STANDARD); + sprintf(gString, "%d", CTimer::GetFrameCounter() & 0x3F); // mb % 63 + AsciiToUnicode(gString, gUString); + CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString); + for (int32 i = 0; i < SCREEN_HEIGHT; i += 4) { + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE); + CSprite2d::Draw2DPolygon(0.0f, i, SCREEN_WIDTH, i, 0.0f, i+1, SCREEN_WIDTH, i+1, CRGBA(0, 100, 0, 100)); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0f, i+2, SCREEN_WIDTH, i+2, 0.0f, i+3, SCREEN_WIDTH, i+3, CRGBA(0, 0, 0, 150)); + } + int32 tmp = (CTimer::GetTimeInMilliseconds() & 0x7ff) * (SCREEN_HEIGHT + 70.0f) / 2048 - 70.0f; //mb % 2048 + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0, tmp, SCREEN_WIDTH, tmp, 0.0, tmp + 70.0f, SCREEN_WIDTH, tmp + 70.0f , CRGBA(0, 100, 0, 60)); + } + if (CSpecialFX::bLiftCam) { + CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(20.0f)); + CFont::SetCentreOff(); + CFont::SetPropOn(); + CFont::SetColor(CRGBA(100, 100, 100, 200)); + FONT_LOCALE(FONT_STANDARD); + CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString); + for (int32 i = 0; i < SCREEN_HEIGHT; i += 4) { + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + CSprite2d::Draw2DPolygon(0.0f, i, SCREEN_WIDTH, i, 0.0f, i + 1, SCREEN_WIDTH, i + 1, CRGBA(100, 100, 100, 100)); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0f, i + 2, SCREEN_WIDTH, i + 2, 0.0f, i + 3, SCREEN_WIDTH, i + 3, CRGBA(0, 0, 0, 150)); + } + int32 tmp = (CTimer::GetTimeInMilliseconds() & 0x7ff) * (SCREEN_HEIGHT + 70.0f) / 2048 - 70.0f; //mb % 2048 + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0, tmp, SCREEN_WIDTH, tmp, 0.0, tmp + 70.0f, SCREEN_WIDTH, tmp + 70.0f, CRGBA(100, 100, 100, 60)); + for (int32 i = 0; i < 200; i++) { + int32 posX = CGeneral::GetRandomNumber() % (int32)SCREEN_WIDTH; + int32 posY = CGeneral::GetRandomNumber() % (int32)SCREEN_HEIGHT; + CSprite2d::DrawRect(CRect(posX, posY + 2, posX+20, posY), CRGBA(255, 255, 255, 64)); + } + } + if (CSpecialFX::bSnapShotActive) { + if (++CSpecialFX::SnapShotFrames > 20) { + CSpecialFX::bSnapShotActive = false; + CTimer::SetTimeScale(1.0f); + } else { + CTimer::SetTimeScale(0.0f); //in andro it's 0.00001 + if (CSpecialFX::SnapShotFrames < 10) { + int32 tmp = (255 - 255 * CSpecialFX::SnapShotFrames / 10) * 0.65f; + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + CSprite2d::Draw2DPolygon(0.0f, 0.0f, SCREEN_WIDTH, 0.0f, 0.0f, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, CRGBA(tmp, tmp, tmp, tmp)); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + } + } + } +} + CRegisteredMotionBlurStreak CMotionBlurStreaks::aStreaks[NUMMBLURSTREAKS]; void @@ -209,7 +306,7 @@ CMotionBlurStreaks::Update(void) { int i; for(i = 0; i < NUMMBLURSTREAKS; i++) - if(aStreaks[i].m_id) + if(aStreaks[i].m_id != 0) aStreaks[i].Update(); } @@ -217,6 +314,7 @@ void CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2) { int i; + for(i = 0; i < NUMMBLURSTREAKS; i++){ if(aStreaks[i].m_id == id){ // Found a streak from last frame, update @@ -229,10 +327,12 @@ CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVecto return; } } + // Find free slot - for(i = 0; aStreaks[i].m_id; i++) + for(i = 0; aStreaks[i].m_id != 0 ; i++) if(i == NUMMBLURSTREAKS-1) return; + // Create a new streak aStreaks[i].m_id = id; aStreaks[i].m_red = r; @@ -251,7 +351,7 @@ CMotionBlurStreaks::Render(void) bool setRenderStates = false; int i; for(i = 0; i < NUMMBLURSTREAKS; i++) - if(aStreaks[i].m_id){ + if(aStreaks[i].m_id != 0){ if(!setRenderStates){ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); @@ -281,20 +381,103 @@ void CBulletTraces::Init(void) aTraces[i].m_bInUse = false; } -void CBulletTraces::AddTrace(CVector* vecStart, CVector* vecTarget) +void CBulletTraces::AddTrace(CVector* start, CVector* end, float thickness, uint32 lifeTime, uint8 visibility) { - int index; - for (index = 0; index < NUMBULLETTRACES; index++) { - if (!aTraces[index].m_bInUse) - break; + int32 enabledCount; + uint32 modifiedLifeTime; + int32 nextSlot; + + enabledCount = 0; + for (int i = 0; i < NUMBULLETTRACES; i++) + if (aTraces[i].m_bInUse) + enabledCount++; + if (enabledCount >= 10) + modifiedLifeTime = lifeTime / 4; + else if (enabledCount >= 5) + modifiedLifeTime = lifeTime / 2; + else + modifiedLifeTime = lifeTime; + + nextSlot = 0; + for (int i = 0; nextSlot < NUMBULLETTRACES && aTraces[i].m_bInUse; i++) + nextSlot++; + if (nextSlot < 16) { + aTraces[nextSlot].m_vecStartPos = *start; + aTraces[nextSlot].m_vecEndPos = *end; + aTraces[nextSlot].m_bInUse = true; + aTraces[nextSlot].m_nCreationTime = CTimer::GetTimeInMilliseconds(); + aTraces[nextSlot].m_fVisibility = visibility; + aTraces[nextSlot].m_fThickness = thickness; + aTraces[nextSlot].m_nLifeTime = modifiedLifeTime; + } + + float startProjFwd = DotProduct(TheCamera.GetForward(), *start - TheCamera.GetPosition()); + float endProjFwd = DotProduct(TheCamera.GetForward(), *end - TheCamera.GetPosition()); + if (startProjFwd * endProjFwd < 0.0f) { //if one of point behind us and second before us + float fStartDistFwd = Abs(startProjFwd) / (Abs(startProjFwd) + Abs(endProjFwd)); + + float startProjUp = DotProduct(TheCamera.GetUp(), *start - TheCamera.GetPosition()); + float endProjUp = DotProduct(TheCamera.GetUp(), *end - TheCamera.GetPosition()); + float distUp = (endProjUp - startProjUp) * fStartDistFwd + startProjUp; + + float startProjRight = DotProduct(TheCamera.GetRight(), *start - TheCamera.GetPosition()); + float endProjRight = DotProduct(TheCamera.GetRight(), *end - TheCamera.GetPosition()); + float distRight = (endProjRight - startProjRight) * fStartDistFwd + startProjRight; + + float dist = Sqrt(SQR(distUp) + SQR(distRight)); + if (dist < 2.0f) { + if(distRight < 0.0f) + DMAudio.PlayFrontEndSound(SOUND_BULLETTRACE_2, 127 * (1.0f - dist * 0.5f)); + else + DMAudio.PlayFrontEndSound(SOUND_BULLETTRACE_1, 127 * (1.0f - dist * 0.5f)); + } + } +} + +void CBulletTraces::AddTrace(CVector* start, CVector* end, int32 weaponType, class CEntity* shooter) +{ + CPhysical* player; + float speed; + int16 camMode; + + if (shooter == (CEntity*)FindPlayerPed() || (FindPlayerVehicle() != nil && FindPlayerVehicle() == (CVehicle*)shooter)) { + camMode = TheCamera.Cams[TheCamera.ActiveCam].Mode; + if (camMode == CCam::MODE_M16_1STPERSON + || camMode == CCam::MODE_CAMERA + || camMode == CCam::MODE_SNIPER + || camMode == CCam::MODE_M16_1STPERSON_RUNABOUT + || camMode == CCam::MODE_ROCKETLAUNCHER + || camMode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT + || camMode == CCam::MODE_SNIPER_RUNABOUT + || camMode == CCam::MODE_HELICANNON_1STPERSON) { + + player = FindPlayerVehicle() ? (CPhysical*)FindPlayerVehicle() : (CPhysical*)FindPlayerPed(); + speed = player->m_vecMoveSpeed.Magnitude(); + if (speed < 0.05f) + return; + } + } + + switch (weaponType) { + case WEAPONTYPE_PYTHON: + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_SPAS12_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: + CBulletTraces::AddTrace(start, end, 0.7f, 1000, 200); + break; + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + case WEAPONTYPE_M60: + case WEAPONTYPE_MINIGUN: + case WEAPONTYPE_HELICANNON: + CBulletTraces::AddTrace(start, end, 1.0f, 2000, 220); + break; + default: + CBulletTraces::AddTrace(start, end, 0.4f, 750, 150); + break; } - if (index == NUMBULLETTRACES) - return; - aTraces[index].m_vecCurrentPos = *vecStart; - aTraces[index].m_vecTargetPos = *vecTarget; - aTraces[index].m_bInUse = true; - aTraces[index].m_framesInUse = 0; - aTraces[index].m_lifeTime = 25 + CGeneral::GetRandomNumber() % 32; } void CBulletTraces::Render(void) @@ -303,35 +486,135 @@ void CBulletTraces::Render(void) if (!aTraces[i].m_bInUse) continue; RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); -#ifdef FIX_BUGS - // Raster has no transparent pixels so it relies on the raster format having alpha - // to turn on blending. librw image conversion might get rid of it right now so let's - // just force it on. - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSmokeTrailTexture)); + + float timeAlive = CTimer::GetTimeInMilliseconds() - aTraces[i].m_nCreationTime; + + float traceThickness = aTraces[i].m_fThickness * timeAlive / aTraces[i].m_nLifeTime; + CVector horizontalOffset = aTraces[i].m_vecEndPos - aTraces[i].m_vecStartPos; + horizontalOffset.Normalise(); + horizontalOffset *= traceThickness; + + //then closer trace to die then it more transparent + uint8 nAlphaValue = aTraces[i].m_fVisibility * (aTraces[i].m_nLifeTime - timeAlive) / aTraces[i].m_nLifeTime; + + CVector start = aTraces[i].m_vecStartPos; + CVector end = aTraces[i].m_vecEndPos; + float startProj = DotProduct(start - TheCamera.GetPosition(), TheCamera.GetForward()) - 0.7f; + float endProj = DotProduct(end - TheCamera.GetPosition(), TheCamera.GetForward()) - 0.7f; + if (startProj < 0.0f && endProj < 0.0f) //we dont need render trace behind us + continue; + + if (startProj < 0.0f) { //if strat behind us move it closer + float absStartProj = Abs(startProj); + float absEndProj = Abs(endProj); + start = (absEndProj * start + absStartProj * end) / (absStartProj + absEndProj); + } else if (endProj < 0.0f) { + float absStartProj = Abs(startProj); + float absEndProj = Abs(endProj); + end = (absEndProj * start + absStartProj * end) / (absStartProj + absEndProj); + } + + //we divide trace at three parts + CVector start2 = (7.0f * start + end) / 8; + CVector end2 = (7.0f * end + start) / 8; + + RwIm3DVertexSetV(&TraceVertices[5], 10.0f); + RwIm3DVertexSetV(&TraceVertices[6], 10.0f); + RwIm3DVertexSetV(&TraceVertices[7], 10.0f); + RwIm3DVertexSetV(&TraceVertices[8], 10.0f); + RwIm3DVertexSetV(&TraceVertices[9], 10.0f); + + RwIm3DVertexSetRGBA(&TraceVertices[0], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[1], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[2], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[3], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[4], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[5], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[6], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[7], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[8], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[9], 255, 255, 255, nAlphaValue); + //two points in center + RwIm3DVertexSetPos(&TraceVertices[0], start2.x, start2.y, start2.z); + RwIm3DVertexSetPos(&TraceVertices[5], end2.x, end2.y, end2.z); + //vertical planes + RwIm3DVertexSetPos(&TraceVertices[1], start2.x, start2.y, start2.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[3], start2.x, start2.y, start2.z - traceThickness); + RwIm3DVertexSetPos(&TraceVertices[6], end2.x, end2.y, end2.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[8], end2.x, end2.y, end2.z - traceThickness); + //horizontal planes + RwIm3DVertexSetPos(&TraceVertices[2], start2.x + horizontalOffset.y, start2.y - horizontalOffset.x, start2.z); + RwIm3DVertexSetPos(&TraceVertices[7], end2.x + horizontalOffset.y, end2.y - horizontalOffset.x, end2.z); +#ifdef FIX_BUGS //this point calculated wrong for some reason + RwIm3DVertexSetPos(&TraceVertices[4], start2.x - horizontalOffset.y, start2.y + horizontalOffset.x, start2.z); + RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y + horizontalOffset.x, end2.z); +#else + RwIm3DVertexSetPos(&TraceVertices[4], start2.x - horizontalOffset.y, start2.y - horizontalOffset.y, start2.z); + RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y - horizontalOffset.y, end2.z); #endif - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpShadowExplosionTex)); - CVector inf = aTraces[i].m_vecCurrentPos; - CVector sup = aTraces[i].m_vecTargetPos; - CVector center = (inf + sup) / 2; - CVector width = CrossProduct(TheCamera.GetForward(), (sup - inf)); - width.Normalise(); - width /= 20; - uint8 intensity = aTraces[i].m_lifeTime; - for (int i = 0; i < ARRAY_SIZE(TraceVertices); i++) - RwIm3DVertexSetRGBA(&TraceVertices[i], intensity, intensity, intensity, 0xFF); - RwIm3DVertexSetPos(&TraceVertices[0], inf.x + width.x, inf.y + width.y, inf.z + width.z); - RwIm3DVertexSetPos(&TraceVertices[1], inf.x - width.x, inf.y - width.y, inf.z - width.z); - RwIm3DVertexSetPos(&TraceVertices[2], center.x + width.x, center.y + width.y, center.z + width.z); - RwIm3DVertexSetPos(&TraceVertices[3], center.x - width.x, center.y - width.y, center.z - width.z); - RwIm3DVertexSetPos(&TraceVertices[4], sup.x + width.x, sup.y + width.y, sup.z + width.z); - RwIm3DVertexSetPos(&TraceVertices[5], sup.x - width.x, sup.y - width.y, sup.z - width.z); - LittleTest(); + if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, 1)) { RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList)); RwIm3DEnd(); } + + RwIm3DVertexSetV(&TraceVertices[5], 2.0f); + RwIm3DVertexSetV(&TraceVertices[6], 2.0f); + RwIm3DVertexSetV(&TraceVertices[7], 2.0f); + RwIm3DVertexSetV(&TraceVertices[8], 2.0f); + RwIm3DVertexSetV(&TraceVertices[9], 2.0f); + RwIm3DVertexSetRGBA(&TraceVertices[0], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[1], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[2], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[3], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[4], 255, 255, 255, 0); + + RwIm3DVertexSetPos(&TraceVertices[0], start.x, start.y, start.z); + RwIm3DVertexSetPos(&TraceVertices[1], start.x, start.y, start.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[3], start.x, start.y, start.z - traceThickness); + RwIm3DVertexSetPos(&TraceVertices[2], start.x + horizontalOffset.y, start.y - horizontalOffset.x, start.z); + + RwIm3DVertexSetPos(&TraceVertices[5], start2.x, start2.y, start2.z); + RwIm3DVertexSetPos(&TraceVertices[6], start2.x, start2.y, start2.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[8], start2.x, start2.y, start2.z - traceThickness); + RwIm3DVertexSetPos(&TraceVertices[7], start2.x + horizontalOffset.y, start2.y - horizontalOffset.x, start2.z); +#ifdef FIX_BUGS + RwIm3DVertexSetPos(&TraceVertices[4], start.x - horizontalOffset.y, start.y + horizontalOffset.x, start.z); + RwIm3DVertexSetPos(&TraceVertices[9], start2.x - horizontalOffset.y, start2.y + horizontalOffset.x, start2.z); +#else + RwIm3DVertexSetPos(&TraceVertices[4], start.x - horizontalOffset.y, start.y - horizontalOffset.y, start.z); + RwIm3DVertexSetPos(&TraceVertices[9], start2.x - horizontalOffset.y, start2.y - horizontalOffset.y, start2.z); +#endif + + if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, rwIM3D_VERTEXUV)) { + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList)); + RwIm3DEnd(); + } + + RwIm3DVertexSetPos(&TraceVertices[1], end.x, end.y, end.z); + RwIm3DVertexSetPos(&TraceVertices[2], end.x, end.y, end.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[4], end.x, end.y, end.z - traceThickness); + RwIm3DVertexSetPos(&TraceVertices[3], end.x + horizontalOffset.y, end.y - horizontalOffset.x, end.z); + + RwIm3DVertexSetPos(&TraceVertices[5], end2.x, end2.y, end2.z); + RwIm3DVertexSetPos(&TraceVertices[6], end2.x, end2.y, end2.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[8], end2.x, end2.y, end2.z - traceThickness); + RwIm3DVertexSetPos(&TraceVertices[7], end2.x + horizontalOffset.y, end2.y - horizontalOffset.x, end2.z); +#ifdef FIX_BUGS + RwIm3DVertexSetPos(&TraceVertices[5], end.x - horizontalOffset.y, end.y + horizontalOffset.x, end.z); + RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y + horizontalOffset.x, end2.z); +#else + RwIm3DVertexSetPos(&TraceVertices[5], end.x - horizontalOffset.y, end.y - horizontalOffset.y, end.z); + RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y - horizontalOffset.y, end2.z); +#endif + + if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, rwIM3D_VERTEXUV)) { + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList)); + RwIm3DEnd(); + } } RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); @@ -348,23 +631,8 @@ void CBulletTraces::Update(void) void CBulletTrace::Update(void) { - if (m_framesInUse == 0) { - m_framesInUse++; - return; - } - if (m_framesInUse > 60) { - m_bInUse = false; - return; - } - CVector diff = m_vecCurrentPos - m_vecTargetPos; - float remaining = diff.Magnitude(); - if (remaining > 0.8f) - m_vecCurrentPos = m_vecTargetPos + (remaining - 0.8f) / remaining * diff; - else + if (CTimer::GetTimeInMilliseconds() - m_nCreationTime >= m_nLifeTime) m_bInUse = false; - if (--m_lifeTime == 0) - m_bInUse = false; - m_framesInUse++; } RpAtomic * @@ -578,7 +846,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } else { pMarker->m_fStdSize = size; } - } else if (type == MARKERTYPE_CYLINDER) { + } else { if (dist < size + 12.0f) { if (dist > size + 1.0f) pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a; @@ -591,15 +859,9 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size float someSin = Sin(TWOPI * (float)((pMarker->m_nPulsePeriod - 1) & (CTimer::GetTimeInMilliseconds() - pMarker->m_nStartTime)) / (float)pMarker->m_nPulsePeriod); pMarker->m_fSize = pMarker->m_fStdSize - pulseFraction * pMarker->m_fStdSize * someSin; - if (type == MARKERTYPE_ARROW) { + if (type == MARKERTYPE_ARROW) pos.z += 0.25f * pMarker->m_fStdSize * someSin; - } else if (type == MARKERTYPE_0) { - if (someSin > 0.0f) - pMarker->m_Color.alpha = (float)a * 0.7f * someSin + a; - else - pMarker->m_Color.alpha = (float)a * 0.4f * someSin + a; - } - if (pMarker->m_nRotateRate) { + if (pMarker->m_nRotateRate != 0) { RwV3d pos = pMarker->m_Matrix.m_matrix.pos; pMarker->m_Matrix.RotateZ(DEGTORAD(pMarker->m_nRotateRate * CTimer::GetTimeStep())); pMarker->m_Matrix.GetPosition() = pos; @@ -623,7 +885,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size pMarker->DeleteMarkerObject(); pMarker->AddMarker(identifier, type, size, r, g, b, a, pulsePeriod, pulseFraction, rotateRate); - if (type == MARKERTYPE_CYLINDER || type == MARKERTYPE_0 || type == MARKERTYPE_2) { + if (type == MARKERTYPE_CYLINDER) { if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(CVector2D(pos))) { float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil); if (z != 0.0f) @@ -634,10 +896,6 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } } pMarker->m_Matrix.SetTranslate(pos.x, pos.y, pos.z); - if (type == MARKERTYPE_2) { - pMarker->m_Matrix.RotateX(PI); - pMarker->m_Matrix.GetPosition() = pos; - } pMarker->m_Matrix.UpdateRW(); if (type == MARKERTYPE_ARROW) { if (dist < 25.0f) { @@ -648,7 +906,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } else { pMarker->m_fStdSize = size; } - } else if (type == MARKERTYPE_CYLINDER) { + } else { if (dist < size + 12.0f) { if (dist > size + 1.0f) pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a; @@ -752,6 +1010,9 @@ CBrightLights::Render(void) RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil); + TempBufferVerticesStored = 0; + TempBufferIndicesStored = 0; + for(i = 0; i < NumBrightLights; i++){ if(TempBufferIndicesStored > TEMPBUFFERINDEXSIZE-40 || TempBufferVerticesStored > TEMPBUFFERVERTSIZE-40) RenderOutGeometryBuffer(); @@ -788,6 +1049,10 @@ CBrightLights::Render(void) g = aBrightLights[i].m_green; b = aBrightLights[i].m_blue; break; +#ifdef FIX_BUGS //just to make sure that color never will be undefined + default: + return; +#endif } if(aBrightLights[i].m_camDist < BRIGHTLIGHTS_FADE_DIST) @@ -851,6 +1116,22 @@ CBrightLights::Render(void) TempBufferIndicesStored += 12*3; break; + case BRIGHTLIGHT_FRONT_BIG: + case BRIGHTLIGHT_REAR_BIG: + for (j = 0; j < 8; j++) { + pos = BigCarHeadLightsSide[j] * aBrightLights[i].m_side + + BigCarHeadLightsUp[j] * aBrightLights[i].m_up + + BigCarHeadLightsFront[j] * aBrightLights[i].m_front + + aBrightLights[i].m_pos; + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + j], r, g, b, a); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + j], pos.x, pos.y, pos.z); + } + for (j = 0; j < 12 * 3; j++) + TempBufferRenderIndexList[TempBufferIndicesStored + j] = CubeIndices[j] + TempBufferVerticesStored; + TempBufferVerticesStored += 8; + TempBufferIndicesStored += 12 * 3; + break; + case BRIGHTLIGHT_FRONT_TALL: case BRIGHTLIGHT_REAR_TALL: for(j = 0; j < 8; j++){ @@ -869,8 +1150,8 @@ CBrightLights::Render(void) case BRIGHTLIGHT_SIREN: for(j = 0; j < 6; j++){ - pos = SirenLightsSide[j]*aBrightLights[i].m_side + - SirenLightsUp[j]*aBrightLights[i].m_up + + pos = SirenLightsSide[j] * TheCamera.GetRight() + + SirenLightsUp[j] * TheCamera.GetUp() + aBrightLights[i].m_pos; RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a); RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z); @@ -1056,8 +1337,9 @@ CMoneyMessage::Render() { const float MAX_SCALE = 4.0f; uint32 nLifeTime = CTimer::GetTimeInMilliseconds() - m_nTimeRegistered; - if (nLifeTime >= MONEY_MESSAGE_LIFETIME_MS) m_nTimeRegistered = 0; - else { + if (nLifeTime >= MONEY_MESSAGE_LIFETIME_MS) { + m_nTimeRegistered = 0; + } else { float fLifeTime = (float)nLifeTime / MONEY_MESSAGE_LIFETIME_MS; RwV3d vecOut; float fDistX, fDistY; @@ -1066,20 +1348,15 @@ CMoneyMessage::Render() fDistY *= (0.7 * fLifeTime + 2.0) * m_fSize; CFont::SetPropOn(); CFont::SetBackgroundOff(); - - float fScaleY = fDistY / 100.0f; - if (fScaleY > MAX_SCALE) fScaleY = MAX_SCALE; - - float fScaleX = fDistX / 100.0f; - if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE; - + float fScaleY = Min(fDistY / 100.0f, MAX_SCALE); + float fScaleX = Min(fDistX / 100.0f, MAX_SCALE); CFont::SetScale(fScaleX, fScaleY); // maybe use SCREEN_SCALE_X and SCREEN_SCALE_Y here? CFont::SetCentreOn(); CFont::SetCentreSize(SCREEN_WIDTH); CFont::SetJustifyOff(); CFont::SetColor(CRGBA(m_Colour.r, m_Colour.g, m_Colour.b, (255.0f - 255.0f * fLifeTime) * m_fOpacity)); CFont::SetBackGroundOnlyTextOff(); - CFont::SetFontStyle(FONT_STANDARD); + FONT_LOCALE(FONT_STANDARD); CFont::PrintString(vecOut.x, vecOut.y, m_aText); } } diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h index 8bd0d5e1..f163d8ca 100644 --- a/src/render/SpecialFX.h +++ b/src/render/SpecialFX.h @@ -1,8 +1,12 @@ #pragma once +//file done + class CSpecialFX { public: + static bool bVideoCam; + static bool bLiftCam; static bool bSnapShotActive; static int32 SnapShotFrames; @@ -10,8 +14,11 @@ public: static void Update(void); static void Init(void); static void Shutdown(void); + static void AddWeaponStreak(int type); + static void Render2DFXs(); }; + class CRegisteredMotionBlurStreak { public: @@ -27,6 +34,7 @@ public: void Render(void); }; + class CMotionBlurStreaks { static CRegisteredMotionBlurStreak aStreaks[NUMMBLURSTREAKS]; @@ -37,33 +45,31 @@ public: static void Render(void); }; + struct CBulletTrace { - CVector m_vecCurrentPos; - CVector m_vecTargetPos; + CVector m_vecStartPos; + CVector m_vecEndPos; bool m_bInUse; - uint8 m_framesInUse; - uint8 m_lifeTime; + uint32 m_nCreationTime; + uint32 m_nLifeTime; + float m_fThickness; + uint8 m_fVisibility; void Update(void); }; + class CBulletTraces { public: static CBulletTrace aTraces[NUMBULLETTRACES]; static void Init(void); - static void AddTrace(CVector*, CVector*); static void Render(void); static void Update(void); - -//TODO(MIAMI) - static void AddTrace(CVector *, CVector *, float, unsigned int, unsigned char) {} - static void AddTrace(CVector *a, CVector *b, int32 weapontype, class CEntity *shooter) - { - AddTrace(a, b); //TODO: temp - } + static void AddTrace(CVector* start, CVector* end, float thickness, uint32 lifeTime, uint8 visibility); + static void AddTrace(CVector* start, CVector* end, int32 weaponType, class CEntity* shooter); }; enum @@ -104,6 +110,7 @@ public: void Render(); }; + class C3dMarkers { public: @@ -144,6 +151,7 @@ enum BRIGHTLIGHT_REAR = BRIGHTLIGHT_REAR_LONG, }; + class CBrightLight { public: @@ -158,6 +166,7 @@ public: uint8 m_blue; }; + class CBrightLights { static int NumBrightLights; @@ -177,6 +186,7 @@ enum SHINYTEXT_FLAT }; + class CShinyText { public: @@ -189,7 +199,8 @@ public: uint8 m_blue; }; -class CShinyTexts + +class CShinyTexts { static int NumShinyTexts; static CShinyText aShinyTexts[NUMSHINYTEXTS]; @@ -197,11 +208,12 @@ public: static void Init(void); static void RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3, float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3, - uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist); + uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist); //not used static void Render(void); static void RenderOutGeometryBuffer(void); }; + class CMoneyMessage { friend class CMoneyMessages; @@ -216,6 +228,7 @@ public: void Render(); }; + class CMoneyMessages { static CMoneyMessage aMoneyMessages[NUMMONEYMESSAGES]; @@ -225,11 +238,12 @@ public: static void RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 bGreen, uint8 bBlue, float fSize, float fOpacity); }; + class CSpecialParticleStuff { static uint32 BoatFromStart; public: - static void CreateFoamAroundObject(CMatrix*, float, float, float, int32); - static void StartBoatFoamAnimation(); - static void UpdateBoatFoamAnimation(CMatrix*); + static void CreateFoamAroundObject(CMatrix*, float, float, float, int32); //not used + static void StartBoatFoamAnimation(); //not used + static void UpdateBoatFoamAnimation(CMatrix*); //not used }; diff --git a/src/render/WaterCannon.cpp b/src/render/WaterCannon.cpp index bd2b9a68..91304be3 100644 --- a/src/render/WaterCannon.cpp +++ b/src/render/WaterCannon.cpp @@ -11,6 +11,9 @@ #include "Fire.h" #include "WaterLevel.h" #include "Camera.h" +#include "Particle.h" + +// --MIAMI: file done #define WATERCANNONVERTS 4 #define WATERCANNONINDEXES 12 @@ -64,7 +67,7 @@ void CWaterCannon::Update_OncePerFrame(int16 index) if (CTimer::GetTimeInMilliseconds() > m_nTimeCreated + WATERCANNON_LIFETIME ) { - m_nCur = (m_nCur + 1) % -NUM_SEGMENTPOINTS; + m_nCur = (m_nCur + 1) % NUM_SEGMENTPOINTS; m_abUsed[m_nCur] = false; } @@ -128,7 +131,7 @@ void CWaterCannon::Render(void) RwIm3DVertexSetV(&WaterCannonVertices[2], v); RwIm3DVertexSetV(&WaterCannonVertices[3], v); - int16 pointA = m_nCur % -NUM_SEGMENTPOINTS; + int16 pointA = m_nCur % NUM_SEGMENTPOINTS; int16 pointB = pointA - 1; if ( (pointA - 1) < 0 ) @@ -235,11 +238,16 @@ void CWaterCannon::PushPeds(void) ped->m_vecMoveSpeed.x = (0.6f * m_avecVelocity[j].x + ped->m_vecMoveSpeed.x) * 0.5f; ped->m_vecMoveSpeed.y = (0.6f * m_avecVelocity[j].y + ped->m_vecMoveSpeed.y) * 0.5f; - ped->SetFall(2000, AnimationId(ANIM_KO_SKID_FRONT + localDir), 0); - - CFire *fire = ped->m_pFire; - if ( fire ) - fire->Extinguish(); + float pedSpeed2D = ped->m_vecMoveSpeed.Magnitude2D(); + + if ( pedSpeed2D > 0.2f ) { + ped->m_vecMoveSpeed.x *= (0.2f / pedSpeed2D); + ped->m_vecMoveSpeed.y *= (0.2f / pedSpeed2D); + } + ped->SetFall(2000, (AnimationId)(localDir + ANIM_KO_SKID_FRONT), 0); + CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, ped->GetPosition(), ped->m_vecMoveSpeed * 0.3f, 0, 0.5f); + CParticle::AddParticle(PARTICLE_CAR_SPLASH, ped->GetPosition(), ped->m_vecMoveSpeed * -0.3f + CVector(0.f, 0.f, 0.5f), 0, 0.5f, + CGeneral::GetRandomNumberInRange(0.f, 10.f), CGeneral::GetRandomNumberInRange(0.f, 90.f), 1); j = NUM_SEGMENTPOINTS; } diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 07304b77..85418edd 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -534,12 +534,13 @@ CameraSize(RwCamera * camera, RwRect * rect, } } - // BUG: game just changes camera raster's sizes, but this is a hack - if (( origSize.w != rect->w ) && ( origSize.h != rect->h )) + if (( origSize.w != rect->w ) || ( origSize.h != rect->h )) { RwRaster *raster; RwRaster *zRaster; + // BUG: game just changes camera raster's sizes, but this is a hack +#ifdef FIX_BUGS /* * Destroy rasters... */ @@ -597,6 +598,13 @@ CameraSize(RwCamera * camera, RwRect * rect, RwCameraSetRaster(camera, raster); RwCameraSetZRaster(camera, zRaster); } +#else + raster = RwCameraGetRaster(camera); + zRaster = RwCameraGetZRaster(camera); + + raster->width = zRaster->width = rect->w; + raster->height = zRaster->height = rect->h; +#endif } /* Figure out the view window */ diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index 18eecd95..966f353a 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -41,8 +41,10 @@ #include "Timecycle.h" #include "Fluff.h" -#define BLOCK_COUNT 20 -#define SIZE_OF_SIMPLEVARS 0xFC +// --MIAMI: file done + +#define BLOCK_COUNT 22 +#define SIZE_OF_SIMPLEVARS 0xE4 const uint32 SIZE_OF_ONE_GAME_IN_BYTES = 201729; @@ -60,7 +62,6 @@ int CheckSum; eLevelName m_LevelToLoad; char SaveFileNameJustSaved[260]; int Slots[SLOT_COUNT]; -CDate CompileDateAndTime; bool b_FoundRecentSavedGameWantToLoad; bool JustLoadedDontFadeInYet; @@ -112,13 +113,14 @@ do {\ buf += size;\ } while (0) -#define WriteSaveDataBlock(save_func)\ +#define WriteSaveDataBlock(save_func, msg)\ do {\ size = 0;\ buf = work_buff;\ reserved = 0;\ MakeSpaceForSizeInBufferPointer(presize, buf, postsize);\ save_func(buf, &size);\ + debug(msg"== %i \n", size);\ CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);\ if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff))\ return false;\ @@ -145,9 +147,10 @@ GenericSave(int file) reserved = 0; // Save simple vars - lastMissionPassed = TheText.Get(CStats::LastMissionPassedName); + lastMissionPassed = TheText.Get(CStats::LastMissionPassedName[0] ? CStats::LastMissionPassedName : "ITBEG"); if (lastMissionPassed[0] != '\0') { AsciiToUnicode("...'", suffix); + suffix[3] = L'\0'; #ifdef FIX_BUGS // fix buffer overflow int len = UnicodeStrlen(lastMissionPassed); @@ -194,12 +197,6 @@ GenericSave(int file) WriteDataToBufferPointer(buf, CWeather::NewWeatherType); WriteDataToBufferPointer(buf, CWeather::ForcedWeatherType); WriteDataToBufferPointer(buf, CWeather::InterpolationValue); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nSecond); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nMinute); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nHour); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nDay); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nMonth); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nYear); WriteDataToBufferPointer(buf, CWeather::WeatherTypeInList); #ifdef COMPATIBLE_SAVES // converted to float for compatibility with original format @@ -227,6 +224,7 @@ GenericSave(int file) buf += 4; postsize = buf; CTheScripts::SaveAllScripts(buf, &size); + debug("ScriptSize== %i \n", size); CopySizeAndPreparePointer(presize, buf, postsize, reserved, size); if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff)) return false; @@ -234,28 +232,28 @@ GenericSave(int file) totalSize = buf - work_buff; // Save the rest - WriteSaveDataBlock(CPools::SavePedPool); - WriteSaveDataBlock(CGarages::Save); - WriteSaveDataBlock(CGameLogic::Save); - WriteSaveDataBlock(CPools::SaveVehiclePool); - WriteSaveDataBlock(CPools::SaveObjectPool); - WriteSaveDataBlock(ThePaths.Save); - WriteSaveDataBlock(CCranes::Save); - WriteSaveDataBlock(CPickups::Save); - WriteSaveDataBlock(gPhoneInfo.Save); - WriteSaveDataBlock(CRestart::SaveAllRestartPoints); - WriteSaveDataBlock(CRadar::SaveAllRadarBlips); - WriteSaveDataBlock(CTheZones::SaveAllZones); - WriteSaveDataBlock(CGangs::SaveAllGangData); - WriteSaveDataBlock(CTheCarGenerators::SaveAllCarGenerators); - WriteSaveDataBlock(CParticleObject::SaveParticle); - WriteSaveDataBlock(cAudioScriptObject::SaveAllAudioScriptObjects); - WriteSaveDataBlock(CScriptPaths::Save); - WriteSaveDataBlock(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo); - WriteSaveDataBlock(CStats::SaveStats); - WriteSaveDataBlock(CSetPieces::Save); - WriteSaveDataBlock(CStreaming::MemoryCardSave); - WriteSaveDataBlock(CPedType::Save); + WriteSaveDataBlock(CPools::SavePedPool, "PedPoolSize"); + WriteSaveDataBlock(CGarages::Save, "GaragesSize"); + WriteSaveDataBlock(CGameLogic::Save, "GameLogicSize"); + WriteSaveDataBlock(CPools::SaveVehiclePool, "VehPoolSize"); + WriteSaveDataBlock(CPools::SaveObjectPool, "ObjectPoolSize"); + WriteSaveDataBlock(ThePaths.Save, "ThePathsSize"); + WriteSaveDataBlock(CCranes::Save, "CranesSize"); + WriteSaveDataBlock(CPickups::Save, "PickUpsSize"); + WriteSaveDataBlock(gPhoneInfo.Save, "PhoneInfoSize"); + WriteSaveDataBlock(CRestart::SaveAllRestartPoints, "RestartPointsBufferSize"); + WriteSaveDataBlock(CRadar::SaveAllRadarBlips, "RadarBlipsBufferSize"); + WriteSaveDataBlock(CTheZones::SaveAllZones, "AllZonesBufferSize"); + WriteSaveDataBlock(CGangs::SaveAllGangData, "AllGangDataSize"); + WriteSaveDataBlock(CTheCarGenerators::SaveAllCarGenerators, "AllCarGeneratorsSize"); + WriteSaveDataBlock(CParticleObject::SaveParticle, "ParticlesSize"); + WriteSaveDataBlock(cAudioScriptObject::SaveAllAudioScriptObjects, "AllAudioScriptObjectsSize"); + WriteSaveDataBlock(CScriptPaths::Save, "ScriptPathsSize"); + WriteSaveDataBlock(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo, "PlayerInfoSize"); + WriteSaveDataBlock(CStats::SaveStats, "StatsSize"); + WriteSaveDataBlock(CSetPieces::Save, "SetPiecesSize"); + WriteSaveDataBlock(CStreaming::MemoryCardSave, "StreamingSize"); + WriteSaveDataBlock(CPedType::Save, "PedTypeSize"); // Write padding for (int i = 0; i < 4; i++) { @@ -331,12 +329,6 @@ GenericLoad() ReadDataFromBufferPointer(buf, CWeather::NewWeatherType); ReadDataFromBufferPointer(buf, CWeather::ForcedWeatherType); ReadDataFromBufferPointer(buf, CWeather::InterpolationValue); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nSecond); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nMinute); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nHour); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nDay); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nMonth); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nYear); ReadDataFromBufferPointer(buf, CWeather::WeatherTypeInList); #ifdef COMPATIBLE_SAVES // converted to float for compatibility with original format @@ -470,8 +462,13 @@ CloseFile(int32 file) void DoGameSpecificStuffAfterSucessLoad() { + CCollision::SortOutCollisionAfterLoad(); + CStreaming::LoadSceneCollision(TheCamera.GetPosition()); + CStreaming::LoadScene(TheCamera.GetPosition()); + CGame::TidyUpMemory(true, false); StillToFadeOut = true; JustLoadedDontFadeInYet = true; + TheCamera.Fade(0.0f, 0); CTheScripts::Process(); } diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h index 236e34f5..07aa23ca 100644 --- a/src/save/GenericGameStorage.h +++ b/src/save/GenericGameStorage.h @@ -25,8 +25,6 @@ bool CheckDataNotCorrupt(int32 slot, char *name); bool RestoreForStartLoad(); int align4bytes(int32 size); -extern class CDate CompileDateAndTime; - extern char DefaultPCSaveFileName[260]; extern char ValidSaveName[260]; extern char LoadFileName[256]; diff --git a/src/skel/crossplatform.cpp b/src/skel/crossplatform.cpp index 452ad9fa..4b7d3d9a 100644 --- a/src/skel/crossplatform.cpp +++ b/src/skel/crossplatform.cpp @@ -26,19 +26,35 @@ void GetLocalTime_CP(SYSTEMTIME *out) { // Compatible with Linux/POSIX and MinGW on Windows #ifndef _WIN32 HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) { - char newpathname[32]; - strncpy(newpathname, pathname, 32); - char* path = strtok(newpathname, "\\*"); - strncpy(firstfile->folder, path, sizeof(firstfile->folder)); - - // Both w/ extension and w/o extension is ok - if (strlen(path) + 2 != strlen(pathname)) - strncpy(firstfile->extension, strtok(NULL, "\\*"), sizeof(firstfile->extension)); + char pathCopy[MAX_PATH]; + strcpy(pathCopy, pathname); + + char *folder = strtok(pathCopy, "*"); + char *extension = strtok(NULL, "*"); + + // because strtok doesn't return NULL for last delimiter + if (extension - folder == strlen(pathname)) + extension = nil; + + // Case-sensitivity and backslashes... + // Will be freed at the bottom + char *realFolder = casepath(folder); + if (realFolder) { + folder = realFolder; + } + + strncpy(firstfile->folder, folder, sizeof(firstfile->folder)); + + if (extension) + strncpy(firstfile->extension, extension, sizeof(firstfile->extension)); else - strncpy(firstfile->extension, "", sizeof(firstfile->extension)); + firstfile->extension[0] = '\0'; + + if (realFolder) + free(realFolder); HANDLE d; - if ((d = (HANDLE)opendir(path)) == NULL || !FindNextFile(d, firstfile)) + if ((d = (HANDLE)opendir(firstfile->folder)) == NULL || !FindNextFile(d, firstfile)) return NULL; return d; @@ -52,8 +68,8 @@ bool FindNextFile(HANDLE d, WIN32_FIND_DATA* finddata) { while ((file = readdir((DIR*)d)) != NULL) { // We only want "DT_REG"ular Files, but reportedly some FS and OSes gives DT_UNKNOWN as type. - if ((file->d_type == DT_UNKNOWN || file->d_type == DT_REG) && - (extensionLen == 0 || strncmp(&file->d_name[strlen(file->d_name) - extensionLen], finddata->extension, extensionLen) == 0)) { + if ((file->d_type == DT_UNKNOWN || file->d_type == DT_REG || file->d_type == DT_LNK) && + (extensionLen == 0 || strncasecmp(&file->d_name[strlen(file->d_name) - extensionLen], finddata->extension, extensionLen) == 0)) { sprintf(relativepath, "%s/%s", finddata->folder, file->d_name); realpath(relativepath, path); diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index 08e5c021..26a3a509 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -43,6 +43,7 @@ #define MAX_SUBSYSTEMS (16) +// --MIAMI: file done rw::EngineOpenParams openParams; @@ -152,7 +153,7 @@ const char *_psGetUserFilesFolder() &KeycbData) == ERROR_SUCCESS ) { RegCloseKey(hKey); - strcat(szUserFiles, "\\GTA3 User Files"); + strcat(szUserFiles, "\\GTA Vice City User Files"); _psCreateFolder(szUserFiles); return szUserFiles; } @@ -386,10 +387,6 @@ psInitialize(void) InitialiseLanguage(); -#ifndef GTA3_1_1_PATCH - FrontEndMenuManager.LoadSettings(); -#endif - #endif gGameState = GS_START_UP; @@ -422,7 +419,7 @@ psInitialize(void) } else if ( verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { - if ( verInfo.dwMajorVersion > 4 || verInfo.dwMajorVersion == 4 && verInfo.dwMinorVersion == 1 ) + if ( verInfo.dwMajorVersion > 4 || verInfo.dwMajorVersion == 4 && verInfo.dwMinorVersion != 0 ) { debug("Operating System is Win98\n"); _dwOperatingSystemVersion = OS_WIN98; @@ -439,13 +436,9 @@ psInitialize(void) #ifndef PS2_MENU - -#ifdef GTA3_1_1_PATCH FrontEndMenuManager.LoadSettings(); #endif -#endif - #ifdef _WIN32 MEMORYSTATUS memstats; @@ -867,7 +860,8 @@ bool IsThisJoystickBlacklisted(int i) const char* joyname = glfwGetJoystickName(i); - if (strncmp(joyname, gSelectedJoystickName, strlen(gSelectedJoystickName)) == 0) + if (gSelectedJoystickName[0] != '\0' && + strncmp(joyname, gSelectedJoystickName, strlen(gSelectedJoystickName)) == 0) return false; return true; @@ -1250,14 +1244,17 @@ void resizeCB(GLFWwindow* window, int width, int height) { * memory things don't work. */ /* redraw window */ - if (RwInitialised && (gGameState == GS_PLAYING_GAME #ifndef MASTER - || gGameState == GS_ANIMVIEWER -#endif - )) + if (RwInitialised && (gGameState == GS_PLAYING_GAME || gGameState == GS_ANIMVIEWER)) { - RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void*)TRUE); + RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void *)TRUE); } +#else + if (RwInitialised && gGameState == GS_PLAYING_GAME) + { + RsEventHandler(rsIDLE, (void *)TRUE); + } +#endif if (RwInitialised && height > 0 && width > 0) { RwRect r; @@ -1765,6 +1762,7 @@ main(int argc, char *argv[]) printf("Into TheGame!!!\n"); #else LoadingScreen(nil, nil, "loadsc0"); + // LoadingScreen(nil, nil, "loadsc0"); // duplicate #endif if ( !CGame::InitialiseOnceAfterRW() ) RsGlobal.quit = TRUE; @@ -1781,6 +1779,7 @@ main(int argc, char *argv[]) case GS_INIT_FRONTEND: { LoadingScreen(nil, nil, "loadsc0"); + // LoadingScreen(nil, nil, "loadsc0"); // duplicate FrontEndMenuManager.m_bGameNotLoaded = true; diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp index 99f44fed..e21abb17 100644 --- a/src/skel/skeleton.cpp +++ b/src/skel/skeleton.cpp @@ -11,7 +11,7 @@ #include "skeleton.h" #include "platform.h" - +// --MIAMI: file done static RwBool DefaultVideoMode = TRUE; @@ -371,8 +371,8 @@ RsRwInitialize(void *displayID) psNativeTextureSupport(); + RwTextureSetAutoMipmapping(TRUE); RwTextureSetMipmapping(FALSE); - RwTextureSetAutoMipmapping(FALSE); return TRUE; } diff --git a/src/skel/win/resource.h b/src/skel/win/resource.h index 84dffb95..93f14216 100644 --- a/src/skel/win/resource.h +++ b/src/skel/win/resource.h @@ -8,7 +8,7 @@ #define IDEXIT 1002 #define IDC_SELECTDEVICE 1005 -#define IDI_MAIN_ICON 1042 +#define IDI_MAIN_ICON 100 // Next default values for new objects // #ifdef APSTUDIO_INVOKED diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index 1d1037af..a10a1a92 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -53,6 +53,7 @@ #define MAX_SUBSYSTEMS (16) +// --MIAMI: file done static RwBool ForegroundApp = TRUE; @@ -189,7 +190,7 @@ const char *_psGetUserFilesFolder() &KeycbData) == ERROR_SUCCESS ) { RegCloseKey(hKey); - strcat(szUserFiles, "\\GTA3 User Files"); + strcat(szUserFiles, "\\GTA Vice City User Files"); _psCreateFolder(szUserFiles); return szUserFiles; } @@ -650,10 +651,6 @@ psInitialize(void) C_PcSave::SetSaveDirectory(_psGetUserFilesFolder()); InitialiseLanguage(); -#ifndef GTA3_1_1_PATCH - FrontEndMenuManager.LoadSettings(); -#endif - #endif gGameState = GS_START_UP; @@ -688,7 +685,7 @@ psInitialize(void) } else if ( verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { - if ( verInfo.dwMajorVersion > 4 || verInfo.dwMajorVersion == 4 && verInfo.dwMinorVersion == 1 ) + if ( verInfo.dwMajorVersion > 4 || verInfo.dwMajorVersion == 4 && verInfo.dwMinorVersion != 0 ) { debug("Operating System is Win98\n"); _dwOperatingSystemVersion = OS_WIN98; @@ -701,13 +698,9 @@ psInitialize(void) } #ifndef PS2_MENU - -#ifdef GTA3_1_1_PATCH FrontEndMenuManager.LoadSettings(); #endif -#endif - dwDXVersion = GetDXVersion(); debug("DirectX version 0x%x\n", dwDXVersion); @@ -945,8 +938,7 @@ void HandleGraphEvent(void) /* ***************************************************************************** - */ - + */ LRESULT CALLBACK MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) { @@ -1016,10 +1008,17 @@ MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) RECT rect; /* redraw window */ +#ifndef MASTER if (RwInitialised && (gGameState == GS_PLAYING_GAME || gGameState == GS_ANIMVIEWER)) { RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void *)TRUE); } +#else + if (RwInitialised && gGameState == GS_PLAYING_GAME) + { + RsEventHandler(rsIDLE, (void *)TRUE); + } +#endif /* Manually resize window */ rect.left = rect.top = 0; @@ -1327,7 +1326,7 @@ InitApplication(HANDLE instance) windowClass.cbClsExtra = 0; windowClass.cbWndExtra = 0; windowClass.hInstance = (HINSTANCE)instance; - windowClass.hIcon = nil; + windowClass.hIcon = LoadIcon((HINSTANCE)instance, (LPCSTR)IDI_MAIN_ICON); windowClass.hCursor = LoadCursor(nil, IDC_ARROW); windowClass.hbrBackground = nil; windowClass.lpszMenuName = NULL; @@ -1382,17 +1381,17 @@ UINT GetBestRefreshRate(UINT width, UINT height, UINT depth) #endif if ( mode.Width == width && mode.Height == height && mode.Format == format ) { - if ( mode.RefreshRate == 0 ) + if ( mode.RefreshRate == 0 ) { + d3d->Release(); return 0; + } if ( mode.RefreshRate < refreshRate && mode.RefreshRate >= 60 ) refreshRate = mode.RefreshRate; } } -#ifdef FIX_BUGS d3d->Release(); -#endif if ( refreshRate == -1 ) return -1; @@ -2255,6 +2254,8 @@ WinMain(HINSTANCE instance, if ( startupDeactivate || ControlsManager.GetJoyButtonJustDown() != 0 ) ++gGameState; + else if ( CPad::GetPad(0)->NewState.CheckForInput() ) + ++gGameState; else if ( CPad::GetPad(0)->GetLeftMouseJustDown() ) ++gGameState; else if ( CPad::GetPad(0)->GetEnterJustDown() ) @@ -2292,6 +2293,8 @@ WinMain(HINSTANCE instance, if ( startupDeactivate || ControlsManager.GetJoyButtonJustDown() != 0 ) ++gGameState; + else if ( CPad::GetPad(0)->NewState.CheckForInput() ) + ++gGameState; else if ( CPad::GetPad(0)->GetLeftMouseJustDown() ) ++gGameState; else if ( CPad::GetPad(0)->GetEnterJustDown() ) @@ -2328,6 +2331,7 @@ WinMain(HINSTANCE instance, printf("Into TheGame!!!\n"); #else LoadingScreen(nil, nil, "loadsc0"); + // LoadingScreen(nil, nil, "loadsc0"); // duplicate #endif if ( !CGame::InitialiseOnceAfterRW() ) RsGlobal.quit = TRUE; @@ -2345,6 +2349,7 @@ WinMain(HINSTANCE instance, case GS_INIT_FRONTEND: { LoadingScreen(nil, nil, "loadsc0"); + // LoadingScreen(nil, nil, "loadsc0"); // duplicate FrontEndMenuManager.m_bGameNotLoaded = true; diff --git a/src/text/Messages.cpp b/src/text/Messages.cpp index 82ab294c..a2409289 100644 --- a/src/text/Messages.cpp +++ b/src/text/Messages.cpp @@ -11,6 +11,8 @@ #include "Font.h" +// --MIAMI: file done + tMessage CMessages::BriefMessages[NUMBRIEFMESSAGES]; tPreviousBrief CMessages::PreviousBriefs[NUMPREVIOUSBRIEFS]; tBigMessage CMessages::BIGMessages[NUMBIGMESSAGES]; @@ -69,10 +71,7 @@ CMessages::WideStringCompare(wchar *str1, wchar *str2, uint16 size) if (len1 != len2 && (len1 < size || len2 < size)) return false; - for (int32 i = 0; i < size; i++) { - if (FixupChar(str1[i]) == '\0') - break; - + for (int32 i = 0; FixupChar(str1[i]) != '\0' && i < size; i++) { if (FixupChar(str1[i]) != FixupChar(str2[i])) return false; } @@ -297,6 +296,7 @@ CMessages::AddBigMessage(wchar *msg, uint32 time, uint16 style) BIGMessages[style].m_Stack[0].m_nNumber[5] = -1; BIGMessages[style].m_Stack[0].m_pString = nil; } + void CMessages::AddBigMessageQ(wchar *msg, uint32 time, uint16 style) { @@ -327,10 +327,8 @@ CMessages::AddBigMessageQ(wchar *msg, uint32 time, uint16 style) void CMessages::AddToPreviousBriefArray(wchar *text, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, wchar *string) { - int32 i = 0; - while (i < NUMPREVIOUSBRIEFS) { - if (PreviousBriefs[i].m_pText == nil) - break; + int32 i; + for (i = 0; PreviousBriefs[i].m_pText && i < NUMPREVIOUSBRIEFS; i++) { if (PreviousBriefs[i].m_nNumber[0] == n1 && PreviousBriefs[i].m_nNumber[1] == n2 && PreviousBriefs[i].m_nNumber[2] == n3 @@ -340,8 +338,6 @@ CMessages::AddToPreviousBriefArray(wchar *text, int32 n1, int32 n2, int32 n3, in && PreviousBriefs[i].m_pText == text && PreviousBriefs[i].m_pString == string) return; - - i++; } if (i != 0) { @@ -374,6 +370,14 @@ CMessages::InsertNumberInString(wchar *str, int32 n1, int32 n2, int32 n3, int32 return; } + sprintf(numStr, "%d", n1); + size_t outLen = strlen(numStr); + AsciiToUnicode(numStr, wNumStr); + if (str[0] == 0) { + *outstr = '\0'; + return; + } + int32 size = GetWideStringLength(str); int32 i = 0; @@ -385,22 +389,20 @@ CMessages::InsertNumberInString(wchar *str, int32 n1, int32 n2, int32 n3, int32 #else if (str[c] == '~' && str[c + 1] == '1' && str[c + 2] == '~') { #endif + c += 3; + for (int j = 0; j < outLen; ) + *(outstr++) = wNumStr[j++]; + + i++; switch (i) { - case 0: sprintf(numStr, "%d", n1); break; case 1: sprintf(numStr, "%d", n2); break; case 2: sprintf(numStr, "%d", n3); break; case 3: sprintf(numStr, "%d", n4); break; case 4: sprintf(numStr, "%d", n5); break; case 5: sprintf(numStr, "%d", n6); break; } - i++; + outLen = strlen(numStr); AsciiToUnicode(numStr, wNumStr); - - int j = 0; - while (wNumStr[j] != '\0') - *(outstr++) = wNumStr[j++]; - - c += 3; } else { *(outstr++) = str[c++]; } @@ -424,10 +426,9 @@ CMessages::InsertStringInString(wchar *str1, wchar *str2) for (i = 0; i < total_size; ) { #ifdef MORE_LANGUAGES if ((CFont::IsJapanese() && *_str1 == (0x8000 | '~') && *(_str1 + 1) == (0x8000 | 'a') && *(_str1 + 2) == (0x8000 | '~')) - || (*_str1 == '~' && *(_str1 + 1) == 'a' && *(_str1 + 2) == '~')) - { + || (*_str1 == '~' && *(_str1 + 1) == 'a' && *(_str1 + 2) == '~')) { #else - if (*_str1 == '~' && *(_str1 + 1) == 'a' && *(_str1 + 2) == '~') { + if (*_str1 == '~' && *(_str1 + 1) == 'a' && *(_str1 + 2) == '~') { #endif _str1 += 3; for (int j = 0; j < str2_size; j++) { @@ -466,10 +467,12 @@ CMessages::InsertPlayerControlKeysInString(wchar *str) if (str[i] == '~' && str[i + 1] == 'k' && str[i + 2] == '~') { #endif i += 4; - for (int32 cont = 0; cont < MAX_CONTROLLERACTIONS; cont++) { + bool done = false; + for (int32 cont = 0; cont < MAX_CONTROLLERACTIONS && !done; cont++) { uint16 contSize = GetWideStringLength(ControlsManager.m_aActionNames[cont]); if (contSize != 0) { if (WideStringCompare(&str[i], ControlsManager.m_aActionNames[cont], contSize)) { + done = true; ControlsManager.GetWideStringOfCommandKeys(cont, keybuf, 256); uint16 keybuf_size = GetWideStringLength(keybuf); for (uint16 j = 0; j < keybuf_size; j++) { @@ -751,7 +754,7 @@ CMessages::ClearThisPrint(wchar *str) } BriefMessages[i].m_pText = nil; BriefMessages[0].m_nStartTime = CTimer::GetTimeInMilliseconds(); - if (BriefMessages[0].m_pText == nil) + if (BriefMessages[0].m_pText != nil) AddToPreviousBriefArray( BriefMessages[0].m_pText, BriefMessages[0].m_nNumber[0], @@ -801,7 +804,7 @@ CMessages::ClearThisBigPrint(wchar *str) } BIGMessages[style].m_Stack[i].m_pText = nil; } else { - BIGMessages[style].m_Stack[0].m_pText = 0; + BIGMessages[style].m_Stack[0].m_pText = nil; i = 0; while (i < 3) { if (BIGMessages[style].m_Stack[i + 1].m_pText == nil) diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 1316985d..d1a7505e 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -1,4 +1,4 @@ -#include "common.h" +#include "common.h" #include "main.h" #include "General.h" @@ -59,7 +59,7 @@ bool CAutomobile::m_sAllTaxiLights; const uint32 CAutomobile::nSaveStructSize = #ifdef COMPATIBLE_SAVES - 1448; + 1500; #else sizeof(CAutomobile); #endif @@ -4635,7 +4635,6 @@ CAutomobile::ProcessOpenDoor(uint32 component, uint32 anim, float time) case ANIM_CAR_ROLLDOOR_LOW: ProcessDoorOpenCloseAnimation(this, component, door, time, 0.1f, 0.6f, 0.95f); break; - break; case ANIM_CAR_GETOUT_LHS: case ANIM_CAR_GETOUT_LOW_LHS: case ANIM_CAR_GETOUT_RHS: @@ -4649,6 +4648,7 @@ CAutomobile::ProcessOpenDoor(uint32 component, uint32 anim, float time) case ANIM_CAR_PULLOUT_RHS: case ANIM_CAR_PULLOUT_LOW_RHS: OpenDoor(component, door, 1.0f); + break; case ANIM_COACH_OPEN_L: case ANIM_COACH_OPEN_R: ProcessDoorOpenAnimation(this, component, door, time, 0.66f, 0.8f); @@ -5349,7 +5349,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type) obj->m_fElasticity = 0.1f; obj->m_fBuoyancy = obj->m_fMass*GRAVITY/0.75f; obj->ObjectCreatedBy = TEMP_OBJECT; - obj->bIsStatic = false; + obj->SetIsStatic(false); obj->bIsPickup = false; obj->bUseVehicleColours = true; obj->m_colour1 = m_currentColour1; @@ -5713,7 +5713,7 @@ CAutomobile::Save(uint8*& buf) { CVehicle::Save(buf); WriteSaveBuf<CDamageManager>(buf, Damage); - SkipSaveBuf(buf, 800 - sizeof(CDamageManager)); + SkipSaveBuf(buf, 1500 - 672 - sizeof(CDamageManager)); } void @@ -5721,7 +5721,7 @@ CAutomobile::Load(uint8*& buf) { CVehicle::Load(buf); Damage = ReadSaveBuf<CDamageManager>(buf); - SkipSaveBuf(buf, 800 - sizeof(CDamageManager)); + SkipSaveBuf(buf, 1500 - 672 - sizeof(CDamageManager)); SetupDamageAfterLoad(); } #endif diff --git a/src/vehicles/Bike.cpp b/src/vehicles/Bike.cpp index b5bc9480..4a4b0516 100644 --- a/src/vehicles/Bike.cpp +++ b/src/vehicles/Bike.cpp @@ -39,6 +39,14 @@ //--MIAMI: file done +const uint32 CBike::nSaveStructSize = +#ifdef COMPATIBLE_SAVES + 1260; +#else + sizeof(CBoat); +#endif + + // TODO: maybe put this somewhere else inline void GetRelativeMatrix(RwMatrix *mat, RwFrame *frm, RwFrame *end) @@ -2922,3 +2930,19 @@ CBike::ReduceHornCounter(void) if(m_nCarHornTimer != 0) m_nCarHornTimer--; } + +#ifdef COMPATIBLE_SAVES +void +CBike::Save(uint8*& buf) +{ + CVehicle::Save(buf); + SkipSaveBuf(buf, 1260 - 672); +} + +void +CBike::Load(uint8*& buf) +{ + CVehicle::Load(buf); + SkipSaveBuf(buf, 1260 - 672); +} +#endif diff --git a/src/vehicles/Bike.h b/src/vehicles/Bike.h index 885fe1b0..3fcf66a2 100644 --- a/src/vehicles/Bike.h +++ b/src/vehicles/Bike.h @@ -132,6 +132,12 @@ public: void Fix(void); void SetupModelNodes(void); void ReduceHornCounter(void); + +#ifdef COMPATIBLE_SAVES + virtual void Save(uint8*& buf); + virtual void Load(uint8*& buf); +#endif + static const uint32 nSaveStructSize; }; // These functions and function names are made up diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index 8c9dd241..8b5de929 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -43,7 +43,7 @@ CBoat *CBoat::apFrameWakeGeneratingBoats[4]; const uint32 CBoat::nSaveStructSize = #ifdef COMPATIBLE_SAVES - 1156; + 1216; #else sizeof(CBoat); #endif @@ -893,7 +893,7 @@ CBoat::BlowUpCar(CEntity *culprit) obj->m_fElasticity = 0.1f; obj->m_fBuoyancy = obj->m_fMass*GRAVITY/0.75f; obj->ObjectCreatedBy = TEMP_OBJECT; - obj->bIsStatic = false; + obj->SetIsStatic(false); obj->bIsPickup = false; // life time @@ -1449,13 +1449,13 @@ void CBoat::Save(uint8*& buf) { CVehicle::Save(buf); - SkipSaveBuf(buf, 1156 - 648); + SkipSaveBuf(buf, 1216 - 672); } void CBoat::Load(uint8*& buf) { CVehicle::Load(buf); - SkipSaveBuf(buf, 1156 - 648); + SkipSaveBuf(buf, 1216 - 672); } #endif diff --git a/src/vehicles/CarGen.cpp b/src/vehicles/CarGen.cpp index 598b8342..77d66cbf 100644 --- a/src/vehicles/CarGen.cpp +++ b/src/vehicles/CarGen.cpp @@ -91,7 +91,7 @@ void CCarGenerator::DoInternalProcessing() pVehicle = pBoat; if (pos.z <= -100.0f) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); - pBoat->bExtendedRange = false; + pBoat->bExtendedRange = true; }else{ bool groundFound; pos = m_vecPos; diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp index 1ab31574..2a571a67 100644 --- a/src/vehicles/Cranes.cpp +++ b/src/vehicles/Cranes.cpp @@ -12,6 +12,8 @@ #include "Object.h" #include "World.h" +// --MIAMI: file done + #define MAX_DISTANCE_TO_FIND_CRANE (10.0f) #define CRANE_UPDATE_RADIUS (300.0f) #define CRANE_MOVEMENT_PROCESSING_RADIUS (150.0f) @@ -259,7 +261,6 @@ void CCrane::Update(void) m_pVehiclePickedUp->bUsesCollision = false; if (m_bIsCrusher) m_pVehiclePickedUp->bCollisionProof = true; - DMAudio.PlayOneShot(m_nAudioEntity, SOUND_CRANE_PICKUP, 0.0f); } } } @@ -439,8 +440,6 @@ bool CCrane::DoesCranePickUpThisCarType(uint32 mi) mi != MI_TRASH && #ifdef FIX_BUGS mi != MI_COACH && -#else - mi != MI_BLISTA && #endif mi != MI_SECURICA && mi != MI_BUS && @@ -657,11 +656,6 @@ void CCranes::Load(uint8* buf, uint32 size) if (pCrane->m_pVehiclePickedUp != nil) pCrane->m_pVehiclePickedUp = CPools::GetVehiclePool()->GetSlot((uintptr)pCrane->m_pVehiclePickedUp - 1); } - /*for (int i = 0; i < NUM_CRANES; i++) { - aCranes[i].m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[i]); - if (aCranes[i].m_nAudioEntity != 0) - DMAudio.SetEntityStatus(aCranes[i].m_nAudioEntity, 1); - }*/ VALIDATESAVEBUF(size); } diff --git a/src/vehicles/Cranes.h b/src/vehicles/Cranes.h index 6d877d82..45ea7a8d 100644 --- a/src/vehicles/Cranes.h +++ b/src/vehicles/Cranes.h @@ -26,7 +26,6 @@ public: }; CBuilding *m_pCraneEntity; CObject *m_pHook; - int32 m_nAudioEntity; float m_fPickupX1; float m_fPickupX2; float m_fPickupY1; diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp index 2c2fb33c..d6a237e5 100644 --- a/src/vehicles/Heli.cpp +++ b/src/vehicles/Heli.cpp @@ -671,7 +671,7 @@ CHeli::SpawnFlyingComponent(int32 component) obj->m_fElasticity = 0.1f; obj->m_fBuoyancy = obj->m_fMass*GRAVITY/0.75f; obj->ObjectCreatedBy = TEMP_OBJECT; - obj->bIsStatic = false; + obj->SetIsStatic(false); obj->bIsPickup = false; // life time diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp index 546f72c2..fb8361c5 100644 --- a/src/vehicles/Train.cpp +++ b/src/vehicles/Train.cpp @@ -663,6 +663,7 @@ PlayAnnouncement(uint8 sound, uint8 station) void ProcessTrainAnnouncements(void) { +#ifdef GTA_TRAIN for (int i = 0; i < ARRAY_SIZE(StationDist); i++) { for (int j = 0; j < ARRAY_SIZE(EngineTrackPosition); j++) { if (!bTrainArrivalAnnounced[i]) { @@ -691,6 +692,7 @@ ProcessTrainAnnouncements(void) } } } +#endif } void diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 994f3c99..cba465b7 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -2367,15 +2367,15 @@ CVehicle::Save(uint8*& buf) WriteSaveBuf<float>(buf, GetPosition().z); SkipSaveBuf(buf, 16); SaveEntityFlags(buf); - SkipSaveBuf(buf, 212); + SkipSaveBuf(buf, 208); AutoPilot.Save(buf); WriteSaveBuf<int8>(buf, m_currentColour1); WriteSaveBuf<int8>(buf, m_currentColour2); SkipSaveBuf(buf, 2); WriteSaveBuf<int16>(buf, m_nAlarmState); - SkipSaveBuf(buf, 43); + SkipSaveBuf(buf, 42); WriteSaveBuf<uint8>(buf, m_nNumMaxPassengers); - SkipSaveBuf(buf, 2); + SkipSaveBuf(buf, 3); WriteSaveBuf<float>(buf, field_1D0[0]); WriteSaveBuf<float>(buf, field_1D0[1]); WriteSaveBuf<float>(buf, field_1D0[2]); @@ -2398,13 +2398,13 @@ CVehicle::Save(uint8*& buf) WriteSaveBuf<uint8>(buf, m_nCurrentGear); SkipSaveBuf(buf, 3); WriteSaveBuf<float>(buf, m_fChangeGearTime); - SkipSaveBuf(buf, 4); + SkipSaveBuf(buf, 12); WriteSaveBuf<uint32>(buf, m_nTimeOfDeath); SkipSaveBuf(buf, 2); WriteSaveBuf<int16>(buf, m_nBombTimer); SkipSaveBuf(buf, 12); WriteSaveBuf<int8>(buf, m_nDoorLock); - SkipSaveBuf(buf, 99); + SkipSaveBuf(buf, 111); } void @@ -2430,15 +2430,15 @@ CVehicle::Load(uint8*& buf) m_matrix = tmp; SkipSaveBuf(buf, 16); LoadEntityFlags(buf); - SkipSaveBuf(buf, 212); + SkipSaveBuf(buf, 208); AutoPilot.Load(buf); m_currentColour1 = ReadSaveBuf<int8>(buf); m_currentColour2 = ReadSaveBuf<int8>(buf); SkipSaveBuf(buf, 2); m_nAlarmState = ReadSaveBuf<int16>(buf); - SkipSaveBuf(buf, 43); + SkipSaveBuf(buf, 42); m_nNumMaxPassengers = ReadSaveBuf<int8>(buf); - SkipSaveBuf(buf, 2); + SkipSaveBuf(buf, 3); field_1D0[0] = ReadSaveBuf<float>(buf); field_1D0[1] = ReadSaveBuf<float>(buf); field_1D0[2] = ReadSaveBuf<float>(buf); @@ -2460,13 +2460,13 @@ CVehicle::Load(uint8*& buf) m_nCurrentGear = ReadSaveBuf<uint8>(buf); SkipSaveBuf(buf, 3); m_fChangeGearTime = ReadSaveBuf<float>(buf); - SkipSaveBuf(buf, 4); + SkipSaveBuf(buf, 12); m_nTimeOfDeath = ReadSaveBuf<uint32>(buf); SkipSaveBuf(buf, 2); m_nBombTimer = ReadSaveBuf<int16>(buf); SkipSaveBuf(buf, 12); m_nDoorLock = (eCarLock)ReadSaveBuf<int8>(buf); - SkipSaveBuf(buf, 99); + SkipSaveBuf(buf, 111); } #endif diff --git a/src/weapons/BulletInfo.cpp b/src/weapons/BulletInfo.cpp index 375a2ca9..13032300 100644 --- a/src/weapons/BulletInfo.cpp +++ b/src/weapons/BulletInfo.cpp @@ -205,13 +205,13 @@ void CBulletInfo::Update(void) if (pHitEntity->IsObject()) { CObject *pHitObject = (CObject*)pHitEntity; if ( !pHitObject->bInfiniteMass && pHitObject->m_fCollisionDamageMultiplier < 99.9f) { - bool notStatic = !pHitObject->IsStatic(); + bool notStatic = !pHitObject->GetIsStatic(); if (notStatic && pHitObject->m_fUprootLimit <= 0.0f) { pHitObject->bIsStatic = false; pHitObject->AddToMovingList(); } - notStatic = !pHitObject->IsStatic(); + notStatic = !pHitObject->GetIsStatic(); if (!notStatic) { CVector moveForce = point.normal * -BULLET_HIT_FORCE; pHitObject->ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z); diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index 48f90897..5d9686b5 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -1526,14 +1526,14 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim, if ( !victimObject->bInfiniteMass && victimObject->m_fCollisionDamageMultiplier < 99.9f) { - bool notStatic = !victimObject->IsStatic(); + bool notStatic = !victimObject->GetIsStatic(); if (notStatic && victimObject->m_fUprootLimit <= 0.0f) { - victimObject->bIsStatic = false; + victimObject->SetIsStatic(false); victimObject->AddToMovingList(); } - notStatic = !victimObject->IsStatic(); + notStatic = !victimObject->GetIsStatic(); if (!notStatic) { CVector moveForce = point->normal * -4.0f; @@ -1922,14 +1922,14 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) if ( !victimObject->bInfiniteMass ) { - bool notStatic = !victimObject->IsStatic(); + bool notStatic = !victimObject->GetIsStatic(); if ( notStatic && victimObject->m_fUprootLimit <= 0.0f ) { - victimObject->bIsStatic = false; + victimObject->SetIsStatic(false); victimObject->AddToMovingList(); } - notStatic = !victimObject->IsStatic(); + notStatic = !victimObject->GetIsStatic(); if ( !notStatic ) { CVector moveForce = point.normal*-5.0f; @@ -3149,9 +3149,9 @@ CWeapon::BlowUpExplosiveThings(CEntity *thing) object->m_vecMoveSpeed.x += float((CGeneral::GetRandomNumber()&255) - 128) * 0.0002f; object->m_vecMoveSpeed.y += float((CGeneral::GetRandomNumber()&255) - 128) * 0.0002f; - if ( object->IsStatic()) + if ( object->GetIsStatic()) { - object->bIsStatic = false; + object->SetIsStatic(false); object->AddToMovingList(); } } diff --git a/src/weapons/WeaponType.h b/src/weapons/WeaponType.h index 65d715ec..1220196f 100644 --- a/src/weapons/WeaponType.h +++ b/src/weapons/WeaponType.h @@ -54,7 +54,17 @@ enum eWeaponType }; enum { - TOTAL_WEAPON_SLOTS = 10, + WEAPONSLOT_UNARMED = 0, + WEAPONSLOT_MELEE, + WEAPONSLOT_PROJECTILE, + WEAPONSLOT_HANDGUN, + WEAPONSLOT_SHOTGUN, + WEAPONSLOT_SUBMACHINEGUN, + WEAPONSLOT_RIFLE, + WEAPONSLOT_HEAVY, + WEAPONSLOT_SNIPER, + WEAPONSLOT_OTHER, + TOTAL_WEAPON_SLOTS }; enum eWeaponFire { |